Home | History | Annotate | Download | only in os
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.os;
     18 
     19 import java.io.PrintWriter;
     20 import java.util.ArrayList;
     21 import java.util.Collections;
     22 import java.util.Comparator;
     23 import java.util.Formatter;
     24 import java.util.List;
     25 import java.util.Map;
     26 
     27 import android.content.pm.ApplicationInfo;
     28 import android.telephony.SignalStrength;
     29 import android.util.Log;
     30 import android.util.Printer;
     31 import android.util.Slog;
     32 import android.util.SparseArray;
     33 import android.util.TimeUtils;
     34 
     35 /**
     36  * A class providing access to battery usage statistics, including information on
     37  * wakelocks, processes, packages, and services.  All times are represented in microseconds
     38  * except where indicated otherwise.
     39  * @hide
     40  */
     41 public abstract class BatteryStats implements Parcelable {
     42 
     43     private static final boolean LOCAL_LOGV = false;
     44 
     45     /** @hide */
     46     public static final String SERVICE_NAME = "batterystats";
     47 
     48     /**
     49      * A constant indicating a partial wake lock timer.
     50      */
     51     public static final int WAKE_TYPE_PARTIAL = 0;
     52 
     53     /**
     54      * A constant indicating a full wake lock timer.
     55      */
     56     public static final int WAKE_TYPE_FULL = 1;
     57 
     58     /**
     59      * A constant indicating a window wake lock timer.
     60      */
     61     public static final int WAKE_TYPE_WINDOW = 2;
     62 
     63     /**
     64      * A constant indicating a sensor timer.
     65      */
     66     public static final int SENSOR = 3;
     67 
     68     /**
     69      * A constant indicating a a wifi running timer
     70      */
     71     public static final int WIFI_RUNNING = 4;
     72 
     73     /**
     74      * A constant indicating a full wifi lock timer
     75      */
     76     public static final int FULL_WIFI_LOCK = 5;
     77 
     78     /**
     79      * A constant indicating a wifi scan
     80      */
     81     public static final int WIFI_SCAN = 6;
     82 
     83      /**
     84       * A constant indicating a wifi multicast timer
     85       */
     86      public static final int WIFI_MULTICAST_ENABLED = 7;
     87 
     88     /**
     89      * A constant indicating an audio turn on timer
     90      */
     91     public static final int AUDIO_TURNED_ON = 7;
     92 
     93     /**
     94      * A constant indicating a video turn on timer
     95      */
     96     public static final int VIDEO_TURNED_ON = 8;
     97 
     98     /**
     99      * A constant indicating a vibrator on timer
    100      */
    101     public static final int VIBRATOR_ON = 9;
    102 
    103     /**
    104      * A constant indicating a foreground activity timer
    105      */
    106     public static final int FOREGROUND_ACTIVITY = 10;
    107 
    108     /**
    109      * Include all of the data in the stats, including previously saved data.
    110      */
    111     public static final int STATS_SINCE_CHARGED = 0;
    112 
    113     /**
    114      * Include only the last run in the stats.
    115      */
    116     public static final int STATS_LAST = 1;
    117 
    118     /**
    119      * Include only the current run in the stats.
    120      */
    121     public static final int STATS_CURRENT = 2;
    122 
    123     /**
    124      * Include only the run since the last time the device was unplugged in the stats.
    125      */
    126     public static final int STATS_SINCE_UNPLUGGED = 3;
    127 
    128     // NOTE: Update this list if you add/change any stats above.
    129     // These characters are supposed to represent "total", "last", "current",
    130     // and "unplugged". They were shortened for efficiency sake.
    131     private static final String[] STAT_NAMES = { "t", "l", "c", "u" };
    132 
    133     /**
    134      * Bump the version on this if the checkin format changes.
    135      */
    136     private static final int BATTERY_STATS_CHECKIN_VERSION = 7;
    137 
    138     private static final long BYTES_PER_KB = 1024;
    139     private static final long BYTES_PER_MB = 1048576; // 1024^2
    140     private static final long BYTES_PER_GB = 1073741824; //1024^3
    141 
    142 
    143     private static final String UID_DATA = "uid";
    144     private static final String APK_DATA = "apk";
    145     private static final String PROCESS_DATA = "pr";
    146     private static final String SENSOR_DATA = "sr";
    147     private static final String VIBRATOR_DATA = "vib";
    148     private static final String FOREGROUND_DATA = "fg";
    149     private static final String WAKELOCK_DATA = "wl";
    150     private static final String KERNEL_WAKELOCK_DATA = "kwl";
    151     private static final String NETWORK_DATA = "nt";
    152     private static final String USER_ACTIVITY_DATA = "ua";
    153     private static final String BATTERY_DATA = "bt";
    154     private static final String BATTERY_DISCHARGE_DATA = "dc";
    155     private static final String BATTERY_LEVEL_DATA = "lv";
    156     private static final String WIFI_DATA = "wfl";
    157     private static final String MISC_DATA = "m";
    158     private static final String HISTORY_DATA = "h";
    159     private static final String SCREEN_BRIGHTNESS_DATA = "br";
    160     private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
    161     private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
    162     private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
    163     private static final String DATA_CONNECTION_TIME_DATA = "dct";
    164     private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
    165 
    166     private final StringBuilder mFormatBuilder = new StringBuilder(32);
    167     private final Formatter mFormatter = new Formatter(mFormatBuilder);
    168 
    169     /**
    170      * State for keeping track of counting information.
    171      */
    172     public static abstract class Counter {
    173 
    174         /**
    175          * Returns the count associated with this Counter for the
    176          * selected type of statistics.
    177          *
    178          * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
    179          */
    180         public abstract int getCountLocked(int which);
    181 
    182         /**
    183          * Temporary for debugging.
    184          */
    185         public abstract void logState(Printer pw, String prefix);
    186     }
    187 
    188     /**
    189      * State for keeping track of timing information.
    190      */
    191     public static abstract class Timer {
    192 
    193         /**
    194          * Returns the count associated with this Timer for the
    195          * selected type of statistics.
    196          *
    197          * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
    198          */
    199         public abstract int getCountLocked(int which);
    200 
    201         /**
    202          * Returns the total time in microseconds associated with this Timer for the
    203          * selected type of statistics.
    204          *
    205          * @param batteryRealtime system realtime on  battery in microseconds
    206          * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
    207          * @return a time in microseconds
    208          */
    209         public abstract long getTotalTimeLocked(long batteryRealtime, int which);
    210 
    211         /**
    212          * Temporary for debugging.
    213          */
    214         public abstract void logState(Printer pw, String prefix);
    215     }
    216 
    217     /**
    218      * The statistics associated with a particular uid.
    219      */
    220     public static abstract class Uid {
    221 
    222         /**
    223          * Returns a mapping containing wakelock statistics.
    224          *
    225          * @return a Map from Strings to Uid.Wakelock objects.
    226          */
    227         public abstract Map<String, ? extends Wakelock> getWakelockStats();
    228 
    229         /**
    230          * The statistics associated with a particular wake lock.
    231          */
    232         public static abstract class Wakelock {
    233             public abstract Timer getWakeTime(int type);
    234         }
    235 
    236         /**
    237          * Returns a mapping containing sensor statistics.
    238          *
    239          * @return a Map from Integer sensor ids to Uid.Sensor objects.
    240          */
    241         public abstract Map<Integer, ? extends Sensor> getSensorStats();
    242 
    243         /**
    244          * Returns a mapping containing active process data.
    245          */
    246         public abstract SparseArray<? extends Pid> getPidStats();
    247 
    248         /**
    249          * Returns a mapping containing process statistics.
    250          *
    251          * @return a Map from Strings to Uid.Proc objects.
    252          */
    253         public abstract Map<String, ? extends Proc> getProcessStats();
    254 
    255         /**
    256          * Returns a mapping containing package statistics.
    257          *
    258          * @return a Map from Strings to Uid.Pkg objects.
    259          */
    260         public abstract Map<String, ? extends Pkg> getPackageStats();
    261 
    262         /**
    263          * {@hide}
    264          */
    265         public abstract int getUid();
    266 
    267         public abstract void noteWifiRunningLocked();
    268         public abstract void noteWifiStoppedLocked();
    269         public abstract void noteFullWifiLockAcquiredLocked();
    270         public abstract void noteFullWifiLockReleasedLocked();
    271         public abstract void noteWifiScanStartedLocked();
    272         public abstract void noteWifiScanStoppedLocked();
    273         public abstract void noteWifiMulticastEnabledLocked();
    274         public abstract void noteWifiMulticastDisabledLocked();
    275         public abstract void noteAudioTurnedOnLocked();
    276         public abstract void noteAudioTurnedOffLocked();
    277         public abstract void noteVideoTurnedOnLocked();
    278         public abstract void noteVideoTurnedOffLocked();
    279         public abstract void noteActivityResumedLocked();
    280         public abstract void noteActivityPausedLocked();
    281         public abstract long getWifiRunningTime(long batteryRealtime, int which);
    282         public abstract long getFullWifiLockTime(long batteryRealtime, int which);
    283         public abstract long getWifiScanTime(long batteryRealtime, int which);
    284         public abstract long getWifiMulticastTime(long batteryRealtime,
    285                                                   int which);
    286         public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
    287         public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
    288         public abstract Timer getForegroundActivityTimer();
    289         public abstract Timer getVibratorOnTimer();
    290 
    291         /**
    292          * Note that these must match the constants in android.os.PowerManager.
    293          * Also, if the user activity types change, the BatteryStatsImpl.VERSION must
    294          * also be bumped.
    295          */
    296         static final String[] USER_ACTIVITY_TYPES = {
    297             "other", "button", "touch"
    298         };
    299 
    300         public static final int NUM_USER_ACTIVITY_TYPES = 3;
    301 
    302         public abstract void noteUserActivityLocked(int type);
    303         public abstract boolean hasUserActivity();
    304         public abstract int getUserActivityCount(int type, int which);
    305 
    306         public abstract boolean hasNetworkActivity();
    307         public abstract long getNetworkActivityCount(int type, int which);
    308 
    309         public static abstract class Sensor {
    310             /*
    311              * FIXME: it's not correct to use this magic value because it
    312              * could clash with a sensor handle (which are defined by
    313              * the sensor HAL, and therefore out of our control
    314              */
    315             // Magic sensor number for the GPS.
    316             public static final int GPS = -10000;
    317 
    318             public abstract int getHandle();
    319 
    320             public abstract Timer getSensorTime();
    321         }
    322 
    323         public class Pid {
    324             public long mWakeSum;
    325             public long mWakeStart;
    326         }
    327 
    328         /**
    329          * The statistics associated with a particular process.
    330          */
    331         public static abstract class Proc {
    332 
    333             public static class ExcessivePower {
    334                 public static final int TYPE_WAKE = 1;
    335                 public static final int TYPE_CPU = 2;
    336 
    337                 public int type;
    338                 public long overTime;
    339                 public long usedTime;
    340             }
    341 
    342             /**
    343              * Returns the total time (in 1/100 sec) spent executing in user code.
    344              *
    345              * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
    346              */
    347             public abstract long getUserTime(int which);
    348 
    349             /**
    350              * Returns the total time (in 1/100 sec) spent executing in system code.
    351              *
    352              * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
    353              */
    354             public abstract long getSystemTime(int which);
    355 
    356             /**
    357              * Returns the number of times the process has been started.
    358              *
    359              * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
    360              */
    361             public abstract int getStarts(int which);
    362 
    363             /**
    364              * Returns the cpu time spent in microseconds while the process was in the foreground.
    365              * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
    366              * @return foreground cpu time in microseconds
    367              */
    368             public abstract long getForegroundTime(int which);
    369 
    370             /**
    371              * Returns the approximate cpu time spent in microseconds, at a certain CPU speed.
    372              * @param speedStep the index of the CPU speed. This is not the actual speed of the
    373              * CPU.
    374              * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
    375              * @see BatteryStats#getCpuSpeedSteps()
    376              */
    377             public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
    378 
    379             public abstract int countExcessivePowers();
    380 
    381             public abstract ExcessivePower getExcessivePower(int i);
    382         }
    383 
    384         /**
    385          * The statistics associated with a particular package.
    386          */
    387         public static abstract class Pkg {
    388 
    389             /**
    390              * Returns the number of times this package has done something that could wake up the
    391              * device from sleep.
    392              *
    393              * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
    394              */
    395             public abstract int getWakeups(int which);
    396 
    397             /**
    398              * Returns a mapping containing service statistics.
    399              */
    400             public abstract Map<String, ? extends Serv> getServiceStats();
    401 
    402             /**
    403              * The statistics associated with a particular service.
    404              */
    405             public abstract class Serv {
    406 
    407                 /**
    408                  * Returns the amount of time spent started.
    409                  *
    410                  * @param batteryUptime elapsed uptime on battery in microseconds.
    411                  * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
    412                  * @return
    413                  */
    414                 public abstract long getStartTime(long batteryUptime, int which);
    415 
    416                 /**
    417                  * Returns the total number of times startService() has been called.
    418                  *
    419                  * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
    420                  */
    421                 public abstract int getStarts(int which);
    422 
    423                 /**
    424                  * Returns the total number times the service has been launched.
    425                  *
    426                  * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
    427                  */
    428                 public abstract int getLaunches(int which);
    429             }
    430         }
    431     }
    432 
    433     public final static class HistoryItem implements Parcelable {
    434         static final String TAG = "HistoryItem";
    435         static final boolean DEBUG = false;
    436 
    437         public HistoryItem next;
    438 
    439         public long time;
    440 
    441         public static final byte CMD_NULL = 0;
    442         public static final byte CMD_UPDATE = 1;
    443         public static final byte CMD_START = 2;
    444         public static final byte CMD_OVERFLOW = 3;
    445 
    446         public byte cmd = CMD_NULL;
    447 
    448         public byte batteryLevel;
    449         public byte batteryStatus;
    450         public byte batteryHealth;
    451         public byte batteryPlugType;
    452 
    453         public char batteryTemperature;
    454         public char batteryVoltage;
    455 
    456         // Constants from SCREEN_BRIGHTNESS_*
    457         public static final int STATE_BRIGHTNESS_MASK = 0x0000000f;
    458         public static final int STATE_BRIGHTNESS_SHIFT = 0;
    459         // Constants from SIGNAL_STRENGTH_*
    460         public static final int STATE_SIGNAL_STRENGTH_MASK = 0x000000f0;
    461         public static final int STATE_SIGNAL_STRENGTH_SHIFT = 4;
    462         // Constants from ServiceState.STATE_*
    463         public static final int STATE_PHONE_STATE_MASK = 0x00000f00;
    464         public static final int STATE_PHONE_STATE_SHIFT = 8;
    465         // Constants from DATA_CONNECTION_*
    466         public static final int STATE_DATA_CONNECTION_MASK = 0x0000f000;
    467         public static final int STATE_DATA_CONNECTION_SHIFT = 12;
    468 
    469         // These states always appear directly in the first int token
    470         // of a delta change; they should be ones that change relatively
    471         // frequently.
    472         public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
    473         public static final int STATE_SENSOR_ON_FLAG = 1<<29;
    474         public static final int STATE_GPS_ON_FLAG = 1<<28;
    475         public static final int STATE_PHONE_SCANNING_FLAG = 1<<27;
    476         public static final int STATE_WIFI_RUNNING_FLAG = 1<<26;
    477         public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<25;
    478         public static final int STATE_WIFI_SCAN_FLAG = 1<<24;
    479         public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<23;
    480         // These are on the lower bits used for the command; if they change
    481         // we need to write another int of data.
    482         public static final int STATE_AUDIO_ON_FLAG = 1<<22;
    483         public static final int STATE_VIDEO_ON_FLAG = 1<<21;
    484         public static final int STATE_SCREEN_ON_FLAG = 1<<20;
    485         public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19;
    486         public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18;
    487         public static final int STATE_WIFI_ON_FLAG = 1<<17;
    488         public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16;
    489 
    490         public static final int MOST_INTERESTING_STATES =
    491             STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG
    492             | STATE_GPS_ON_FLAG | STATE_PHONE_IN_CALL_FLAG;
    493 
    494         public int states;
    495 
    496         public HistoryItem() {
    497         }
    498 
    499         public HistoryItem(long time, Parcel src) {
    500             this.time = time;
    501             readFromParcel(src);
    502         }
    503 
    504         public int describeContents() {
    505             return 0;
    506         }
    507 
    508         public void writeToParcel(Parcel dest, int flags) {
    509             dest.writeLong(time);
    510             int bat = (((int)cmd)&0xff)
    511                     | ((((int)batteryLevel)<<8)&0xff00)
    512                     | ((((int)batteryStatus)<<16)&0xf0000)
    513                     | ((((int)batteryHealth)<<20)&0xf00000)
    514                     | ((((int)batteryPlugType)<<24)&0xf000000);
    515             dest.writeInt(bat);
    516             bat = (((int)batteryTemperature)&0xffff)
    517                     | ((((int)batteryVoltage)<<16)&0xffff0000);
    518             dest.writeInt(bat);
    519             dest.writeInt(states);
    520         }
    521 
    522         private void readFromParcel(Parcel src) {
    523             int bat = src.readInt();
    524             cmd = (byte)(bat&0xff);
    525             batteryLevel = (byte)((bat>>8)&0xff);
    526             batteryStatus = (byte)((bat>>16)&0xf);
    527             batteryHealth = (byte)((bat>>20)&0xf);
    528             batteryPlugType = (byte)((bat>>24)&0xf);
    529             bat = src.readInt();
    530             batteryTemperature = (char)(bat&0xffff);
    531             batteryVoltage = (char)((bat>>16)&0xffff);
    532             states = src.readInt();
    533         }
    534 
    535         // Part of initial delta int that specifies the time delta.
    536         static final int DELTA_TIME_MASK = 0x3ffff;
    537         static final int DELTA_TIME_ABS = 0x3fffd;    // Following is an entire abs update.
    538         static final int DELTA_TIME_INT = 0x3fffe;    // The delta is a following int
    539         static final int DELTA_TIME_LONG = 0x3ffff;   // The delta is a following long
    540         // Part of initial delta int holding the command code.
    541         static final int DELTA_CMD_MASK = 0x3;
    542         static final int DELTA_CMD_SHIFT = 18;
    543         // Flag in delta int: a new battery level int follows.
    544         static final int DELTA_BATTERY_LEVEL_FLAG = 1<<20;
    545         // Flag in delta int: a new full state and battery status int follows.
    546         static final int DELTA_STATE_FLAG = 1<<21;
    547         static final int DELTA_STATE_MASK = 0xffc00000;
    548 
    549         public void writeDelta(Parcel dest, HistoryItem last) {
    550             if (last == null || last.cmd != CMD_UPDATE) {
    551                 dest.writeInt(DELTA_TIME_ABS);
    552                 writeToParcel(dest, 0);
    553                 return;
    554             }
    555 
    556             final long deltaTime = time - last.time;
    557             final int lastBatteryLevelInt = last.buildBatteryLevelInt();
    558             final int lastStateInt = last.buildStateInt();
    559 
    560             int deltaTimeToken;
    561             if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
    562                 deltaTimeToken = DELTA_TIME_LONG;
    563             } else if (deltaTime >= DELTA_TIME_ABS) {
    564                 deltaTimeToken = DELTA_TIME_INT;
    565             } else {
    566                 deltaTimeToken = (int)deltaTime;
    567             }
    568             int firstToken = deltaTimeToken
    569                     | (cmd<<DELTA_CMD_SHIFT)
    570                     | (states&DELTA_STATE_MASK);
    571             final int batteryLevelInt = buildBatteryLevelInt();
    572             final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
    573             if (batteryLevelIntChanged) {
    574                 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
    575             }
    576             final int stateInt = buildStateInt();
    577             final boolean stateIntChanged = stateInt != lastStateInt;
    578             if (stateIntChanged) {
    579                 firstToken |= DELTA_STATE_FLAG;
    580             }
    581             dest.writeInt(firstToken);
    582             if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
    583                     + " deltaTime=" + deltaTime);
    584 
    585             if (deltaTimeToken >= DELTA_TIME_INT) {
    586                 if (deltaTimeToken == DELTA_TIME_INT) {
    587                     if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
    588                     dest.writeInt((int)deltaTime);
    589                 } else {
    590                     if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
    591                     dest.writeLong(deltaTime);
    592                 }
    593             }
    594             if (batteryLevelIntChanged) {
    595                 dest.writeInt(batteryLevelInt);
    596                 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
    597                         + Integer.toHexString(batteryLevelInt)
    598                         + " batteryLevel=" + batteryLevel
    599                         + " batteryTemp=" + (int)batteryTemperature
    600                         + " batteryVolt=" + (int)batteryVoltage);
    601             }
    602             if (stateIntChanged) {
    603                 dest.writeInt(stateInt);
    604                 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
    605                         + Integer.toHexString(stateInt)
    606                         + " batteryStatus=" + batteryStatus
    607                         + " batteryHealth=" + batteryHealth
    608                         + " batteryPlugType=" + batteryPlugType
    609                         + " states=0x" + Integer.toHexString(states));
    610             }
    611         }
    612 
    613         private int buildBatteryLevelInt() {
    614             return ((((int)batteryLevel)<<24)&0xff000000)
    615                     | ((((int)batteryTemperature)<<14)&0x00ffc000)
    616                     | (((int)batteryVoltage)&0x00003fff);
    617         }
    618 
    619         private int buildStateInt() {
    620             return ((((int)batteryStatus)<<28)&0xf0000000)
    621                     | ((((int)batteryHealth)<<24)&0x0f000000)
    622                     | ((((int)batteryPlugType)<<22)&0x00c00000)
    623                     | (states&(~DELTA_STATE_MASK));
    624         }
    625 
    626         public void readDelta(Parcel src) {
    627             int firstToken = src.readInt();
    628             int deltaTimeToken = firstToken&DELTA_TIME_MASK;
    629             cmd = (byte)((firstToken>>DELTA_CMD_SHIFT)&DELTA_CMD_MASK);
    630             if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
    631                     + " deltaTimeToken=" + deltaTimeToken);
    632 
    633             if (deltaTimeToken < DELTA_TIME_ABS) {
    634                 time += deltaTimeToken;
    635             } else if (deltaTimeToken == DELTA_TIME_ABS) {
    636                 time = src.readLong();
    637                 readFromParcel(src);
    638                 return;
    639             } else if (deltaTimeToken == DELTA_TIME_INT) {
    640                 int delta = src.readInt();
    641                 time += delta;
    642                 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + time);
    643             } else {
    644                 long delta = src.readLong();
    645                 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + time);
    646                 time += delta;
    647             }
    648 
    649             if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
    650                 int batteryLevelInt = src.readInt();
    651                 batteryLevel = (byte)((batteryLevelInt>>24)&0xff);
    652                 batteryTemperature = (char)((batteryLevelInt>>14)&0x3ff);
    653                 batteryVoltage = (char)(batteryLevelInt&0x3fff);
    654                 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
    655                         + Integer.toHexString(batteryLevelInt)
    656                         + " batteryLevel=" + batteryLevel
    657                         + " batteryTemp=" + (int)batteryTemperature
    658                         + " batteryVolt=" + (int)batteryVoltage);
    659             }
    660 
    661             if ((firstToken&DELTA_STATE_FLAG) != 0) {
    662                 int stateInt = src.readInt();
    663                 states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
    664                 batteryStatus = (byte)((stateInt>>28)&0xf);
    665                 batteryHealth = (byte)((stateInt>>24)&0xf);
    666                 batteryPlugType = (byte)((stateInt>>22)&0x3);
    667                 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
    668                         + Integer.toHexString(stateInt)
    669                         + " batteryStatus=" + batteryStatus
    670                         + " batteryHealth=" + batteryHealth
    671                         + " batteryPlugType=" + batteryPlugType
    672                         + " states=0x" + Integer.toHexString(states));
    673             } else {
    674                 states = (firstToken&DELTA_STATE_MASK) | (states&(~DELTA_STATE_MASK));
    675             }
    676         }
    677 
    678         public void clear() {
    679             time = 0;
    680             cmd = CMD_NULL;
    681             batteryLevel = 0;
    682             batteryStatus = 0;
    683             batteryHealth = 0;
    684             batteryPlugType = 0;
    685             batteryTemperature = 0;
    686             batteryVoltage = 0;
    687             states = 0;
    688         }
    689 
    690         public void setTo(HistoryItem o) {
    691             time = o.time;
    692             cmd = o.cmd;
    693             batteryLevel = o.batteryLevel;
    694             batteryStatus = o.batteryStatus;
    695             batteryHealth = o.batteryHealth;
    696             batteryPlugType = o.batteryPlugType;
    697             batteryTemperature = o.batteryTemperature;
    698             batteryVoltage = o.batteryVoltage;
    699             states = o.states;
    700         }
    701 
    702         public void setTo(long time, byte cmd, HistoryItem o) {
    703             this.time = time;
    704             this.cmd = cmd;
    705             batteryLevel = o.batteryLevel;
    706             batteryStatus = o.batteryStatus;
    707             batteryHealth = o.batteryHealth;
    708             batteryPlugType = o.batteryPlugType;
    709             batteryTemperature = o.batteryTemperature;
    710             batteryVoltage = o.batteryVoltage;
    711             states = o.states;
    712         }
    713 
    714         public boolean same(HistoryItem o) {
    715             return batteryLevel == o.batteryLevel
    716                     && batteryStatus == o.batteryStatus
    717                     && batteryHealth == o.batteryHealth
    718                     && batteryPlugType == o.batteryPlugType
    719                     && batteryTemperature == o.batteryTemperature
    720                     && batteryVoltage == o.batteryVoltage
    721                     && states == o.states;
    722         }
    723     }
    724 
    725     public static final class BitDescription {
    726         public final int mask;
    727         public final int shift;
    728         public final String name;
    729         public final String[] values;
    730 
    731         public BitDescription(int mask, String name) {
    732             this.mask = mask;
    733             this.shift = -1;
    734             this.name = name;
    735             this.values = null;
    736         }
    737 
    738         public BitDescription(int mask, int shift, String name, String[] values) {
    739             this.mask = mask;
    740             this.shift = shift;
    741             this.name = name;
    742             this.values = values;
    743         }
    744     }
    745 
    746     public abstract boolean startIteratingHistoryLocked();
    747 
    748     public abstract boolean getNextHistoryLocked(HistoryItem out);
    749 
    750     public abstract void finishIteratingHistoryLocked();
    751 
    752     public abstract boolean startIteratingOldHistoryLocked();
    753 
    754     public abstract boolean getNextOldHistoryLocked(HistoryItem out);
    755 
    756     public abstract void finishIteratingOldHistoryLocked();
    757 
    758     /**
    759      * Return the base time offset for the battery history.
    760      */
    761     public abstract long getHistoryBaseTime();
    762 
    763     /**
    764      * Returns the number of times the device has been started.
    765      */
    766     public abstract int getStartCount();
    767 
    768     /**
    769      * Returns the time in microseconds that the screen has been on while the device was
    770      * running on battery.
    771      *
    772      * {@hide}
    773      */
    774     public abstract long getScreenOnTime(long batteryRealtime, int which);
    775 
    776     public static final int SCREEN_BRIGHTNESS_DARK = 0;
    777     public static final int SCREEN_BRIGHTNESS_DIM = 1;
    778     public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
    779     public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
    780     public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
    781 
    782     static final String[] SCREEN_BRIGHTNESS_NAMES = {
    783         "dark", "dim", "medium", "light", "bright"
    784     };
    785 
    786     public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
    787 
    788     /**
    789      * Returns the time in microseconds that the screen has been on with
    790      * the given brightness
    791      *
    792      * {@hide}
    793      */
    794     public abstract long getScreenBrightnessTime(int brightnessBin,
    795             long batteryRealtime, int which);
    796 
    797     public abstract int getInputEventCount(int which);
    798 
    799     /**
    800      * Returns the time in microseconds that the phone has been on while the device was
    801      * running on battery.
    802      *
    803      * {@hide}
    804      */
    805     public abstract long getPhoneOnTime(long batteryRealtime, int which);
    806 
    807     /**
    808      * Returns the time in microseconds that the phone has been running with
    809      * the given signal strength.
    810      *
    811      * {@hide}
    812      */
    813     public abstract long getPhoneSignalStrengthTime(int strengthBin,
    814             long batteryRealtime, int which);
    815 
    816     /**
    817      * Returns the time in microseconds that the phone has been trying to
    818      * acquire a signal.
    819      *
    820      * {@hide}
    821      */
    822     public abstract long getPhoneSignalScanningTime(
    823             long batteryRealtime, int which);
    824 
    825     /**
    826      * Returns the number of times the phone has entered the given signal strength.
    827      *
    828      * {@hide}
    829      */
    830     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
    831 
    832     public static final int DATA_CONNECTION_NONE = 0;
    833     public static final int DATA_CONNECTION_GPRS = 1;
    834     public static final int DATA_CONNECTION_EDGE = 2;
    835     public static final int DATA_CONNECTION_UMTS = 3;
    836     public static final int DATA_CONNECTION_CDMA = 4;
    837     public static final int DATA_CONNECTION_EVDO_0 = 5;
    838     public static final int DATA_CONNECTION_EVDO_A = 6;
    839     public static final int DATA_CONNECTION_1xRTT = 7;
    840     public static final int DATA_CONNECTION_HSDPA = 8;
    841     public static final int DATA_CONNECTION_HSUPA = 9;
    842     public static final int DATA_CONNECTION_HSPA = 10;
    843     public static final int DATA_CONNECTION_IDEN = 11;
    844     public static final int DATA_CONNECTION_EVDO_B = 12;
    845     public static final int DATA_CONNECTION_LTE = 13;
    846     public static final int DATA_CONNECTION_EHRPD = 14;
    847     public static final int DATA_CONNECTION_OTHER = 15;
    848 
    849     static final String[] DATA_CONNECTION_NAMES = {
    850         "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
    851         "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
    852         "ehrpd", "other"
    853     };
    854 
    855     public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
    856 
    857     /**
    858      * Returns the time in microseconds that the phone has been running with
    859      * the given data connection.
    860      *
    861      * {@hide}
    862      */
    863     public abstract long getPhoneDataConnectionTime(int dataType,
    864             long batteryRealtime, int which);
    865 
    866     /**
    867      * Returns the number of times the phone has entered the given data
    868      * connection type.
    869      *
    870      * {@hide}
    871      */
    872     public abstract int getPhoneDataConnectionCount(int dataType, int which);
    873 
    874     public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
    875             = new BitDescription[] {
    876         new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged"),
    877         new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen"),
    878         new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps"),
    879         new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call"),
    880         new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning"),
    881         new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi"),
    882         new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running"),
    883         new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock"),
    884         new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan"),
    885         new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast"),
    886         new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth"),
    887         new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio"),
    888         new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video"),
    889         new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock"),
    890         new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor"),
    891         new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
    892                 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness",
    893                 SCREEN_BRIGHTNESS_NAMES),
    894         new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK,
    895                 HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength",
    896                 SignalStrength.SIGNAL_STRENGTH_NAMES),
    897         new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
    898                 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state",
    899                 new String[] {"in", "out", "emergency", "off"}),
    900         new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
    901                 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn",
    902                 DATA_CONNECTION_NAMES),
    903     };
    904 
    905     /**
    906      * Returns the time in microseconds that wifi has been on while the device was
    907      * running on battery.
    908      *
    909      * {@hide}
    910      */
    911     public abstract long getWifiOnTime(long batteryRealtime, int which);
    912 
    913     /**
    914      * Returns the time in microseconds that wifi has been on and the driver has
    915      * been in the running state while the device was running on battery.
    916      *
    917      * {@hide}
    918      */
    919     public abstract long getGlobalWifiRunningTime(long batteryRealtime, int which);
    920 
    921     /**
    922      * Returns the time in microseconds that bluetooth has been on while the device was
    923      * running on battery.
    924      *
    925      * {@hide}
    926      */
    927     public abstract long getBluetoothOnTime(long batteryRealtime, int which);
    928 
    929     public static final int NETWORK_MOBILE_RX_BYTES = 0;
    930     public static final int NETWORK_MOBILE_TX_BYTES = 1;
    931     public static final int NETWORK_WIFI_RX_BYTES = 2;
    932     public static final int NETWORK_WIFI_TX_BYTES = 3;
    933 
    934     public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_BYTES + 1;
    935 
    936     public abstract long getNetworkActivityCount(int type, int which);
    937 
    938     /**
    939      * Return whether we are currently running on battery.
    940      */
    941     public abstract boolean getIsOnBattery();
    942 
    943     /**
    944      * Returns a SparseArray containing the statistics for each uid.
    945      */
    946     public abstract SparseArray<? extends Uid> getUidStats();
    947 
    948     /**
    949      * Returns the current battery uptime in microseconds.
    950      *
    951      * @param curTime the amount of elapsed realtime in microseconds.
    952      */
    953     public abstract long getBatteryUptime(long curTime);
    954 
    955     /**
    956      * @deprecated use getRadioDataUptime
    957      */
    958     public long getRadioDataUptimeMs() {
    959         return getRadioDataUptime() / 1000;
    960     }
    961 
    962     /**
    963      * Returns the time that the radio was on for data transfers.
    964      * @return the uptime in microseconds while unplugged
    965      */
    966     public abstract long getRadioDataUptime();
    967 
    968     /**
    969      * Returns the current battery realtime in microseconds.
    970      *
    971      * @param curTime the amount of elapsed realtime in microseconds.
    972      */
    973     public abstract long getBatteryRealtime(long curTime);
    974 
    975     /**
    976      * Returns the battery percentage level at the last time the device was unplugged from power, or
    977      * the last time it booted on battery power.
    978      */
    979     public abstract int getDischargeStartLevel();
    980 
    981     /**
    982      * Returns the current battery percentage level if we are in a discharge cycle, otherwise
    983      * returns the level at the last plug event.
    984      */
    985     public abstract int getDischargeCurrentLevel();
    986 
    987     /**
    988      * Get the amount the battery has discharged since the stats were
    989      * last reset after charging, as a lower-end approximation.
    990      */
    991     public abstract int getLowDischargeAmountSinceCharge();
    992 
    993     /**
    994      * Get the amount the battery has discharged since the stats were
    995      * last reset after charging, as an upper-end approximation.
    996      */
    997     public abstract int getHighDischargeAmountSinceCharge();
    998 
    999     /**
   1000      * Get the amount the battery has discharged while the screen was on,
   1001      * since the last time power was unplugged.
   1002      */
   1003     public abstract int getDischargeAmountScreenOn();
   1004 
   1005     /**
   1006      * Get the amount the battery has discharged while the screen was on,
   1007      * since the last time the device was charged.
   1008      */
   1009     public abstract int getDischargeAmountScreenOnSinceCharge();
   1010 
   1011     /**
   1012      * Get the amount the battery has discharged while the screen was off,
   1013      * since the last time power was unplugged.
   1014      */
   1015     public abstract int getDischargeAmountScreenOff();
   1016 
   1017     /**
   1018      * Get the amount the battery has discharged while the screen was off,
   1019      * since the last time the device was charged.
   1020      */
   1021     public abstract int getDischargeAmountScreenOffSinceCharge();
   1022 
   1023     /**
   1024      * Returns the total, last, or current battery uptime in microseconds.
   1025      *
   1026      * @param curTime the elapsed realtime in microseconds.
   1027      * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
   1028      */
   1029     public abstract long computeBatteryUptime(long curTime, int which);
   1030 
   1031     /**
   1032      * Returns the total, last, or current battery realtime in microseconds.
   1033      *
   1034      * @param curTime the current elapsed realtime in microseconds.
   1035      * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
   1036      */
   1037     public abstract long computeBatteryRealtime(long curTime, int which);
   1038 
   1039     /**
   1040      * Returns the total, last, or current uptime in microseconds.
   1041      *
   1042      * @param curTime the current elapsed realtime in microseconds.
   1043      * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
   1044      */
   1045     public abstract long computeUptime(long curTime, int which);
   1046 
   1047     /**
   1048      * Returns the total, last, or current realtime in microseconds.
   1049      * *
   1050      * @param curTime the current elapsed realtime in microseconds.
   1051      * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
   1052      */
   1053     public abstract long computeRealtime(long curTime, int which);
   1054 
   1055     public abstract Map<String, ? extends Timer> getKernelWakelockStats();
   1056 
   1057     /** Returns the number of different speeds that the CPU can run at */
   1058     public abstract int getCpuSpeedSteps();
   1059 
   1060     private final static void formatTimeRaw(StringBuilder out, long seconds) {
   1061         long days = seconds / (60 * 60 * 24);
   1062         if (days != 0) {
   1063             out.append(days);
   1064             out.append("d ");
   1065         }
   1066         long used = days * 60 * 60 * 24;
   1067 
   1068         long hours = (seconds - used) / (60 * 60);
   1069         if (hours != 0 || used != 0) {
   1070             out.append(hours);
   1071             out.append("h ");
   1072         }
   1073         used += hours * 60 * 60;
   1074 
   1075         long mins = (seconds-used) / 60;
   1076         if (mins != 0 || used != 0) {
   1077             out.append(mins);
   1078             out.append("m ");
   1079         }
   1080         used += mins * 60;
   1081 
   1082         if (seconds != 0 || used != 0) {
   1083             out.append(seconds-used);
   1084             out.append("s ");
   1085         }
   1086     }
   1087 
   1088     private final static void formatTime(StringBuilder sb, long time) {
   1089         long sec = time / 100;
   1090         formatTimeRaw(sb, sec);
   1091         sb.append((time - (sec * 100)) * 10);
   1092         sb.append("ms ");
   1093     }
   1094 
   1095     private final static void formatTimeMs(StringBuilder sb, long time) {
   1096         long sec = time / 1000;
   1097         formatTimeRaw(sb, sec);
   1098         sb.append(time - (sec * 1000));
   1099         sb.append("ms ");
   1100     }
   1101 
   1102     private final String formatRatioLocked(long num, long den) {
   1103         if (den == 0L) {
   1104             return "---%";
   1105         }
   1106         float perc = ((float)num) / ((float)den) * 100;
   1107         mFormatBuilder.setLength(0);
   1108         mFormatter.format("%.1f%%", perc);
   1109         return mFormatBuilder.toString();
   1110     }
   1111 
   1112     private final String formatBytesLocked(long bytes) {
   1113         mFormatBuilder.setLength(0);
   1114 
   1115         if (bytes < BYTES_PER_KB) {
   1116             return bytes + "B";
   1117         } else if (bytes < BYTES_PER_MB) {
   1118             mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
   1119             return mFormatBuilder.toString();
   1120         } else if (bytes < BYTES_PER_GB){
   1121             mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
   1122             return mFormatBuilder.toString();
   1123         } else {
   1124             mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
   1125             return mFormatBuilder.toString();
   1126         }
   1127     }
   1128 
   1129     private static long computeWakeLock(Timer timer, long batteryRealtime, int which) {
   1130         if (timer != null) {
   1131             // Convert from microseconds to milliseconds with rounding
   1132             long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
   1133             long totalTimeMillis = (totalTimeMicros + 500) / 1000;
   1134             return totalTimeMillis;
   1135         }
   1136         return 0;
   1137     }
   1138 
   1139     /**
   1140      *
   1141      * @param sb a StringBuilder object.
   1142      * @param timer a Timer object contining the wakelock times.
   1143      * @param batteryRealtime the current on-battery time in microseconds.
   1144      * @param name the name of the wakelock.
   1145      * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
   1146      * @param linePrefix a String to be prepended to each line of output.
   1147      * @return the line prefix
   1148      */
   1149     private static final String printWakeLock(StringBuilder sb, Timer timer,
   1150             long batteryRealtime, String name, int which, String linePrefix) {
   1151 
   1152         if (timer != null) {
   1153             long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which);
   1154 
   1155             int count = timer.getCountLocked(which);
   1156             if (totalTimeMillis != 0) {
   1157                 sb.append(linePrefix);
   1158                 formatTimeMs(sb, totalTimeMillis);
   1159                 if (name != null) {
   1160                     sb.append(name);
   1161                     sb.append(' ');
   1162                 }
   1163                 sb.append('(');
   1164                 sb.append(count);
   1165                 sb.append(" times)");
   1166                 return ", ";
   1167             }
   1168         }
   1169         return linePrefix;
   1170     }
   1171 
   1172     /**
   1173      * Checkin version of wakelock printer. Prints simple comma-separated list.
   1174      *
   1175      * @param sb a StringBuilder object.
   1176      * @param timer a Timer object contining the wakelock times.
   1177      * @param now the current time in microseconds.
   1178      * @param name the name of the wakelock.
   1179      * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
   1180      * @param linePrefix a String to be prepended to each line of output.
   1181      * @return the line prefix
   1182      */
   1183     private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
   1184             String name, int which, String linePrefix) {
   1185         long totalTimeMicros = 0;
   1186         int count = 0;
   1187         if (timer != null) {
   1188             totalTimeMicros = timer.getTotalTimeLocked(now, which);
   1189             count = timer.getCountLocked(which);
   1190         }
   1191         sb.append(linePrefix);
   1192         sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
   1193         sb.append(',');
   1194         sb.append(name != null ? name + "," : "");
   1195         sb.append(count);
   1196         return ",";
   1197     }
   1198 
   1199     /**
   1200      * Dump a comma-separated line of values for terse checkin mode.
   1201      *
   1202      * @param pw the PageWriter to dump log to
   1203      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
   1204      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
   1205      * @param args type-dependent data arguments
   1206      */
   1207     private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
   1208            Object... args ) {
   1209         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
   1210         pw.print(uid); pw.print(',');
   1211         pw.print(category); pw.print(',');
   1212         pw.print(type);
   1213 
   1214         for (Object arg : args) {
   1215             pw.print(',');
   1216             pw.print(arg);
   1217         }
   1218         pw.println();
   1219     }
   1220 
   1221     /**
   1222      * Checkin server version of dump to produce more compact, computer-readable log.
   1223      *
   1224      * NOTE: all times are expressed in 'ms'.
   1225      */
   1226     public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) {
   1227         final long rawUptime = SystemClock.uptimeMillis() * 1000;
   1228         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
   1229         final long batteryUptime = getBatteryUptime(rawUptime);
   1230         final long batteryRealtime = getBatteryRealtime(rawRealtime);
   1231         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
   1232         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
   1233         final long totalRealtime = computeRealtime(rawRealtime, which);
   1234         final long totalUptime = computeUptime(rawUptime, which);
   1235         final long screenOnTime = getScreenOnTime(batteryRealtime, which);
   1236         final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
   1237         final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
   1238         final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
   1239         final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
   1240 
   1241         StringBuilder sb = new StringBuilder(128);
   1242 
   1243         SparseArray<? extends Uid> uidStats = getUidStats();
   1244         final int NU = uidStats.size();
   1245 
   1246         String category = STAT_NAMES[which];
   1247 
   1248         // Dump "battery" stat
   1249         dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
   1250                 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
   1251                 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
   1252                 totalRealtime / 1000, totalUptime / 1000);
   1253 
   1254         // Calculate total network and wakelock times across all uids.
   1255         long mobileRxTotal = 0;
   1256         long mobileTxTotal = 0;
   1257         long wifiRxTotal = 0;
   1258         long wifiTxTotal = 0;
   1259         long fullWakeLockTimeTotal = 0;
   1260         long partialWakeLockTimeTotal = 0;
   1261 
   1262         for (int iu = 0; iu < NU; iu++) {
   1263             Uid u = uidStats.valueAt(iu);
   1264             mobileRxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which);
   1265             mobileTxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which);
   1266             wifiRxTotal += u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which);
   1267             wifiTxTotal += u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which);
   1268 
   1269             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
   1270             if (wakelocks.size() > 0) {
   1271                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
   1272                         : wakelocks.entrySet()) {
   1273                     Uid.Wakelock wl = ent.getValue();
   1274 
   1275                     Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
   1276                     if (fullWakeTimer != null) {
   1277                         fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
   1278                     }
   1279 
   1280                     Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
   1281                     if (partialWakeTimer != null) {
   1282                         partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
   1283                             batteryRealtime, which);
   1284                     }
   1285                 }
   1286             }
   1287         }
   1288 
   1289         // Dump misc stats
   1290         dumpLine(pw, 0 /* uid */, category, MISC_DATA,
   1291                 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
   1292                 wifiRunningTime / 1000, bluetoothOnTime / 1000,
   1293                 mobileRxTotal, mobileTxTotal, wifiRxTotal, wifiTxTotal,
   1294                 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
   1295                 getInputEventCount(which));
   1296 
   1297         // Dump screen brightness stats
   1298         Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
   1299         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
   1300             args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
   1301         }
   1302         dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
   1303 
   1304         // Dump signal strength stats
   1305         args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
   1306         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
   1307             args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
   1308         }
   1309         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
   1310         dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
   1311                 getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
   1312         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
   1313             args[i] = getPhoneSignalStrengthCount(i, which);
   1314         }
   1315         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
   1316 
   1317         // Dump network type stats
   1318         args = new Object[NUM_DATA_CONNECTION_TYPES];
   1319         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
   1320             args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
   1321         }
   1322         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
   1323         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
   1324             args[i] = getPhoneDataConnectionCount(i, which);
   1325         }
   1326         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
   1327 
   1328         if (which == STATS_SINCE_UNPLUGGED) {
   1329             dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
   1330                     getDischargeCurrentLevel());
   1331         }
   1332 
   1333         if (which == STATS_SINCE_UNPLUGGED) {
   1334             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
   1335                     getDischargeStartLevel()-getDischargeCurrentLevel(),
   1336                     getDischargeStartLevel()-getDischargeCurrentLevel(),
   1337                     getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
   1338         } else {
   1339             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
   1340                     getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
   1341                     getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
   1342         }
   1343 
   1344         if (reqUid < 0) {
   1345             Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
   1346             if (kernelWakelocks.size() > 0) {
   1347                 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
   1348                     sb.setLength(0);
   1349                     printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
   1350 
   1351                     dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
   1352                             sb.toString());
   1353                 }
   1354             }
   1355         }
   1356 
   1357         for (int iu = 0; iu < NU; iu++) {
   1358             final int uid = uidStats.keyAt(iu);
   1359             if (reqUid >= 0 && uid != reqUid) {
   1360                 continue;
   1361             }
   1362             Uid u = uidStats.valueAt(iu);
   1363             // Dump Network stats per uid, if any
   1364             long mobileRx = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which);
   1365             long mobileTx = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which);
   1366             long wifiRx = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which);
   1367             long wifiTx = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which);
   1368             long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
   1369             long wifiScanTime = u.getWifiScanTime(batteryRealtime, which);
   1370             long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
   1371 
   1372             if (mobileRx > 0 || mobileTx > 0 || wifiRx > 0 || wifiTx > 0) {
   1373                 dumpLine(pw, uid, category, NETWORK_DATA, mobileRx, mobileTx, wifiRx, wifiTx);
   1374             }
   1375 
   1376             if (fullWifiLockOnTime != 0 || wifiScanTime != 0
   1377                     || uidWifiRunningTime != 0) {
   1378                 dumpLine(pw, uid, category, WIFI_DATA,
   1379                         fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime);
   1380             }
   1381 
   1382             if (u.hasUserActivity()) {
   1383                 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
   1384                 boolean hasData = false;
   1385                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
   1386                     int val = u.getUserActivityCount(i, which);
   1387                     args[i] = val;
   1388                     if (val != 0) hasData = true;
   1389                 }
   1390                 if (hasData) {
   1391                     dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args);
   1392                 }
   1393             }
   1394 
   1395             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
   1396             if (wakelocks.size() > 0) {
   1397                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
   1398                         : wakelocks.entrySet()) {
   1399                     Uid.Wakelock wl = ent.getValue();
   1400                     String linePrefix = "";
   1401                     sb.setLength(0);
   1402                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
   1403                             batteryRealtime, "f", which, linePrefix);
   1404                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
   1405                             batteryRealtime, "p", which, linePrefix);
   1406                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
   1407                             batteryRealtime, "w", which, linePrefix);
   1408 
   1409                     // Only log if we had at lease one wakelock...
   1410                     if (sb.length() > 0) {
   1411                         String name = ent.getKey();
   1412                         if (name.indexOf(',') >= 0) {
   1413                             name = name.replace(',', '_');
   1414                         }
   1415                         dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
   1416                     }
   1417                 }
   1418             }
   1419 
   1420             Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
   1421             if (sensors.size() > 0)  {
   1422                 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
   1423                         : sensors.entrySet()) {
   1424                     Uid.Sensor se = ent.getValue();
   1425                     int sensorNumber = ent.getKey();
   1426                     Timer timer = se.getSensorTime();
   1427                     if (timer != null) {
   1428                         // Convert from microseconds to milliseconds with rounding
   1429                         long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
   1430                         int count = timer.getCountLocked(which);
   1431                         if (totalTime != 0) {
   1432                             dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
   1433                         }
   1434                     }
   1435                 }
   1436             }
   1437 
   1438             Timer vibTimer = u.getVibratorOnTimer();
   1439             if (vibTimer != null) {
   1440                 // Convert from microseconds to milliseconds with rounding
   1441                 long totalTime = (vibTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
   1442                 int count = vibTimer.getCountLocked(which);
   1443                 if (totalTime != 0) {
   1444                     dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count);
   1445                 }
   1446             }
   1447 
   1448             Timer fgTimer = u.getForegroundActivityTimer();
   1449             if (fgTimer != null) {
   1450                 // Convert from microseconds to milliseconds with rounding
   1451                 long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
   1452                 int count = fgTimer.getCountLocked(which);
   1453                 if (totalTime != 0) {
   1454                     dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count);
   1455                 }
   1456             }
   1457 
   1458             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
   1459             if (processStats.size() > 0) {
   1460                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
   1461                         : processStats.entrySet()) {
   1462                     Uid.Proc ps = ent.getValue();
   1463 
   1464                     final long userMillis = ps.getUserTime(which) * 10;
   1465                     final long systemMillis = ps.getSystemTime(which) * 10;
   1466                     final long foregroundMillis = ps.getForegroundTime(which) * 10;
   1467                     final long starts = ps.getStarts(which);
   1468 
   1469                     if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
   1470                             || starts != 0) {
   1471                         dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis,
   1472                                 systemMillis, foregroundMillis, starts);
   1473                     }
   1474                 }
   1475             }
   1476 
   1477             Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
   1478             if (packageStats.size() > 0) {
   1479                 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
   1480                         : packageStats.entrySet()) {
   1481 
   1482                     Uid.Pkg ps = ent.getValue();
   1483                     int wakeups = ps.getWakeups(which);
   1484                     Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
   1485                     for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
   1486                             : serviceStats.entrySet()) {
   1487                         BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
   1488                         long startTime = ss.getStartTime(batteryUptime, which);
   1489                         int starts = ss.getStarts(which);
   1490                         int launches = ss.getLaunches(which);
   1491                         if (startTime != 0 || starts != 0 || launches != 0) {
   1492                             dumpLine(pw, uid, category, APK_DATA,
   1493                                     wakeups, // wakeup alarms
   1494                                     ent.getKey(), // Apk
   1495                                     sent.getKey(), // service
   1496                                     startTime / 1000, // time spent started, in ms
   1497                                     starts,
   1498                                     launches);
   1499                         }
   1500                     }
   1501                 }
   1502             }
   1503         }
   1504     }
   1505 
   1506     static final class TimerEntry {
   1507         final String mName;
   1508         final int mId;
   1509         final BatteryStats.Timer mTimer;
   1510         final long mTime;
   1511         TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
   1512             mName = name;
   1513             mId = id;
   1514             mTimer = timer;
   1515             mTime = time;
   1516         }
   1517     }
   1518 
   1519     @SuppressWarnings("unused")
   1520     public final void dumpLocked(PrintWriter pw, String prefix, final int which, int reqUid) {
   1521         final long rawUptime = SystemClock.uptimeMillis() * 1000;
   1522         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
   1523         final long batteryUptime = getBatteryUptime(rawUptime);
   1524         final long batteryRealtime = getBatteryRealtime(rawRealtime);
   1525 
   1526         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
   1527         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
   1528         final long totalRealtime = computeRealtime(rawRealtime, which);
   1529         final long totalUptime = computeUptime(rawUptime, which);
   1530 
   1531         StringBuilder sb = new StringBuilder(128);
   1532 
   1533         SparseArray<? extends Uid> uidStats = getUidStats();
   1534         final int NU = uidStats.size();
   1535 
   1536         sb.setLength(0);
   1537         sb.append(prefix);
   1538                 sb.append("  Time on battery: ");
   1539                 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
   1540                 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
   1541                 sb.append(") realtime, ");
   1542                 formatTimeMs(sb, whichBatteryUptime / 1000);
   1543                 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
   1544                 sb.append(") uptime");
   1545         pw.println(sb.toString());
   1546         sb.setLength(0);
   1547         sb.append(prefix);
   1548                 sb.append("  Total run time: ");
   1549                 formatTimeMs(sb, totalRealtime / 1000);
   1550                 sb.append("realtime, ");
   1551                 formatTimeMs(sb, totalUptime / 1000);
   1552                 sb.append("uptime, ");
   1553         pw.println(sb.toString());
   1554 
   1555         final long screenOnTime = getScreenOnTime(batteryRealtime, which);
   1556         final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
   1557         final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
   1558         final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
   1559         final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
   1560         sb.setLength(0);
   1561         sb.append(prefix);
   1562                 sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
   1563                 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
   1564                 sb.append("), Input events: "); sb.append(getInputEventCount(which));
   1565                 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
   1566                 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
   1567                 sb.append(")");
   1568         pw.println(sb.toString());
   1569         sb.setLength(0);
   1570         sb.append(prefix);
   1571         sb.append("  Screen brightnesses: ");
   1572         boolean didOne = false;
   1573         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
   1574             final long time = getScreenBrightnessTime(i, batteryRealtime, which);
   1575             if (time == 0) {
   1576                 continue;
   1577             }
   1578             if (didOne) sb.append(", ");
   1579             didOne = true;
   1580             sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
   1581             sb.append(" ");
   1582             formatTimeMs(sb, time/1000);
   1583             sb.append("(");
   1584             sb.append(formatRatioLocked(time, screenOnTime));
   1585             sb.append(")");
   1586         }
   1587         if (!didOne) sb.append("No activity");
   1588         pw.println(sb.toString());
   1589 
   1590         // Calculate total network and wakelock times across all uids.
   1591         long mobileRxTotal = 0;
   1592         long mobileTxTotal = 0;
   1593         long wifiRxTotal = 0;
   1594         long wifiTxTotal = 0;
   1595         long fullWakeLockTimeTotalMicros = 0;
   1596         long partialWakeLockTimeTotalMicros = 0;
   1597 
   1598         final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
   1599             @Override
   1600             public int compare(TimerEntry lhs, TimerEntry rhs) {
   1601                 long lhsTime = lhs.mTime;
   1602                 long rhsTime = rhs.mTime;
   1603                 if (lhsTime < rhsTime) {
   1604                     return 1;
   1605                 }
   1606                 if (lhsTime > rhsTime) {
   1607                     return -1;
   1608                 }
   1609                 return 0;
   1610             }
   1611         };
   1612 
   1613         if (reqUid < 0) {
   1614             Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
   1615             if (kernelWakelocks.size() > 0) {
   1616                 final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
   1617                 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
   1618                     BatteryStats.Timer timer = ent.getValue();
   1619                     long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which);
   1620                     if (totalTimeMillis > 0) {
   1621                         timers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
   1622                     }
   1623                 }
   1624                 Collections.sort(timers, timerComparator);
   1625                 for (int i=0; i<timers.size(); i++) {
   1626                     TimerEntry timer = timers.get(i);
   1627                     String linePrefix = ": ";
   1628                     sb.setLength(0);
   1629                     sb.append(prefix);
   1630                     sb.append("  Kernel Wake lock ");
   1631                     sb.append(timer.mName);
   1632                     linePrefix = printWakeLock(sb, timer.mTimer, batteryRealtime, null,
   1633                             which, linePrefix);
   1634                     if (!linePrefix.equals(": ")) {
   1635                         sb.append(" realtime");
   1636                         // Only print out wake locks that were held
   1637                         pw.println(sb.toString());
   1638                     }
   1639                 }
   1640             }
   1641         }
   1642 
   1643         final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
   1644 
   1645         for (int iu = 0; iu < NU; iu++) {
   1646             Uid u = uidStats.valueAt(iu);
   1647             mobileRxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which);
   1648             mobileTxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which);
   1649             wifiRxTotal += u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which);
   1650             wifiTxTotal += u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which);
   1651 
   1652             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
   1653             if (wakelocks.size() > 0) {
   1654                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
   1655                         : wakelocks.entrySet()) {
   1656                     Uid.Wakelock wl = ent.getValue();
   1657 
   1658                     Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
   1659                     if (fullWakeTimer != null) {
   1660                         fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
   1661                                 batteryRealtime, which);
   1662                     }
   1663 
   1664                     Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
   1665                     if (partialWakeTimer != null) {
   1666                         long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
   1667                                 batteryRealtime, which);
   1668                         if (totalTimeMicros > 0) {
   1669                             if (reqUid < 0) {
   1670                                 // Only show the ordered list of all wake
   1671                                 // locks if the caller is not asking for data
   1672                                 // about a specific uid.
   1673                                 timers.add(new TimerEntry(ent.getKey(), u.getUid(),
   1674                                         partialWakeTimer, totalTimeMicros));
   1675                             }
   1676                             partialWakeLockTimeTotalMicros += totalTimeMicros;
   1677                         }
   1678                     }
   1679                 }
   1680             }
   1681         }
   1682 
   1683         pw.print(prefix);
   1684                 pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotal));
   1685                 pw.print(", Total sent: "); pw.println(formatBytesLocked(mobileTxTotal));
   1686         pw.print(prefix);
   1687                 pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotal));
   1688                 pw.print(", Total sent: "); pw.println(formatBytesLocked(wifiTxTotal));
   1689         sb.setLength(0);
   1690         sb.append(prefix);
   1691                 sb.append("  Total full wakelock time: "); formatTimeMs(sb,
   1692                         (fullWakeLockTimeTotalMicros + 500) / 1000);
   1693                 sb.append(", Total partial wakelock time: "); formatTimeMs(sb,
   1694                         (partialWakeLockTimeTotalMicros + 500) / 1000);
   1695         pw.println(sb.toString());
   1696 
   1697         sb.setLength(0);
   1698         sb.append(prefix);
   1699         sb.append("  Signal levels: ");
   1700         didOne = false;
   1701         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
   1702             final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
   1703             if (time == 0) {
   1704                 continue;
   1705             }
   1706             if (didOne) sb.append(", ");
   1707             didOne = true;
   1708             sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
   1709             sb.append(" ");
   1710             formatTimeMs(sb, time/1000);
   1711             sb.append("(");
   1712             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   1713             sb.append(") ");
   1714             sb.append(getPhoneSignalStrengthCount(i, which));
   1715             sb.append("x");
   1716         }
   1717         if (!didOne) sb.append("No activity");
   1718         pw.println(sb.toString());
   1719 
   1720         sb.setLength(0);
   1721         sb.append(prefix);
   1722         sb.append("  Signal scanning time: ");
   1723         formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
   1724         pw.println(sb.toString());
   1725 
   1726         sb.setLength(0);
   1727         sb.append(prefix);
   1728         sb.append("  Radio types: ");
   1729         didOne = false;
   1730         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
   1731             final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
   1732             if (time == 0) {
   1733                 continue;
   1734             }
   1735             if (didOne) sb.append(", ");
   1736             didOne = true;
   1737             sb.append(DATA_CONNECTION_NAMES[i]);
   1738             sb.append(" ");
   1739             formatTimeMs(sb, time/1000);
   1740             sb.append("(");
   1741             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   1742             sb.append(") ");
   1743             sb.append(getPhoneDataConnectionCount(i, which));
   1744             sb.append("x");
   1745         }
   1746         if (!didOne) sb.append("No activity");
   1747         pw.println(sb.toString());
   1748 
   1749         sb.setLength(0);
   1750         sb.append(prefix);
   1751         sb.append("  Radio data uptime when unplugged: ");
   1752         sb.append(getRadioDataUptime() / 1000);
   1753         sb.append(" ms");
   1754         pw.println(sb.toString());
   1755 
   1756         sb.setLength(0);
   1757         sb.append(prefix);
   1758                 sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
   1759                 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
   1760                 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
   1761                 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
   1762                 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
   1763                 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
   1764                 sb.append(")");
   1765         pw.println(sb.toString());
   1766 
   1767         pw.println(" ");
   1768 
   1769         if (which == STATS_SINCE_UNPLUGGED) {
   1770             if (getIsOnBattery()) {
   1771                 pw.print(prefix); pw.println("  Device is currently unplugged");
   1772                 pw.print(prefix); pw.print("    Discharge cycle start level: ");
   1773                         pw.println(getDischargeStartLevel());
   1774                 pw.print(prefix); pw.print("    Discharge cycle current level: ");
   1775                         pw.println(getDischargeCurrentLevel());
   1776             } else {
   1777                 pw.print(prefix); pw.println("  Device is currently plugged into power");
   1778                 pw.print(prefix); pw.print("    Last discharge cycle start level: ");
   1779                         pw.println(getDischargeStartLevel());
   1780                 pw.print(prefix); pw.print("    Last discharge cycle end level: ");
   1781                         pw.println(getDischargeCurrentLevel());
   1782             }
   1783             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
   1784                     pw.println(getDischargeAmountScreenOn());
   1785             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
   1786                     pw.println(getDischargeAmountScreenOff());
   1787             pw.println(" ");
   1788         } else {
   1789             pw.print(prefix); pw.println("  Device battery use since last full charge");
   1790             pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
   1791                     pw.println(getLowDischargeAmountSinceCharge());
   1792             pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
   1793                     pw.println(getHighDischargeAmountSinceCharge());
   1794             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
   1795                     pw.println(getDischargeAmountScreenOnSinceCharge());
   1796             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
   1797                     pw.println(getDischargeAmountScreenOffSinceCharge());
   1798             pw.println();
   1799         }
   1800 
   1801         if (timers.size() > 0) {
   1802             Collections.sort(timers, timerComparator);
   1803             pw.print(prefix); pw.println("  All partial wake locks:");
   1804             for (int i=0; i<timers.size(); i++) {
   1805                 TimerEntry timer = timers.get(i);
   1806                 sb.setLength(0);
   1807                 sb.append("  Wake lock ");
   1808                 UserHandle.formatUid(sb, timer.mId);
   1809                 sb.append(" ");
   1810                 sb.append(timer.mName);
   1811                 printWakeLock(sb, timer.mTimer, batteryRealtime, null, which, ": ");
   1812                 sb.append(" realtime");
   1813                 pw.println(sb.toString());
   1814             }
   1815             timers.clear();
   1816             pw.println();
   1817         }
   1818 
   1819         for (int iu=0; iu<NU; iu++) {
   1820             final int uid = uidStats.keyAt(iu);
   1821             if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
   1822                 continue;
   1823             }
   1824 
   1825             Uid u = uidStats.valueAt(iu);
   1826 
   1827             pw.print(prefix);
   1828             pw.print("  ");
   1829             UserHandle.formatUid(pw, uid);
   1830             pw.println(":");
   1831             boolean uidActivity = false;
   1832 
   1833             long mobileRxBytes = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which);
   1834             long mobileTxBytes = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which);
   1835             long wifiRxBytes = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which);
   1836             long wifiTxBytes = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which);
   1837             long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
   1838             long wifiScanTime = u.getWifiScanTime(batteryRealtime, which);
   1839             long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
   1840 
   1841             if (mobileRxBytes > 0 || mobileTxBytes > 0) {
   1842                 pw.print(prefix); pw.print("    Mobile network: ");
   1843                         pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
   1844                         pw.print(formatBytesLocked(mobileTxBytes)); pw.println(" sent");
   1845             }
   1846             if (wifiRxBytes > 0 || wifiTxBytes > 0) {
   1847                 pw.print(prefix); pw.print("    Wi-Fi network: ");
   1848                         pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
   1849                         pw.print(formatBytesLocked(wifiTxBytes)); pw.println(" sent");
   1850             }
   1851 
   1852             if (u.hasUserActivity()) {
   1853                 boolean hasData = false;
   1854                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
   1855                     int val = u.getUserActivityCount(i, which);
   1856                     if (val != 0) {
   1857                         if (!hasData) {
   1858                             sb.setLength(0);
   1859                             sb.append("    User activity: ");
   1860                             hasData = true;
   1861                         } else {
   1862                             sb.append(", ");
   1863                         }
   1864                         sb.append(val);
   1865                         sb.append(" ");
   1866                         sb.append(Uid.USER_ACTIVITY_TYPES[i]);
   1867                     }
   1868                 }
   1869                 if (hasData) {
   1870                     pw.println(sb.toString());
   1871                 }
   1872             }
   1873 
   1874             if (fullWifiLockOnTime != 0 || wifiScanTime != 0
   1875                     || uidWifiRunningTime != 0) {
   1876                 sb.setLength(0);
   1877                 sb.append(prefix); sb.append("    Wifi Running: ");
   1878                         formatTimeMs(sb, uidWifiRunningTime / 1000);
   1879                         sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
   1880                                 whichBatteryRealtime)); sb.append(")\n");
   1881                 sb.append(prefix); sb.append("    Full Wifi Lock: ");
   1882                         formatTimeMs(sb, fullWifiLockOnTime / 1000);
   1883                         sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
   1884                                 whichBatteryRealtime)); sb.append(")\n");
   1885                 sb.append(prefix); sb.append("    Wifi Scan: ");
   1886                         formatTimeMs(sb, wifiScanTime / 1000);
   1887                         sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
   1888                                 whichBatteryRealtime)); sb.append(")");
   1889                 pw.println(sb.toString());
   1890             }
   1891 
   1892             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
   1893             if (wakelocks.size() > 0) {
   1894                 long totalFull = 0, totalPartial = 0, totalWindow = 0;
   1895                 int count = 0;
   1896                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
   1897                     : wakelocks.entrySet()) {
   1898                     Uid.Wakelock wl = ent.getValue();
   1899                     String linePrefix = ": ";
   1900                     sb.setLength(0);
   1901                     sb.append(prefix);
   1902                     sb.append("    Wake lock ");
   1903                     sb.append(ent.getKey());
   1904                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
   1905                             "full", which, linePrefix);
   1906                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
   1907                             "partial", which, linePrefix);
   1908                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
   1909                             "window", which, linePrefix);
   1910                     if (!linePrefix.equals(": ")) {
   1911                         sb.append(" realtime");
   1912                         // Only print out wake locks that were held
   1913                         pw.println(sb.toString());
   1914                         uidActivity = true;
   1915                         count++;
   1916                     }
   1917                     totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
   1918                             batteryRealtime, which);
   1919                     totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
   1920                             batteryRealtime, which);
   1921                     totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
   1922                             batteryRealtime, which);
   1923                 }
   1924                 if (count > 1) {
   1925                     if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) {
   1926                         sb.setLength(0);
   1927                         sb.append(prefix);
   1928                         sb.append("    TOTAL wake: ");
   1929                         boolean needComma = false;
   1930                         if (totalFull != 0) {
   1931                             needComma = true;
   1932                             formatTimeMs(sb, totalFull);
   1933                             sb.append("full");
   1934                         }
   1935                         if (totalPartial != 0) {
   1936                             if (needComma) {
   1937                                 sb.append(", ");
   1938                             }
   1939                             needComma = true;
   1940                             formatTimeMs(sb, totalPartial);
   1941                             sb.append("partial");
   1942                         }
   1943                         if (totalWindow != 0) {
   1944                             if (needComma) {
   1945                                 sb.append(", ");
   1946                             }
   1947                             needComma = true;
   1948                             formatTimeMs(sb, totalWindow);
   1949                             sb.append("window");
   1950                         }
   1951                         sb.append(" realtime");
   1952                         pw.println(sb.toString());
   1953                     }
   1954                 }
   1955             }
   1956 
   1957             Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
   1958             if (sensors.size() > 0) {
   1959                 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
   1960                     : sensors.entrySet()) {
   1961                     Uid.Sensor se = ent.getValue();
   1962                     int sensorNumber = ent.getKey();
   1963                     sb.setLength(0);
   1964                     sb.append(prefix);
   1965                     sb.append("    Sensor ");
   1966                     int handle = se.getHandle();
   1967                     if (handle == Uid.Sensor.GPS) {
   1968                         sb.append("GPS");
   1969                     } else {
   1970                         sb.append(handle);
   1971                     }
   1972                     sb.append(": ");
   1973 
   1974                     Timer timer = se.getSensorTime();
   1975                     if (timer != null) {
   1976                         // Convert from microseconds to milliseconds with rounding
   1977                         long totalTime = (timer.getTotalTimeLocked(
   1978                                 batteryRealtime, which) + 500) / 1000;
   1979                         int count = timer.getCountLocked(which);
   1980                         //timer.logState();
   1981                         if (totalTime != 0) {
   1982                             formatTimeMs(sb, totalTime);
   1983                             sb.append("realtime (");
   1984                             sb.append(count);
   1985                             sb.append(" times)");
   1986                         } else {
   1987                             sb.append("(not used)");
   1988                         }
   1989                     } else {
   1990                         sb.append("(not used)");
   1991                     }
   1992 
   1993                     pw.println(sb.toString());
   1994                     uidActivity = true;
   1995                 }
   1996             }
   1997 
   1998             Timer vibTimer = u.getVibratorOnTimer();
   1999             if (vibTimer != null) {
   2000                 // Convert from microseconds to milliseconds with rounding
   2001                 long totalTime = (vibTimer.getTotalTimeLocked(
   2002                         batteryRealtime, which) + 500) / 1000;
   2003                 int count = vibTimer.getCountLocked(which);
   2004                 //timer.logState();
   2005                 if (totalTime != 0) {
   2006                     sb.setLength(0);
   2007                     sb.append(prefix);
   2008                     sb.append("    Vibrator: ");
   2009                     formatTimeMs(sb, totalTime);
   2010                     sb.append("realtime (");
   2011                     sb.append(count);
   2012                     sb.append(" times)");
   2013                     pw.println(sb.toString());
   2014                     uidActivity = true;
   2015                 }
   2016             }
   2017 
   2018             Timer fgTimer = u.getForegroundActivityTimer();
   2019             if (fgTimer != null) {
   2020                 // Convert from microseconds to milliseconds with rounding
   2021                 long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
   2022                 int count = fgTimer.getCountLocked(which);
   2023                 if (totalTime != 0) {
   2024                     sb.setLength(0);
   2025                     sb.append(prefix);
   2026                     sb.append("    Foreground activities: ");
   2027                     formatTimeMs(sb, totalTime);
   2028                     sb.append("realtime (");
   2029                     sb.append(count);
   2030                     sb.append(" times)");
   2031                     pw.println(sb.toString());
   2032                     uidActivity = true;
   2033                 }
   2034             }
   2035 
   2036             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
   2037             if (processStats.size() > 0) {
   2038                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
   2039                     : processStats.entrySet()) {
   2040                     Uid.Proc ps = ent.getValue();
   2041                     long userTime;
   2042                     long systemTime;
   2043                     long foregroundTime;
   2044                     int starts;
   2045                     int numExcessive;
   2046 
   2047                     userTime = ps.getUserTime(which);
   2048                     systemTime = ps.getSystemTime(which);
   2049                     foregroundTime = ps.getForegroundTime(which);
   2050                     starts = ps.getStarts(which);
   2051                     numExcessive = which == STATS_SINCE_CHARGED
   2052                             ? ps.countExcessivePowers() : 0;
   2053 
   2054                     if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
   2055                             || numExcessive != 0) {
   2056                         sb.setLength(0);
   2057                         sb.append(prefix); sb.append("    Proc ");
   2058                                 sb.append(ent.getKey()); sb.append(":\n");
   2059                         sb.append(prefix); sb.append("      CPU: ");
   2060                                 formatTime(sb, userTime); sb.append("usr + ");
   2061                                 formatTime(sb, systemTime); sb.append("krn ; ");
   2062                                 formatTime(sb, foregroundTime); sb.append("fg");
   2063                         if (starts != 0) {
   2064                             sb.append("\n"); sb.append(prefix); sb.append("      ");
   2065                                     sb.append(starts); sb.append(" proc starts");
   2066                         }
   2067                         pw.println(sb.toString());
   2068                         for (int e=0; e<numExcessive; e++) {
   2069                             Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
   2070                             if (ew != null) {
   2071                                 pw.print(prefix); pw.print("      * Killed for ");
   2072                                         if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
   2073                                             pw.print("wake lock");
   2074                                         } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
   2075                                             pw.print("cpu");
   2076                                         } else {
   2077                                             pw.print("unknown");
   2078                                         }
   2079                                         pw.print(" use: ");
   2080                                         TimeUtils.formatDuration(ew.usedTime, pw);
   2081                                         pw.print(" over ");
   2082                                         TimeUtils.formatDuration(ew.overTime, pw);
   2083                                         pw.print(" (");
   2084                                         pw.print((ew.usedTime*100)/ew.overTime);
   2085                                         pw.println("%)");
   2086                             }
   2087                         }
   2088                         uidActivity = true;
   2089                     }
   2090                 }
   2091             }
   2092 
   2093             Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
   2094             if (packageStats.size() > 0) {
   2095                 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
   2096                     : packageStats.entrySet()) {
   2097                     pw.print(prefix); pw.print("    Apk "); pw.print(ent.getKey()); pw.println(":");
   2098                     boolean apkActivity = false;
   2099                     Uid.Pkg ps = ent.getValue();
   2100                     int wakeups = ps.getWakeups(which);
   2101                     if (wakeups != 0) {
   2102                         pw.print(prefix); pw.print("      ");
   2103                                 pw.print(wakeups); pw.println(" wakeup alarms");
   2104                         apkActivity = true;
   2105                     }
   2106                     Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
   2107                     if (serviceStats.size() > 0) {
   2108                         for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
   2109                                 : serviceStats.entrySet()) {
   2110                             BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
   2111                             long startTime = ss.getStartTime(batteryUptime, which);
   2112                             int starts = ss.getStarts(which);
   2113                             int launches = ss.getLaunches(which);
   2114                             if (startTime != 0 || starts != 0 || launches != 0) {
   2115                                 sb.setLength(0);
   2116                                 sb.append(prefix); sb.append("      Service ");
   2117                                         sb.append(sent.getKey()); sb.append(":\n");
   2118                                 sb.append(prefix); sb.append("        Created for: ");
   2119                                         formatTimeMs(sb, startTime / 1000);
   2120                                         sb.append("uptime\n");
   2121                                 sb.append(prefix); sb.append("        Starts: ");
   2122                                         sb.append(starts);
   2123                                         sb.append(", launches: "); sb.append(launches);
   2124                                 pw.println(sb.toString());
   2125                                 apkActivity = true;
   2126                             }
   2127                         }
   2128                     }
   2129                     if (!apkActivity) {
   2130                         pw.print(prefix); pw.println("      (nothing executed)");
   2131                     }
   2132                     uidActivity = true;
   2133                 }
   2134             }
   2135             if (!uidActivity) {
   2136                 pw.print(prefix); pw.println("    (nothing executed)");
   2137             }
   2138         }
   2139     }
   2140 
   2141     static void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) {
   2142         int diff = oldval ^ newval;
   2143         if (diff == 0) return;
   2144         for (int i=0; i<descriptions.length; i++) {
   2145             BitDescription bd = descriptions[i];
   2146             if ((diff&bd.mask) != 0) {
   2147                 if (bd.shift < 0) {
   2148                     pw.print((newval&bd.mask) != 0 ? " +" : " -");
   2149                     pw.print(bd.name);
   2150                 } else {
   2151                     pw.print(" ");
   2152                     pw.print(bd.name);
   2153                     pw.print("=");
   2154                     int val = (newval&bd.mask)>>bd.shift;
   2155                     if (bd.values != null && val >= 0 && val < bd.values.length) {
   2156                         pw.print(bd.values[val]);
   2157                     } else {
   2158                         pw.print(val);
   2159                     }
   2160                 }
   2161             }
   2162         }
   2163     }
   2164 
   2165     public void prepareForDumpLocked() {
   2166     }
   2167 
   2168     public static class HistoryPrinter {
   2169         int oldState = 0;
   2170         int oldStatus = -1;
   2171         int oldHealth = -1;
   2172         int oldPlug = -1;
   2173         int oldTemp = -1;
   2174         int oldVolt = -1;
   2175 
   2176         public void printNextItem(PrintWriter pw, HistoryItem rec, long now) {
   2177             pw.print("  ");
   2178             TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
   2179             pw.print(" ");
   2180             if (rec.cmd == HistoryItem.CMD_START) {
   2181                 pw.println(" START");
   2182             } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
   2183                 pw.println(" *OVERFLOW*");
   2184             } else {
   2185                 if (rec.batteryLevel < 10) pw.print("00");
   2186                 else if (rec.batteryLevel < 100) pw.print("0");
   2187                 pw.print(rec.batteryLevel);
   2188                 pw.print(" ");
   2189                 if (rec.states < 0x10) pw.print("0000000");
   2190                 else if (rec.states < 0x100) pw.print("000000");
   2191                 else if (rec.states < 0x1000) pw.print("00000");
   2192                 else if (rec.states < 0x10000) pw.print("0000");
   2193                 else if (rec.states < 0x100000) pw.print("000");
   2194                 else if (rec.states < 0x1000000) pw.print("00");
   2195                 else if (rec.states < 0x10000000) pw.print("0");
   2196                 pw.print(Integer.toHexString(rec.states));
   2197                 if (oldStatus != rec.batteryStatus) {
   2198                     oldStatus = rec.batteryStatus;
   2199                     pw.print(" status=");
   2200                     switch (oldStatus) {
   2201                         case BatteryManager.BATTERY_STATUS_UNKNOWN:
   2202                             pw.print("unknown");
   2203                             break;
   2204                         case BatteryManager.BATTERY_STATUS_CHARGING:
   2205                             pw.print("charging");
   2206                             break;
   2207                         case BatteryManager.BATTERY_STATUS_DISCHARGING:
   2208                             pw.print("discharging");
   2209                             break;
   2210                         case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
   2211                             pw.print("not-charging");
   2212                             break;
   2213                         case BatteryManager.BATTERY_STATUS_FULL:
   2214                             pw.print("full");
   2215                             break;
   2216                         default:
   2217                             pw.print(oldStatus);
   2218                             break;
   2219                     }
   2220                 }
   2221                 if (oldHealth != rec.batteryHealth) {
   2222                     oldHealth = rec.batteryHealth;
   2223                     pw.print(" health=");
   2224                     switch (oldHealth) {
   2225                         case BatteryManager.BATTERY_HEALTH_UNKNOWN:
   2226                             pw.print("unknown");
   2227                             break;
   2228                         case BatteryManager.BATTERY_HEALTH_GOOD:
   2229                             pw.print("good");
   2230                             break;
   2231                         case BatteryManager.BATTERY_HEALTH_OVERHEAT:
   2232                             pw.print("overheat");
   2233                             break;
   2234                         case BatteryManager.BATTERY_HEALTH_DEAD:
   2235                             pw.print("dead");
   2236                             break;
   2237                         case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
   2238                             pw.print("over-voltage");
   2239                             break;
   2240                         case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
   2241                             pw.print("failure");
   2242                             break;
   2243                         default:
   2244                             pw.print(oldHealth);
   2245                             break;
   2246                     }
   2247                 }
   2248                 if (oldPlug != rec.batteryPlugType) {
   2249                     oldPlug = rec.batteryPlugType;
   2250                     pw.print(" plug=");
   2251                     switch (oldPlug) {
   2252                         case 0:
   2253                             pw.print("none");
   2254                             break;
   2255                         case BatteryManager.BATTERY_PLUGGED_AC:
   2256                             pw.print("ac");
   2257                             break;
   2258                         case BatteryManager.BATTERY_PLUGGED_USB:
   2259                             pw.print("usb");
   2260                             break;
   2261                         case BatteryManager.BATTERY_PLUGGED_WIRELESS:
   2262                             pw.print("wireless");
   2263                             break;
   2264                         default:
   2265                             pw.print(oldPlug);
   2266                             break;
   2267                     }
   2268                 }
   2269                 if (oldTemp != rec.batteryTemperature) {
   2270                     oldTemp = rec.batteryTemperature;
   2271                     pw.print(" temp=");
   2272                     pw.print(oldTemp);
   2273                 }
   2274                 if (oldVolt != rec.batteryVoltage) {
   2275                     oldVolt = rec.batteryVoltage;
   2276                     pw.print(" volt=");
   2277                     pw.print(oldVolt);
   2278                 }
   2279                 printBitDescriptions(pw, oldState, rec.states,
   2280                         HISTORY_STATE_DESCRIPTIONS);
   2281                 pw.println();
   2282             }
   2283             oldState = rec.states;
   2284         }
   2285 
   2286         public void printNextItemCheckin(PrintWriter pw, HistoryItem rec, long now) {
   2287             pw.print(rec.time-now);
   2288             pw.print(",");
   2289             if (rec.cmd == HistoryItem.CMD_START) {
   2290                 pw.print("start");
   2291             } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
   2292                 pw.print("overflow");
   2293             } else {
   2294                 pw.print(rec.batteryLevel);
   2295                 pw.print(",");
   2296                 pw.print(rec.states);
   2297                 pw.print(",");
   2298                 pw.print(rec.batteryStatus);
   2299                 pw.print(",");
   2300                 pw.print(rec.batteryHealth);
   2301                 pw.print(",");
   2302                 pw.print(rec.batteryPlugType);
   2303                 pw.print(",");
   2304                 pw.print((int)rec.batteryTemperature);
   2305                 pw.print(",");
   2306                 pw.print((int)rec.batteryVoltage);
   2307             }
   2308         }
   2309     }
   2310 
   2311     /**
   2312      * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
   2313      *
   2314      * @param pw a Printer to receive the dump output.
   2315      */
   2316     @SuppressWarnings("unused")
   2317     public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
   2318         prepareForDumpLocked();
   2319 
   2320         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
   2321 
   2322         final HistoryItem rec = new HistoryItem();
   2323         if (startIteratingHistoryLocked()) {
   2324             pw.println("Battery History:");
   2325             HistoryPrinter hprinter = new HistoryPrinter();
   2326             while (getNextHistoryLocked(rec)) {
   2327                 hprinter.printNextItem(pw, rec, now);
   2328             }
   2329             finishIteratingHistoryLocked();
   2330             pw.println("");
   2331         }
   2332 
   2333         if (startIteratingOldHistoryLocked()) {
   2334             pw.println("Old battery History:");
   2335             HistoryPrinter hprinter = new HistoryPrinter();
   2336             while (getNextOldHistoryLocked(rec)) {
   2337                 hprinter.printNextItem(pw, rec, now);
   2338             }
   2339             finishIteratingOldHistoryLocked();
   2340             pw.println("");
   2341         }
   2342 
   2343         SparseArray<? extends Uid> uidStats = getUidStats();
   2344         final int NU = uidStats.size();
   2345         boolean didPid = false;
   2346         long nowRealtime = SystemClock.elapsedRealtime();
   2347         for (int i=0; i<NU; i++) {
   2348             Uid uid = uidStats.valueAt(i);
   2349             SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
   2350             if (pids != null) {
   2351                 for (int j=0; j<pids.size(); j++) {
   2352                     Uid.Pid pid = pids.valueAt(j);
   2353                     if (!didPid) {
   2354                         pw.println("Per-PID Stats:");
   2355                         didPid = true;
   2356                     }
   2357                     long time = pid.mWakeSum + (pid.mWakeStart != 0
   2358                             ? (nowRealtime - pid.mWakeStart) : 0);
   2359                     pw.print("  PID "); pw.print(pids.keyAt(j));
   2360                             pw.print(" wake time: ");
   2361                             TimeUtils.formatDuration(time, pw);
   2362                             pw.println("");
   2363                 }
   2364             }
   2365         }
   2366         if (didPid) {
   2367             pw.println("");
   2368         }
   2369 
   2370         if (!isUnpluggedOnly) {
   2371             pw.println("Statistics since last charge:");
   2372             pw.println("  System starts: " + getStartCount()
   2373                     + ", currently on battery: " + getIsOnBattery());
   2374             dumpLocked(pw, "", STATS_SINCE_CHARGED, reqUid);
   2375             pw.println("");
   2376         }
   2377         pw.println("Statistics since last unplugged:");
   2378         dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, reqUid);
   2379     }
   2380 
   2381     @SuppressWarnings("unused")
   2382     public void dumpCheckinLocked(
   2383             PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly,
   2384             boolean includeHistory) {
   2385         prepareForDumpLocked();
   2386 
   2387         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
   2388 
   2389         if (includeHistory) {
   2390             final HistoryItem rec = new HistoryItem();
   2391             if (startIteratingHistoryLocked()) {
   2392                 HistoryPrinter hprinter = new HistoryPrinter();
   2393                 while (getNextHistoryLocked(rec)) {
   2394                     pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
   2395                     pw.print(0); pw.print(',');
   2396                     pw.print(HISTORY_DATA); pw.print(',');
   2397                     hprinter.printNextItemCheckin(pw, rec, now);
   2398                     pw.println();
   2399                 }
   2400                 finishIteratingHistoryLocked();
   2401             }
   2402         }
   2403 
   2404         if (apps != null) {
   2405             SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
   2406             for (int i=0; i<apps.size(); i++) {
   2407                 ApplicationInfo ai = apps.get(i);
   2408                 ArrayList<String> pkgs = uids.get(ai.uid);
   2409                 if (pkgs == null) {
   2410                     pkgs = new ArrayList<String>();
   2411                     uids.put(ai.uid, pkgs);
   2412                 }
   2413                 pkgs.add(ai.packageName);
   2414             }
   2415             SparseArray<? extends Uid> uidStats = getUidStats();
   2416             final int NU = uidStats.size();
   2417             String[] lineArgs = new String[2];
   2418             for (int i=0; i<NU; i++) {
   2419                 int uid = uidStats.keyAt(i);
   2420                 ArrayList<String> pkgs = uids.get(uid);
   2421                 if (pkgs != null) {
   2422                     for (int j=0; j<pkgs.size(); j++) {
   2423                         lineArgs[0] = Integer.toString(uid);
   2424                         lineArgs[1] = pkgs.get(j);
   2425                         dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
   2426                                 (Object[])lineArgs);
   2427                     }
   2428                 }
   2429             }
   2430         }
   2431         if (isUnpluggedOnly) {
   2432             dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
   2433         }
   2434         else {
   2435             dumpCheckinLocked(pw, STATS_SINCE_CHARGED, -1);
   2436             dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
   2437         }
   2438     }
   2439 }
   2440