summaryrefslogtreecommitdiffstats
path: root/core/java/android/os/BatteryStats.java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2014-07-11 16:03:36 -0700
committerDianne Hackborn <hackbod@google.com>2014-07-15 14:48:48 -0700
commitfdb1956ff71ff57fcdaafaaeb7f42c19de3d7c2f (patch)
tree5d9736ffd82bd9d37b7bc1e6b09b66cf887f02d7 /core/java/android/os/BatteryStats.java
parent213bb2fd4da092826e45aae1a50403ab9c634d70 (diff)
downloadframeworks_base-fdb1956ff71ff57fcdaafaaeb7f42c19de3d7c2f.zip
frameworks_base-fdb1956ff71ff57fcdaafaaeb7f42c19de3d7c2f.tar.gz
frameworks_base-fdb1956ff71ff57fcdaafaaeb7f42c19de3d7c2f.tar.bz2
Fix issue #15681802: Missing RESET:TIME in complete battery histories
But wait, there's more! - Keep track of sync durations in the aggregated stats. - Add events for users that are running and in the foreground. - Rework the activity manager's tracking of stuff using battery in the background to be based on proc stats, which allows it to be better about determing when it should reset its tracking of background work. - Also add tracking of scheduled job execution, like we are doing for syncs. - And once I started hooking battery stats in to JobSchedulerService, I found a few things I couldn't stop myself from changing: (1) make it very explicit that it doesn't start scheduling jobs until we have reached the point in system boot where third party apps are allowed to run, and (2) adjust the various for loops to not use iterators. Change-Id: I69d812e27bcfee9e58a614f0f6b1c7545d7530b1
Diffstat (limited to 'core/java/android/os/BatteryStats.java')
-rw-r--r--core/java/android/os/BatteryStats.java133
1 files changed, 123 insertions, 10 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 7fd1660..aab7b1f 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -120,6 +120,16 @@ public abstract class BatteryStats implements Parcelable {
public static final int PROCESS_STATE = 12;
/**
+ * A constant indicating a sync timer
+ */
+ public static final int SYNC = 13;
+
+ /**
+ * A constant indicating a job timer
+ */
+ public static final int JOB = 14;
+
+ /**
* Include all of the data in the stats, including previously saved data.
*/
public static final int STATS_SINCE_CHARGED = 0;
@@ -157,6 +167,8 @@ public abstract class BatteryStats implements Parcelable {
private static final String FOREGROUND_DATA = "fg";
private static final String STATE_TIME_DATA = "st";
private static final String WAKELOCK_DATA = "wl";
+ private static final String SYNC_DATA = "sy";
+ private static final String JOB_DATA = "jb";
private static final String KERNEL_WAKELOCK_DATA = "kwl";
private static final String WAKEUP_REASON_DATA = "wr";
private static final String NETWORK_DATA = "nt";
@@ -273,6 +285,20 @@ public abstract class BatteryStats implements Parcelable {
public abstract Map<String, ? extends Wakelock> getWakelockStats();
/**
+ * Returns a mapping containing sync statistics.
+ *
+ * @return a Map from Strings to Timer objects.
+ */
+ public abstract Map<String, ? extends Timer> getSyncStats();
+
+ /**
+ * Returns a mapping containing scheduled job statistics.
+ *
+ * @return a Map from Strings to Timer objects.
+ */
+ public abstract Map<String, ? extends Timer> getJobStats();
+
+ /**
* The statistics associated with a particular wake lock.
*/
public static abstract class Wakelock {
@@ -660,13 +686,19 @@ public abstract class BatteryStats implements Parcelable {
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;
- // Event is about an application package that is at the top of the screen.
+ // Event is about active sync operations.
public static final int EVENT_SYNC = 0x0004;
// Events for all additional wake locks aquired/release within a wake block.
// These are not generated by default.
public static final int EVENT_WAKE_LOCK = 0x0005;
+ // Event is about an application executing a scheduled job.
+ public static final int EVENT_JOB = 0x0006;
+ // Events for users running.
+ public static final int EVENT_USER_RUNNING = 0x0007;
+ // Events for foreground user.
+ public static final int EVENT_USER_FOREGROUND = 0x0008;
// Number of event types.
- public static final int EVENT_COUNT = 0x0006;
+ public static final int EVENT_COUNT = 0x0009;
// Mask to extract out only the type part of the event.
public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
@@ -680,6 +712,14 @@ public abstract class BatteryStats implements Parcelable {
public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
public static final int EVENT_WAKE_LOCK_START = EVENT_WAKE_LOCK | EVENT_FLAG_START;
public static final int EVENT_WAKE_LOCK_FINISH = EVENT_WAKE_LOCK | EVENT_FLAG_FINISH;
+ public static final int EVENT_JOB_START = EVENT_JOB | EVENT_FLAG_START;
+ public static final int EVENT_JOB_FINISH = EVENT_JOB | EVENT_FLAG_FINISH;
+ public static final int EVENT_USER_RUNNING_START = EVENT_USER_RUNNING | EVENT_FLAG_START;
+ public static final int EVENT_USER_RUNNING_FINISH = EVENT_USER_RUNNING | EVENT_FLAG_FINISH;
+ public static final int EVENT_USER_FOREGROUND_START =
+ EVENT_USER_FOREGROUND | EVENT_FLAG_START;
+ public static final int EVENT_USER_FOREGROUND_FINISH =
+ EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
// For CMD_EVENT.
public int eventCode;
@@ -1269,11 +1309,11 @@ public abstract class BatteryStats implements Parcelable {
};
public static final String[] HISTORY_EVENT_NAMES = new String[] {
- "null", "proc", "fg", "top", "sync", "wake_lock_in"
+ "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg"
};
public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
- "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl"
+ "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf"
};
/**
@@ -2080,10 +2120,9 @@ public abstract class BatteryStats implements Parcelable {
}
}
- Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
+ Map<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
if (wakelocks.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
- : wakelocks.entrySet()) {
+ for (Map.Entry<String, ? extends Uid.Wakelock> ent : wakelocks.entrySet()) {
Uid.Wakelock wl = ent.getValue();
String linePrefix = "";
sb.setLength(0);
@@ -2105,6 +2144,32 @@ public abstract class BatteryStats implements Parcelable {
}
}
+ Map<String, ? extends Timer> syncs = u.getSyncStats();
+ if (syncs.size() > 0) {
+ for (Map.Entry<String, ? extends Timer> ent : syncs.entrySet()) {
+ Timer timer = ent.getValue();
+ // Convert from microseconds to milliseconds with rounding
+ long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+ int count = timer.getCountLocked(which);
+ if (totalTime != 0) {
+ dumpLine(pw, uid, category, SYNC_DATA, ent.getKey(), totalTime, count);
+ }
+ }
+ }
+
+ Map<String, ? extends Timer> jobs = u.getJobStats();
+ if (jobs.size() > 0) {
+ for (Map.Entry<String, ? extends Timer> ent : jobs.entrySet()) {
+ Timer timer = ent.getValue();
+ // Convert from microseconds to milliseconds with rounding
+ long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+ int count = timer.getCountLocked(which);
+ if (totalTime != 0) {
+ dumpLine(pw, uid, category, JOB_DATA, ent.getKey(), totalTime, count);
+ }
+ }
+ }
+
SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
int NSE = sensors.size();
for (int ise=0; ise<NSE; ise++) {
@@ -2937,8 +3002,7 @@ public abstract class BatteryStats implements Parcelable {
if (wakelocks.size() > 0) {
long totalFull = 0, totalPartial = 0, totalWindow = 0;
int count = 0;
- for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
- : wakelocks.entrySet()) {
+ for (Map.Entry<String, ? extends Uid.Wakelock> ent : wakelocks.entrySet()) {
Uid.Wakelock wl = ent.getValue();
String linePrefix = ": ";
sb.setLength(0);
@@ -2998,6 +3062,56 @@ public abstract class BatteryStats implements Parcelable {
}
}
+ Map<String, ? extends Timer> syncs = u.getSyncStats();
+ if (syncs.size() > 0) {
+ for (Map.Entry<String, ? extends Timer> ent : syncs.entrySet()) {
+ Timer timer = ent.getValue();
+ // Convert from microseconds to milliseconds with rounding
+ long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+ int count = timer.getCountLocked(which);
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Sync ");
+ sb.append(ent.getKey());
+ sb.append(": ");
+ if (totalTime != 0) {
+ formatTimeMs(sb, totalTime);
+ sb.append("realtime (");
+ sb.append(count);
+ sb.append(" times)");
+ } else {
+ sb.append("(not used)");
+ }
+ pw.println(sb.toString());
+ uidActivity = true;
+ }
+ }
+
+ Map<String, ? extends Timer> jobs = u.getJobStats();
+ if (syncs.size() > 0) {
+ for (Map.Entry<String, ? extends Timer> ent : jobs.entrySet()) {
+ Timer timer = ent.getValue();
+ // Convert from microseconds to milliseconds with rounding
+ long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+ int count = timer.getCountLocked(which);
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Job ");
+ sb.append(ent.getKey());
+ sb.append(": ");
+ if (totalTime != 0) {
+ formatTimeMs(sb, totalTime);
+ sb.append("realtime (");
+ sb.append(count);
+ sb.append(" times)");
+ } else {
+ sb.append("(not used)");
+ }
+ pw.println(sb.toString());
+ uidActivity = true;
+ }
+ }
+
SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
int NSE = sensors.size();
for (int ise=0; ise<NSE; ise++) {
@@ -3260,7 +3374,6 @@ public abstract class BatteryStats implements Parcelable {
int oldTemp = -1;
int oldVolt = -1;
long lastTime = -1;
- long firstTime = -1;
void reset() {
oldState = oldState2 = 0;