diff --git a/res/values/strings.xml b/res/values/strings.xml
index 22e542b511c..71bc6adf633 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3604,6 +3604,10 @@
Tablet idle
Phone idle
+
+ Unaccounted
+
+ Over-counted
CPU total
@@ -3635,6 +3639,14 @@
Time on
Time without a signal
+
+ Total battery capacity
+
+ Computed power
+
+ Min real power
+
+ Max real power
Force stop
@@ -3690,6 +3702,13 @@
Battery used by user
+
+ Unaccounted power use
+
+ Over-counted power use
+
+ %d mAh
+
%1$s since unplugged
diff --git a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java b/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
index 8ae940990b7..a02917e00f3 100644
--- a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
+++ b/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
@@ -89,8 +89,11 @@ public class BatteryStatsHelper {
private long mStatsPeriod = 0;
private double mMaxPower = 1;
private double mTotalPower;
+ private double mTotalPowermAh;
private double mWifiPower;
private double mBluetoothPower;
+ private double mMinDrainedPower;
+ private double mMaxDrainedPower;
// How much the apps together have left WIFI running.
private long mAppWifiRunning;
@@ -304,6 +307,22 @@ public class BatteryStatsHelper {
sipper.wifiTxPackets,
};
} break;
+ case UNACCOUNTED:
+ case OVERCOUNTED:
+ {
+ types = new int[] {
+ R.string.usage_type_total_battery_capacity,
+ R.string.usage_type_computed_power,
+ R.string.usage_type_min_actual_power,
+ R.string.usage_type_max_actual_power,
+ };
+ values = new double[] {
+ mPowerProfile.getBatteryCapacity(),
+ mTotalPowermAh,
+ mMinDrainedPower,
+ mMaxDrainedPower,
+ };
+ } break;
default:
{
types = new int[] {
@@ -341,9 +360,35 @@ public class BatteryStatsHelper {
mUserSippers.clear();
mUserPower.clear();
+ mMinDrainedPower = (mStats.getLowDischargeAmountSinceCharge()
+ * mPowerProfile.getBatteryCapacity()) / 100;
+ mMaxDrainedPower = (mStats.getHighDischargeAmountSinceCharge()
+ * mPowerProfile.getBatteryCapacity()) / 100;
+
processAppUsage(includeZeroConsumption);
processMiscUsage();
+ // We have been computing totals in seconds, convert to hours.
+ mTotalPowermAh = mTotalPower / 3600;
+
+ if (true || mStats.getLowDischargeAmountSinceCharge() > 10) {
+ if (mMinDrainedPower > mTotalPowermAh) {
+ double amount = mMinDrainedPower - mTotalPowermAh;
+ if (mMaxPower < amount) {
+ mMaxPower = amount;
+ }
+ addEntryNoTotal(mActivity.getString(R.string.power_unaccounted),
+ DrainType.UNACCOUNTED, 0, R.drawable.ic_power_system, amount * 3600);
+ } else if (mMaxDrainedPower < mTotalPowermAh) {
+ double amount = mTotalPowermAh - mMaxDrainedPower;
+ if (mMaxPower < amount) {
+ mMaxPower = amount;
+ }
+ addEntryNoTotal(mActivity.getString(R.string.power_overcounted),
+ DrainType.OVERCOUNTED, 0, R.drawable.ic_power_system, amount * 3600);
+ }
+ }
+
Collections.sort(mUsageList);
if (mHandler != null) {
@@ -807,6 +852,12 @@ public class BatteryStatsHelper {
private BatterySipper addEntry(String label, DrainType drainType, long time, int iconId,
double power) {
+ mTotalPower += power;
+ return addEntryNoTotal(label, drainType, time, iconId, power);
+ }
+
+ private BatterySipper addEntryNoTotal(String label, DrainType drainType, long time, int iconId,
+ double power) {
if (power > mMaxPower) mMaxPower = power;
mTotalPower += power;
BatterySipper bs = new BatterySipper(mActivity, mRequestQueue, mHandler,
@@ -832,6 +883,14 @@ public class BatteryStatsHelper {
return mTotalPower;
}
+ public double getMinDrainedPower() {
+ return mMinDrainedPower;
+ }
+
+ public double getMaxDrainedPower() {
+ return mMaxDrainedPower;
+ }
+
private void load() {
try {
byte[] data = mBatteryInfo.getStatistics();
diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
index 8d316cfc0c0..79b7c4269d5 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
@@ -67,7 +67,9 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener
BLUETOOTH,
SCREEN,
APP,
- USER
+ USER,
+ UNACCOUNTED,
+ OVERCOUNTED
}
// Note: Must match the sequence of the DrainType
@@ -80,6 +82,8 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener
R.string.battery_desc_display,
R.string.battery_desc_apps,
R.string.battery_desc_users,
+ R.string.battery_desc_unaccounted,
+ R.string.battery_desc_overcounted,
};
public static final int ACTION_DISPLAY_SETTINGS = 1;
@@ -329,6 +333,12 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener
final int percentage = (int) Math.floor(mValues[i]);
value = getActivity().getString(R.string.percentage, percentage);
break;
+ case R.string.usage_type_total_battery_capacity:
+ case R.string.usage_type_computed_power:
+ case R.string.usage_type_min_actual_power:
+ case R.string.usage_type_max_actual_power:
+ value = getActivity().getString(R.string.mah, (long)(mValues[i]));
+ break;
case R.string.usage_type_gps:
mUsesGps = true;
// Fall through
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index dc86b8de210..2c78375d225 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -60,6 +60,8 @@ public class PowerUsageSummary extends PreferenceFragment {
private static final int MENU_HELP = Menu.FIRST + 2;
private PreferenceGroup mAppListGroup;
+ private String mBatteryLevel;
+ private String mBatteryStatus;
private Preference mBatteryStatusPref;
private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
@@ -74,13 +76,8 @@ public class PowerUsageSummary extends PreferenceFragment {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
- String batteryLevel = com.android.settings.Utils.getBatteryPercentage(intent);
- String batteryStatus = com.android.settings.Utils.getBatteryStatus(getResources(),
- intent);
- String batterySummary = context.getResources().getString(
- R.string.power_usage_level_and_status, batteryLevel, batteryStatus);
- mBatteryStatusPref.setTitle(batterySummary);
+ if (Intent.ACTION_BATTERY_CHANGED.equals(action)
+ && updateBatteryStatus(intent)) {
mStatsHelper.clearStats();
refreshStats();
}
@@ -107,8 +104,8 @@ public class PowerUsageSummary extends PreferenceFragment {
@Override
public void onResume() {
super.onResume();
- getActivity().registerReceiver(mBatteryInfoReceiver,
- new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ updateBatteryStatus(getActivity().registerReceiver(mBatteryInfoReceiver,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED)));
refreshStats();
}
@@ -194,12 +191,32 @@ public class PowerUsageSummary extends PreferenceFragment {
mAppListGroup.addPreference(notAvailable);
}
+ private boolean updateBatteryStatus(Intent intent) {
+ if (intent != null) {
+ String batteryLevel = com.android.settings.Utils.getBatteryPercentage(intent);
+ String batteryStatus = com.android.settings.Utils.getBatteryStatus(getResources(),
+ intent);
+ if (!batteryLevel.equals(mBatteryLevel) || !batteryStatus.equals(mBatteryStatus)) {
+ mBatteryLevel = batteryLevel;
+ mBatteryStatus = batteryStatus;
+ return true;
+ }
+ }
+ return false;
+ }
+
private void refreshStats() {
mAppListGroup.removeAll();
mAppListGroup.setOrderingAsAdded(false);
mBatteryStatusPref.setOrder(-2);
+ if (mBatteryLevel != null && mBatteryStatus != null) {
+ String batterySummary = getActivity().getResources().getString(
+ R.string.power_usage_level_and_status, mBatteryLevel, mBatteryStatus);
+ mBatteryStatusPref.setTitle(batterySummary);
+ }
mAppListGroup.addPreference(mBatteryStatusPref);
+
BatteryHistoryPreference hist = new BatteryHistoryPreference(
getActivity(), mStatsHelper.getStats());
hist.setOrder(-1);