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