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