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);