diff options
5 files changed, 143 insertions, 17 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 2c63be255c0b..959b30946c8a 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -1157,6 +1157,8 @@ public abstract class BatteryStats implements Parcelable { public short batteryTemperature; public char batteryVoltage; + + public int batteryChargeCoulombs; // Constants from SCREEN_BRIGHTNESS_* public static final int STATE_BRIGHTNESS_SHIFT = 0; @@ -1181,6 +1183,8 @@ public abstract class BatteryStats implements Parcelable { public static final int STATE_WIFI_SCAN_FLAG = 1<<27; public static final int STATE_WIFI_RADIO_ACTIVE_FLAG = 1<<26; public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25; + // Do not use, this is used for coulomb delta count. + private static final int STATE_RESERVED_0 = 1<<24; // These are on the lower bits used for the command; if they change // we need to write another int of data. public static final int STATE_SENSOR_ON_FLAG = 1<<23; @@ -1352,6 +1356,7 @@ public abstract class BatteryStats implements Parcelable { bat = (((int)batteryTemperature)&0xffff) | ((((int)batteryVoltage)<<16)&0xffff0000); dest.writeInt(bat); + dest.writeInt(batteryChargeCoulombs); dest.writeInt(states); dest.writeInt(states2); if (wakelockTag != null) { @@ -1380,6 +1385,7 @@ public abstract class BatteryStats implements Parcelable { int bat2 = src.readInt(); batteryTemperature = (short)(bat2&0xffff); batteryVoltage = (char)((bat2>>16)&0xffff); + batteryChargeCoulombs = src.readInt(); states = src.readInt(); states2 = src.readInt(); if ((bat&0x10000000) != 0) { @@ -1419,6 +1425,7 @@ public abstract class BatteryStats implements Parcelable { batteryPlugType = 0; batteryTemperature = 0; batteryVoltage = 0; + batteryChargeCoulombs = 0; states = 0; states2 = 0; wakelockTag = null; @@ -1446,6 +1453,7 @@ public abstract class BatteryStats implements Parcelable { batteryPlugType = o.batteryPlugType; batteryTemperature = o.batteryTemperature; batteryVoltage = o.batteryVoltage; + batteryChargeCoulombs = o.batteryChargeCoulombs; states = o.states; states2 = o.states2; if (o.wakelockTag != null) { @@ -1477,6 +1485,7 @@ public abstract class BatteryStats implements Parcelable { && batteryPlugType == o.batteryPlugType && batteryTemperature == o.batteryTemperature && batteryVoltage == o.batteryVoltage + && batteryChargeCoulombs == o.batteryChargeCoulombs && states == o.states && states2 == o.states2 && currentTime == o.currentTime; @@ -4527,6 +4536,7 @@ public abstract class BatteryStats implements Parcelable { int oldPlug = -1; int oldTemp = -1; int oldVolt = -1; + int oldCharge = -1; long lastTime = -1; void reset() { @@ -4537,6 +4547,7 @@ public abstract class BatteryStats implements Parcelable { oldPlug = -1; oldTemp = -1; oldVolt = -1; + oldCharge = -1; } public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin, @@ -4698,6 +4709,11 @@ public abstract class BatteryStats implements Parcelable { pw.print(checkin ? ",Bv=" : " volt="); pw.print(oldVolt); } + if (oldCharge != rec.batteryChargeCoulombs) { + oldCharge = rec.batteryChargeCoulombs; + pw.print(checkin ? ",Bcc=" : " charge="); + pw.print(oldCharge); + } printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag, HISTORY_STATE_DESCRIPTIONS, !checkin); printBitDescriptions(pw, oldState2, rec.states2, null, diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index a2a135b59a73..42b89d53c9b6 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -122,7 +122,8 @@ interface IBatteryStats { void noteNetworkInterfaceType(String iface, int type); void noteNetworkStatsEnabled(); void noteDeviceIdleMode(int mode, String activeReason, int activeUid); - void setBatteryState(int status, int health, int plugType, int level, int temp, int volt); + void setBatteryState(int status, int health, int plugType, int level, int temp, int volt, + int chargeCount); long getAwakeTimeBattery(); long getAwakeTimePlugged(); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 5358d78e1b02..b76221fadd29 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 = 143 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 144 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -2089,27 +2089,111 @@ public class BatteryStatsImpl extends BatteryStats { tag.poolIdx = index; } + /* + The history delta format uses flags to denote further data in subsequent ints in the parcel. + + There is always the first token, which may contain the delta time, or an indicator of + the length of the time (int or long) following this token. + + First token: always present, + 31 23 15 7 0 + █M|L|K|J|I|H|G|F█E|D|C|B|A|T|T|T█T|T|T|T|T|T|T|T█T|T|T|T|T|T|T|T█ + + T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately + follows containing the time, and 0x7ffff indicates a long immediately follows with the + delta time. + A: battery level changed and an int follows with battery data. + B: state changed and an int follows with state change data. + C: state2 has changed and an int follows with state2 change data. + D: wakelock/wakereason has changed and an wakelock/wakereason struct follows. + E: event data has changed and an event struct follows. + F: battery charge in coulombs has changed and an int with the charge follows. + G: state flag denoting that the mobile radio was active. + H: state flag denoting that the wifi radio was active. + I: state flag denoting that a wifi scan occurred. + J: state flag denoting that a wifi full lock was held. + K: state flag denoting that the gps was on. + L: state flag denoting that a wakelock was held. + M: state flag denoting that the cpu was running. + + Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows + with the time delta. + + Battery level int: if A in the first token is set, + 31 23 15 7 0 + █L|L|L|L|L|L|L|T█T|T|T|T|T|T|T|T█T|V|V|V|V|V|V|V█V|V|V|V|V|V|V|D█ + + D: indicates that extra history details follow. + V: the battery voltage. + T: the battery temperature. + L: the battery level (out of 100). + + State change int: if B in the first token is set, + 31 23 15 7 0 + █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █ + + A: wifi multicast was on. + B: battery was plugged in. + C: screen was on. + D: phone was scanning for signal. + E: audio was on. + F: a sensor was active. + + State2 change int: if C in the first token is set, + 31 23 15 7 0 + █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█ + + A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}. + B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4. + C: a bluetooth scan was active. + D: the camera was active. + E: bluetooth was on. + F: a phone call was active. + G: the device was charging. + H: 2 bits indicating the device-idle (doze) state: off, light, full + I: the flashlight was on. + J: wifi was on. + K: wifi was running. + L: video was playing. + M: power save mode was on. + + Wakelock/wakereason struct: if D in the first token is set, + TODO(adamlesinski): describe wakelock/wakereason struct. + + Event struct: if E in the first token is set, + TODO(adamlesinski): describe the event struct. + + History step details struct: if D in the battery level int is set, + TODO(adamlesinski): describe the history step details struct. + + Battery charge int: if F in the first token is set, an int representing the battery charge + in coulombs follows. + */ + // Part of initial delta int that specifies the time delta. static final int DELTA_TIME_MASK = 0x7ffff; static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. // Flag in delta int: a new battery level int follows. - static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; + static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; // Flag in delta int: a new full state and battery status int follows. - static final int DELTA_STATE_FLAG = 0x00100000; + static final int DELTA_STATE_FLAG = 0x00100000; // Flag in delta int: a new full state2 int follows. - static final int DELTA_STATE2_FLAG = 0x00200000; + static final int DELTA_STATE2_FLAG = 0x00200000; // Flag in delta int: contains a wakelock or wakeReason tag. - static final int DELTA_WAKELOCK_FLAG = 0x00400000; + static final int DELTA_WAKELOCK_FLAG = 0x00400000; // Flag in delta int: contains an event description. - static final int DELTA_EVENT_FLAG = 0x00800000; + static final int DELTA_EVENT_FLAG = 0x00800000; + // Flag in delta int: contains a coulomb charge count. + static final int DELTA_BATTERY_CHARGE_COULOMBS_FLAG = 0x01000000; // These upper bits are the frequently changing state bits. - static final int DELTA_STATE_MASK = 0xff000000; + static final int DELTA_STATE_MASK = 0xfe000000; // These are the pieces of battery state that are packed in to the upper bits of // the state int that have been packed in to the first delta int. They must fit - // in DELTA_STATE_MASK. + // in STATE_BATTERY_MASK. + static final int STATE_BATTERY_MASK = 0xff000000; static final int STATE_BATTERY_STATUS_MASK = 0x00000007; static final int STATE_BATTERY_STATUS_SHIFT = 29; static final int STATE_BATTERY_HEALTH_MASK = 0x00000007; @@ -2165,6 +2249,12 @@ public class BatteryStatsImpl extends BatteryStats { if (cur.eventCode != HistoryItem.EVENT_NONE) { firstToken |= DELTA_EVENT_FLAG; } + + final boolean batteryChargeCoulombsChanged = cur.batteryChargeCoulombs + != last.batteryChargeCoulombs; + if (batteryChargeCoulombsChanged) { + firstToken |= DELTA_BATTERY_CHARGE_COULOMBS_FLAG; + } dest.writeInt(firstToken); if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) + " deltaTime=" + deltaTime); @@ -2247,6 +2337,12 @@ public class BatteryStatsImpl extends BatteryStats { mLastHistoryStepDetails = null; } mLastHistoryStepLevel = cur.batteryLevel; + + if (batteryChargeCoulombsChanged) { + if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeCoulombs=" + + cur.batteryChargeCoulombs); + dest.writeInt(cur.batteryChargeCoulombs); + } } private int buildBatteryLevelInt(HistoryItem h) { @@ -2273,7 +2369,7 @@ public class BatteryStatsImpl extends BatteryStats { return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT) | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT) | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT) - | (h.states&(~DELTA_STATE_MASK)); + | (h.states&(~STATE_BATTERY_MASK)); } private void computeHistoryStepDetails(final HistoryStepDetails out, @@ -2412,7 +2508,7 @@ public class BatteryStatsImpl extends BatteryStats { if ((firstToken&DELTA_STATE_FLAG) != 0) { int stateInt = src.readInt(); - cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK)); + cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK)); cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT) & STATE_BATTERY_STATUS_MASK); cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT) @@ -2438,7 +2534,7 @@ public class BatteryStatsImpl extends BatteryStats { + " batteryPlugType=" + cur.batteryPlugType + " states=0x" + Integer.toHexString(cur.states)); } else { - cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK)); + cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK)); } if ((firstToken&DELTA_STATE2_FLAG) != 0) { @@ -2493,6 +2589,10 @@ public class BatteryStatsImpl extends BatteryStats { } else { cur.stepDetails = null; } + + if ((firstToken&DELTA_BATTERY_CHARGE_COULOMBS_FLAG) != 0) { + cur.batteryChargeCoulombs = src.readInt(); + } } @Override @@ -9210,7 +9310,7 @@ public class BatteryStatsImpl extends BatteryStats { public static final int BATTERY_PLUGGED_NONE = 0; public void setBatteryStateLocked(int status, int health, int plugType, int level, - int temp, int volt) { + int temp, int volt, int chargeCount) { final boolean onBattery = plugType == BATTERY_PLUGGED_NONE; final long uptime = mClocks.uptimeMillis(); final long elapsedRealtime = mClocks.elapsedRealtime(); @@ -9254,6 +9354,7 @@ public class BatteryStatsImpl extends BatteryStats { if (mDischargePlugLevel < 0) { mDischargePlugLevel = level; } + if (onBattery != mOnBattery) { mHistoryCur.batteryLevel = (byte)level; mHistoryCur.batteryStatus = (byte)status; @@ -9261,6 +9362,7 @@ public class BatteryStatsImpl extends BatteryStats { mHistoryCur.batteryPlugType = (byte)plugType; mHistoryCur.batteryTemperature = (short)temp; mHistoryCur.batteryVoltage = (char)volt; + mHistoryCur.batteryChargeCoulombs = chargeCount; setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level); } else { boolean changed = false; @@ -9294,6 +9396,11 @@ public class BatteryStatsImpl extends BatteryStats { mHistoryCur.batteryVoltage = (char)volt; changed = true; } + if (chargeCount >= (mHistoryCur.batteryChargeCoulombs+10) + || chargeCount <= (mHistoryCur.batteryChargeCoulombs-10)) { + mHistoryCur.batteryChargeCoulombs = chargeCount; + changed = true; + } long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 87539921be78..6b517210ef31 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -358,7 +358,7 @@ public final class BatteryService extends SystemService { try { mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature, - mBatteryProps.batteryVoltage); + mBatteryProps.batteryVoltage, mBatteryProps.batteryChargeCounter); } catch (RemoteException e) { // Should never happen. } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index c6786defd3f9..d34ec868dc1c 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -974,7 +974,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub @Override public void setBatteryState(final int status, final int health, final int plugType, - final int level, final int temp, final int volt) { + final int level, final int temp, final int volt, final int chargeCount) { enforceCallingPermission(); // BatteryService calls us here and we may update external state. It would be wrong @@ -987,7 +987,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub if (mStats.isOnBattery() == onBattery) { // The battery state has not changed, so we don't need to sync external // stats immediately. - mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt); + mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt, + chargeCount); return; } } @@ -996,7 +997,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub // immediately here, we may not collect the relevant data later. updateExternalStatsSync("battery-state", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL); synchronized (mStats) { - mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt); + mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt, + chargeCount); } } }); |