diff options
Diffstat (limited to 'core/java/android/os/BatteryStats.java')
-rw-r--r-- | core/java/android/os/BatteryStats.java | 350 |
1 files changed, 308 insertions, 42 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index b0ae0e6..17594d4 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -41,18 +41,25 @@ public abstract class BatteryStats implements Parcelable { public static final int SENSOR = 3; /** + * A constant indicating a a wifi turn on timer + * + * {@hide} + */ + public static final int WIFI_TURNED_ON = 4; + + /** * A constant indicating a full wifi lock timer * * {@hide} */ - public static final int FULL_WIFI_LOCK = 4; + public static final int FULL_WIFI_LOCK = 5; /** * A constant indicating a scan wifi lock timer * * {@hide} */ - public static final int SCAN_WIFI_LOCK = 5; + public static final int SCAN_WIFI_LOCK = 6; /** * Include all of the data in the stats, including previously saved data. @@ -77,7 +84,11 @@ public abstract class BatteryStats implements Parcelable { /** * Bump the version on this if the checkin format changes. */ - private static final int BATTERY_STATS_CHECKIN_VERSION = 1; + private static final int BATTERY_STATS_CHECKIN_VERSION = 3; + + private static final long BYTES_PER_KB = 1024; + private static final long BYTES_PER_MB = 1048576; // 1024^2 + private static final long BYTES_PER_GB = 1073741824; //1024^3 // TODO: Update this list if you add/change any stats above. private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" }; @@ -87,16 +98,39 @@ public abstract class BatteryStats implements Parcelable { private static final String SENSOR_DATA = "sensor"; private static final String WAKELOCK_DATA = "wakelock"; private static final String NETWORK_DATA = "network"; + private static final String USER_ACTIVITY_DATA = "useract"; private static final String BATTERY_DATA = "battery"; private static final String WIFI_LOCK_DATA = "wifilock"; private static final String MISC_DATA = "misc"; - private static final String SIGNAL_STRENGTH_DATA = "signal"; - private static final String DATA_CONNECTION_DATA = "dataconn"; + private static final String SCREEN_BRIGHTNESS_DATA = "brightness"; + private static final String SIGNAL_STRENGTH_TIME_DATA = "sigtime"; + private static final String SIGNAL_STRENGTH_COUNT_DATA = "sigcnt"; + private static final String DATA_CONNECTION_TIME_DATA = "dconntime"; + private static final String DATA_CONNECTION_COUNT_DATA = "dconncnt"; private final StringBuilder mFormatBuilder = new StringBuilder(8); private final Formatter mFormatter = new Formatter(mFormatBuilder); /** + * State for keeping track of counting information. + */ + public static abstract class Counter { + + /** + * Returns the count associated with this Counter for the + * selected type of statistics. + * + * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT + */ + public abstract int getCount(int which); + + /** + * Temporary for debugging. + */ + public abstract void logState(Printer pw, String prefix); + } + + /** * State for keeping track of timing information. */ public static abstract class Timer { @@ -180,13 +214,29 @@ public abstract class BatteryStats implements Parcelable { */ public abstract long getTcpBytesSent(int which); + public abstract void noteWifiTurnedOnLocked(); + public abstract void noteWifiTurnedOffLocked(); public abstract void noteFullWifiLockAcquiredLocked(); public abstract void noteFullWifiLockReleasedLocked(); public abstract void noteScanWifiLockAcquiredLocked(); public abstract void noteScanWifiLockReleasedLocked(); + public abstract long getWifiTurnedOnTime(long batteryRealtime, int which); public abstract long getFullWifiLockTime(long batteryRealtime, int which); public abstract long getScanWifiLockTime(long batteryRealtime, int which); + /** + * Note that these must match the constants in android.os.LocalPowerManager. + */ + static final String[] USER_ACTIVITY_TYPES = { + "other", "cheek", "touch", "long_touch", "touch_up", "button", "unknown" + }; + + public static final int NUM_USER_ACTIVITY_TYPES = 7; + + public abstract void noteUserActivityLocked(int type); + public abstract boolean hasUserActivity(); + public abstract int getUserActivityCount(int type, int which); + public static abstract class Sensor { // Magic sensor number for the GPS. public static final int GPS = -10000; @@ -285,6 +335,29 @@ public abstract class BatteryStats implements Parcelable { */ public abstract long getScreenOnTime(long batteryRealtime, int which); + public static final int SCREEN_BRIGHTNESS_DARK = 0; + public static final int SCREEN_BRIGHTNESS_DIM = 1; + public static final int SCREEN_BRIGHTNESS_MEDIUM = 2; + public static final int SCREEN_BRIGHTNESS_LIGHT = 3; + public static final int SCREEN_BRIGHTNESS_BRIGHT = 4; + + static final String[] SCREEN_BRIGHTNESS_NAMES = { + "dark", "dim", "medium", "light", "bright" + }; + + public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5; + + /** + * Returns the time in milliseconds that the screen has been on with + * the given brightness + * + * {@hide} + */ + public abstract long getScreenBrightnessTime(int brightnessBin, + long batteryRealtime, int which); + + public abstract int getInputEventCount(int which); + /** * Returns the time in milliseconds that the phone has been on while the device was * running on battery. @@ -314,6 +387,13 @@ public abstract class BatteryStats implements Parcelable { public abstract long getPhoneSignalStrengthTime(int strengthBin, long batteryRealtime, int which); + /** + * Returns the number of times the phone has entered the given signal strength. + * + * {@hide} + */ + public abstract int getPhoneSignalStrengthCount(int strengthBin, int which); + public static final int DATA_CONNECTION_NONE = 0; public static final int DATA_CONNECTION_GPRS = 1; public static final int DATA_CONNECTION_EDGE = 2; @@ -336,6 +416,14 @@ public abstract class BatteryStats implements Parcelable { long batteryRealtime, int which); /** + * Returns the number of times the phone has entered the given data + * connection type. + * + * {@hide} + */ + public abstract int getPhoneDataConnectionCount(int dataType, int which); + + /** * Returns the time in milliseconds that wifi has been on while the device was * running on battery. * @@ -482,6 +570,23 @@ public abstract class BatteryStats implements Parcelable { return mFormatBuilder.toString(); } + private final String formatBytesLocked(long bytes) { + mFormatBuilder.setLength(0); + + if (bytes < BYTES_PER_KB) { + return bytes + "B"; + } else if (bytes < BYTES_PER_MB) { + mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB); + return mFormatBuilder.toString(); + } else if (bytes < BYTES_PER_GB){ + mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB); + return mFormatBuilder.toString(); + } else { + mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB); + return mFormatBuilder.toString(); + } + } + /** * * @param sb a StringBuilder object. @@ -590,40 +695,89 @@ public abstract class BatteryStats implements Parcelable { StringBuilder sb = new StringBuilder(128); + SparseArray<? extends Uid> uidStats = getUidStats(); + final int NU = uidStats.size(); + String category = STAT_NAMES[which]; // Dump "battery" stat dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, which == STATS_TOTAL ? getStartCount() : "N/A", - whichBatteryUptime / 1000, whichBatteryRealtime / 1000, - totalUptime / 1000, totalRealtime / 1000); + whichBatteryRealtime / 1000, whichBatteryUptime / 1000, + totalRealtime / 1000, totalUptime / 1000); + + // Calculate total network and wakelock times across all uids. + long rxTotal = 0; + long txTotal = 0; + long fullWakeLockTimeTotal = 0; + long partialWakeLockTimeTotal = 0; + + for (int iu = 0; iu < NU; iu++) { + Uid u = uidStats.valueAt(iu); + rxTotal += u.getTcpBytesReceived(which); + txTotal += u.getTcpBytesSent(which); + + Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); + if (wakelocks.size() > 0) { + for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent + : wakelocks.entrySet()) { + Uid.Wakelock wl = ent.getValue(); + + Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); + if (fullWakeTimer != null) { + fullWakeLockTimeTotal += fullWakeTimer.getTotalTime(batteryRealtime, which); + } + + Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); + if (partialWakeTimer != null) { + partialWakeLockTimeTotal += partialWakeTimer.getTotalTime( + batteryRealtime, which); + } + } + } + } // Dump misc stats dumpLine(pw, 0 /* uid */, category, MISC_DATA, screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, - wifiRunningTime / 1000, bluetoothOnTime / 1000); + wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal, + fullWakeLockTimeTotal, partialWakeLockTimeTotal, + getInputEventCount(which)); + + // Dump screen brightness stats + Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; + for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { + args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000; + } + dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args); // Dump signal strength stats - Object[] args = new Object[NUM_SIGNAL_STRENGTH_BINS]; + args = new Object[NUM_SIGNAL_STRENGTH_BINS]; for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000; } - dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_DATA, args); + dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args); + for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { + args[i] = getPhoneSignalStrengthCount(i, which); + } + dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args); // Dump network type stats args = new Object[NUM_DATA_CONNECTION_TYPES]; for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000; } - dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_DATA, args); + dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args); + for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { + args[i] = getPhoneDataConnectionCount(i, which); + } + dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args); if (which == STATS_UNPLUGGED) { dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, getUnpluggedStartLevel(), getPluggedStartLevel()); } - SparseArray<? extends Uid> uidStats = getUidStats(); - final int NU = uidStats.size(); for (int iu = 0; iu < NU; iu++) { final int uid = uidStats.keyAt(iu); Uid u = uidStats.valueAt(iu); @@ -632,14 +786,29 @@ public abstract class BatteryStats implements Parcelable { long tx = u.getTcpBytesSent(which); long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); + long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which); if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx); - if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) { + if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0 + || wifiTurnedOnTime != 0) { dumpLine(pw, uid, category, WIFI_LOCK_DATA, - fullWifiLockOnTime, scanWifiLockOnTime); + fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime); } + if (u.hasUserActivity()) { + args = new Object[Uid.NUM_USER_ACTIVITY_TYPES]; + boolean hasData = false; + for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { + int val = u.getUserActivityCount(i, which); + args[i] = val; + if (val != 0) hasData = true; + } + if (hasData) { + dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args); + } + } + Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); if (wakelocks.size() > 0) { for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent @@ -741,20 +910,24 @@ public abstract class BatteryStats implements Parcelable { final long totalUptime = computeUptime(rawUptime, which); StringBuilder sb = new StringBuilder(128); + + SparseArray<? extends Uid> uidStats = getUidStats(); + final int NU = uidStats.size(); pw.println(prefix - + " Time on battery: " + formatTimeMs(whichBatteryUptime / 1000) - + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime) - + ") uptime, " + + " Time on battery: " + formatTimeMs(whichBatteryRealtime / 1000) + "(" + formatRatioLocked(whichBatteryRealtime, totalRealtime) - + ") realtime"); + + ") realtime, " + + formatTimeMs(whichBatteryUptime / 1000) + + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime) + + ") uptime"); pw.println(prefix - + " Total: " - + formatTimeMs(totalUptime / 1000) - + "uptime, " + + " Total run time: " + formatTimeMs(totalRealtime / 1000) - + "realtime"); + + "realtime, " + + formatTimeMs(totalUptime / 1000) + + "uptime, "); final long screenOnTime = getScreenOnTime(batteryRealtime, which); final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); @@ -764,19 +937,73 @@ public abstract class BatteryStats implements Parcelable { pw.println(prefix + " Screen on: " + formatTimeMs(screenOnTime / 1000) + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime) - + "), Phone on: " + formatTimeMs(phoneOnTime / 1000) - + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime)); + + "), Input events: " + getInputEventCount(which) + + ", Active phone call: " + formatTimeMs(phoneOnTime / 1000) + + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime) + ")"); + sb.setLength(0); + sb.append(" Screen brightnesses: "); + boolean didOne = false; + for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { + final long time = getScreenBrightnessTime(i, batteryRealtime, which); + if (time == 0) { + continue; + } + if (didOne) sb.append(", "); + didOne = true; + sb.append(SCREEN_BRIGHTNESS_NAMES[i]); + sb.append(" "); + sb.append(formatTimeMs(time/1000)); + sb.append("("); + sb.append(formatRatioLocked(time, screenOnTime)); + sb.append(")"); + } + if (!didOne) sb.append("No activity"); + pw.println(sb.toString()); + + // Calculate total network and wakelock times across all uids. + long rxTotal = 0; + long txTotal = 0; + long fullWakeLockTimeTotalMicros = 0; + long partialWakeLockTimeTotalMicros = 0; + + for (int iu = 0; iu < NU; iu++) { + Uid u = uidStats.valueAt(iu); + rxTotal += u.getTcpBytesReceived(which); + txTotal += u.getTcpBytesSent(which); + + Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); + if (wakelocks.size() > 0) { + for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent + : wakelocks.entrySet()) { + Uid.Wakelock wl = ent.getValue(); + + Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); + if (fullWakeTimer != null) { + fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTime( + batteryRealtime, which); + } + + Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); + if (partialWakeTimer != null) { + partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTime( + batteryRealtime, which); + } + } + } + } + pw.println(prefix - + " Wifi on: " + formatTimeMs(wifiOnTime / 1000) - + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime) - + "), Wifi running: " + formatTimeMs(wifiRunningTime / 1000) - + "(" + formatRatioLocked(wifiRunningTime, whichBatteryRealtime) - + "), Bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000) - + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")"); + + " Total received: " + formatBytesLocked(rxTotal) + + ", Total sent: " + formatBytesLocked(txTotal)); + pw.println(prefix + + " Total full wakelock time: " + formatTimeMs( + (fullWakeLockTimeTotalMicros + 500) / 1000) + + ", Total partial waklock time: " + formatTimeMs( + (partialWakeLockTimeTotalMicros + 500) / 1000)); sb.setLength(0); - sb.append(" Signal strengths: "); - boolean didOne = false; + sb.append(" Signal levels: "); + didOne = false; for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which); if (time == 0) { @@ -789,13 +1016,15 @@ public abstract class BatteryStats implements Parcelable { sb.append(formatTimeMs(time/1000)); sb.append("("); sb.append(formatRatioLocked(time, whichBatteryRealtime)); - sb.append(")"); + sb.append(") "); + sb.append(getPhoneSignalStrengthCount(i, which)); + sb.append("x"); } if (!didOne) sb.append("No activity"); pw.println(sb.toString()); sb.setLength(0); - sb.append(" Data types: "); + sb.append(" Radio types: "); didOne = false; for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { final long time = getPhoneDataConnectionTime(i, batteryRealtime, which); @@ -809,11 +1038,21 @@ public abstract class BatteryStats implements Parcelable { sb.append(formatTimeMs(time/1000)); sb.append("("); sb.append(formatRatioLocked(time, whichBatteryRealtime)); - sb.append(")"); + sb.append(") "); + sb.append(getPhoneDataConnectionCount(i, which)); + sb.append("x"); } if (!didOne) sb.append("No activity"); pw.println(sb.toString()); + pw.println(prefix + + " Wifi on: " + formatTimeMs(wifiOnTime / 1000) + + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime) + + "), Wifi running: " + formatTimeMs(wifiRunningTime / 1000) + + "(" + formatRatioLocked(wifiRunningTime, whichBatteryRealtime) + + "), Bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000) + + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")"); + pw.println(" "); if (which == STATS_UNPLUGGED) { @@ -828,12 +1067,10 @@ public abstract class BatteryStats implements Parcelable { pw.println(prefix + " Last discharge cycle end level: " + getPluggedStartLevel()); } + pw.println(" "); } - pw.println(" "); - SparseArray<? extends Uid> uidStats = getUidStats(); - final int NU = uidStats.size(); for (int iu=0; iu<NU; iu++) { final int uid = uidStats.keyAt(iu); Uid u = uidStats.valueAt(iu); @@ -844,12 +1081,41 @@ public abstract class BatteryStats implements Parcelable { long tcpSent = u.getTcpBytesSent(which); long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); + long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which); if (tcpReceived != 0 || tcpSent != 0) { - pw.println(prefix + " Network: " + tcpReceived + " bytes received, " - + tcpSent + " bytes sent"); + pw.println(prefix + " Network: " + formatBytesLocked(tcpReceived) + " received, " + + formatBytesLocked(tcpSent) + " sent"); } - if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) { + + if (u.hasUserActivity()) { + boolean hasData = false; + for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { + int val = u.getUserActivityCount(i, which); + if (val != 0) { + if (!hasData) { + sb.setLength(0); + sb.append(" User activity: "); + hasData = true; + } else { + sb.append(", "); + } + sb.append(val); + sb.append(" "); + sb.append(Uid.USER_ACTIVITY_TYPES[i]); + } + } + if (hasData) { + pw.println(sb.toString()); + } + } + + if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0 + || wifiTurnedOnTime != 0) { + pw.println(prefix + " Turned Wifi On Time: " + + formatTimeMs(wifiTurnedOnTime / 1000) + + "(" + formatRatioLocked(wifiTurnedOnTime, + whichBatteryRealtime)+ ")"); pw.println(prefix + " Full Wifi Lock Time: " + formatTimeMs(fullWifiLockOnTime / 1000) + "(" + formatRatioLocked(fullWifiLockOnTime, |