Merge "More code cleaning"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 22e542b..71bc6ad 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3604,6 +3604,10 @@
     <string name="power_idle" product="tablet">Tablet idle</string>
     <!-- Label for power consumed when Idle -->
     <string name="power_idle" product="default">Phone idle</string>
+    <!-- Label for power that we aren't able to account for -->
+    <string name="power_unaccounted">Unaccounted</string>
+    <!-- Label for power that we computed too much for -->
+    <string name="power_overcounted">Over-counted</string>
 
     <!-- Label for CPU usage time -->
     <string name="usage_type_cpu">CPU total</string>
@@ -3635,6 +3639,14 @@
     <string name="usage_type_on_time">Time on</string>
     <!-- Label for time that there was no cell coverage -->
     <string name="usage_type_no_coverage">Time without a signal</string>
+    <!-- Label for the total power capacity of the device's battery -->
+    <string name="usage_type_total_battery_capacity">Total battery capacity</string>
+    <!-- Label for amount of power use that was computed -->
+    <string name="usage_type_computed_power">Computed power</string>
+    <!-- Label for minimum amount of actual power use -->
+    <string name="usage_type_min_actual_power">Min real power</string>
+    <!-- Label for maximum amount of power use -->
+    <string name="usage_type_max_actual_power">Max real power</string>
     <!-- Label for force stop action -->
     <string name="battery_action_stop">Force stop</string>
     <!-- Label for app details action -->
@@ -3690,6 +3702,13 @@
     <!-- [CHAR LIMIT=50] Description for power consumed by users -->
     <string name="battery_desc_users">Battery used by user</string>
 
+    <!-- [CHAR LIMIT=50] Description for unaccounted power use -->
+    <string name="battery_desc_unaccounted">Unaccounted power use</string>
+    <!-- [CHAR LIMIT=50] Description for over-counted power use -->
+    <string name="battery_desc_overcounted">Over-counted power use</string>
+    <!-- Representation of a mAh value. [CHAR LIMIT=NONE] -->
+    <string name="mah"><xliff:g id="number" example="30">%d</xliff:g> mAh</string>
+
     <!-- Menu label for viewing battery usage since unplugged -->
     <string name="menu_stats_unplugged"><xliff:g id="unplugged">%1$s</xliff:g> since unplugged</string>
     <!-- Menu label for viewing battery usage since unplugged -->
diff --git a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java b/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
index 8ae9409..a02917e 100644
--- a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
+++ b/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
@@ -89,8 +89,11 @@
     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 @@
                     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 @@
         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 @@
 
     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 @@
         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 8d316cf..79b7c42 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
@@ -67,7 +67,9 @@
         BLUETOOTH,
         SCREEN,
         APP,
-        USER
+        USER,
+        UNACCOUNTED,
+        OVERCOUNTED
     }
 
     // Note: Must match the sequence of the DrainType
@@ -80,6 +82,8 @@
         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 @@
                         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 dc86b8d..2c78375 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -60,6 +60,8 @@
     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 @@
         @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 @@
     @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 @@
         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);