diff options
-rw-r--r-- | core/java/android/os/BatteryStats.java | 47 | ||||
-rw-r--r-- | core/java/android/util/TimeUtils.java | 181 | ||||
-rw-r--r-- | core/java/com/android/internal/os/BatteryStatsImpl.java | 14 |
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; } |