summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/BatteryStats.java47
-rw-r--r--core/java/android/util/TimeUtils.java181
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java14
3 files changed, 158 insertions, 84 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 9fe6e01..a857e58 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -216,6 +216,11 @@ public abstract class BatteryStats implements Parcelable {
public abstract Map<Integer, ? extends Sensor> getSensorStats();
/**
+ * Returns a mapping containing active process data.
+ */
+ public abstract SparseArray<? extends Pid> getPidStats();
+
+ /**
* Returns a mapping containing process statistics.
*
* @return a Map from Strings to Uid.Proc objects.
@@ -286,6 +291,11 @@ public abstract class BatteryStats implements Parcelable {
public abstract Timer getSensorTime();
}
+ public class Pid {
+ public long mWakeSum;
+ public long mWakeStart;
+ }
+
/**
* The statistics associated with a particular process.
*/
@@ -521,6 +531,11 @@ public abstract class BatteryStats implements Parcelable {
public abstract HistoryItem getHistory();
/**
+ * Return the base time offset for the battery history.
+ */
+ public abstract long getHistoryBaseTime();
+
+ /**
* Returns the number of times the device has been started.
*/
public abstract int getStartCount();
@@ -1673,6 +1688,7 @@ public abstract class BatteryStats implements Parcelable {
HistoryItem rec = getHistory();
if (rec != null) {
pw.println("Battery History:");
+ long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
int oldState = 0;
int oldStatus = -1;
int oldHealth = -1;
@@ -1681,7 +1697,7 @@ public abstract class BatteryStats implements Parcelable {
int oldVolt = -1;
while (rec != null) {
pw.print(" ");
- pw.print(rec.time);
+ TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
pw.print(" ");
if (rec.cmd == HistoryItem.CMD_START) {
pw.println(" START");
@@ -1784,6 +1800,35 @@ public abstract class BatteryStats implements Parcelable {
oldState = rec.states;
rec = rec.next;
}
+ pw.println("");
+ }
+
+ SparseArray<? extends Uid> uidStats = getUidStats();
+ final int NU = uidStats.size();
+ boolean didPid = false;
+ long nowRealtime = SystemClock.elapsedRealtime();
+ StringBuilder sb = new StringBuilder(64);
+ for (int i=0; i<NU; i++) {
+ Uid uid = uidStats.valueAt(i);
+ SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
+ if (pids != null) {
+ for (int j=0; j<pids.size(); j++) {
+ Uid.Pid pid = pids.valueAt(j);
+ if (!didPid) {
+ pw.println("Per-PID Stats:");
+ didPid = true;
+ }
+ long time = pid.mWakeSum + (pid.mWakeStart != 0
+ ? (nowRealtime - pid.mWakeStart) : 0);
+ pw.print(" PID "); pw.print(pids.keyAt(j));
+ pw.print(" wake time: ");
+ TimeUtils.formatDuration(time, pw);
+ pw.println("");
+ }
+ }
+ }
+ if (didPid) {
+ pw.println("");
}
pw.println("Statistics since last charge:");
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index b01a71d..60ca384 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -132,75 +132,76 @@ public class TimeUtils {
return ZoneInfoDB.getVersion();
}
+ /** @hide Field length that can hold 999 days of time */
+ public static final int HUNDRED_DAY_FIELD_LEN = 19;
+
private static final int SECONDS_PER_MINUTE = 60;
private static final int SECONDS_PER_HOUR = 60 * 60;
private static final int SECONDS_PER_DAY = 24 * 60 * 60;
- /** @hide Just for debugging; not internationalized. */
- public static void formatDuration(long duration, StringBuilder builder) {
- if (duration == 0) {
- builder.append("0");
- return;
- }
- if (duration > 0) {
- builder.append("+");
- } else {
- builder.append("-");
- duration = -duration;
- }
-
- int millis = (int)(duration%1000);
- int seconds = (int) Math.floor(duration / 1000);
- int days = 0, hours = 0, minutes = 0;
-
- if (seconds > SECONDS_PER_DAY) {
- days = seconds / SECONDS_PER_DAY;
- seconds -= days * SECONDS_PER_DAY;
- }
- if (seconds > SECONDS_PER_HOUR) {
- hours = seconds / SECONDS_PER_HOUR;
- seconds -= hours * SECONDS_PER_HOUR;
- }
- if (seconds > SECONDS_PER_MINUTE) {
- minutes = seconds / SECONDS_PER_MINUTE;
- seconds -= minutes * SECONDS_PER_MINUTE;
- }
-
- boolean doall = false;
- if (days > 0) {
- builder.append(days);
- builder.append('d');
- doall = true;
+ private static final Object sFormatSync = new Object();
+ private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+5];
+
+ static private int accumField(int amt, int suffix, boolean always, int zeropad) {
+ if (amt > 99 || (always && zeropad >= 3)) {
+ return 3+suffix;
}
- if (doall || hours > 0) {
- builder.append(hours);
- builder.append('h');
- doall = true;
+ if (amt > 9 || (always && zeropad >= 2)) {
+ return 2+suffix;
}
- if (doall || minutes > 0) {
- builder.append(minutes);
- builder.append('m');
- doall = true;
+ if (always || amt > 0) {
+ return 1+suffix;
}
- if (doall || seconds > 0) {
- builder.append(seconds);
- builder.append('s');
- doall = true;
+ return 0;
+ }
+
+ static private int printField(char[] formatStr, int amt, char suffix, int pos,
+ boolean always, int zeropad) {
+ if (always || amt > 0) {
+ if ((always && zeropad >= 3) || amt > 99) {
+ int dig = amt/100;
+ formatStr[pos] = (char)(dig + '0');
+ pos++;
+ always = true;
+ amt -= (dig*100);
+ }
+ if ((always && zeropad >= 2) || amt > 9) {
+ int dig = amt/10;
+ formatStr[pos] = (char)(dig + '0');
+ pos++;
+ always = true;
+ amt -= (dig*10);
+ }
+ formatStr[pos] = (char)(amt + '0');
+ pos++;
+ formatStr[pos] = suffix;
+ pos++;
}
- builder.append(millis);
- builder.append("ms");
+ return pos;
}
-
- /** @hide Just for debugging; not internationalized. */
- public static void formatDuration(long duration, PrintWriter pw) {
+
+ private static int formatDurationLocked(long duration, int fieldLen) {
+ if (sFormatStr.length < fieldLen) {
+ sFormatStr = new char[fieldLen];
+ }
+
+ char[] formatStr = sFormatStr;
+
if (duration == 0) {
- pw.print("0");
- return;
+ int pos = 0;
+ fieldLen -= 1;
+ while (pos < fieldLen) {
+ formatStr[pos] = ' ';
+ }
+ formatStr[pos] = '0';
+ return pos+1;
}
+
+ char prefix;
if (duration > 0) {
- pw.print("+");
+ prefix = '+';
} else {
- pw.print("-");
+ prefix = '-';
duration = -duration;
}
@@ -221,38 +222,62 @@ public class TimeUtils {
seconds -= minutes * SECONDS_PER_MINUTE;
}
- boolean doall = false;
- if (days > 0) {
- pw.print(days);
- pw.print('d');
- doall = true;
- }
- if (doall || hours > 0) {
- pw.print(hours);
- pw.print('h');
- doall = true;
- }
- if (doall || minutes > 0) {
- pw.print(minutes);
- pw.print('m');
- doall = true;
+ int pos = 0;
+
+ if (fieldLen != 0) {
+ int myLen = accumField(days, 1, false, 0);
+ myLen += accumField(hours, 1, myLen > 0, 2);
+ myLen += accumField(minutes, 1, myLen > 0, 2);
+ myLen += accumField(seconds, 1, myLen > 0, 2);
+ myLen += accumField(millis, 2, true, myLen > 0 ? 3 : 0) + 1;
+ while (myLen < fieldLen) {
+ formatStr[pos] = ' ';
+ pos++;
+ myLen++;
+ }
}
- if (doall || seconds > 0) {
- pw.print(seconds);
- pw.print('s');
- doall = true;
+
+ formatStr[pos] = prefix;
+ pos++;
+
+ int start = pos;
+ boolean zeropad = fieldLen != 0;
+ pos = printField(formatStr, days, 'd', pos, false, 0);
+ pos = printField(formatStr, hours, 'h', pos, pos != start, zeropad ? 2 : 0);
+ pos = printField(formatStr, minutes, 'm', pos, pos != start, zeropad ? 2 : 0);
+ pos = printField(formatStr, seconds, 's', pos, pos != start, zeropad ? 2 : 0);
+ pos = printField(formatStr, millis, 'm', pos, true, (zeropad && pos != start) ? 3 : 0);
+ formatStr[pos] = 's';
+ return pos + 1;
+ }
+
+ /** @hide Just for debugging; not internationalized. */
+ public static void formatDuration(long duration, StringBuilder builder) {
+ synchronized (sFormatSync) {
+ int len = formatDurationLocked(duration, 0);
+ builder.append(sFormatStr, 0, len);
}
- pw.print(millis);
- pw.print("ms");
}
+ /** @hide Just for debugging; not internationalized. */
+ public static void formatDuration(long duration, PrintWriter pw, int fieldLen) {
+ synchronized (sFormatSync) {
+ int len = formatDurationLocked(duration, fieldLen);
+ pw.print(new String(sFormatStr, 0, len));
+ }
+ }
/** @hide Just for debugging; not internationalized. */
+ public static void formatDuration(long duration, PrintWriter pw) {
+ formatDuration(duration, pw, 0);
+ }
+
+ /** @hide Just for debugging; not internationalized. */
public static void formatDuration(long time, long now, PrintWriter pw) {
if (time == 0) {
pw.print("--");
return;
}
- formatDuration(time-now, pw);
+ formatDuration(time-now, pw, 0);
}
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f4447ab..566ed29 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3343,11 +3343,6 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- public class Pid {
- long mWakeSum;
- long mWakeStart;
- }
-
/**
* Retrieve the statistics object for a particular process, creating
* if needed.
@@ -3362,6 +3357,10 @@ public final class BatteryStatsImpl extends BatteryStats {
return ps;
}
+ public SparseArray<? extends Pid> getPidStats() {
+ return mPids;
+ }
+
public Pid getPidStatsLocked(int pid) {
Pid p = mPids.get(pid);
if (p == null) {
@@ -3586,6 +3585,11 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
+ public long getHistoryBaseTime() {
+ return mHistoryBaseTime;
+ }
+
+ @Override
public int getStartCount() {
return mStartCount;
}