Implement issue #3326435: Battery stats improvements
Keep track of discharge while screen is on vs. off.
Checkin looks like:
5,0,u,dc,1,1,1,0
The last four numbers are, from left:
- Maximum battery drain over time period.
- Minimum battery drain over time period.
- Battery drain while screen was on.
- Battery drain while screen was off.
Change-Id: Ie4026a7cc8aabb2a6d47d03d2e278aa51c2d5ddf
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 7dd5e31..6e6731e 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -132,6 +132,7 @@
private static final String NETWORK_DATA = "nt";
private static final String USER_ACTIVITY_DATA = "ua";
private static final String BATTERY_DATA = "bt";
+ private static final String BATTERY_DISCHARGE_DATA = "dc";
private static final String BATTERY_LEVEL_DATA = "lv";
private static final String WIFI_LOCK_DATA = "wfl";
private static final String MISC_DATA = "m";
@@ -804,6 +805,30 @@
public abstract int getHighDischargeAmountSinceCharge();
/**
+ * Get the amount the battery has discharged while the screen was on,
+ * since the last time power was unplugged.
+ */
+ public abstract int getDischargeAmountScreenOn();
+
+ /**
+ * Get the amount the battery has discharged while the screen was on,
+ * since the last time the device was charged.
+ */
+ public abstract int getDischargeAmountScreenOnSinceCharge();
+
+ /**
+ * Get the amount the battery has discharged while the screen was off,
+ * since the last time power was unplugged.
+ */
+ public abstract int getDischargeAmountScreenOff();
+
+ /**
+ * Get the amount the battery has discharged while the screen was off,
+ * since the last time the device was charged.
+ */
+ public abstract int getDischargeAmountScreenOffSinceCharge();
+
+ /**
* Returns the total, last, or current battery uptime in microseconds.
*
* @param curTime the elapsed realtime in microseconds.
@@ -1098,6 +1123,17 @@
getDischargeCurrentLevel());
}
+ if (which == STATS_SINCE_UNPLUGGED) {
+ dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
+ getDischargeStartLevel()-getDischargeCurrentLevel(),
+ getDischargeStartLevel()-getDischargeCurrentLevel(),
+ getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
+ } else {
+ dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
+ getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
+ getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
+ }
+
if (reqUid < 0) {
Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
if (kernelWakelocks.size() > 0) {
@@ -1454,6 +1490,10 @@
pw.print(prefix); pw.print(" Last discharge cycle end level: ");
pw.println(getDischargeCurrentLevel());
}
+ pw.print(prefix); pw.print(" Amount discharged while screen on: ");
+ pw.println(getDischargeAmountScreenOn());
+ pw.print(prefix); pw.print(" Amount discharged while screen off: ");
+ pw.println(getDischargeAmountScreenOff());
pw.println(" ");
} else {
pw.print(prefix); pw.println(" Device battery use since last full charge");
@@ -1461,6 +1501,10 @@
pw.println(getLowDischargeAmountSinceCharge());
pw.print(prefix); pw.print(" Amount discharged (upper bound): ");
pw.println(getHighDischargeAmountSinceCharge());
+ pw.print(prefix); pw.print(" Amount discharged while screen on: ");
+ pw.println(getDischargeAmountScreenOnSinceCharge());
+ pw.print(prefix); pw.print(" Amount discharged while screen off: ");
+ pw.println(getDischargeAmountScreenOffSinceCharge());
pw.println(" ");
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 284df1e..b682947 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -70,7 +70,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 52;
+ private static final int VERSION = 54;
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -237,6 +237,12 @@
int mDischargeCurrentLevel;
int mLowDischargeAmountSinceCharge;
int mHighDischargeAmountSinceCharge;
+ int mDischargeScreenOnUnplugLevel;
+ int mDischargeScreenOffUnplugLevel;
+ int mDischargeAmountScreenOn;
+ int mDischargeAmountScreenOnSinceCharge;
+ int mDischargeAmountScreenOff;
+ int mDischargeAmountScreenOffSinceCharge;
long mLastWriteTime = 0; // Milliseconds
@@ -1572,6 +1578,11 @@
// Fake a wake lock, so we consider the device waked as long
// as the screen is on.
noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
+
+ // Update discharge amounts.
+ if (mOnBatteryInternal) {
+ updateDischargeScreenLevels(false, true);
+ }
}
}
@@ -1588,6 +1599,11 @@
}
noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
+
+ // Update discharge amounts.
+ if (mOnBatteryInternal) {
+ updateDischargeScreenLevels(true, false);
+ }
}
}
@@ -3910,8 +3926,7 @@
mDischargeStartLevel = 0;
mDischargeUnplugLevel = 0;
mDischargeCurrentLevel = 0;
- mLowDischargeAmountSinceCharge = 0;
- mHighDischargeAmountSinceCharge = 0;
+ initDischarge();
}
public BatteryStatsImpl(Parcel p) {
@@ -3982,6 +3997,15 @@
mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
}
+ void initDischarge() {
+ mLowDischargeAmountSinceCharge = 0;
+ mHighDischargeAmountSinceCharge = 0;
+ mDischargeAmountScreenOn = 0;
+ mDischargeAmountScreenOnSinceCharge = 0;
+ mDischargeAmountScreenOff = 0;
+ mDischargeAmountScreenOffSinceCharge = 0;
+ }
+
public void resetAllStatsLocked() {
mStartCount = 0;
initTimes();
@@ -4018,12 +4042,34 @@
mKernelWakelockStats.clear();
}
- mLowDischargeAmountSinceCharge = 0;
- mHighDischargeAmountSinceCharge = 0;
+ initDischarge();
clearHistoryLocked();
}
+ void updateDischargeScreenLevels(boolean oldScreenOn, boolean newScreenOn) {
+ if (oldScreenOn) {
+ int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
+ if (diff > 0) {
+ mDischargeAmountScreenOn += diff;
+ mDischargeAmountScreenOnSinceCharge += diff;
+ }
+ } else {
+ int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
+ if (diff > 0) {
+ mDischargeAmountScreenOff += diff;
+ mDischargeAmountScreenOffSinceCharge += diff;
+ }
+ }
+ if (newScreenOn) {
+ mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
+ mDischargeScreenOffUnplugLevel = 0;
+ } else {
+ mDischargeScreenOnUnplugLevel = 0;
+ mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
+ }
+ }
+
void setOnBattery(boolean onBattery, int oldStatus, int level) {
synchronized(this) {
boolean doWrite = false;
@@ -4058,6 +4104,15 @@
mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
mDischargeCurrentLevel = mDischargeUnplugLevel = level;
+ if (mScreenOn) {
+ mDischargeScreenOnUnplugLevel = level;
+ mDischargeScreenOffUnplugLevel = 0;
+ } else {
+ mDischargeScreenOnUnplugLevel = 0;
+ mDischargeScreenOffUnplugLevel = level;
+ }
+ mDischargeAmountScreenOn = 0;
+ mDischargeAmountScreenOff = 0;
doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
} else {
updateKernelWakelocksLocked();
@@ -4073,6 +4128,7 @@
mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
}
+ updateDischargeScreenLevels(mScreenOn, mScreenOn);
doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
}
if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
@@ -4361,6 +4417,50 @@
return val;
}
}
+
+ public int getDischargeAmountScreenOn() {
+ synchronized(this) {
+ int val = mDischargeAmountScreenOn;
+ if (mOnBattery && mScreenOn
+ && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
+ val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
+ }
+ return val;
+ }
+ }
+
+ public int getDischargeAmountScreenOnSinceCharge() {
+ synchronized(this) {
+ int val = mDischargeAmountScreenOnSinceCharge;
+ if (mOnBattery && mScreenOn
+ && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
+ val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
+ }
+ return val;
+ }
+ }
+
+ public int getDischargeAmountScreenOff() {
+ synchronized(this) {
+ int val = mDischargeAmountScreenOff;
+ if (mOnBattery && !mScreenOn
+ && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
+ val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
+ }
+ return val;
+ }
+ }
+
+ public int getDischargeAmountScreenOffSinceCharge() {
+ synchronized(this) {
+ int val = mDischargeAmountScreenOffSinceCharge;
+ if (mOnBattery && !mScreenOn
+ && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
+ val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
+ }
+ return val;
+ }
+ }
@Override
public int getCpuSpeedSteps() {
@@ -4667,6 +4767,8 @@
mDischargeCurrentLevel = in.readInt();
mLowDischargeAmountSinceCharge = in.readInt();
mHighDischargeAmountSinceCharge = in.readInt();
+ mDischargeAmountScreenOnSinceCharge = in.readInt();
+ mDischargeAmountScreenOffSinceCharge = in.readInt();
mStartCount++;
@@ -4862,6 +4964,8 @@
out.writeInt(mDischargeCurrentLevel);
out.writeInt(getLowDischargeAmountSinceCharge());
out.writeInt(getHighDischargeAmountSinceCharge());
+ out.writeInt(getDischargeAmountScreenOnSinceCharge());
+ out.writeInt(getDischargeAmountScreenOffSinceCharge());
mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
@@ -5101,6 +5205,10 @@
mDischargeCurrentLevel = in.readInt();
mLowDischargeAmountSinceCharge = in.readInt();
mHighDischargeAmountSinceCharge = in.readInt();
+ mDischargeAmountScreenOn = in.readInt();
+ mDischargeAmountScreenOnSinceCharge = in.readInt();
+ mDischargeAmountScreenOff = in.readInt();
+ mDischargeAmountScreenOffSinceCharge = in.readInt();
mLastWriteTime = in.readLong();
mMobileDataRx[STATS_LAST] = in.readLong();
@@ -5202,6 +5310,10 @@
out.writeInt(mDischargeCurrentLevel);
out.writeInt(mLowDischargeAmountSinceCharge);
out.writeInt(mHighDischargeAmountSinceCharge);
+ out.writeInt(mDischargeAmountScreenOn);
+ out.writeInt(mDischargeAmountScreenOnSinceCharge);
+ out.writeInt(mDischargeAmountScreenOff);
+ out.writeInt(mDischargeAmountScreenOffSinceCharge);
out.writeLong(mLastWriteTime);
out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED));