From 3ee3f63eb88741bb726c1481387ccf8a46fb57fb Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Wed, 8 Jun 2016 13:55:55 -0700 Subject: [PATCH] BatteryStats: Record fine grained battery discharge For devices that report battery discharge via a coulomb counter, record how much of the battery was discharged while the screen was on/off. Bug:28743761 Change-Id: Ie2d1708864352029ff466c1fed14fc057e19b93b --- core/java/android/os/BatteryStats.java | 53 +++++++++++++++++++++- .../com/android/internal/os/BatteryStatsImpl.java | 50 ++++++++++++++++---- 2 files changed, 94 insertions(+), 9 deletions(-) diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index ea5ae32e8244..93cf8314076b 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -2371,6 +2371,20 @@ public abstract class BatteryStats implements Parcelable { }; /** + * Return the counter keeping track of the amount of battery discharge while the screen was off, + * measured in micro-Ampere-hours. This will be non-zero only if the device's battery has + * a coulomb counter. + */ + public abstract LongCounter getDischargeScreenOffCoulombCounter(); + + /** + * Return the counter keeping track of the amount of battery discharge measured in + * micro-Ampere-hours. This will be non-zero only if the device's battery has + * a coulomb counter. + */ + public abstract LongCounter getDischargeCoulombCounter(); + + /** * Return the array of discharge step durations. */ public abstract LevelStepTracker getDischargeLevelStepTracker(); @@ -2805,6 +2819,9 @@ public abstract class BatteryStats implements Parcelable { rawRealtime, which); final int connChanges = getNumConnectivityChange(which); final long phoneOnTime = getPhoneOnTime(rawRealtime, which); + final long dischargeCount = getDischargeCoulombCounter().getCountLocked(which); + final long dischargeScreenOffCount = getDischargeScreenOffCoulombCounter() + .getCountLocked(which); final StringBuilder sb = new StringBuilder(128); @@ -2819,7 +2836,8 @@ public abstract class BatteryStats implements Parcelable { whichBatteryRealtime / 1000, whichBatteryUptime / 1000, totalRealtime / 1000, totalUptime / 1000, getStartClockTime(), - whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000); + whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000, + dischargeCount / 1000, dischargeScreenOffCount / 1000); // Calculate wakelock times across all uids. long fullWakeLockTimeTotal = 0; @@ -3371,6 +3389,39 @@ public abstract class BatteryStats implements Parcelable { formatTimeMs(sb, chargeTimeRemaining / 1000); pw.println(sb.toString()); } + + final LongCounter dischargeCounter = getDischargeCoulombCounter(); + final long dischargeCount = dischargeCounter.getCountLocked(which); + if (dischargeCount >= 0) { + sb.setLength(0); + sb.append(prefix); + sb.append(" Discharge: "); + sb.append(BatteryStatsHelper.makemAh(dischargeCount / 1000.0)); + sb.append(" mAh"); + pw.println(sb.toString()); + } + + final LongCounter dischargeScreenOffCounter = getDischargeScreenOffCoulombCounter(); + final long dischargeScreenOffCount = dischargeScreenOffCounter.getCountLocked(which); + if (dischargeScreenOffCount >= 0) { + sb.setLength(0); + sb.append(prefix); + sb.append(" Screen off discharge: "); + sb.append(BatteryStatsHelper.makemAh(dischargeScreenOffCount / 1000.0)); + sb.append(" mAh"); + pw.println(sb.toString()); + } + + final long dischargeScreenOnCount = dischargeCount - dischargeScreenOffCount; + if (dischargeScreenOnCount >= 0) { + sb.setLength(0); + sb.append(prefix); + sb.append(" Screen on discharge: "); + sb.append(BatteryStatsHelper.makemAh(dischargeScreenOnCount / 1000.0)); + sb.append(" mAh"); + pw.println(sb.toString()); + } + pw.print(" Start clock time: "); pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString()); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 8b0235249436..7fb178713b95 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -108,7 +108,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 144 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 145 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -509,6 +509,9 @@ public class BatteryStatsImpl extends BatteryStats { int mDischargeAmountScreenOff; int mDischargeAmountScreenOffSinceCharge; + private LongSamplingCounter mDischargeScreenOffCounter; + private LongSamplingCounter mDischargeCounter; + static final int MAX_LEVEL_STEPS = 200; int mInitStepMode = 0; @@ -565,6 +568,16 @@ public class BatteryStatsImpl extends BatteryStats { return mWakeupReasonStats; } + @Override + public LongCounter getDischargeScreenOffCoulombCounter() { + return mDischargeScreenOffCounter; + } + + @Override + public LongCounter getDischargeCoulombCounter() { + return mDischargeCounter; + } + public BatteryStatsImpl() { this(new SystemClocks()); } @@ -912,7 +925,6 @@ public class BatteryStatsImpl extends BatteryStats { final TimeBase mTimeBase; long mCount; long mLoadedCount; - long mLastCount; long mUnpluggedCount; long mPluggedCount; @@ -921,7 +933,6 @@ public class BatteryStatsImpl extends BatteryStats { mPluggedCount = in.readLong(); mCount = mPluggedCount; mLoadedCount = in.readLong(); - mLastCount = 0; mUnpluggedCount = in.readLong(); timeBase.add(this); } @@ -949,20 +960,19 @@ public class BatteryStatsImpl extends BatteryStats { } public long getCountLocked(int which) { - long val = mCount; + long val = mTimeBase.isRunning() ? mCount : mPluggedCount; if (which == STATS_SINCE_UNPLUGGED) { val -= mUnpluggedCount; } else if (which != STATS_SINCE_CHARGED) { val -= mLoadedCount; } - return val; } @Override public void logState(Printer pw, String prefix) { pw.println(prefix + "mCount=" + mCount - + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount + + " mLoadedCount=" + mLoadedCount + " mUnpluggedCount=" + mUnpluggedCount + " mPluggedCount=" + mPluggedCount); } @@ -976,7 +986,7 @@ public class BatteryStatsImpl extends BatteryStats { */ void reset(boolean detachIfReset) { mCount = 0; - mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0; + mLoadedCount = mPluggedCount = mUnpluggedCount = 0; if (detachIfReset) { detach(); } @@ -993,7 +1003,6 @@ public class BatteryStatsImpl extends BatteryStats { void readSummaryFromParcelLocked(Parcel in) { mLoadedCount = in.readLong(); mCount = mLoadedCount; - mLastCount = 0; mUnpluggedCount = mPluggedCount = mLoadedCount; } } @@ -7566,6 +7575,8 @@ public class BatteryStatsImpl extends BatteryStats { mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase); mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); + mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); + mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); mOnBattery = mOnBatteryInternal = false; long uptime = mClocks.uptimeMillis() * 1000; long realtime = mClocks.elapsedRealtime() * 1000; @@ -8123,6 +8134,8 @@ public class BatteryStatsImpl extends BatteryStats { mDischargeAmountScreenOffSinceCharge = 0; mDischargeStepTracker.init(); mChargeStepTracker.init(); + mDischargeScreenOffCounter.reset(false); + mDischargeCounter.reset(false); } public void resetAllStatsCmdLocked() { @@ -9327,6 +9340,7 @@ public class BatteryStatsImpl extends BatteryStats { mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; mHistoryCur.batteryStatus = (byte)status; mHistoryCur.batteryLevel = (byte)level; + mHistoryCur.batteryChargeUAh = chargeUAh; mMaxChargeStepLevel = mMinDischargeStepLevel = mLastChargeStepLevel = mLastDischargeStepLevel = level; mLastChargingStateLevel = level; @@ -9358,6 +9372,12 @@ public class BatteryStatsImpl extends BatteryStats { mHistoryCur.batteryPlugType = (byte)plugType; mHistoryCur.batteryTemperature = (short)temp; mHistoryCur.batteryVoltage = (char)volt; + if (chargeUAh < mHistoryCur.batteryChargeUAh) { + // Only record discharges + final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; + mDischargeCounter.addCountLocked(chargeDiff); + mDischargeScreenOffCounter.addCountLocked(chargeDiff); + } mHistoryCur.batteryChargeUAh = chargeUAh; setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level); } else { @@ -9394,6 +9414,12 @@ public class BatteryStatsImpl extends BatteryStats { } if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10) || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) { + if (chargeUAh < mHistoryCur.batteryChargeUAh) { + // Only record discharges + final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; + mDischargeCounter.addCountLocked(chargeDiff); + mDischargeScreenOffCounter.addCountLocked(chargeDiff); + } mHistoryCur.batteryChargeUAh = chargeUAh; changed = true; } @@ -10075,6 +10101,8 @@ public class BatteryStatsImpl extends BatteryStats { mChargeStepTracker.readFromParcel(in); mDailyDischargeStepTracker.readFromParcel(in); mDailyChargeStepTracker.readFromParcel(in); + mDischargeCounter.readSummaryFromParcelLocked(in); + mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); int NPKG = in.readInt(); if (NPKG > 0) { mDailyPackageChanges = new ArrayList<>(NPKG); @@ -10423,6 +10451,8 @@ public class BatteryStatsImpl extends BatteryStats { out.writeInt(getDischargeAmountScreenOffSinceCharge()); mDischargeStepTracker.writeToParcel(out); mChargeStepTracker.writeToParcel(out); + mDischargeCounter.writeSummaryFromParcelLocked(out); + mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); mDailyDischargeStepTracker.writeToParcel(out); mDailyChargeStepTracker.writeToParcel(out); if (mDailyPackageChanges != null) { @@ -10880,6 +10910,8 @@ public class BatteryStatsImpl extends BatteryStats { mDischargeAmountScreenOffSinceCharge = in.readInt(); mDischargeStepTracker.readFromParcel(in); mChargeStepTracker.readFromParcel(in); + mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); + mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); mLastWriteTime = in.readLong(); mKernelWakelockStats.clear(); @@ -11028,6 +11060,8 @@ public class BatteryStatsImpl extends BatteryStats { out.writeInt(mDischargeAmountScreenOffSinceCharge); mDischargeStepTracker.writeToParcel(out); mChargeStepTracker.writeToParcel(out); + mDischargeCounter.writeToParcel(out); + mDischargeScreenOffCounter.writeToParcel(out); out.writeLong(mLastWriteTime); if (inclUids) { -- 2.11.0