FileDocCategorySizeDatePackage
BatteryStats.javaAPI DocAndroid 1.5 API51791Wed May 06 22:41:56 BST 2009android.os

BatteryStats

public abstract class BatteryStats extends Object implements Parcelable
A class providing access to battery usage statistics, including information on wakelocks, processes, packages, and services. All times are represented in microseconds except where indicated otherwise.
hide

Fields Summary
private static final boolean
LOCAL_LOGV
public static final int
WAKE_TYPE_PARTIAL
A constant indicating a partial wake lock timer.
public static final int
WAKE_TYPE_FULL
A constant indicating a full wake lock timer.
public static final int
WAKE_TYPE_WINDOW
A constant indicating a window wake lock timer.
public static final int
SENSOR
A constant indicating a sensor timer. {@hide}
public static final int
WIFI_TURNED_ON
A constant indicating a a wifi turn on timer {@hide}
public static final int
FULL_WIFI_LOCK
A constant indicating a full wifi lock timer {@hide}
public static final int
SCAN_WIFI_LOCK
A constant indicating a scan wifi lock timer {@hide}
public static final int
STATS_TOTAL
Include all of the data in the stats, including previously saved data.
public static final int
STATS_LAST
Include only the last run in the stats.
public static final int
STATS_CURRENT
Include only the current run in the stats.
public static final int
STATS_UNPLUGGED
Include only the run since the last time the device was unplugged in the stats.
private static final int
BATTERY_STATS_CHECKIN_VERSION
Bump the version on this if the checkin format changes.
private static final long
BYTES_PER_KB
private static final long
BYTES_PER_MB
private static final long
BYTES_PER_GB
private static final String[]
STAT_NAMES
private static final String
APK_DATA
private static final String
PROCESS_DATA
private static final String
SENSOR_DATA
private static final String
WAKELOCK_DATA
private static final String
NETWORK_DATA
private static final String
USER_ACTIVITY_DATA
private static final String
BATTERY_DATA
private static final String
WIFI_LOCK_DATA
private static final String
MISC_DATA
private static final String
SCREEN_BRIGHTNESS_DATA
private static final String
SIGNAL_STRENGTH_TIME_DATA
private static final String
SIGNAL_STRENGTH_COUNT_DATA
private static final String
DATA_CONNECTION_TIME_DATA
private static final String
DATA_CONNECTION_COUNT_DATA
private final StringBuilder
mFormatBuilder
private final Formatter
mFormatter
public static final int
SCREEN_BRIGHTNESS_DARK
public static final int
SCREEN_BRIGHTNESS_DIM
public static final int
SCREEN_BRIGHTNESS_MEDIUM
public static final int
SCREEN_BRIGHTNESS_LIGHT
public static final int
SCREEN_BRIGHTNESS_BRIGHT
static final String[]
SCREEN_BRIGHTNESS_NAMES
public static final int
NUM_SCREEN_BRIGHTNESS_BINS
public static final int
SIGNAL_STRENGTH_NONE_OR_UNKNOWN
public static final int
SIGNAL_STRENGTH_POOR
public static final int
SIGNAL_STRENGTH_MODERATE
public static final int
SIGNAL_STRENGTH_GOOD
public static final int
SIGNAL_STRENGTH_GREAT
static final String[]
SIGNAL_STRENGTH_NAMES
public static final int
NUM_SIGNAL_STRENGTH_BINS
public static final int
DATA_CONNECTION_NONE
public static final int
DATA_CONNECTION_GPRS
public static final int
DATA_CONNECTION_EDGE
public static final int
DATA_CONNECTION_UMTS
public static final int
DATA_CONNECTION_OTHER
static final String[]
DATA_CONNECTION_NAMES
public static final int
NUM_DATA_CONNECTION_TYPES
Constructors Summary
Methods Summary
public abstract longcomputeBatteryRealtime(long curTime, int which)
Returns the total, last, or current battery realtime in microseconds.

param
curTime the current elapsed realtime in microseconds.
param
which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.

public abstract longcomputeBatteryUptime(long curTime, int which)
Returns the total, last, or current battery uptime in microseconds.

param
curTime the elapsed realtime in microseconds.
param
which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.

public abstract longcomputeRealtime(long curTime, int which)
Returns the total, last, or current realtime in microseconds. *

param
curTime the current elapsed realtime in microseconds.
param
which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.

public abstract longcomputeUptime(long curTime, int which)
Returns the total, last, or current uptime in microseconds.

param
curTime the current elapsed realtime in microseconds.
param
which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.

private final voiddumpCheckinLocked(java.io.PrintWriter pw, int which)
Checkin server version of dump to produce more compact, computer-readable log. NOTE: all times are expressed in 'ms'.

param
fd
param
pw
param
which

        final long rawUptime = SystemClock.uptimeMillis() * 1000;
        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
        final long batteryUptime = getBatteryUptime(rawUptime);
        final long batteryRealtime = getBatteryRealtime(rawRealtime);
        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
        final long totalRealtime = computeRealtime(rawRealtime, which);
        final long totalUptime = computeUptime(rawUptime, which);
        final long screenOnTime = getScreenOnTime(batteryRealtime, which);
        final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
        final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
        final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
        final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
       
        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",
                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, 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
        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_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_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());
        }
        
        for (int iu = 0; iu < NU; iu++) {
            final int uid = uidStats.keyAt(iu);
            Uid u = uidStats.valueAt(iu);
            // Dump Network stats per uid, if any
            long rx = u.getTcpBytesReceived(which);
            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
                    || wifiTurnedOnTime != 0) {
                dumpLine(pw, uid, category, WIFI_LOCK_DATA, 
                        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
                        : wakelocks.entrySet()) {
                    Uid.Wakelock wl = ent.getValue();
                    String linePrefix = "";
                    sb.setLength(0);
                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
                            "full", which, linePrefix);
                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
                            "partial", which, linePrefix);
                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
                            "window", which, linePrefix);
                    
                    // Only log if we had at lease one wakelock...
                    if (sb.length() > 0) {
                       dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
                    }
                }
            }
                
            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
            if (sensors.size() > 0)  {
                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
                        : sensors.entrySet()) {
                    Uid.Sensor se = ent.getValue();
                    int sensorNumber = ent.getKey();
                    Timer timer = se.getSensorTime();
                    if (timer != null) {
                        // Convert from microseconds to milliseconds with rounding
                        long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
                        int count = timer.getCount(which);
                        if (totalTime != 0) {
                            dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
                        }
                    } 
                }
            }

            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
            if (processStats.size() > 0) {
                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
                        : processStats.entrySet()) {
                    Uid.Proc ps = ent.getValue();
    
                    long userTime = ps.getUserTime(which);
                    long systemTime = ps.getSystemTime(which);
                    int starts = ps.getStarts(which);
    
                    if (userTime != 0 || systemTime != 0 || starts != 0) {
                        dumpLine(pw, uid, category, PROCESS_DATA, 
                                ent.getKey(), // proc
                                userTime * 10, // cpu time in ms
                                systemTime * 10, // user time in ms
                                starts); // process starts
                    }
                }
            }

            Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
            if (packageStats.size() > 0) {
                for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
                        : packageStats.entrySet()) {
              
                    Uid.Pkg ps = ent.getValue();
                    int wakeups = ps.getWakeups(which);
                    Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
                    for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
                            : serviceStats.entrySet()) {
                        BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
                        long startTime = ss.getStartTime(batteryUptime, which);
                        int starts = ss.getStarts(which);
                        int launches = ss.getLaunches(which);
                        if (startTime != 0 || starts != 0 || launches != 0) {
                            dumpLine(pw, uid, category, APK_DATA, 
                                    wakeups, // wakeup alarms
                                    ent.getKey(), // Apk
                                    sent.getKey(), // service
                                    startTime / 1000, // time spent started, in ms
                                    starts,
                                    launches);
                        }
                    }
                }
            }
        }
    
public voiddumpCheckinLocked(java.io.PrintWriter pw, java.lang.String[] args)

        boolean isUnpluggedOnly = false;
        
        for (String arg : args) {
            if ("-u".equals(arg)) {
                if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
                isUnpluggedOnly = true;
            }
        }
        
        if (isUnpluggedOnly) {
            dumpCheckinLocked(pw, STATS_UNPLUGGED);
        }
        else {
            dumpCheckinLocked(pw, STATS_TOTAL);
            dumpCheckinLocked(pw, STATS_LAST);
            dumpCheckinLocked(pw, STATS_UNPLUGGED);
            dumpCheckinLocked(pw, STATS_CURRENT);
        }
    
private static final voiddumpLine(java.io.PrintWriter pw, int uid, java.lang.String category, java.lang.String type, java.lang.Object args)
Dump a comma-separated line of values for terse checkin mode.

param
pw the PageWriter to dump log to
param
category category of data (e.g. "total", "last", "unplugged", "current" )
param
type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
param
args type-dependent data arguments

        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',");
        pw.print(uid); pw.print(',");
        pw.print(category); pw.print(',");
        pw.print(type); 
        
        for (Object arg : args) {  
            pw.print(',"); 
            pw.print(arg); 
        }
        pw.print('\n");
    
private final voiddumpLocked(android.util.Printer pw, java.lang.String prefix, int which)

        final long rawUptime = SystemClock.uptimeMillis() * 1000;
        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
        final long batteryUptime = getBatteryUptime(rawUptime);
        final long batteryRealtime = getBatteryRealtime(rawRealtime);

        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
        final long totalRealtime = computeRealtime(rawRealtime, which);
        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(whichBatteryRealtime / 1000) + "("
                + formatRatioLocked(whichBatteryRealtime, totalRealtime)
                + ") realtime, "
                + formatTimeMs(whichBatteryUptime / 1000)
                + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime)
                + ") uptime");
        pw.println(prefix
                + "  Total run time: "
                + formatTimeMs(totalRealtime / 1000)
                + "realtime, "
                + formatTimeMs(totalUptime / 1000)
                + "uptime, ");
        
        final long screenOnTime = getScreenOnTime(batteryRealtime, which);
        final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
        final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
        final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
        final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
        pw.println(prefix
                + "  Screen on: " + formatTimeMs(screenOnTime / 1000)
                + "(" + formatRatioLocked(screenOnTime, 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
                + "  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 levels: ");
        didOne = false;
        for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
            final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
            if (time == 0) {
                continue;
            }
            if (didOne) sb.append(", ");
            didOne = true;
            sb.append(SIGNAL_STRENGTH_NAMES[i]);
            sb.append(" ");
            sb.append(formatTimeMs(time/1000));
            sb.append("(");
            sb.append(formatRatioLocked(time, whichBatteryRealtime));
            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("  Radio types: ");
        didOne = false;
        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
            final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
            if (time == 0) {
                continue;
            }
            if (didOne) sb.append(", ");
            didOne = true;
            sb.append(DATA_CONNECTION_NAMES[i]);
            sb.append(" ");
            sb.append(formatTimeMs(time/1000));
            sb.append("(");
            sb.append(formatRatioLocked(time, whichBatteryRealtime));
            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) {
            if (getIsOnBattery()) {
                pw.println(prefix + "  Device is currently unplugged");
                pw.println(prefix + "    Discharge cycle start level: " + 
                        getUnpluggedStartLevel());
            } else {
                pw.println(prefix + "  Device is currently plugged into power");
                pw.println(prefix + "    Last discharge cycle start level: " + 
                        getUnpluggedStartLevel());
                pw.println(prefix + "    Last discharge cycle end level: " + 
                        getPluggedStartLevel());
            }
            pw.println(" ");
        }
        

        for (int iu=0; iu<NU; iu++) {
            final int uid = uidStats.keyAt(iu);
            Uid u = uidStats.valueAt(iu);
            pw.println(prefix + "  #" + uid + ":");
            boolean uidActivity = false;
            
            long tcpReceived = u.getTcpBytesReceived(which);
            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: " + formatBytesLocked(tcpReceived) + " received, "
                        + formatBytesLocked(tcpSent) + " sent");
            }
            
            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, 
                                whichBatteryRealtime)+ ")");
                pw.println(prefix + "    Scan Wifi Lock Time: " 
                        + formatTimeMs(scanWifiLockOnTime / 1000)
                        + "(" + formatRatioLocked(scanWifiLockOnTime, 
                                whichBatteryRealtime)+ ")");
            }

            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();
                    String linePrefix = ": ";
                    sb.setLength(0);
                    sb.append(prefix);
                    sb.append("    Wake lock ");
                    sb.append(ent.getKey());
                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
                            "full", which, linePrefix);
                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
                            "partial", which, linePrefix);
                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
                            "window", which, linePrefix);
                    if (!linePrefix.equals(": ")) {
                        sb.append(" realtime");
                    } else {
                        sb.append(": (nothing executed)");
                    }
                    pw.println(sb.toString());
                    uidActivity = true;
                }
            }

            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
            if (sensors.size() > 0) {
                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
                    : sensors.entrySet()) {
                    Uid.Sensor se = ent.getValue();
                    int sensorNumber = ent.getKey();
                    sb.setLength(0);
                    sb.append(prefix);
                    sb.append("    Sensor ");
                    int handle = se.getHandle();
                    if (handle == Uid.Sensor.GPS) {
                        sb.append("GPS");
                    } else {
                        sb.append(handle);
                    }
                    sb.append(": ");

                    Timer timer = se.getSensorTime();
                    if (timer != null) {
                        // Convert from microseconds to milliseconds with rounding
                        long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
                        int count = timer.getCount(which);
                        //timer.logState();
                        if (totalTime != 0) {
                            sb.append(formatTimeMs(totalTime));
                            sb.append("realtime (");
                            sb.append(count);
                            sb.append(" times)");
                        } else {
                            sb.append("(not used)");
                        }
                    } else {
                        sb.append("(not used)");
                    }

                    pw.println(sb.toString());
                    uidActivity = true;
                }
            }

            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
            if (processStats.size() > 0) {
                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
                    : processStats.entrySet()) {
                    Uid.Proc ps = ent.getValue();
                    long userTime;
                    long systemTime;
                    int starts;

                    userTime = ps.getUserTime(which);
                    systemTime = ps.getSystemTime(which);
                    starts = ps.getStarts(which);

                    if (userTime != 0 || systemTime != 0 || starts != 0) {
                        pw.println(prefix + "    Proc " + ent.getKey() + ":");
                        pw.println(prefix + "      CPU: " + formatTime(userTime) + "user + "
                                + formatTime(systemTime) + "kernel");
                        pw.println(prefix + "      " + starts + " process starts");
                        uidActivity = true;
                    }
                }
            }

            Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
            if (packageStats.size() > 0) {
                for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
                    : packageStats.entrySet()) {
                    pw.println(prefix + "    Apk " + ent.getKey() + ":");
                    boolean apkActivity = false;
                    Uid.Pkg ps = ent.getValue();
                    int wakeups = ps.getWakeups(which);
                    if (wakeups != 0) {
                        pw.println(prefix + "      " + wakeups + " wakeup alarms");
                        apkActivity = true;
                    }
                    Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
                    if (serviceStats.size() > 0) {
                        for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
                                : serviceStats.entrySet()) {
                            BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
                            long startTime = ss.getStartTime(batteryUptime, which);
                            int starts = ss.getStarts(which);
                            int launches = ss.getLaunches(which);
                            if (startTime != 0 || starts != 0 || launches != 0) {
                                pw.println(prefix + "      Service " + sent.getKey() + ":");
                                pw.println(prefix + "        Created for: "
                                        + formatTimeMs(startTime / 1000)
                                        + " uptime");
                                pw.println(prefix + "        Starts: " + starts
                                        + ", launches: " + launches);
                                apkActivity = true;
                            }
                        }
                    }
                    if (!apkActivity) {
                        pw.println(prefix + "      (nothing executed)");
                    }
                    uidActivity = true;
                }
            }
            if (!uidActivity) {
                pw.println(prefix + "    (nothing executed)");
            }
        }
    
public voiddumpLocked(android.util.Printer pw)
Dumps a human-readable summary of the battery statistics to the given PrintWriter.

param
pw a Printer to receive the dump output.

        pw.println("Total Statistics (Current and Historic):");
        pw.println("  System starts: " + getStartCount()
                + ", currently on battery: " + getIsOnBattery());
        dumpLocked(pw, "", STATS_TOTAL);
        pw.println("");
        pw.println("Last Run Statistics (Previous run of system):");
        dumpLocked(pw, "", STATS_LAST);
        pw.println("");
        pw.println("Current Battery Statistics (Currently running system):");
        dumpLocked(pw, "", STATS_CURRENT);
        pw.println("");
        pw.println("Unplugged Statistics (Since last unplugged from power):");
        dumpLocked(pw, "", STATS_UNPLUGGED);
    
private final java.lang.StringformatBytesLocked(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();
        }
    
private final java.lang.StringformatRatioLocked(long num, long den)

        if (den == 0L) {
            return "---%";
        }
        float perc = ((float)num) / ((float)den) * 100;
        mFormatBuilder.setLength(0);
        mFormatter.format("%.1f%%", perc);
        return mFormatBuilder.toString();
    
private static final voidformatTime(java.lang.StringBuilder out, long seconds)

    
                           
        
               

                         
          

                            
          

                                    
          

                            
          
    
                 
       
    
                  
         

                         
        

                         
        
    
                                  
       
    
                        
       

                                  
          

                                   
          

                                  
          

                                   
          

            
        long days = seconds / (60 * 60 * 24);
        if (days != 0) {
            out.append(days);
            out.append("d ");
        }
        long used = days * 60 * 60 * 24;

        long hours = (seconds - used) / (60 * 60);
        if (hours != 0 || used != 0) {
            out.append(hours);
            out.append("h ");
        }
        used += hours * 60 * 60;

        long mins = (seconds-used) / 60;
        if (mins != 0 || used != 0) {
            out.append(mins);
            out.append("m ");
        }
        used += mins * 60;

        if (seconds != 0 || used != 0) {
            out.append(seconds-used);
            out.append("s ");
        }
    
private static final java.lang.StringformatTime(long time)

        long sec = time / 100;
        StringBuilder sb = new StringBuilder();
        formatTime(sb, sec);
        sb.append((time - (sec * 100)) * 10);
        sb.append("ms ");
        return sb.toString();
    
private static final java.lang.StringformatTimeMs(long time)

        long sec = time / 1000;
        StringBuilder sb = new StringBuilder();
        formatTime(sb, sec);
        sb.append(time - (sec * 1000));
        sb.append("ms ");
        return sb.toString();
    
public abstract longgetBatteryRealtime(long curTime)
Returns the current battery realtime in microseconds.

param
curTime the amount of elapsed realtime in microseconds.

public abstract longgetBatteryUptime(long curTime)
Returns the current battery uptime in microseconds.

param
curTime the amount of elapsed realtime in microseconds.

public abstract longgetBluetoothOnTime(long batteryRealtime, int which)
Returns the time in milliseconds that bluetooth has been on while the device was running on battery. {@hide}

public abstract intgetInputEventCount(int which)

public abstract booleangetIsOnBattery()
Return whether we are currently running on battery.

public abstract intgetPhoneDataConnectionCount(int dataType, int which)
Returns the number of times the phone has entered the given data connection type. {@hide}

public abstract longgetPhoneDataConnectionTime(int dataType, long batteryRealtime, int which)
Returns the time in milliseconds that the phone has been running with the given data connection. {@hide}

public abstract longgetPhoneOnTime(long batteryRealtime, int which)
Returns the time in milliseconds that the phone has been on while the device was running on battery. {@hide}

public abstract intgetPhoneSignalStrengthCount(int strengthBin, int which)
Returns the number of times the phone has entered the given signal strength. {@hide}

public abstract longgetPhoneSignalStrengthTime(int strengthBin, long batteryRealtime, int which)
Returns the time in milliseconds that the phone has been running with the given signal strength. {@hide}

public abstract intgetPluggedStartLevel()
Returns the battery percentage level at the last time the device was plugged into power.

public abstract longgetScreenBrightnessTime(int brightnessBin, long batteryRealtime, int which)
Returns the time in milliseconds that the screen has been on with the given brightness {@hide}

public abstract longgetScreenOnTime(long batteryRealtime, int which)
Returns the time in milliseconds that the screen has been on while the device was running on battery. {@hide}

public abstract intgetStartCount()
Returns the number of times the device has been started.

public abstract android.util.SparseArraygetUidStats()
Returns a SparseArray containing the statistics for each uid.

public abstract intgetUnpluggedStartLevel()
Returns the battery percentage level at the last time the device was unplugged from power, or the last time it was booted while unplugged.

public abstract longgetWifiOnTime(long batteryRealtime, int which)
Returns the time in milliseconds that wifi has been on while the device was running on battery. {@hide}

public abstract longgetWifiRunningTime(long batteryRealtime, int which)
Returns the time in milliseconds that wifi has been on and the driver has been in the running state while the device was running on battery. {@hide}

private static final java.lang.StringprintWakeLock(java.lang.StringBuilder sb, android.os.BatteryStats$Timer timer, long batteryRealtime, java.lang.String name, int which, java.lang.String linePrefix)

param
sb a StringBuilder object.
param
timer a Timer object contining the wakelock times.
param
batteryRealtime the current on-battery time in microseconds.
param
name the name of the wakelock.
param
which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
param
linePrefix a String to be prepended to each line of output.
return
the line prefix

        
        if (timer != null) {
            // Convert from microseconds to milliseconds with rounding
            long totalTimeMicros = timer.getTotalTime(batteryRealtime, which);
            long totalTimeMillis = (totalTimeMicros + 500) / 1000;
            
            int count = timer.getCount(which);
            if (totalTimeMillis != 0) {
                sb.append(linePrefix);
                sb.append(formatTimeMs(totalTimeMillis));
                sb.append(name);
                sb.append(' ");
                sb.append('(");
                sb.append(count);
                sb.append(" times)");
                return ", ";
            }
        }
        return linePrefix;
    
private static final java.lang.StringprintWakeLockCheckin(java.lang.StringBuilder sb, android.os.BatteryStats$Timer timer, long now, java.lang.String name, int which, java.lang.String linePrefix)
Checkin version of wakelock printer. Prints simple comma-separated list.

param
sb a StringBuilder object.
param
timer a Timer object contining the wakelock times.
param
now the current time in microseconds.
param
name the name of the wakelock.
param
which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
param
linePrefix a String to be prepended to each line of output.
return
the line prefix

        long totalTimeMicros = 0;
        int count = 0;
        if (timer != null) {
            totalTimeMicros = timer.getTotalTime(now, which);
            count = timer.getCount(which); 
        }
        sb.append(linePrefix);
        sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
        sb.append(',");
        sb.append(name);
        sb.append(',");
        sb.append(count);
        return ",";