BatteryStats: Keep track of coulomb counter
Bug:27174034
Change-Id: Ica66817faa20b9788536f28f0e593483f033904b
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 2c63be2..959b309 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1157,6 +1157,8 @@
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 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 @@
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 @@
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 @@
batteryPlugType = 0;
batteryTemperature = 0;
batteryVoltage = 0;
+ batteryChargeCoulombs = 0;
states = 0;
states2 = 0;
wakelockTag = null;
@@ -1446,6 +1453,7 @@
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 @@
&& 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 @@
int oldPlug = -1;
int oldTemp = -1;
int oldVolt = -1;
+ int oldCharge = -1;
long lastTime = -1;
void reset() {
@@ -4537,6 +4547,7 @@
oldPlug = -1;
oldTemp = -1;
oldVolt = -1;
+ oldCharge = -1;
}
public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
@@ -4698,6 +4709,11 @@
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 a2a135b..42b89d5 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -122,7 +122,8 @@
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 5358d78..b76221f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -108,7 +108,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
+ " 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 @@
} else {
cur.stepDetails = null;
}
+
+ if ((firstToken&DELTA_BATTERY_CHARGE_COULOMBS_FLAG) != 0) {
+ cur.batteryChargeCoulombs = src.readInt();
+ }
}
@Override
@@ -9210,7 +9310,7 @@
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 @@
if (mDischargePlugLevel < 0) {
mDischargePlugLevel = level;
}
+
if (onBattery != mOnBattery) {
mHistoryCur.batteryLevel = (byte)level;
mHistoryCur.batteryStatus = (byte)status;
@@ -9261,6 +9362,7 @@
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 @@
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);