summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2014-02-07 13:01:07 -0800
committerDianne Hackborn <hackbod@google.com>2014-02-07 13:45:01 -0800
commiteaf2ac464b1cd741d7d0fe700771b1b7c00ddb29 (patch)
tree713aa82660964bf18afdc6067f60f1d3663b73ec /core
parent6eb0fdb99bc09210bea4df054a9c8a05daea3d1b (diff)
downloadframeworks_base-eaf2ac464b1cd741d7d0fe700771b1b7c00ddb29.zip
frameworks_base-eaf2ac464b1cd741d7d0fe700771b1b7c00ddb29.tar.gz
frameworks_base-eaf2ac464b1cd741d7d0fe700771b1b7c00ddb29.tar.bz2
Battery stats: more events, fixes.
Add new history events for top application package and foreground application packages. Doing this involved a fair amount of improvement to history events. The event code is now separated out to have "start" and "finish" identifies, and we use that to now keep track of which events are active. With that, when resetting the stats, we can spit out all of the currently active events at the front of the new history. Also fixed some problems when I re-arranged the history delta int bits that were conflicting with the packing of the battery status bits. These packing structures are changed to work together correctly. Change-Id: Ic8b815060dd8a50ff4a0a209efc2e1044215cd88
Diffstat (limited to 'core')
-rw-r--r--core/java/android/os/BatteryStats.java70
-rw-r--r--core/java/android/util/SparseBooleanArray.java12
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHelper.java2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java124
4 files changed, 172 insertions, 36 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 4879be6..345ff82 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -551,9 +551,9 @@ public abstract class BatteryStats implements Parcelable {
public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
public static final int STATE_WIFI_SCAN_FLAG = 1<<29;
public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<26;
+ public static final int STATE_WIFI_RUNNING_FLAG = 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_WIFI_RUNNING_FLAG = 1<<24;
public static final int STATE_PHONE_SCANNING_FLAG = 1<<23;
public static final int STATE_AUDIO_ON_FLAG = 1<<22;
public static final int STATE_VIDEO_ON_FLAG = 1<<21;
@@ -572,9 +572,26 @@ public abstract class BatteryStats implements Parcelable {
// The wake lock that was acquired at this point.
public HistoryTag wakelockTag;
- public static final int EVENT_NONE = 0;
- public static final int EVENT_PROC_STARTED = 1;
- public static final int EVENT_PROC_FINISHED = 2;
+ public static final int EVENT_FLAG_START = 0x8000;
+ public static final int EVENT_FLAG_FINISH = 0x4000;
+
+ // No event in this item.
+ public static final int EVENT_NONE = 0x0000;
+ // Event is about a process that is running.
+ public static final int EVENT_PROC = 0x0001;
+ // Event is about an application package that is in the foreground.
+ public static final int EVENT_FOREGROUND = 0x0002;
+ // Event is about an application package that is at the top of the screen.
+ public static final int EVENT_TOP = 0x0003;
+ // Number of event types.
+ public static final int EVENT_COUNT = 0x0004;
+
+ public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
+ public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
+ public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START;
+ public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
+ public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
+ public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
// For CMD_EVENT.
public int eventCode;
@@ -942,6 +959,14 @@ public abstract class BatteryStats implements Parcelable {
SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
};
+ public static final String[] HISTORY_EVENT_NAMES = new String[] {
+ "null", "proc", "fg", "top"
+ };
+
+ public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
+ "Nl", "Pr", "Fg", "Tp"
+ };
+
/**
* Returns the time in microseconds that wifi has been on while the device was
* running on battery.
@@ -2497,6 +2522,9 @@ public abstract class BatteryStats implements Parcelable {
case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
pw.print(checkin ? "f" : "failure");
break;
+ case BatteryManager.BATTERY_HEALTH_COLD:
+ pw.print(checkin ? "c" : "cold");
+ break;
default:
pw.print(oldHealth);
break;
@@ -2536,25 +2564,23 @@ public abstract class BatteryStats implements Parcelable {
printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
HISTORY_STATE_DESCRIPTIONS, !checkin);
if (rec.eventCode != HistoryItem.EVENT_NONE) {
- switch (rec.eventCode) {
- case HistoryItem.EVENT_PROC_STARTED:
- pw.print(checkin ? ",PrSt=" : " procstart=");
- break;
- case HistoryItem.EVENT_PROC_FINISHED:
- pw.print(checkin ? ",PrFn=" : " procfin=");
- break;
- default:
- if (checkin) {
- pw.print(",?cmd_");
- pw.print(rec.eventCode);
- pw.print("=");
- } else {
- pw.print(" cmd_");
- pw.print(rec.eventCode);
- pw.print("=");
- }
- break;
+ pw.print(checkin ? "," : " ");
+ if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
+ pw.print("+");
+ } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
+ pw.print("-");
}
+ String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
+ : HISTORY_EVENT_NAMES;
+ int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
+ | HistoryItem.EVENT_FLAG_FINISH);
+ if (idx >= 0 && idx < eventNames.length) {
+ pw.print(eventNames[idx]);
+ } else {
+ pw.print(checkin ? "Ev" : "event");
+ pw.print(idx);
+ }
+ pw.print("=");
if (checkin) {
pw.print(rec.eventTag.poolIdx);
} else {
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index 905dcb0..f59ef0f6d 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -115,6 +115,13 @@ public class SparseBooleanArray implements Cloneable {
}
}
+ /** @hide */
+ public void removeAt(int index) {
+ System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+ System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1));
+ mSize--;
+ }
+
/**
* Adds a mapping from the specified key to the specified value,
* replacing the previous mapping from the specified key if there
@@ -191,6 +198,11 @@ public class SparseBooleanArray implements Cloneable {
return mValues[index];
}
+ /** @hide */
+ public void setValueAt(int index, boolean value) {
+ mValues[index] = value;
+ }
+
/**
* Returns the index for which {@link #keyAt} would return the
* specified key, or a negative number if the specified
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index e7e8006..c22a5e9 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -54,7 +54,7 @@ import java.util.Map;
*/
public class BatteryStatsHelper {
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private static final String TAG = BatteryStatsHelper.class.getSimpleName();
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 21d2e52..82dcbdb 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -45,6 +45,7 @@ import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.TimeUtils;
@@ -77,7 +78,7 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public final class BatteryStatsImpl extends BatteryStats {
private static final String TAG = "BatteryStatsImpl";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private static final boolean DEBUG_HISTORY = false;
private static final boolean USE_OLD_HISTORY = false; // for debugging.
@@ -87,7 +88,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 77 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 79 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -178,6 +179,9 @@ public final class BatteryStatsImpl extends BatteryStats {
boolean mShuttingDown;
+ HashMap<String, SparseBooleanArray>[] mActiveEvents
+ = (HashMap<String, SparseBooleanArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
+
long mHistoryBaseTime;
boolean mHaveBatteryLevel = false;
boolean mRecordingHistory = true;
@@ -1521,15 +1525,25 @@ public final class BatteryStatsImpl extends BatteryStats {
static final int DELTA_TIME_INT = 0xffffe; // The delta is a following int
static final int DELTA_TIME_ABS = 0xffffd; // Following is an entire abs update.
// Flag in delta int: a new battery level int follows.
- static final int DELTA_BATTERY_LEVEL_FLAG = 0x00400000;
+ static final int DELTA_BATTERY_LEVEL_FLAG = 0x00100000;
// Flag in delta int: a new full state and battery status int follows.
- static final int DELTA_STATE_FLAG = 0x00800000;
+ static final int DELTA_STATE_FLAG = 0x00200000;
// Flag in delta int: contains a wakelock tag.
- static final int DELTA_WAKELOCK_FLAG = 0x01000000;
+ static final int DELTA_WAKELOCK_FLAG = 0x00400000;
// Flag in delta int: contains an event description.
- static final int DELTA_EVENT_FLAG = 0x02000000;
+ static final int DELTA_EVENT_FLAG = 0x00800000;
// These upper bits are the frequently changing state bits.
- static final int DELTA_STATE_MASK = 0xfc000000;
+ static final int DELTA_STATE_MASK = 0xff000000;
+
+ // 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.
+ static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
+ static final int STATE_BATTERY_STATUS_SHIFT = 29;
+ static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
+ static final int STATE_BATTERY_HEALTH_SHIFT = 26;
+ static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
+ static final int STATE_BATTERY_PLUG_SHIFT = 24;
public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
@@ -1620,9 +1634,17 @@ public final class BatteryStatsImpl extends BatteryStats {
}
private int buildStateInt(HistoryItem h) {
- return ((((int)h.batteryStatus)<<28)&0xf0000000)
- | ((((int)h.batteryHealth)<<24)&0x0f000000)
- | ((((int)h.batteryPlugType)<<22)&0x00c00000)
+ int plugType = 0;
+ if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
+ plugType = 1;
+ } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
+ plugType = 2;
+ } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
+ plugType = 3;
+ }
+ 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));
}
@@ -1670,9 +1692,23 @@ public final 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.batteryStatus = (byte)((stateInt>>28)&0xf);
- cur.batteryHealth = (byte)((stateInt>>24)&0xf);
- cur.batteryPlugType = (byte)((stateInt>>22)&0x3);
+ cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
+ & STATE_BATTERY_STATUS_MASK);
+ cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
+ & STATE_BATTERY_HEALTH_MASK);
+ cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
+ & STATE_BATTERY_PLUG_MASK);
+ switch (cur.batteryPlugType) {
+ case 1:
+ cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
+ break;
+ case 2:
+ cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
+ break;
+ case 3:
+ cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
+ break;
+ }
cur.numReadInts += 1;
if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
+ Integer.toHexString(stateInt)
@@ -1968,6 +2004,45 @@ public final class BatteryStatsImpl extends BatteryStats {
public void noteEventLocked(int code, String name, int uid) {
uid = mapUid(uid);
+ if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
+ int idx = code&~HistoryItem.EVENT_FLAG_START;
+ HashMap<String, SparseBooleanArray> active = mActiveEvents[idx];
+ if (active == null) {
+ active = new HashMap<String, SparseBooleanArray>();
+ mActiveEvents[idx] = active;
+ }
+ SparseBooleanArray uids = active.get(name);
+ if (uids == null) {
+ uids = new SparseBooleanArray();
+ active.put(name, uids);
+ }
+ if (uids.get(uid)) {
+ // Already set, nothing to do!
+ return;
+ }
+ uids.put(uid, true);
+ } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
+ int idx = code&~HistoryItem.EVENT_FLAG_FINISH;
+ HashMap<String, SparseBooleanArray> active = mActiveEvents[idx];
+ if (active == null) {
+ // not currently active, nothing to do.
+ return;
+ }
+ SparseBooleanArray uids = active.get(name);
+ if (uids == null) {
+ // not currently active, nothing to do.
+ return;
+ }
+ idx = uids.indexOfKey(uid);
+ if (idx < 0 || !uids.valueAt(idx)) {
+ // not currently active, nothing to do.
+ return;
+ }
+ uids.removeAt(idx);
+ if (uids.size() <= 0) {
+ active.remove(name);
+ }
+ }
addHistoryEventLocked(SystemClock.elapsedRealtime(), code, name, uid);
}
@@ -5125,6 +5200,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mDischargeAmountScreenOn = 0;
mDischargeAmountScreenOff = 0;
}
+ initActiveHistoryEventsLocked(mSecRealtime);
}
private void resetAllStatsLocked() {
@@ -5172,6 +5248,23 @@ public final class BatteryStatsImpl extends BatteryStats {
clearHistoryLocked();
}
+ private void initActiveHistoryEventsLocked(long nowRealtime) {
+ for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
+ HashMap<String, SparseBooleanArray> active = mActiveEvents[i];
+ if (active == null) {
+ continue;
+ }
+ for (HashMap.Entry<String, SparseBooleanArray> ent : active.entrySet()) {
+ SparseBooleanArray uids = ent.getValue();
+ for (int j=0; j<uids.size(); j++) {
+ if (uids.valueAt(j)) {
+ addHistoryEventLocked(nowRealtime, i, ent.getKey(), uids.keyAt(j));
+ }
+ }
+ }
+ }
+ }
+
void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
if (oldScreenOn) {
int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
@@ -5221,12 +5314,14 @@ public final class BatteryStatsImpl extends BatteryStats {
// battery was last full, or the level is at 100, or
// we have gone through a significant charge (from a very low
// level to a now very high level).
+ boolean reset = false;
if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
|| level >= 90
|| (mDischargeCurrentLevel < 20 && level >= 80)) {
doWrite = true;
resetAllStatsLocked();
mDischargeStartLevel = level;
+ reset = true;
}
pullPendingStateUpdatesLocked();
mHistoryCur.batteryLevel = (byte)level;
@@ -5249,6 +5344,9 @@ public final class BatteryStatsImpl extends BatteryStats {
mDischargeAmountScreenOn = 0;
mDischargeAmountScreenOff = 0;
doUnplugLocked(realtime, mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
+ if (reset) {
+ initActiveHistoryEventsLocked(mSecRealtime);
+ }
} else {
pullPendingStateUpdatesLocked();
mHistoryCur.batteryLevel = (byte)level;