Home | History | Annotate | Download | only in os
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.os;
     18 
     19 import java.io.PrintWriter;
     20 import java.util.ArrayList;
     21 import java.util.Collections;
     22 import java.util.Comparator;
     23 import java.util.Formatter;
     24 import java.util.HashMap;
     25 import java.util.List;
     26 import java.util.Map;
     27 
     28 import android.content.Context;
     29 import android.content.pm.ApplicationInfo;
     30 import android.telephony.SignalStrength;
     31 import android.text.format.DateFormat;
     32 import android.util.ArrayMap;
     33 import android.util.MutableBoolean;
     34 import android.util.Pair;
     35 import android.util.Printer;
     36 import android.util.SparseArray;
     37 import android.util.SparseIntArray;
     38 import android.util.TimeUtils;
     39 import android.view.Display;
     40 import com.android.internal.os.BatterySipper;
     41 import com.android.internal.os.BatteryStatsHelper;
     42 
     43 /**
     44  * A class providing access to battery usage statistics, including information on
     45  * wakelocks, processes, packages, and services.  All times are represented in microseconds
     46  * except where indicated otherwise.
     47  * @hide
     48  */
     49 public abstract class BatteryStats implements Parcelable {
     50 
     51     private static final boolean LOCAL_LOGV = false;
     52 
     53     /** @hide */
     54     public static final String SERVICE_NAME = "batterystats";
     55 
     56     /**
     57      * A constant indicating a partial wake lock timer.
     58      */
     59     public static final int WAKE_TYPE_PARTIAL = 0;
     60 
     61     /**
     62      * A constant indicating a full wake lock timer.
     63      */
     64     public static final int WAKE_TYPE_FULL = 1;
     65 
     66     /**
     67      * A constant indicating a window wake lock timer.
     68      */
     69     public static final int WAKE_TYPE_WINDOW = 2;
     70 
     71     /**
     72      * A constant indicating a sensor timer.
     73      */
     74     public static final int SENSOR = 3;
     75 
     76     /**
     77      * A constant indicating a a wifi running timer
     78      */
     79     public static final int WIFI_RUNNING = 4;
     80 
     81     /**
     82      * A constant indicating a full wifi lock timer
     83      */
     84     public static final int FULL_WIFI_LOCK = 5;
     85 
     86     /**
     87      * A constant indicating a wifi scan
     88      */
     89     public static final int WIFI_SCAN = 6;
     90 
     91     /**
     92      * A constant indicating a wifi multicast timer
     93      */
     94     public static final int WIFI_MULTICAST_ENABLED = 7;
     95 
     96     /**
     97      * A constant indicating a video turn on timer
     98      */
     99     public static final int VIDEO_TURNED_ON = 8;
    100 
    101     /**
    102      * A constant indicating a vibrator on timer
    103      */
    104     public static final int VIBRATOR_ON = 9;
    105 
    106     /**
    107      * A constant indicating a foreground activity timer
    108      */
    109     public static final int FOREGROUND_ACTIVITY = 10;
    110 
    111     /**
    112      * A constant indicating a wifi batched scan is active
    113      */
    114     public static final int WIFI_BATCHED_SCAN = 11;
    115 
    116     /**
    117      * A constant indicating a process state timer
    118      */
    119     public static final int PROCESS_STATE = 12;
    120 
    121     /**
    122      * A constant indicating a sync timer
    123      */
    124     public static final int SYNC = 13;
    125 
    126     /**
    127      * A constant indicating a job timer
    128      */
    129     public static final int JOB = 14;
    130 
    131     /**
    132      * A constant indicating an audio turn on timer
    133      */
    134     public static final int AUDIO_TURNED_ON = 15;
    135 
    136     /**
    137      * A constant indicating a flashlight turn on timer
    138      */
    139     public static final int FLASHLIGHT_TURNED_ON = 16;
    140 
    141     /**
    142      * A constant indicating a camera turn on timer
    143      */
    144     public static final int CAMERA_TURNED_ON = 17;
    145 
    146     /**
    147      * A constant indicating a draw wake lock timer.
    148      */
    149     public static final int WAKE_TYPE_DRAW = 18;
    150 
    151     /**
    152      * A constant indicating a bluetooth scan timer.
    153      */
    154     public static final int BLUETOOTH_SCAN_ON = 19;
    155 
    156     /**
    157      * Include all of the data in the stats, including previously saved data.
    158      */
    159     public static final int STATS_SINCE_CHARGED = 0;
    160 
    161     /**
    162      * Include only the current run in the stats.
    163      */
    164     public static final int STATS_CURRENT = 1;
    165 
    166     /**
    167      * Include only the run since the last time the device was unplugged in the stats.
    168      */
    169     public static final int STATS_SINCE_UNPLUGGED = 2;
    170 
    171     // NOTE: Update this list if you add/change any stats above.
    172     // These characters are supposed to represent "total", "last", "current",
    173     // and "unplugged". They were shortened for efficiency sake.
    174     private static final String[] STAT_NAMES = { "l", "c", "u" };
    175 
    176     /**
    177      * Current version of checkin data format.
    178      */
    179     static final String CHECKIN_VERSION = "18";
    180 
    181     /**
    182      * Old version, we hit 9 and ran out of room, need to remove.
    183      */
    184     private static final int BATTERY_STATS_CHECKIN_VERSION = 9;
    185 
    186     private static final long BYTES_PER_KB = 1024;
    187     private static final long BYTES_PER_MB = 1048576; // 1024^2
    188     private static final long BYTES_PER_GB = 1073741824; //1024^3
    189 
    190     private static final String VERSION_DATA = "vers";
    191     private static final String UID_DATA = "uid";
    192     private static final String WAKEUP_ALARM_DATA = "wua";
    193     private static final String APK_DATA = "apk";
    194     private static final String PROCESS_DATA = "pr";
    195     private static final String CPU_DATA = "cpu";
    196     private static final String SENSOR_DATA = "sr";
    197     private static final String VIBRATOR_DATA = "vib";
    198     private static final String FOREGROUND_DATA = "fg";
    199     private static final String STATE_TIME_DATA = "st";
    200     private static final String WAKELOCK_DATA = "wl";
    201     private static final String SYNC_DATA = "sy";
    202     private static final String JOB_DATA = "jb";
    203     private static final String KERNEL_WAKELOCK_DATA = "kwl";
    204     private static final String WAKEUP_REASON_DATA = "wr";
    205     private static final String NETWORK_DATA = "nt";
    206     private static final String USER_ACTIVITY_DATA = "ua";
    207     private static final String BATTERY_DATA = "bt";
    208     private static final String BATTERY_DISCHARGE_DATA = "dc";
    209     private static final String BATTERY_LEVEL_DATA = "lv";
    210     private static final String GLOBAL_WIFI_DATA = "gwfl";
    211     private static final String WIFI_DATA = "wfl";
    212     private static final String GLOBAL_WIFI_CONTROLLER_DATA = "gwfcd";
    213     private static final String WIFI_CONTROLLER_DATA = "wfcd";
    214     private static final String GLOBAL_BLUETOOTH_CONTROLLER_DATA = "gble";
    215     private static final String BLUETOOTH_CONTROLLER_DATA = "ble";
    216     private static final String BLUETOOTH_MISC_DATA = "blem";
    217     private static final String MISC_DATA = "m";
    218     private static final String GLOBAL_NETWORK_DATA = "gn";
    219     private static final String GLOBAL_MODEM_CONTROLLER_DATA = "gmcd";
    220     private static final String MODEM_CONTROLLER_DATA = "mcd";
    221     private static final String HISTORY_STRING_POOL = "hsp";
    222     private static final String HISTORY_DATA = "h";
    223     private static final String SCREEN_BRIGHTNESS_DATA = "br";
    224     private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
    225     private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
    226     private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
    227     private static final String DATA_CONNECTION_TIME_DATA = "dct";
    228     private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
    229     private static final String WIFI_STATE_TIME_DATA = "wst";
    230     private static final String WIFI_STATE_COUNT_DATA = "wsc";
    231     private static final String WIFI_SUPPL_STATE_TIME_DATA = "wsst";
    232     private static final String WIFI_SUPPL_STATE_COUNT_DATA = "wssc";
    233     private static final String WIFI_SIGNAL_STRENGTH_TIME_DATA = "wsgt";
    234     private static final String WIFI_SIGNAL_STRENGTH_COUNT_DATA = "wsgc";
    235     private static final String POWER_USE_SUMMARY_DATA = "pws";
    236     private static final String POWER_USE_ITEM_DATA = "pwi";
    237     private static final String DISCHARGE_STEP_DATA = "dsd";
    238     private static final String CHARGE_STEP_DATA = "csd";
    239     private static final String DISCHARGE_TIME_REMAIN_DATA = "dtr";
    240     private static final String CHARGE_TIME_REMAIN_DATA = "ctr";
    241     private static final String FLASHLIGHT_DATA = "fla";
    242     private static final String CAMERA_DATA = "cam";
    243     private static final String VIDEO_DATA = "vid";
    244     private static final String AUDIO_DATA = "aud";
    245 
    246     public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
    247 
    248     private final StringBuilder mFormatBuilder = new StringBuilder(32);
    249     private final Formatter mFormatter = new Formatter(mFormatBuilder);
    250 
    251     /**
    252      * State for keeping track of counting information.
    253      */
    254     public static abstract class Counter {
    255 
    256         /**
    257          * Returns the count associated with this Counter for the
    258          * selected type of statistics.
    259          *
    260          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
    261          */
    262         public abstract int getCountLocked(int which);
    263 
    264         /**
    265          * Temporary for debugging.
    266          */
    267         public abstract void logState(Printer pw, String prefix);
    268     }
    269 
    270     /**
    271      * State for keeping track of long counting information.
    272      */
    273     public static abstract class LongCounter {
    274 
    275         /**
    276          * Returns the count associated with this Counter for the
    277          * selected type of statistics.
    278          *
    279          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
    280          */
    281         public abstract long getCountLocked(int which);
    282 
    283         /**
    284          * Temporary for debugging.
    285          */
    286         public abstract void logState(Printer pw, String prefix);
    287     }
    288 
    289     /**
    290      * Container class that aggregates counters for transmit, receive, and idle state of a
    291      * radio controller.
    292      */
    293     public static abstract class ControllerActivityCounter {
    294         /**
    295          * @return a non-null {@link LongCounter} representing time spent (milliseconds) in the
    296          * idle state.
    297          */
    298         public abstract LongCounter getIdleTimeCounter();
    299 
    300         /**
    301          * @return a non-null {@link LongCounter} representing time spent (milliseconds) in the
    302          * receive state.
    303          */
    304         public abstract LongCounter getRxTimeCounter();
    305 
    306         /**
    307          * An array of {@link LongCounter}, representing various transmit levels, where each level
    308          * may draw a different amount of power. The levels themselves are controller-specific.
    309          * @return non-null array of {@link LongCounter}s representing time spent (milliseconds) in
    310          * various transmit level states.
    311          */
    312         public abstract LongCounter[] getTxTimeCounters();
    313 
    314         /**
    315          * @return a non-null {@link LongCounter} representing the power consumed by the controller
    316          * in all states, measured in milli-ampere-milliseconds (mAms). The counter may always
    317          * yield a value of 0 if the device doesn't support power calculations.
    318          */
    319         public abstract LongCounter getPowerCounter();
    320     }
    321 
    322     /**
    323      * State for keeping track of timing information.
    324      */
    325     public static abstract class Timer {
    326 
    327         /**
    328          * Returns the count associated with this Timer for the
    329          * selected type of statistics.
    330          *
    331          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
    332          */
    333         public abstract int getCountLocked(int which);
    334 
    335         /**
    336          * Returns the total time in microseconds associated with this Timer for the
    337          * selected type of statistics.
    338          *
    339          * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
    340          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
    341          * @return a time in microseconds
    342          */
    343         public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which);
    344 
    345         /**
    346          * Returns the total time in microseconds associated with this Timer since the
    347          * 'mark' was last set.
    348          *
    349          * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
    350          * @return a time in microseconds
    351          */
    352         public abstract long getTimeSinceMarkLocked(long elapsedRealtimeUs);
    353 
    354         /**
    355          * Temporary for debugging.
    356          */
    357         public abstract void logState(Printer pw, String prefix);
    358     }
    359 
    360     /**
    361      * The statistics associated with a particular uid.
    362      */
    363     public static abstract class Uid {
    364 
    365         /**
    366          * Returns a mapping containing wakelock statistics.
    367          *
    368          * @return a Map from Strings to Uid.Wakelock objects.
    369          */
    370         public abstract ArrayMap<String, ? extends Wakelock> getWakelockStats();
    371 
    372         /**
    373          * Returns a mapping containing sync statistics.
    374          *
    375          * @return a Map from Strings to Timer objects.
    376          */
    377         public abstract ArrayMap<String, ? extends Timer> getSyncStats();
    378 
    379         /**
    380          * Returns a mapping containing scheduled job statistics.
    381          *
    382          * @return a Map from Strings to Timer objects.
    383          */
    384         public abstract ArrayMap<String, ? extends Timer> getJobStats();
    385 
    386         /**
    387          * The statistics associated with a particular wake lock.
    388          */
    389         public static abstract class Wakelock {
    390             public abstract Timer getWakeTime(int type);
    391         }
    392 
    393         /**
    394          * Returns a mapping containing sensor statistics.
    395          *
    396          * @return a Map from Integer sensor ids to Uid.Sensor objects.
    397          */
    398         public abstract SparseArray<? extends Sensor> getSensorStats();
    399 
    400         /**
    401          * Returns a mapping containing active process data.
    402          */
    403         public abstract SparseArray<? extends Pid> getPidStats();
    404 
    405         /**
    406          * Returns a mapping containing process statistics.
    407          *
    408          * @return a Map from Strings to Uid.Proc objects.
    409          */
    410         public abstract ArrayMap<String, ? extends Proc> getProcessStats();
    411 
    412         /**
    413          * Returns a mapping containing package statistics.
    414          *
    415          * @return a Map from Strings to Uid.Pkg objects.
    416          */
    417         public abstract ArrayMap<String, ? extends Pkg> getPackageStats();
    418 
    419         public abstract ControllerActivityCounter getWifiControllerActivity();
    420         public abstract ControllerActivityCounter getBluetoothControllerActivity();
    421         public abstract ControllerActivityCounter getModemControllerActivity();
    422 
    423         /**
    424          * {@hide}
    425          */
    426         public abstract int getUid();
    427 
    428         public abstract void noteWifiRunningLocked(long elapsedRealtime);
    429         public abstract void noteWifiStoppedLocked(long elapsedRealtime);
    430         public abstract void noteFullWifiLockAcquiredLocked(long elapsedRealtime);
    431         public abstract void noteFullWifiLockReleasedLocked(long elapsedRealtime);
    432         public abstract void noteWifiScanStartedLocked(long elapsedRealtime);
    433         public abstract void noteWifiScanStoppedLocked(long elapsedRealtime);
    434         public abstract void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime);
    435         public abstract void noteWifiBatchedScanStoppedLocked(long elapsedRealtime);
    436         public abstract void noteWifiMulticastEnabledLocked(long elapsedRealtime);
    437         public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime);
    438         public abstract void noteActivityResumedLocked(long elapsedRealtime);
    439         public abstract void noteActivityPausedLocked(long elapsedRealtime);
    440         public abstract long getWifiRunningTime(long elapsedRealtimeUs, int which);
    441         public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which);
    442         public abstract long getWifiScanTime(long elapsedRealtimeUs, int which);
    443         public abstract int getWifiScanCount(int which);
    444         public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which);
    445         public abstract int getWifiBatchedScanCount(int csphBin, int which);
    446         public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which);
    447         public abstract Timer getAudioTurnedOnTimer();
    448         public abstract Timer getVideoTurnedOnTimer();
    449         public abstract Timer getFlashlightTurnedOnTimer();
    450         public abstract Timer getCameraTurnedOnTimer();
    451         public abstract Timer getForegroundActivityTimer();
    452         public abstract Timer getBluetoothScanTimer();
    453 
    454         // Note: the following times are disjoint.  They can be added together to find the
    455         // total time a uid has had any processes running at all.
    456 
    457         /**
    458          * Time this uid has any processes in the top state (or above such as persistent).
    459          */
    460         public static final int PROCESS_STATE_TOP = 0;
    461         /**
    462          * Time this uid has any process with a started out bound foreground service, but
    463          * none in the "top" state.
    464          */
    465         public static final int PROCESS_STATE_FOREGROUND_SERVICE = 1;
    466         /**
    467          * Time this uid has any process that is top while the device is sleeping, but none
    468          * in the "foreground service" or better state.
    469          */
    470         public static final int PROCESS_STATE_TOP_SLEEPING = 2;
    471         /**
    472          * Time this uid has any process in an active foreground state, but none in the
    473          * "top sleeping" or better state.
    474          */
    475         public static final int PROCESS_STATE_FOREGROUND = 3;
    476         /**
    477          * Time this uid has any process in an active background state, but none in the
    478          * "foreground" or better state.
    479          */
    480         public static final int PROCESS_STATE_BACKGROUND = 4;
    481         /**
    482          * Time this uid has any processes that are sitting around cached, not in one of the
    483          * other active states.
    484          */
    485         public static final int PROCESS_STATE_CACHED = 5;
    486         /**
    487          * Total number of process states we track.
    488          */
    489         public static final int NUM_PROCESS_STATE = 6;
    490 
    491         static final String[] PROCESS_STATE_NAMES = {
    492             "Top", "Fg Service", "Top Sleeping", "Foreground", "Background", "Cached"
    493         };
    494 
    495         public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which);
    496         public abstract Timer getProcessStateTimer(int state);
    497 
    498         public abstract Timer getVibratorOnTimer();
    499 
    500         public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5;
    501 
    502         /**
    503          * Note that these must match the constants in android.os.PowerManager.
    504          * Also, if the user activity types change, the BatteryStatsImpl.VERSION must
    505          * also be bumped.
    506          */
    507         static final String[] USER_ACTIVITY_TYPES = {
    508             "other", "button", "touch", "accessibility"
    509         };
    510 
    511         public static final int NUM_USER_ACTIVITY_TYPES = 4;
    512 
    513         public abstract void noteUserActivityLocked(int type);
    514         public abstract boolean hasUserActivity();
    515         public abstract int getUserActivityCount(int type, int which);
    516 
    517         public abstract boolean hasNetworkActivity();
    518         public abstract long getNetworkActivityBytes(int type, int which);
    519         public abstract long getNetworkActivityPackets(int type, int which);
    520         public abstract long getMobileRadioActiveTime(int which);
    521         public abstract int getMobileRadioActiveCount(int which);
    522 
    523         /**
    524          * Get the total cpu time (in microseconds) this UID had processes executing in userspace.
    525          */
    526         public abstract long getUserCpuTimeUs(int which);
    527 
    528         /**
    529          * Get the total cpu time (in microseconds) this UID had processes executing kernel syscalls.
    530          */
    531         public abstract long getSystemCpuTimeUs(int which);
    532 
    533         /**
    534          * Get the total cpu power consumed (in milli-ampere-microseconds).
    535          */
    536         public abstract long getCpuPowerMaUs(int which);
    537 
    538         /**
    539          * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed for a
    540          * given CPU cluster.
    541          * @param cluster the index of the CPU cluster.
    542          * @param step the index of the CPU speed. This is not the actual speed of the CPU.
    543          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    544          * @see com.android.internal.os.PowerProfile#getNumCpuClusters()
    545          * @see com.android.internal.os.PowerProfile#getNumSpeedStepsInCpuCluster(int)
    546          */
    547         public abstract long getTimeAtCpuSpeed(int cluster, int step, int which);
    548 
    549         public static abstract class Sensor {
    550             /*
    551              * FIXME: it's not correct to use this magic value because it
    552              * could clash with a sensor handle (which are defined by
    553              * the sensor HAL, and therefore out of our control
    554              */
    555             // Magic sensor number for the GPS.
    556             public static final int GPS = -10000;
    557 
    558             public abstract int getHandle();
    559 
    560             public abstract Timer getSensorTime();
    561         }
    562 
    563         public class Pid {
    564             public int mWakeNesting;
    565             public long mWakeSumMs;
    566             public long mWakeStartMs;
    567         }
    568 
    569         /**
    570          * The statistics associated with a particular process.
    571          */
    572         public static abstract class Proc {
    573 
    574             public static class ExcessivePower {
    575                 public static final int TYPE_WAKE = 1;
    576                 public static final int TYPE_CPU = 2;
    577 
    578                 public int type;
    579                 public long overTime;
    580                 public long usedTime;
    581             }
    582 
    583             /**
    584              * Returns true if this process is still active in the battery stats.
    585              */
    586             public abstract boolean isActive();
    587 
    588             /**
    589              * Returns the total time (in milliseconds) spent executing in user code.
    590              *
    591              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    592              */
    593             public abstract long getUserTime(int which);
    594 
    595             /**
    596              * Returns the total time (in milliseconds) spent executing in system code.
    597              *
    598              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    599              */
    600             public abstract long getSystemTime(int which);
    601 
    602             /**
    603              * Returns the number of times the process has been started.
    604              *
    605              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    606              */
    607             public abstract int getStarts(int which);
    608 
    609             /**
    610              * Returns the number of times the process has crashed.
    611              *
    612              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    613              */
    614             public abstract int getNumCrashes(int which);
    615 
    616             /**
    617              * Returns the number of times the process has ANRed.
    618              *
    619              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    620              */
    621             public abstract int getNumAnrs(int which);
    622 
    623             /**
    624              * Returns the cpu time (milliseconds) spent while the process was in the foreground.
    625              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    626              * @return foreground cpu time in microseconds
    627              */
    628             public abstract long getForegroundTime(int which);
    629 
    630             public abstract int countExcessivePowers();
    631 
    632             public abstract ExcessivePower getExcessivePower(int i);
    633         }
    634 
    635         /**
    636          * The statistics associated with a particular package.
    637          */
    638         public static abstract class Pkg {
    639 
    640             /**
    641              * Returns information about all wakeup alarms that have been triggered for this
    642              * package.  The mapping keys are tag names for the alarms, the counter contains
    643              * the number of times the alarm was triggered while on battery.
    644              */
    645             public abstract ArrayMap<String, ? extends Counter> getWakeupAlarmStats();
    646 
    647             /**
    648              * Returns a mapping containing service statistics.
    649              */
    650             public abstract ArrayMap<String, ? extends Serv> getServiceStats();
    651 
    652             /**
    653              * The statistics associated with a particular service.
    654              */
    655             public static abstract class Serv {
    656 
    657                 /**
    658                  * Returns the amount of time spent started.
    659                  *
    660                  * @param batteryUptime elapsed uptime on battery in microseconds.
    661                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    662                  * @return
    663                  */
    664                 public abstract long getStartTime(long batteryUptime, int which);
    665 
    666                 /**
    667                  * Returns the total number of times startService() has been called.
    668                  *
    669                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    670                  */
    671                 public abstract int getStarts(int which);
    672 
    673                 /**
    674                  * Returns the total number times the service has been launched.
    675                  *
    676                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    677                  */
    678                 public abstract int getLaunches(int which);
    679             }
    680         }
    681     }
    682 
    683     public static final class LevelStepTracker {
    684         public long mLastStepTime = -1;
    685         public int mNumStepDurations;
    686         public final long[] mStepDurations;
    687 
    688         public LevelStepTracker(int maxLevelSteps) {
    689             mStepDurations = new long[maxLevelSteps];
    690         }
    691 
    692         public LevelStepTracker(int numSteps, long[] steps) {
    693             mNumStepDurations = numSteps;
    694             mStepDurations = new long[numSteps];
    695             System.arraycopy(steps, 0, mStepDurations, 0, numSteps);
    696         }
    697 
    698         public long getDurationAt(int index) {
    699             return mStepDurations[index] & STEP_LEVEL_TIME_MASK;
    700         }
    701 
    702         public int getLevelAt(int index) {
    703             return (int)((mStepDurations[index] & STEP_LEVEL_LEVEL_MASK)
    704                     >> STEP_LEVEL_LEVEL_SHIFT);
    705         }
    706 
    707         public int getInitModeAt(int index) {
    708             return (int)((mStepDurations[index] & STEP_LEVEL_INITIAL_MODE_MASK)
    709                     >> STEP_LEVEL_INITIAL_MODE_SHIFT);
    710         }
    711 
    712         public int getModModeAt(int index) {
    713             return (int)((mStepDurations[index] & STEP_LEVEL_MODIFIED_MODE_MASK)
    714                     >> STEP_LEVEL_MODIFIED_MODE_SHIFT);
    715         }
    716 
    717         private void appendHex(long val, int topOffset, StringBuilder out) {
    718             boolean hasData = false;
    719             while (topOffset >= 0) {
    720                 int digit = (int)( (val>>topOffset) & 0xf );
    721                 topOffset -= 4;
    722                 if (!hasData && digit == 0) {
    723                     continue;
    724                 }
    725                 hasData = true;
    726                 if (digit >= 0 && digit <= 9) {
    727                     out.append((char)('0' + digit));
    728                 } else {
    729                     out.append((char)('a' + digit - 10));
    730                 }
    731             }
    732         }
    733 
    734         public void encodeEntryAt(int index, StringBuilder out) {
    735             long item = mStepDurations[index];
    736             long duration = item & STEP_LEVEL_TIME_MASK;
    737             int level = (int)((item & STEP_LEVEL_LEVEL_MASK)
    738                     >> STEP_LEVEL_LEVEL_SHIFT);
    739             int initMode = (int)((item & STEP_LEVEL_INITIAL_MODE_MASK)
    740                     >> STEP_LEVEL_INITIAL_MODE_SHIFT);
    741             int modMode = (int)((item & STEP_LEVEL_MODIFIED_MODE_MASK)
    742                     >> STEP_LEVEL_MODIFIED_MODE_SHIFT);
    743             switch ((initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
    744                 case Display.STATE_OFF: out.append('f'); break;
    745                 case Display.STATE_ON: out.append('o'); break;
    746                 case Display.STATE_DOZE: out.append('d'); break;
    747                 case Display.STATE_DOZE_SUSPEND: out.append('z'); break;
    748             }
    749             if ((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) {
    750                 out.append('p');
    751             }
    752             if ((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) {
    753                 out.append('i');
    754             }
    755             switch ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
    756                 case Display.STATE_OFF: out.append('F'); break;
    757                 case Display.STATE_ON: out.append('O'); break;
    758                 case Display.STATE_DOZE: out.append('D'); break;
    759                 case Display.STATE_DOZE_SUSPEND: out.append('Z'); break;
    760             }
    761             if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) {
    762                 out.append('P');
    763             }
    764             if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) {
    765                 out.append('I');
    766             }
    767             out.append('-');
    768             appendHex(level, 4, out);
    769             out.append('-');
    770             appendHex(duration, STEP_LEVEL_LEVEL_SHIFT-4, out);
    771         }
    772 
    773         public void decodeEntryAt(int index, String value) {
    774             final int N = value.length();
    775             int i = 0;
    776             char c;
    777             long out = 0;
    778             while (i < N && (c=value.charAt(i)) != '-') {
    779                 i++;
    780                 switch (c) {
    781                     case 'f': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
    782                         break;
    783                     case 'o': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
    784                         break;
    785                     case 'd': out |= (((long)Display.STATE_DOZE-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
    786                         break;
    787                     case 'z': out |= (((long)Display.STATE_DOZE_SUSPEND-1)
    788                             << STEP_LEVEL_INITIAL_MODE_SHIFT);
    789                         break;
    790                     case 'p': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE)
    791                             << STEP_LEVEL_INITIAL_MODE_SHIFT);
    792                         break;
    793                     case 'i': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE)
    794                             << STEP_LEVEL_INITIAL_MODE_SHIFT);
    795                         break;
    796                     case 'F': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
    797                         break;
    798                     case 'O': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
    799                         break;
    800                     case 'D': out |= (((long)Display.STATE_DOZE-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
    801                         break;
    802                     case 'Z': out |= (((long)Display.STATE_DOZE_SUSPEND-1)
    803                             << STEP_LEVEL_MODIFIED_MODE_SHIFT);
    804                         break;
    805                     case 'P': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE)
    806                             << STEP_LEVEL_MODIFIED_MODE_SHIFT);
    807                         break;
    808                     case 'I': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE)
    809                             << STEP_LEVEL_MODIFIED_MODE_SHIFT);
    810                         break;
    811                 }
    812             }
    813             i++;
    814             long level = 0;
    815             while (i < N && (c=value.charAt(i)) != '-') {
    816                 i++;
    817                 level <<= 4;
    818                 if (c >= '0' && c <= '9') {
    819                     level += c - '0';
    820                 } else if (c >= 'a' && c <= 'f') {
    821                     level += c - 'a' + 10;
    822                 } else if (c >= 'A' && c <= 'F') {
    823                     level += c - 'A' + 10;
    824                 }
    825             }
    826             i++;
    827             out |= (level << STEP_LEVEL_LEVEL_SHIFT) & STEP_LEVEL_LEVEL_MASK;
    828             long duration = 0;
    829             while (i < N && (c=value.charAt(i)) != '-') {
    830                 i++;
    831                 duration <<= 4;
    832                 if (c >= '0' && c <= '9') {
    833                     duration += c - '0';
    834                 } else if (c >= 'a' && c <= 'f') {
    835                     duration += c - 'a' + 10;
    836                 } else if (c >= 'A' && c <= 'F') {
    837                     duration += c - 'A' + 10;
    838                 }
    839             }
    840             mStepDurations[index] = out | (duration & STEP_LEVEL_TIME_MASK);
    841         }
    842 
    843         public void init() {
    844             mLastStepTime = -1;
    845             mNumStepDurations = 0;
    846         }
    847 
    848         public void clearTime() {
    849             mLastStepTime = -1;
    850         }
    851 
    852         public long computeTimePerLevel() {
    853             final long[] steps = mStepDurations;
    854             final int numSteps = mNumStepDurations;
    855 
    856             // For now we'll do a simple average across all steps.
    857             if (numSteps <= 0) {
    858                 return -1;
    859             }
    860             long total = 0;
    861             for (int i=0; i<numSteps; i++) {
    862                 total += steps[i] & STEP_LEVEL_TIME_MASK;
    863             }
    864             return total / numSteps;
    865             /*
    866             long[] buckets = new long[numSteps];
    867             int numBuckets = 0;
    868             int numToAverage = 4;
    869             int i = 0;
    870             while (i < numSteps) {
    871                 long totalTime = 0;
    872                 int num = 0;
    873                 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
    874                     totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
    875                     num++;
    876                 }
    877                 buckets[numBuckets] = totalTime / num;
    878                 numBuckets++;
    879                 numToAverage *= 2;
    880                 i += num;
    881             }
    882             if (numBuckets < 1) {
    883                 return -1;
    884             }
    885             long averageTime = buckets[numBuckets-1];
    886             for (i=numBuckets-2; i>=0; i--) {
    887                 averageTime = (averageTime + buckets[i]) / 2;
    888             }
    889             return averageTime;
    890             */
    891         }
    892 
    893         public long computeTimeEstimate(long modesOfInterest, long modeValues,
    894                 int[] outNumOfInterest) {
    895             final long[] steps = mStepDurations;
    896             final int count = mNumStepDurations;
    897             if (count <= 0) {
    898                 return -1;
    899             }
    900             long total = 0;
    901             int numOfInterest = 0;
    902             for (int i=0; i<count; i++) {
    903                 long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK)
    904                         >> STEP_LEVEL_INITIAL_MODE_SHIFT;
    905                 long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK)
    906                         >> STEP_LEVEL_MODIFIED_MODE_SHIFT;
    907                 // If the modes of interest didn't change during this step period...
    908                 if ((modMode&modesOfInterest) == 0) {
    909                     // And the mode values during this period match those we are measuring...
    910                     if ((initMode&modesOfInterest) == modeValues) {
    911                         // Then this can be used to estimate the total time!
    912                         numOfInterest++;
    913                         total += steps[i] & STEP_LEVEL_TIME_MASK;
    914                     }
    915                 }
    916             }
    917             if (numOfInterest <= 0) {
    918                 return -1;
    919             }
    920 
    921             if (outNumOfInterest != null) {
    922                 outNumOfInterest[0] = numOfInterest;
    923             }
    924 
    925             // The estimated time is the average time we spend in each level, multipled
    926             // by 100 -- the total number of battery levels
    927             return (total / numOfInterest) * 100;
    928         }
    929 
    930         public void addLevelSteps(int numStepLevels, long modeBits, long elapsedRealtime) {
    931             int stepCount = mNumStepDurations;
    932             final long lastStepTime = mLastStepTime;
    933             if (lastStepTime >= 0 && numStepLevels > 0) {
    934                 final long[] steps = mStepDurations;
    935                 long duration = elapsedRealtime - lastStepTime;
    936                 for (int i=0; i<numStepLevels; i++) {
    937                     System.arraycopy(steps, 0, steps, 1, steps.length-1);
    938                     long thisDuration = duration / (numStepLevels-i);
    939                     duration -= thisDuration;
    940                     if (thisDuration > STEP_LEVEL_TIME_MASK) {
    941                         thisDuration = STEP_LEVEL_TIME_MASK;
    942                     }
    943                     steps[0] = thisDuration | modeBits;
    944                 }
    945                 stepCount += numStepLevels;
    946                 if (stepCount > steps.length) {
    947                     stepCount = steps.length;
    948                 }
    949             }
    950             mNumStepDurations = stepCount;
    951             mLastStepTime = elapsedRealtime;
    952         }
    953 
    954         public void readFromParcel(Parcel in) {
    955             final int N = in.readInt();
    956             if (N > mStepDurations.length) {
    957                 throw new ParcelFormatException("more step durations than available: " + N);
    958             }
    959             mNumStepDurations = N;
    960             for (int i=0; i<N; i++) {
    961                 mStepDurations[i] = in.readLong();
    962             }
    963         }
    964 
    965         public void writeToParcel(Parcel out) {
    966             final int N = mNumStepDurations;
    967             out.writeInt(N);
    968             for (int i=0; i<N; i++) {
    969                 out.writeLong(mStepDurations[i]);
    970             }
    971         }
    972     }
    973 
    974     public static final class PackageChange {
    975         public String mPackageName;
    976         public boolean mUpdate;
    977         public int mVersionCode;
    978     }
    979 
    980     public static final class DailyItem {
    981         public long mStartTime;
    982         public long mEndTime;
    983         public LevelStepTracker mDischargeSteps;
    984         public LevelStepTracker mChargeSteps;
    985         public ArrayList<PackageChange> mPackageChanges;
    986     }
    987 
    988     public abstract DailyItem getDailyItemLocked(int daysAgo);
    989 
    990     public abstract long getCurrentDailyStartTime();
    991 
    992     public abstract long getNextMinDailyDeadline();
    993 
    994     public abstract long getNextMaxDailyDeadline();
    995 
    996     public final static class HistoryTag {
    997         public String string;
    998         public int uid;
    999 
   1000         public int poolIdx;
   1001 
   1002         public void setTo(HistoryTag o) {
   1003             string = o.string;
   1004             uid = o.uid;
   1005             poolIdx = o.poolIdx;
   1006         }
   1007 
   1008         public void setTo(String _string, int _uid) {
   1009             string = _string;
   1010             uid = _uid;
   1011             poolIdx = -1;
   1012         }
   1013 
   1014         public void writeToParcel(Parcel dest, int flags) {
   1015             dest.writeString(string);
   1016             dest.writeInt(uid);
   1017         }
   1018 
   1019         public void readFromParcel(Parcel src) {
   1020             string = src.readString();
   1021             uid = src.readInt();
   1022             poolIdx = -1;
   1023         }
   1024 
   1025         @Override
   1026         public boolean equals(Object o) {
   1027             if (this == o) return true;
   1028             if (o == null || getClass() != o.getClass()) return false;
   1029 
   1030             HistoryTag that = (HistoryTag) o;
   1031 
   1032             if (uid != that.uid) return false;
   1033             if (!string.equals(that.string)) return false;
   1034 
   1035             return true;
   1036         }
   1037 
   1038         @Override
   1039         public int hashCode() {
   1040             int result = string.hashCode();
   1041             result = 31 * result + uid;
   1042             return result;
   1043         }
   1044     }
   1045 
   1046     /**
   1047      * Optional detailed information that can go into a history step.  This is typically
   1048      * generated each time the battery level changes.
   1049      */
   1050     public final static class HistoryStepDetails {
   1051         // Time (in 1/100 second) spent in user space and the kernel since the last step.
   1052         public int userTime;
   1053         public int systemTime;
   1054 
   1055         // Top three apps using CPU in the last step, with times in 1/100 second.
   1056         public int appCpuUid1;
   1057         public int appCpuUTime1;
   1058         public int appCpuSTime1;
   1059         public int appCpuUid2;
   1060         public int appCpuUTime2;
   1061         public int appCpuSTime2;
   1062         public int appCpuUid3;
   1063         public int appCpuUTime3;
   1064         public int appCpuSTime3;
   1065 
   1066         // Information from /proc/stat
   1067         public int statUserTime;
   1068         public int statSystemTime;
   1069         public int statIOWaitTime;
   1070         public int statIrqTime;
   1071         public int statSoftIrqTime;
   1072         public int statIdlTime;
   1073 
   1074         // Platform-level low power state stats
   1075         public String statPlatformIdleState;
   1076 
   1077         public HistoryStepDetails() {
   1078             clear();
   1079         }
   1080 
   1081         public void clear() {
   1082             userTime = systemTime = 0;
   1083             appCpuUid1 = appCpuUid2 = appCpuUid3 = -1;
   1084             appCpuUTime1 = appCpuSTime1 = appCpuUTime2 = appCpuSTime2
   1085                     = appCpuUTime3 = appCpuSTime3 = 0;
   1086         }
   1087 
   1088         public void writeToParcel(Parcel out) {
   1089             out.writeInt(userTime);
   1090             out.writeInt(systemTime);
   1091             out.writeInt(appCpuUid1);
   1092             out.writeInt(appCpuUTime1);
   1093             out.writeInt(appCpuSTime1);
   1094             out.writeInt(appCpuUid2);
   1095             out.writeInt(appCpuUTime2);
   1096             out.writeInt(appCpuSTime2);
   1097             out.writeInt(appCpuUid3);
   1098             out.writeInt(appCpuUTime3);
   1099             out.writeInt(appCpuSTime3);
   1100             out.writeInt(statUserTime);
   1101             out.writeInt(statSystemTime);
   1102             out.writeInt(statIOWaitTime);
   1103             out.writeInt(statIrqTime);
   1104             out.writeInt(statSoftIrqTime);
   1105             out.writeInt(statIdlTime);
   1106             out.writeString(statPlatformIdleState);
   1107         }
   1108 
   1109         public void readFromParcel(Parcel in) {
   1110             userTime = in.readInt();
   1111             systemTime = in.readInt();
   1112             appCpuUid1 = in.readInt();
   1113             appCpuUTime1 = in.readInt();
   1114             appCpuSTime1 = in.readInt();
   1115             appCpuUid2 = in.readInt();
   1116             appCpuUTime2 = in.readInt();
   1117             appCpuSTime2 = in.readInt();
   1118             appCpuUid3 = in.readInt();
   1119             appCpuUTime3 = in.readInt();
   1120             appCpuSTime3 = in.readInt();
   1121             statUserTime = in.readInt();
   1122             statSystemTime = in.readInt();
   1123             statIOWaitTime = in.readInt();
   1124             statIrqTime = in.readInt();
   1125             statSoftIrqTime = in.readInt();
   1126             statIdlTime = in.readInt();
   1127             statPlatformIdleState = in.readString();
   1128         }
   1129     }
   1130 
   1131     public final static class HistoryItem implements Parcelable {
   1132         public HistoryItem next;
   1133 
   1134         // The time of this event in milliseconds, as per SystemClock.elapsedRealtime().
   1135         public long time;
   1136 
   1137         public static final byte CMD_UPDATE = 0;        // These can be written as deltas
   1138         public static final byte CMD_NULL = -1;
   1139         public static final byte CMD_START = 4;
   1140         public static final byte CMD_CURRENT_TIME = 5;
   1141         public static final byte CMD_OVERFLOW = 6;
   1142         public static final byte CMD_RESET = 7;
   1143         public static final byte CMD_SHUTDOWN = 8;
   1144 
   1145         public byte cmd = CMD_NULL;
   1146 
   1147         /**
   1148          * Return whether the command code is a delta data update.
   1149          */
   1150         public boolean isDeltaData() {
   1151             return cmd == CMD_UPDATE;
   1152         }
   1153 
   1154         public byte batteryLevel;
   1155         public byte batteryStatus;
   1156         public byte batteryHealth;
   1157         public byte batteryPlugType;
   1158 
   1159         public short batteryTemperature;
   1160         public char batteryVoltage;
   1161 
   1162         // The charge of the battery in micro-Ampere-hours.
   1163         public int batteryChargeUAh;
   1164 
   1165         // Constants from SCREEN_BRIGHTNESS_*
   1166         public static final int STATE_BRIGHTNESS_SHIFT = 0;
   1167         public static final int STATE_BRIGHTNESS_MASK = 0x7;
   1168         // Constants from SIGNAL_STRENGTH_*
   1169         public static final int STATE_PHONE_SIGNAL_STRENGTH_SHIFT = 3;
   1170         public static final int STATE_PHONE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_PHONE_SIGNAL_STRENGTH_SHIFT;
   1171         // Constants from ServiceState.STATE_*
   1172         public static final int STATE_PHONE_STATE_SHIFT = 6;
   1173         public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT;
   1174         // Constants from DATA_CONNECTION_*
   1175         public static final int STATE_DATA_CONNECTION_SHIFT = 9;
   1176         public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT;
   1177 
   1178         // These states always appear directly in the first int token
   1179         // of a delta change; they should be ones that change relatively
   1180         // frequently.
   1181         public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
   1182         public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
   1183         public static final int STATE_GPS_ON_FLAG = 1<<29;
   1184         public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
   1185         public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
   1186         public static final int STATE_WIFI_RADIO_ACTIVE_FLAG = 1<<26;
   1187         public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
   1188         // Do not use, this is used for coulomb delta count.
   1189         private static final int STATE_RESERVED_0 = 1<<24;
   1190         // These are on the lower bits used for the command; if they change
   1191         // we need to write another int of data.
   1192         public static final int STATE_SENSOR_ON_FLAG = 1<<23;
   1193         public static final int STATE_AUDIO_ON_FLAG = 1<<22;
   1194         public static final int STATE_PHONE_SCANNING_FLAG = 1<<21;
   1195         public static final int STATE_SCREEN_ON_FLAG = 1<<20;       // consider moving to states2
   1196         public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; // consider moving to states2
   1197         // empty slot
   1198         // empty slot
   1199         public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<16;
   1200 
   1201         public static final int MOST_INTERESTING_STATES =
   1202             STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG;
   1203 
   1204         public static final int SETTLE_TO_ZERO_STATES = 0xffff0000 & ~MOST_INTERESTING_STATES;
   1205 
   1206         public int states;
   1207 
   1208         // Constants from WIFI_SUPPL_STATE_*
   1209         public static final int STATE2_WIFI_SUPPL_STATE_SHIFT = 0;
   1210         public static final int STATE2_WIFI_SUPPL_STATE_MASK = 0xf;
   1211         // Values for NUM_WIFI_SIGNAL_STRENGTH_BINS
   1212         public static final int STATE2_WIFI_SIGNAL_STRENGTH_SHIFT = 4;
   1213         public static final int STATE2_WIFI_SIGNAL_STRENGTH_MASK =
   1214                 0x7 << STATE2_WIFI_SIGNAL_STRENGTH_SHIFT;
   1215 
   1216         public static final int STATE2_POWER_SAVE_FLAG = 1<<31;
   1217         public static final int STATE2_VIDEO_ON_FLAG = 1<<30;
   1218         public static final int STATE2_WIFI_RUNNING_FLAG = 1<<29;
   1219         public static final int STATE2_WIFI_ON_FLAG = 1<<28;
   1220         public static final int STATE2_FLASHLIGHT_FLAG = 1<<27;
   1221         public static final int STATE2_DEVICE_IDLE_SHIFT = 25;
   1222         public static final int STATE2_DEVICE_IDLE_MASK = 0x3 << STATE2_DEVICE_IDLE_SHIFT;
   1223         public static final int STATE2_CHARGING_FLAG = 1<<24;
   1224         public static final int STATE2_PHONE_IN_CALL_FLAG = 1<<23;
   1225         public static final int STATE2_BLUETOOTH_ON_FLAG = 1<<22;
   1226         public static final int STATE2_CAMERA_FLAG = 1<<21;
   1227         public static final int STATE2_BLUETOOTH_SCAN_FLAG = 1 << 20;
   1228 
   1229         public static final int MOST_INTERESTING_STATES2 =
   1230             STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_MASK
   1231             | STATE2_CHARGING_FLAG | STATE2_PHONE_IN_CALL_FLAG | STATE2_BLUETOOTH_ON_FLAG;
   1232 
   1233         public static final int SETTLE_TO_ZERO_STATES2 = 0xffff0000 & ~MOST_INTERESTING_STATES2;
   1234 
   1235         public int states2;
   1236 
   1237         // The wake lock that was acquired at this point.
   1238         public HistoryTag wakelockTag;
   1239 
   1240         // Kernel wakeup reason at this point.
   1241         public HistoryTag wakeReasonTag;
   1242 
   1243         // Non-null when there is more detailed information at this step.
   1244         public HistoryStepDetails stepDetails;
   1245 
   1246         public static final int EVENT_FLAG_START = 0x8000;
   1247         public static final int EVENT_FLAG_FINISH = 0x4000;
   1248 
   1249         // No event in this item.
   1250         public static final int EVENT_NONE = 0x0000;
   1251         // Event is about a process that is running.
   1252         public static final int EVENT_PROC = 0x0001;
   1253         // Event is about an application package that is in the foreground.
   1254         public static final int EVENT_FOREGROUND = 0x0002;
   1255         // Event is about an application package that is at the top of the screen.
   1256         public static final int EVENT_TOP = 0x0003;
   1257         // Event is about active sync operations.
   1258         public static final int EVENT_SYNC = 0x0004;
   1259         // Events for all additional wake locks aquired/release within a wake block.
   1260         // These are not generated by default.
   1261         public static final int EVENT_WAKE_LOCK = 0x0005;
   1262         // Event is about an application executing a scheduled job.
   1263         public static final int EVENT_JOB = 0x0006;
   1264         // Events for users running.
   1265         public static final int EVENT_USER_RUNNING = 0x0007;
   1266         // Events for foreground user.
   1267         public static final int EVENT_USER_FOREGROUND = 0x0008;
   1268         // Event for connectivity changed.
   1269         public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009;
   1270         // Event for becoming active taking us out of idle mode.
   1271         public static final int EVENT_ACTIVE = 0x000a;
   1272         // Event for a package being installed.
   1273         public static final int EVENT_PACKAGE_INSTALLED = 0x000b;
   1274         // Event for a package being uninstalled.
   1275         public static final int EVENT_PACKAGE_UNINSTALLED = 0x000c;
   1276         // Event for a package being uninstalled.
   1277         public static final int EVENT_ALARM = 0x000d;
   1278         // Record that we have decided we need to collect new stats data.
   1279         public static final int EVENT_COLLECT_EXTERNAL_STATS = 0x000e;
   1280         // Event for a package becoming inactive due to being unused for a period of time.
   1281         public static final int EVENT_PACKAGE_INACTIVE = 0x000f;
   1282         // Event for a package becoming active due to an interaction.
   1283         public static final int EVENT_PACKAGE_ACTIVE = 0x0010;
   1284         // Event for a package being on the temporary whitelist.
   1285         public static final int EVENT_TEMP_WHITELIST = 0x0011;
   1286         // Event for the screen waking up.
   1287         public static final int EVENT_SCREEN_WAKE_UP = 0x0012;
   1288 
   1289         // Number of event types.
   1290         public static final int EVENT_COUNT = 0x0013;
   1291         // Mask to extract out only the type part of the event.
   1292         public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
   1293 
   1294         public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
   1295         public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
   1296         public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START;
   1297         public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
   1298         public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
   1299         public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
   1300         public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
   1301         public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
   1302         public static final int EVENT_WAKE_LOCK_START = EVENT_WAKE_LOCK | EVENT_FLAG_START;
   1303         public static final int EVENT_WAKE_LOCK_FINISH = EVENT_WAKE_LOCK | EVENT_FLAG_FINISH;
   1304         public static final int EVENT_JOB_START = EVENT_JOB | EVENT_FLAG_START;
   1305         public static final int EVENT_JOB_FINISH = EVENT_JOB | EVENT_FLAG_FINISH;
   1306         public static final int EVENT_USER_RUNNING_START = EVENT_USER_RUNNING | EVENT_FLAG_START;
   1307         public static final int EVENT_USER_RUNNING_FINISH = EVENT_USER_RUNNING | EVENT_FLAG_FINISH;
   1308         public static final int EVENT_USER_FOREGROUND_START =
   1309                 EVENT_USER_FOREGROUND | EVENT_FLAG_START;
   1310         public static final int EVENT_USER_FOREGROUND_FINISH =
   1311                 EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
   1312         public static final int EVENT_ALARM_START = EVENT_ALARM | EVENT_FLAG_START;
   1313         public static final int EVENT_ALARM_FINISH = EVENT_ALARM | EVENT_FLAG_FINISH;
   1314         public static final int EVENT_TEMP_WHITELIST_START =
   1315                 EVENT_TEMP_WHITELIST | EVENT_FLAG_START;
   1316         public static final int EVENT_TEMP_WHITELIST_FINISH =
   1317                 EVENT_TEMP_WHITELIST | EVENT_FLAG_FINISH;
   1318 
   1319         // For CMD_EVENT.
   1320         public int eventCode;
   1321         public HistoryTag eventTag;
   1322 
   1323         // Only set for CMD_CURRENT_TIME or CMD_RESET, as per System.currentTimeMillis().
   1324         public long currentTime;
   1325 
   1326         // Meta-data when reading.
   1327         public int numReadInts;
   1328 
   1329         // Pre-allocated objects.
   1330         public final HistoryTag localWakelockTag = new HistoryTag();
   1331         public final HistoryTag localWakeReasonTag = new HistoryTag();
   1332         public final HistoryTag localEventTag = new HistoryTag();
   1333 
   1334         public HistoryItem() {
   1335         }
   1336 
   1337         public HistoryItem(long time, Parcel src) {
   1338             this.time = time;
   1339             numReadInts = 2;
   1340             readFromParcel(src);
   1341         }
   1342 
   1343         public int describeContents() {
   1344             return 0;
   1345         }
   1346 
   1347         public void writeToParcel(Parcel dest, int flags) {
   1348             dest.writeLong(time);
   1349             int bat = (((int)cmd)&0xff)
   1350                     | ((((int)batteryLevel)<<8)&0xff00)
   1351                     | ((((int)batteryStatus)<<16)&0xf0000)
   1352                     | ((((int)batteryHealth)<<20)&0xf00000)
   1353                     | ((((int)batteryPlugType)<<24)&0xf000000)
   1354                     | (wakelockTag != null ? 0x10000000 : 0)
   1355                     | (wakeReasonTag != null ? 0x20000000 : 0)
   1356                     | (eventCode != EVENT_NONE ? 0x40000000 : 0);
   1357             dest.writeInt(bat);
   1358             bat = (((int)batteryTemperature)&0xffff)
   1359                     | ((((int)batteryVoltage)<<16)&0xffff0000);
   1360             dest.writeInt(bat);
   1361             dest.writeInt(batteryChargeUAh);
   1362             dest.writeInt(states);
   1363             dest.writeInt(states2);
   1364             if (wakelockTag != null) {
   1365                 wakelockTag.writeToParcel(dest, flags);
   1366             }
   1367             if (wakeReasonTag != null) {
   1368                 wakeReasonTag.writeToParcel(dest, flags);
   1369             }
   1370             if (eventCode != EVENT_NONE) {
   1371                 dest.writeInt(eventCode);
   1372                 eventTag.writeToParcel(dest, flags);
   1373             }
   1374             if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
   1375                 dest.writeLong(currentTime);
   1376             }
   1377         }
   1378 
   1379         public void readFromParcel(Parcel src) {
   1380             int start = src.dataPosition();
   1381             int bat = src.readInt();
   1382             cmd = (byte)(bat&0xff);
   1383             batteryLevel = (byte)((bat>>8)&0xff);
   1384             batteryStatus = (byte)((bat>>16)&0xf);
   1385             batteryHealth = (byte)((bat>>20)&0xf);
   1386             batteryPlugType = (byte)((bat>>24)&0xf);
   1387             int bat2 = src.readInt();
   1388             batteryTemperature = (short)(bat2&0xffff);
   1389             batteryVoltage = (char)((bat2>>16)&0xffff);
   1390             batteryChargeUAh = src.readInt();
   1391             states = src.readInt();
   1392             states2 = src.readInt();
   1393             if ((bat&0x10000000) != 0) {
   1394                 wakelockTag = localWakelockTag;
   1395                 wakelockTag.readFromParcel(src);
   1396             } else {
   1397                 wakelockTag = null;
   1398             }
   1399             if ((bat&0x20000000) != 0) {
   1400                 wakeReasonTag = localWakeReasonTag;
   1401                 wakeReasonTag.readFromParcel(src);
   1402             } else {
   1403                 wakeReasonTag = null;
   1404             }
   1405             if ((bat&0x40000000) != 0) {
   1406                 eventCode = src.readInt();
   1407                 eventTag = localEventTag;
   1408                 eventTag.readFromParcel(src);
   1409             } else {
   1410                 eventCode = EVENT_NONE;
   1411                 eventTag = null;
   1412             }
   1413             if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
   1414                 currentTime = src.readLong();
   1415             } else {
   1416                 currentTime = 0;
   1417             }
   1418             numReadInts += (src.dataPosition()-start)/4;
   1419         }
   1420 
   1421         public void clear() {
   1422             time = 0;
   1423             cmd = CMD_NULL;
   1424             batteryLevel = 0;
   1425             batteryStatus = 0;
   1426             batteryHealth = 0;
   1427             batteryPlugType = 0;
   1428             batteryTemperature = 0;
   1429             batteryVoltage = 0;
   1430             batteryChargeUAh = 0;
   1431             states = 0;
   1432             states2 = 0;
   1433             wakelockTag = null;
   1434             wakeReasonTag = null;
   1435             eventCode = EVENT_NONE;
   1436             eventTag = null;
   1437         }
   1438 
   1439         public void setTo(HistoryItem o) {
   1440             time = o.time;
   1441             cmd = o.cmd;
   1442             setToCommon(o);
   1443         }
   1444 
   1445         public void setTo(long time, byte cmd, HistoryItem o) {
   1446             this.time = time;
   1447             this.cmd = cmd;
   1448             setToCommon(o);
   1449         }
   1450 
   1451         private void setToCommon(HistoryItem o) {
   1452             batteryLevel = o.batteryLevel;
   1453             batteryStatus = o.batteryStatus;
   1454             batteryHealth = o.batteryHealth;
   1455             batteryPlugType = o.batteryPlugType;
   1456             batteryTemperature = o.batteryTemperature;
   1457             batteryVoltage = o.batteryVoltage;
   1458             batteryChargeUAh = o.batteryChargeUAh;
   1459             states = o.states;
   1460             states2 = o.states2;
   1461             if (o.wakelockTag != null) {
   1462                 wakelockTag = localWakelockTag;
   1463                 wakelockTag.setTo(o.wakelockTag);
   1464             } else {
   1465                 wakelockTag = null;
   1466             }
   1467             if (o.wakeReasonTag != null) {
   1468                 wakeReasonTag = localWakeReasonTag;
   1469                 wakeReasonTag.setTo(o.wakeReasonTag);
   1470             } else {
   1471                 wakeReasonTag = null;
   1472             }
   1473             eventCode = o.eventCode;
   1474             if (o.eventTag != null) {
   1475                 eventTag = localEventTag;
   1476                 eventTag.setTo(o.eventTag);
   1477             } else {
   1478                 eventTag = null;
   1479             }
   1480             currentTime = o.currentTime;
   1481         }
   1482 
   1483         public boolean sameNonEvent(HistoryItem o) {
   1484             return batteryLevel == o.batteryLevel
   1485                     && batteryStatus == o.batteryStatus
   1486                     && batteryHealth == o.batteryHealth
   1487                     && batteryPlugType == o.batteryPlugType
   1488                     && batteryTemperature == o.batteryTemperature
   1489                     && batteryVoltage == o.batteryVoltage
   1490                     && batteryChargeUAh == o.batteryChargeUAh
   1491                     && states == o.states
   1492                     && states2 == o.states2
   1493                     && currentTime == o.currentTime;
   1494         }
   1495 
   1496         public boolean same(HistoryItem o) {
   1497             if (!sameNonEvent(o) || eventCode != o.eventCode) {
   1498                 return false;
   1499             }
   1500             if (wakelockTag != o.wakelockTag) {
   1501                 if (wakelockTag == null || o.wakelockTag == null) {
   1502                     return false;
   1503                 }
   1504                 if (!wakelockTag.equals(o.wakelockTag)) {
   1505                     return false;
   1506                 }
   1507             }
   1508             if (wakeReasonTag != o.wakeReasonTag) {
   1509                 if (wakeReasonTag == null || o.wakeReasonTag == null) {
   1510                     return false;
   1511                 }
   1512                 if (!wakeReasonTag.equals(o.wakeReasonTag)) {
   1513                     return false;
   1514                 }
   1515             }
   1516             if (eventTag != o.eventTag) {
   1517                 if (eventTag == null || o.eventTag == null) {
   1518                     return false;
   1519                 }
   1520                 if (!eventTag.equals(o.eventTag)) {
   1521                     return false;
   1522                 }
   1523             }
   1524             return true;
   1525         }
   1526     }
   1527 
   1528     public final static class HistoryEventTracker {
   1529         private final HashMap<String, SparseIntArray>[] mActiveEvents
   1530                 = (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
   1531 
   1532         public boolean updateState(int code, String name, int uid, int poolIdx) {
   1533             if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
   1534                 int idx = code&HistoryItem.EVENT_TYPE_MASK;
   1535                 HashMap<String, SparseIntArray> active = mActiveEvents[idx];
   1536                 if (active == null) {
   1537                     active = new HashMap<>();
   1538                     mActiveEvents[idx] = active;
   1539                 }
   1540                 SparseIntArray uids = active.get(name);
   1541                 if (uids == null) {
   1542                     uids = new SparseIntArray();
   1543                     active.put(name, uids);
   1544                 }
   1545                 if (uids.indexOfKey(uid) >= 0) {
   1546                     // Already set, nothing to do!
   1547                     return false;
   1548                 }
   1549                 uids.put(uid, poolIdx);
   1550             } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
   1551                 int idx = code&HistoryItem.EVENT_TYPE_MASK;
   1552                 HashMap<String, SparseIntArray> active = mActiveEvents[idx];
   1553                 if (active == null) {
   1554                     // not currently active, nothing to do.
   1555                     return false;
   1556                 }
   1557                 SparseIntArray uids = active.get(name);
   1558                 if (uids == null) {
   1559                     // not currently active, nothing to do.
   1560                     return false;
   1561                 }
   1562                 idx = uids.indexOfKey(uid);
   1563                 if (idx < 0) {
   1564                     // not currently active, nothing to do.
   1565                     return false;
   1566                 }
   1567                 uids.removeAt(idx);
   1568                 if (uids.size() <= 0) {
   1569                     active.remove(name);
   1570                 }
   1571             }
   1572             return true;
   1573         }
   1574 
   1575         public void removeEvents(int code) {
   1576             int idx = code&HistoryItem.EVENT_TYPE_MASK;
   1577             mActiveEvents[idx] = null;
   1578         }
   1579 
   1580         public HashMap<String, SparseIntArray> getStateForEvent(int code) {
   1581             return mActiveEvents[code];
   1582         }
   1583     }
   1584 
   1585     public static final class BitDescription {
   1586         public final int mask;
   1587         public final int shift;
   1588         public final String name;
   1589         public final String shortName;
   1590         public final String[] values;
   1591         public final String[] shortValues;
   1592 
   1593         public BitDescription(int mask, String name, String shortName) {
   1594             this.mask = mask;
   1595             this.shift = -1;
   1596             this.name = name;
   1597             this.shortName = shortName;
   1598             this.values = null;
   1599             this.shortValues = null;
   1600         }
   1601 
   1602         public BitDescription(int mask, int shift, String name, String shortName,
   1603                 String[] values, String[] shortValues) {
   1604             this.mask = mask;
   1605             this.shift = shift;
   1606             this.name = name;
   1607             this.shortName = shortName;
   1608             this.values = values;
   1609             this.shortValues = shortValues;
   1610         }
   1611     }
   1612 
   1613     /**
   1614      * Don't allow any more batching in to the current history event.  This
   1615      * is called when printing partial histories, so to ensure that the next
   1616      * history event will go in to a new batch after what was printed in the
   1617      * last partial history.
   1618      */
   1619     public abstract void commitCurrentHistoryBatchLocked();
   1620 
   1621     public abstract int getHistoryTotalSize();
   1622 
   1623     public abstract int getHistoryUsedSize();
   1624 
   1625     public abstract boolean startIteratingHistoryLocked();
   1626 
   1627     public abstract int getHistoryStringPoolSize();
   1628 
   1629     public abstract int getHistoryStringPoolBytes();
   1630 
   1631     public abstract String getHistoryTagPoolString(int index);
   1632 
   1633     public abstract int getHistoryTagPoolUid(int index);
   1634 
   1635     public abstract boolean getNextHistoryLocked(HistoryItem out);
   1636 
   1637     public abstract void finishIteratingHistoryLocked();
   1638 
   1639     public abstract boolean startIteratingOldHistoryLocked();
   1640 
   1641     public abstract boolean getNextOldHistoryLocked(HistoryItem out);
   1642 
   1643     public abstract void finishIteratingOldHistoryLocked();
   1644 
   1645     /**
   1646      * Return the base time offset for the battery history.
   1647      */
   1648     public abstract long getHistoryBaseTime();
   1649 
   1650     /**
   1651      * Returns the number of times the device has been started.
   1652      */
   1653     public abstract int getStartCount();
   1654 
   1655     /**
   1656      * Returns the time in microseconds that the screen has been on while the device was
   1657      * running on battery.
   1658      *
   1659      * {@hide}
   1660      */
   1661     public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
   1662 
   1663     /**
   1664      * Returns the number of times the screen was turned on.
   1665      *
   1666      * {@hide}
   1667      */
   1668     public abstract int getScreenOnCount(int which);
   1669 
   1670     public abstract long getInteractiveTime(long elapsedRealtimeUs, int which);
   1671 
   1672     public static final int SCREEN_BRIGHTNESS_DARK = 0;
   1673     public static final int SCREEN_BRIGHTNESS_DIM = 1;
   1674     public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
   1675     public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
   1676     public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
   1677 
   1678     static final String[] SCREEN_BRIGHTNESS_NAMES = {
   1679         "dark", "dim", "medium", "light", "bright"
   1680     };
   1681 
   1682     static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
   1683         "0", "1", "2", "3", "4"
   1684     };
   1685 
   1686     public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
   1687 
   1688     /**
   1689      * Returns the time in microseconds that the screen has been on with
   1690      * the given brightness
   1691      *
   1692      * {@hide}
   1693      */
   1694     public abstract long getScreenBrightnessTime(int brightnessBin,
   1695             long elapsedRealtimeUs, int which);
   1696 
   1697     /**
   1698      * Returns the time in microseconds that power save mode has been enabled while the device was
   1699      * running on battery.
   1700      *
   1701      * {@hide}
   1702      */
   1703     public abstract long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which);
   1704 
   1705     /**
   1706      * Returns the number of times that power save mode was enabled.
   1707      *
   1708      * {@hide}
   1709      */
   1710     public abstract int getPowerSaveModeEnabledCount(int which);
   1711 
   1712     /**
   1713      * Constant for device idle mode: not active.
   1714      */
   1715     public static final int DEVICE_IDLE_MODE_OFF = 0;
   1716 
   1717     /**
   1718      * Constant for device idle mode: active in lightweight mode.
   1719      */
   1720     public static final int DEVICE_IDLE_MODE_LIGHT = 1;
   1721 
   1722     /**
   1723      * Constant for device idle mode: active in full mode.
   1724      */
   1725     public static final int DEVICE_IDLE_MODE_DEEP = 2;
   1726 
   1727     /**
   1728      * Returns the time in microseconds that device has been in idle mode while
   1729      * running on battery.
   1730      *
   1731      * {@hide}
   1732      */
   1733     public abstract long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which);
   1734 
   1735     /**
   1736      * Returns the number of times that the devie has gone in to idle mode.
   1737      *
   1738      * {@hide}
   1739      */
   1740     public abstract int getDeviceIdleModeCount(int mode, int which);
   1741 
   1742     /**
   1743      * Return the longest duration we spent in a particular device idle mode (fully in the
   1744      * mode, not in idle maintenance etc).
   1745      */
   1746     public abstract long getLongestDeviceIdleModeTime(int mode);
   1747 
   1748     /**
   1749      * Returns the time in microseconds that device has been in idling while on
   1750      * battery.  This is broader than {@link #getDeviceIdleModeTime} -- it
   1751      * counts all of the time that we consider the device to be idle, whether or not
   1752      * it is currently in the actual device idle mode.
   1753      *
   1754      * {@hide}
   1755      */
   1756     public abstract long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which);
   1757 
   1758     /**
   1759      * Returns the number of times that the devie has started idling.
   1760      *
   1761      * {@hide}
   1762      */
   1763     public abstract int getDeviceIdlingCount(int mode, int which);
   1764 
   1765     /**
   1766      * Returns the number of times that connectivity state changed.
   1767      *
   1768      * {@hide}
   1769      */
   1770     public abstract int getNumConnectivityChange(int which);
   1771 
   1772     /**
   1773      * Returns the time in microseconds that the phone has been on while the device was
   1774      * running on battery.
   1775      *
   1776      * {@hide}
   1777      */
   1778     public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
   1779 
   1780     /**
   1781      * Returns the number of times a phone call was activated.
   1782      *
   1783      * {@hide}
   1784      */
   1785     public abstract int getPhoneOnCount(int which);
   1786 
   1787     /**
   1788      * Returns the time in microseconds that the phone has been running with
   1789      * the given signal strength.
   1790      *
   1791      * {@hide}
   1792      */
   1793     public abstract long getPhoneSignalStrengthTime(int strengthBin,
   1794             long elapsedRealtimeUs, int which);
   1795 
   1796     /**
   1797      * Returns the time in microseconds that the phone has been trying to
   1798      * acquire a signal.
   1799      *
   1800      * {@hide}
   1801      */
   1802     public abstract long getPhoneSignalScanningTime(
   1803             long elapsedRealtimeUs, int which);
   1804 
   1805     /**
   1806      * Returns the number of times the phone has entered the given signal strength.
   1807      *
   1808      * {@hide}
   1809      */
   1810     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
   1811 
   1812     /**
   1813      * Returns the time in microseconds that the mobile network has been active
   1814      * (in a high power state).
   1815      *
   1816      * {@hide}
   1817      */
   1818     public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which);
   1819 
   1820     /**
   1821      * Returns the number of times that the mobile network has transitioned to the
   1822      * active state.
   1823      *
   1824      * {@hide}
   1825      */
   1826     public abstract int getMobileRadioActiveCount(int which);
   1827 
   1828     /**
   1829      * Returns the time in microseconds that is the difference between the mobile radio
   1830      * time we saw based on the elapsed timestamp when going down vs. the given time stamp
   1831      * from the radio.
   1832      *
   1833      * {@hide}
   1834      */
   1835     public abstract long getMobileRadioActiveAdjustedTime(int which);
   1836 
   1837     /**
   1838      * Returns the time in microseconds that the mobile network has been active
   1839      * (in a high power state) but not being able to blame on an app.
   1840      *
   1841      * {@hide}
   1842      */
   1843     public abstract long getMobileRadioActiveUnknownTime(int which);
   1844 
   1845     /**
   1846      * Return count of number of times radio was up that could not be blamed on apps.
   1847      *
   1848      * {@hide}
   1849      */
   1850     public abstract int getMobileRadioActiveUnknownCount(int which);
   1851 
   1852     public static final int DATA_CONNECTION_NONE = 0;
   1853     public static final int DATA_CONNECTION_GPRS = 1;
   1854     public static final int DATA_CONNECTION_EDGE = 2;
   1855     public static final int DATA_CONNECTION_UMTS = 3;
   1856     public static final int DATA_CONNECTION_CDMA = 4;
   1857     public static final int DATA_CONNECTION_EVDO_0 = 5;
   1858     public static final int DATA_CONNECTION_EVDO_A = 6;
   1859     public static final int DATA_CONNECTION_1xRTT = 7;
   1860     public static final int DATA_CONNECTION_HSDPA = 8;
   1861     public static final int DATA_CONNECTION_HSUPA = 9;
   1862     public static final int DATA_CONNECTION_HSPA = 10;
   1863     public static final int DATA_CONNECTION_IDEN = 11;
   1864     public static final int DATA_CONNECTION_EVDO_B = 12;
   1865     public static final int DATA_CONNECTION_LTE = 13;
   1866     public static final int DATA_CONNECTION_EHRPD = 14;
   1867     public static final int DATA_CONNECTION_HSPAP = 15;
   1868     public static final int DATA_CONNECTION_OTHER = 16;
   1869 
   1870     static final String[] DATA_CONNECTION_NAMES = {
   1871         "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
   1872         "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
   1873         "ehrpd", "hspap", "other"
   1874     };
   1875 
   1876     public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
   1877 
   1878     /**
   1879      * Returns the time in microseconds that the phone has been running with
   1880      * the given data connection.
   1881      *
   1882      * {@hide}
   1883      */
   1884     public abstract long getPhoneDataConnectionTime(int dataType,
   1885             long elapsedRealtimeUs, int which);
   1886 
   1887     /**
   1888      * Returns the number of times the phone has entered the given data
   1889      * connection type.
   1890      *
   1891      * {@hide}
   1892      */
   1893     public abstract int getPhoneDataConnectionCount(int dataType, int which);
   1894 
   1895     public static final int WIFI_SUPPL_STATE_INVALID = 0;
   1896     public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1;
   1897     public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2;
   1898     public static final int WIFI_SUPPL_STATE_INACTIVE = 3;
   1899     public static final int WIFI_SUPPL_STATE_SCANNING = 4;
   1900     public static final int WIFI_SUPPL_STATE_AUTHENTICATING = 5;
   1901     public static final int WIFI_SUPPL_STATE_ASSOCIATING = 6;
   1902     public static final int WIFI_SUPPL_STATE_ASSOCIATED = 7;
   1903     public static final int WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE = 8;
   1904     public static final int WIFI_SUPPL_STATE_GROUP_HANDSHAKE = 9;
   1905     public static final int WIFI_SUPPL_STATE_COMPLETED = 10;
   1906     public static final int WIFI_SUPPL_STATE_DORMANT = 11;
   1907     public static final int WIFI_SUPPL_STATE_UNINITIALIZED = 12;
   1908 
   1909     public static final int NUM_WIFI_SUPPL_STATES = WIFI_SUPPL_STATE_UNINITIALIZED+1;
   1910 
   1911     static final String[] WIFI_SUPPL_STATE_NAMES = {
   1912         "invalid", "disconn", "disabled", "inactive", "scanning",
   1913         "authenticating", "associating", "associated", "4-way-handshake",
   1914         "group-handshake", "completed", "dormant", "uninit"
   1915     };
   1916 
   1917     static final String[] WIFI_SUPPL_STATE_SHORT_NAMES = {
   1918         "inv", "dsc", "dis", "inact", "scan",
   1919         "auth", "ascing", "asced", "4-way",
   1920         "group", "compl", "dorm", "uninit"
   1921     };
   1922 
   1923     public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
   1924             = new BitDescription[] {
   1925         new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
   1926         new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
   1927         new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
   1928         new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
   1929         new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
   1930         new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
   1931         new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
   1932         new BitDescription(HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG, "wifi_radio", "Wr"),
   1933         new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
   1934         new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
   1935         new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
   1936         new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
   1937         new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
   1938         new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
   1939                 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
   1940                 DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
   1941         new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
   1942                 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
   1943                 new String[] {"in", "out", "emergency", "off"},
   1944                 new String[] {"in", "out", "em", "off"}),
   1945         new BitDescription(HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK,
   1946                 HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT, "phone_signal_strength", "Pss",
   1947                 SignalStrength.SIGNAL_STRENGTH_NAMES,
   1948                 new String[] { "0", "1", "2", "3", "4" }),
   1949         new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
   1950                 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
   1951                 SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
   1952     };
   1953 
   1954     public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
   1955             = new BitDescription[] {
   1956         new BitDescription(HistoryItem.STATE2_POWER_SAVE_FLAG, "power_save", "ps"),
   1957         new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
   1958         new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Ww"),
   1959         new BitDescription(HistoryItem.STATE2_WIFI_ON_FLAG, "wifi", "W"),
   1960         new BitDescription(HistoryItem.STATE2_FLASHLIGHT_FLAG, "flashlight", "fl"),
   1961         new BitDescription(HistoryItem.STATE2_DEVICE_IDLE_MASK,
   1962                 HistoryItem.STATE2_DEVICE_IDLE_SHIFT, "device_idle", "di",
   1963                 new String[] { "off", "light", "full", "???" },
   1964                 new String[] { "off", "light", "full", "???" }),
   1965         new BitDescription(HistoryItem.STATE2_CHARGING_FLAG, "charging", "ch"),
   1966         new BitDescription(HistoryItem.STATE2_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
   1967         new BitDescription(HistoryItem.STATE2_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
   1968         new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
   1969                 HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT, "wifi_signal_strength", "Wss",
   1970                 new String[] { "0", "1", "2", "3", "4" },
   1971                 new String[] { "0", "1", "2", "3", "4" }),
   1972         new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK,
   1973                 HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp",
   1974                 WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES),
   1975         new BitDescription(HistoryItem.STATE2_CAMERA_FLAG, "camera", "ca"),
   1976         new BitDescription(HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG, "ble_scan", "bles"),
   1977     };
   1978 
   1979     public static final String[] HISTORY_EVENT_NAMES = new String[] {
   1980             "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
   1981             "active", "pkginst", "pkgunin", "alarm", "stats", "inactive", "active", "tmpwhitelist",
   1982             "screenwake",
   1983     };
   1984 
   1985     public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
   1986             "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
   1987             "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa", "Etw",
   1988             "Esw",
   1989     };
   1990 
   1991     /**
   1992      * Returns the time in microseconds that wifi has been on while the device was
   1993      * running on battery.
   1994      *
   1995      * {@hide}
   1996      */
   1997     public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
   1998 
   1999     /**
   2000      * Returns the time in microseconds that wifi has been on and the driver has
   2001      * been in the running state while the device was running on battery.
   2002      *
   2003      * {@hide}
   2004      */
   2005     public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
   2006 
   2007     public static final int WIFI_STATE_OFF = 0;
   2008     public static final int WIFI_STATE_OFF_SCANNING = 1;
   2009     public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
   2010     public static final int WIFI_STATE_ON_DISCONNECTED = 3;
   2011     public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
   2012     public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
   2013     public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
   2014     public static final int WIFI_STATE_SOFT_AP = 7;
   2015 
   2016     static final String[] WIFI_STATE_NAMES = {
   2017         "off", "scanning", "no_net", "disconn",
   2018         "sta", "p2p", "sta_p2p", "soft_ap"
   2019     };
   2020 
   2021     public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1;
   2022 
   2023     /**
   2024      * Returns the time in microseconds that WiFi has been running in the given state.
   2025      *
   2026      * {@hide}
   2027      */
   2028     public abstract long getWifiStateTime(int wifiState,
   2029             long elapsedRealtimeUs, int which);
   2030 
   2031     /**
   2032      * Returns the number of times that WiFi has entered the given state.
   2033      *
   2034      * {@hide}
   2035      */
   2036     public abstract int getWifiStateCount(int wifiState, int which);
   2037 
   2038     /**
   2039      * Returns the time in microseconds that the wifi supplicant has been
   2040      * in a given state.
   2041      *
   2042      * {@hide}
   2043      */
   2044     public abstract long getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which);
   2045 
   2046     /**
   2047      * Returns the number of times that the wifi supplicant has transitioned
   2048      * to a given state.
   2049      *
   2050      * {@hide}
   2051      */
   2052     public abstract int getWifiSupplStateCount(int state, int which);
   2053 
   2054     public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5;
   2055 
   2056     /**
   2057      * Returns the time in microseconds that WIFI has been running with
   2058      * the given signal strength.
   2059      *
   2060      * {@hide}
   2061      */
   2062     public abstract long getWifiSignalStrengthTime(int strengthBin,
   2063             long elapsedRealtimeUs, int which);
   2064 
   2065     /**
   2066      * Returns the number of times WIFI has entered the given signal strength.
   2067      *
   2068      * {@hide}
   2069      */
   2070     public abstract int getWifiSignalStrengthCount(int strengthBin, int which);
   2071 
   2072     /**
   2073      * Returns the time in microseconds that the flashlight has been on while the device was
   2074      * running on battery.
   2075      *
   2076      * {@hide}
   2077      */
   2078     public abstract long getFlashlightOnTime(long elapsedRealtimeUs, int which);
   2079 
   2080     /**
   2081      * Returns the number of times that the flashlight has been turned on while the device was
   2082      * running on battery.
   2083      *
   2084      * {@hide}
   2085      */
   2086     public abstract long getFlashlightOnCount(int which);
   2087 
   2088     /**
   2089      * Returns the time in microseconds that the camera has been on while the device was
   2090      * running on battery.
   2091      *
   2092      * {@hide}
   2093      */
   2094     public abstract long getCameraOnTime(long elapsedRealtimeUs, int which);
   2095 
   2096     /**
   2097      * Returns the time in microseconds that bluetooth scans were running while the device was
   2098      * on battery.
   2099      *
   2100      * {@hide}
   2101      */
   2102     public abstract long getBluetoothScanTime(long elapsedRealtimeUs, int which);
   2103 
   2104     public static final int NETWORK_MOBILE_RX_DATA = 0;
   2105     public static final int NETWORK_MOBILE_TX_DATA = 1;
   2106     public static final int NETWORK_WIFI_RX_DATA = 2;
   2107     public static final int NETWORK_WIFI_TX_DATA = 3;
   2108     public static final int NETWORK_BT_RX_DATA = 4;
   2109     public static final int NETWORK_BT_TX_DATA = 5;
   2110     public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_BT_TX_DATA + 1;
   2111 
   2112     public abstract long getNetworkActivityBytes(int type, int which);
   2113     public abstract long getNetworkActivityPackets(int type, int which);
   2114 
   2115     /**
   2116      * Returns true if the BatteryStats object has detailed WiFi power reports.
   2117      * When true, calling {@link #getWifiControllerActivity()} will yield the
   2118      * actual power data.
   2119      */
   2120     public abstract boolean hasWifiActivityReporting();
   2121 
   2122     /**
   2123      * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
   2124      * in various radio controller states, such as transmit, receive, and idle.
   2125      * @return non-null {@link ControllerActivityCounter}
   2126      */
   2127     public abstract ControllerActivityCounter getWifiControllerActivity();
   2128 
   2129     /**
   2130      * Returns true if the BatteryStats object has detailed bluetooth power reports.
   2131      * When true, calling {@link #getBluetoothControllerActivity()} will yield the
   2132      * actual power data.
   2133      */
   2134     public abstract boolean hasBluetoothActivityReporting();
   2135 
   2136     /**
   2137      * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
   2138      * in various radio controller states, such as transmit, receive, and idle.
   2139      * @return non-null {@link ControllerActivityCounter}
   2140      */
   2141     public abstract ControllerActivityCounter getBluetoothControllerActivity();
   2142 
   2143     /**
   2144      * Returns true if the BatteryStats object has detailed modem power reports.
   2145      * When true, calling {@link #getModemControllerActivity()} will yield the
   2146      * actual power data.
   2147      */
   2148     public abstract boolean hasModemActivityReporting();
   2149 
   2150     /**
   2151      * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
   2152      * in various radio controller states, such as transmit, receive, and idle.
   2153      * @return non-null {@link ControllerActivityCounter}
   2154      */
   2155     public abstract ControllerActivityCounter getModemControllerActivity();
   2156 
   2157     /**
   2158      * Return the wall clock time when battery stats data collection started.
   2159      */
   2160     public abstract long getStartClockTime();
   2161 
   2162     /**
   2163      * Return platform version tag that we were running in when the battery stats started.
   2164      */
   2165     public abstract String getStartPlatformVersion();
   2166 
   2167     /**
   2168      * Return platform version tag that we were running in when the battery stats ended.
   2169      */
   2170     public abstract String getEndPlatformVersion();
   2171 
   2172     /**
   2173      * Return the internal version code of the parcelled format.
   2174      */
   2175     public abstract int getParcelVersion();
   2176 
   2177     /**
   2178      * Return whether we are currently running on battery.
   2179      */
   2180     public abstract boolean getIsOnBattery();
   2181 
   2182     /**
   2183      * Returns a SparseArray containing the statistics for each uid.
   2184      */
   2185     public abstract SparseArray<? extends Uid> getUidStats();
   2186 
   2187     /**
   2188      * Returns the current battery uptime in microseconds.
   2189      *
   2190      * @param curTime the amount of elapsed realtime in microseconds.
   2191      */
   2192     public abstract long getBatteryUptime(long curTime);
   2193 
   2194     /**
   2195      * Returns the current battery realtime in microseconds.
   2196      *
   2197      * @param curTime the amount of elapsed realtime in microseconds.
   2198      */
   2199     public abstract long getBatteryRealtime(long curTime);
   2200 
   2201     /**
   2202      * Returns the battery percentage level at the last time the device was unplugged from power, or
   2203      * the last time it booted on battery power.
   2204      */
   2205     public abstract int getDischargeStartLevel();
   2206 
   2207     /**
   2208      * Returns the current battery percentage level if we are in a discharge cycle, otherwise
   2209      * returns the level at the last plug event.
   2210      */
   2211     public abstract int getDischargeCurrentLevel();
   2212 
   2213     /**
   2214      * Get the amount the battery has discharged since the stats were
   2215      * last reset after charging, as a lower-end approximation.
   2216      */
   2217     public abstract int getLowDischargeAmountSinceCharge();
   2218 
   2219     /**
   2220      * Get the amount the battery has discharged since the stats were
   2221      * last reset after charging, as an upper-end approximation.
   2222      */
   2223     public abstract int getHighDischargeAmountSinceCharge();
   2224 
   2225     /**
   2226      * Retrieve the discharge amount over the selected discharge period <var>which</var>.
   2227      */
   2228     public abstract int getDischargeAmount(int which);
   2229 
   2230     /**
   2231      * Get the amount the battery has discharged while the screen was on,
   2232      * since the last time power was unplugged.
   2233      */
   2234     public abstract int getDischargeAmountScreenOn();
   2235 
   2236     /**
   2237      * Get the amount the battery has discharged while the screen was on,
   2238      * since the last time the device was charged.
   2239      */
   2240     public abstract int getDischargeAmountScreenOnSinceCharge();
   2241 
   2242     /**
   2243      * Get the amount the battery has discharged while the screen was off,
   2244      * since the last time power was unplugged.
   2245      */
   2246     public abstract int getDischargeAmountScreenOff();
   2247 
   2248     /**
   2249      * Get the amount the battery has discharged while the screen was off,
   2250      * since the last time the device was charged.
   2251      */
   2252     public abstract int getDischargeAmountScreenOffSinceCharge();
   2253 
   2254     /**
   2255      * Returns the total, last, or current battery uptime in microseconds.
   2256      *
   2257      * @param curTime the elapsed realtime in microseconds.
   2258      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   2259      */
   2260     public abstract long computeBatteryUptime(long curTime, int which);
   2261 
   2262     /**
   2263      * Returns the total, last, or current battery realtime in microseconds.
   2264      *
   2265      * @param curTime the current elapsed realtime in microseconds.
   2266      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   2267      */
   2268     public abstract long computeBatteryRealtime(long curTime, int which);
   2269 
   2270     /**
   2271      * Returns the total, last, or current battery screen off uptime in microseconds.
   2272      *
   2273      * @param curTime the elapsed realtime in microseconds.
   2274      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   2275      */
   2276     public abstract long computeBatteryScreenOffUptime(long curTime, int which);
   2277 
   2278     /**
   2279      * Returns the total, last, or current battery screen off realtime in microseconds.
   2280      *
   2281      * @param curTime the current elapsed realtime in microseconds.
   2282      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   2283      */
   2284     public abstract long computeBatteryScreenOffRealtime(long curTime, int which);
   2285 
   2286     /**
   2287      * Returns the total, last, or current uptime in microseconds.
   2288      *
   2289      * @param curTime the current elapsed realtime in microseconds.
   2290      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   2291      */
   2292     public abstract long computeUptime(long curTime, int which);
   2293 
   2294     /**
   2295      * Returns the total, last, or current realtime in microseconds.
   2296      *
   2297      * @param curTime the current elapsed realtime in microseconds.
   2298      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   2299      */
   2300     public abstract long computeRealtime(long curTime, int which);
   2301 
   2302     /**
   2303      * Compute an approximation for how much run time (in microseconds) is remaining on
   2304      * the battery.  Returns -1 if no time can be computed: either there is not
   2305      * enough current data to make a decision, or the battery is currently
   2306      * charging.
   2307      *
   2308      * @param curTime The current elepsed realtime in microseconds.
   2309      */
   2310     public abstract long computeBatteryTimeRemaining(long curTime);
   2311 
   2312     // The part of a step duration that is the actual time.
   2313     public static final long STEP_LEVEL_TIME_MASK = 0x000000ffffffffffL;
   2314 
   2315     // Bits in a step duration that are the new battery level we are at.
   2316     public static final long STEP_LEVEL_LEVEL_MASK = 0x0000ff0000000000L;
   2317     public static final int STEP_LEVEL_LEVEL_SHIFT = 40;
   2318 
   2319     // Bits in a step duration that are the initial mode we were in at that step.
   2320     public static final long STEP_LEVEL_INITIAL_MODE_MASK = 0x00ff000000000000L;
   2321     public static final int STEP_LEVEL_INITIAL_MODE_SHIFT = 48;
   2322 
   2323     // Bits in a step duration that indicate which modes changed during that step.
   2324     public static final long STEP_LEVEL_MODIFIED_MODE_MASK = 0xff00000000000000L;
   2325     public static final int STEP_LEVEL_MODIFIED_MODE_SHIFT = 56;
   2326 
   2327     // Step duration mode: the screen is on, off, dozed, etc; value is Display.STATE_* - 1.
   2328     public static final int STEP_LEVEL_MODE_SCREEN_STATE = 0x03;
   2329 
   2330     // Step duration mode: power save is on.
   2331     public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04;
   2332 
   2333     // Step duration mode: device is currently in idle mode.
   2334     public static final int STEP_LEVEL_MODE_DEVICE_IDLE = 0x08;
   2335 
   2336     public static final int[] STEP_LEVEL_MODES_OF_INTEREST = new int[] {
   2337             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   2338             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE,
   2339             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
   2340             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   2341             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   2342             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   2343             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   2344             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   2345             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE,
   2346             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
   2347     };
   2348     public static final int[] STEP_LEVEL_MODE_VALUES = new int[] {
   2349             (Display.STATE_OFF-1),
   2350             (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE,
   2351             (Display.STATE_OFF-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
   2352             (Display.STATE_ON-1),
   2353             (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE,
   2354             (Display.STATE_DOZE-1),
   2355             (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE,
   2356             (Display.STATE_DOZE_SUSPEND-1),
   2357             (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE,
   2358             (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
   2359     };
   2360     public static final String[] STEP_LEVEL_MODE_LABELS = new String[] {
   2361             "screen off",
   2362             "screen off power save",
   2363             "screen off device idle",
   2364             "screen on",
   2365             "screen on power save",
   2366             "screen doze",
   2367             "screen doze power save",
   2368             "screen doze-suspend",
   2369             "screen doze-suspend power save",
   2370             "screen doze-suspend device idle",
   2371     };
   2372 
   2373     /**
   2374      * Return the counter keeping track of the amount of battery discharge while the screen was off,
   2375      * measured in micro-Ampere-hours. This will be non-zero only if the device's battery has
   2376      * a coulomb counter.
   2377      */
   2378     public abstract LongCounter getDischargeScreenOffCoulombCounter();
   2379 
   2380     /**
   2381      * Return the counter keeping track of the amount of battery discharge measured in
   2382      * micro-Ampere-hours. This will be non-zero only if the device's battery has
   2383      * a coulomb counter.
   2384      */
   2385     public abstract LongCounter getDischargeCoulombCounter();
   2386 
   2387     /**
   2388      * Returns the estimated real battery capacity, which may be less than the capacity
   2389      * declared by the PowerProfile.
   2390      * @return The estimated battery capacity in mAh.
   2391      */
   2392     public abstract int getEstimatedBatteryCapacity();
   2393 
   2394     /**
   2395      * Return the array of discharge step durations.
   2396      */
   2397     public abstract LevelStepTracker getDischargeLevelStepTracker();
   2398 
   2399     /**
   2400      * Return the array of daily discharge step durations.
   2401      */
   2402     public abstract LevelStepTracker getDailyDischargeLevelStepTracker();
   2403 
   2404     /**
   2405      * Compute an approximation for how much time (in microseconds) remains until the battery
   2406      * is fully charged.  Returns -1 if no time can be computed: either there is not
   2407      * enough current data to make a decision, or the battery is currently
   2408      * discharging.
   2409      *
   2410      * @param curTime The current elepsed realtime in microseconds.
   2411      */
   2412     public abstract long computeChargeTimeRemaining(long curTime);
   2413 
   2414     /**
   2415      * Return the array of charge step durations.
   2416      */
   2417     public abstract LevelStepTracker getChargeLevelStepTracker();
   2418 
   2419     /**
   2420      * Return the array of daily charge step durations.
   2421      */
   2422     public abstract LevelStepTracker getDailyChargeLevelStepTracker();
   2423 
   2424     public abstract ArrayList<PackageChange> getDailyPackageChanges();
   2425 
   2426     public abstract Map<String, ? extends Timer> getWakeupReasonStats();
   2427 
   2428     public abstract Map<String, ? extends Timer> getKernelWakelockStats();
   2429 
   2430     public abstract void writeToParcelWithoutUids(Parcel out, int flags);
   2431 
   2432     private final static void formatTimeRaw(StringBuilder out, long seconds) {
   2433         long days = seconds / (60 * 60 * 24);
   2434         if (days != 0) {
   2435             out.append(days);
   2436             out.append("d ");
   2437         }
   2438         long used = days * 60 * 60 * 24;
   2439 
   2440         long hours = (seconds - used) / (60 * 60);
   2441         if (hours != 0 || used != 0) {
   2442             out.append(hours);
   2443             out.append("h ");
   2444         }
   2445         used += hours * 60 * 60;
   2446 
   2447         long mins = (seconds-used) / 60;
   2448         if (mins != 0 || used != 0) {
   2449             out.append(mins);
   2450             out.append("m ");
   2451         }
   2452         used += mins * 60;
   2453 
   2454         if (seconds != 0 || used != 0) {
   2455             out.append(seconds-used);
   2456             out.append("s ");
   2457         }
   2458     }
   2459 
   2460     public final static void formatTimeMs(StringBuilder sb, long time) {
   2461         long sec = time / 1000;
   2462         formatTimeRaw(sb, sec);
   2463         sb.append(time - (sec * 1000));
   2464         sb.append("ms ");
   2465     }
   2466 
   2467     public final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
   2468         long sec = time / 1000;
   2469         formatTimeRaw(sb, sec);
   2470         sb.append(time - (sec * 1000));
   2471         sb.append("ms");
   2472     }
   2473 
   2474     public final String formatRatioLocked(long num, long den) {
   2475         if (den == 0L) {
   2476             return "--%";
   2477         }
   2478         float perc = ((float)num) / ((float)den) * 100;
   2479         mFormatBuilder.setLength(0);
   2480         mFormatter.format("%.1f%%", perc);
   2481         return mFormatBuilder.toString();
   2482     }
   2483 
   2484     final String formatBytesLocked(long bytes) {
   2485         mFormatBuilder.setLength(0);
   2486 
   2487         if (bytes < BYTES_PER_KB) {
   2488             return bytes + "B";
   2489         } else if (bytes < BYTES_PER_MB) {
   2490             mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
   2491             return mFormatBuilder.toString();
   2492         } else if (bytes < BYTES_PER_GB){
   2493             mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
   2494             return mFormatBuilder.toString();
   2495         } else {
   2496             mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
   2497             return mFormatBuilder.toString();
   2498         }
   2499     }
   2500 
   2501     private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) {
   2502         if (timer != null) {
   2503             // Convert from microseconds to milliseconds with rounding
   2504             long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
   2505             long totalTimeMillis = (totalTimeMicros + 500) / 1000;
   2506             return totalTimeMillis;
   2507         }
   2508         return 0;
   2509     }
   2510 
   2511     /**
   2512      *
   2513      * @param sb a StringBuilder object.
   2514      * @param timer a Timer object contining the wakelock times.
   2515      * @param elapsedRealtimeUs the current on-battery time in microseconds.
   2516      * @param name the name of the wakelock.
   2517      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   2518      * @param linePrefix a String to be prepended to each line of output.
   2519      * @return the line prefix
   2520      */
   2521     private static final String printWakeLock(StringBuilder sb, Timer timer,
   2522             long elapsedRealtimeUs, String name, int which, String linePrefix) {
   2523 
   2524         if (timer != null) {
   2525             long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which);
   2526 
   2527             int count = timer.getCountLocked(which);
   2528             if (totalTimeMillis != 0) {
   2529                 sb.append(linePrefix);
   2530                 formatTimeMs(sb, totalTimeMillis);
   2531                 if (name != null) {
   2532                     sb.append(name);
   2533                     sb.append(' ');
   2534                 }
   2535                 sb.append('(');
   2536                 sb.append(count);
   2537                 sb.append(" times)");
   2538                 return ", ";
   2539             }
   2540         }
   2541         return linePrefix;
   2542     }
   2543 
   2544     /**
   2545      *
   2546      * @param pw a PrintWriter object to print to.
   2547      * @param sb a StringBuilder object.
   2548      * @param timer a Timer object contining the wakelock times.
   2549      * @param rawRealtime the current on-battery time in microseconds.
   2550      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   2551      * @param prefix a String to be prepended to each line of output.
   2552      * @param type the name of the timer.
   2553      */
   2554     private static final boolean printTimer(PrintWriter pw, StringBuilder sb, Timer timer,
   2555             long rawRealtime, int which, String prefix, String type) {
   2556         if (timer != null) {
   2557             // Convert from microseconds to milliseconds with rounding
   2558             final long totalTime = (timer.getTotalTimeLocked(
   2559                     rawRealtime, which) + 500) / 1000;
   2560             final int count = timer.getCountLocked(which);
   2561             if (totalTime != 0) {
   2562                 sb.setLength(0);
   2563                 sb.append(prefix);
   2564                 sb.append("    ");
   2565                 sb.append(type);
   2566                 sb.append(": ");
   2567                 formatTimeMs(sb, totalTime);
   2568                 sb.append("realtime (");
   2569                 sb.append(count);
   2570                 sb.append(" times)");
   2571                 pw.println(sb.toString());
   2572                 return true;
   2573             }
   2574         }
   2575         return false;
   2576     }
   2577 
   2578     /**
   2579      * Checkin version of wakelock printer. Prints simple comma-separated list.
   2580      *
   2581      * @param sb a StringBuilder object.
   2582      * @param timer a Timer object contining the wakelock times.
   2583      * @param elapsedRealtimeUs the current time in microseconds.
   2584      * @param name the name of the wakelock.
   2585      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   2586      * @param linePrefix a String to be prepended to each line of output.
   2587      * @return the line prefix
   2588      */
   2589     private static final String printWakeLockCheckin(StringBuilder sb, Timer timer,
   2590             long elapsedRealtimeUs, String name, int which, String linePrefix) {
   2591         long totalTimeMicros = 0;
   2592         int count = 0;
   2593         if (timer != null) {
   2594             totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
   2595             count = timer.getCountLocked(which);
   2596         }
   2597         sb.append(linePrefix);
   2598         sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
   2599         sb.append(',');
   2600         sb.append(name != null ? name + "," : "");
   2601         sb.append(count);
   2602         return ",";
   2603     }
   2604 
   2605     private static final void dumpLineHeader(PrintWriter pw, int uid, String category,
   2606                                              String type) {
   2607         pw.print(BATTERY_STATS_CHECKIN_VERSION);
   2608         pw.print(',');
   2609         pw.print(uid);
   2610         pw.print(',');
   2611         pw.print(category);
   2612         pw.print(',');
   2613         pw.print(type);
   2614     }
   2615 
   2616     /**
   2617      * Dump a comma-separated line of values for terse checkin mode.
   2618      *
   2619      * @param pw the PageWriter to dump log to
   2620      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
   2621      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
   2622      * @param args type-dependent data arguments
   2623      */
   2624     private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
   2625            Object... args ) {
   2626         dumpLineHeader(pw, uid, category, type);
   2627         for (Object arg : args) {
   2628             pw.print(',');
   2629             pw.print(arg);
   2630         }
   2631         pw.println();
   2632     }
   2633 
   2634     /**
   2635      * Dump a given timer stat for terse checkin mode.
   2636      *
   2637      * @param pw the PageWriter to dump log to
   2638      * @param uid the UID to log
   2639      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
   2640      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
   2641      * @param timer a {@link Timer} to dump stats for
   2642      * @param rawRealtime the current elapsed realtime of the system in microseconds
   2643      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
   2644      */
   2645     private static final void dumpTimer(PrintWriter pw, int uid, String category, String type,
   2646                                         Timer timer, long rawRealtime, int which) {
   2647         if (timer != null) {
   2648             // Convert from microseconds to milliseconds with rounding
   2649             final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
   2650                     / 1000;
   2651             final int count = timer.getCountLocked(which);
   2652             if (totalTime != 0) {
   2653                 dumpLine(pw, uid, category, type, totalTime, count);
   2654             }
   2655         }
   2656     }
   2657 
   2658     /**
   2659      * Checks if the ControllerActivityCounter has any data worth dumping.
   2660      */
   2661     private static boolean controllerActivityHasData(ControllerActivityCounter counter, int which) {
   2662         if (counter == null) {
   2663             return false;
   2664         }
   2665 
   2666         if (counter.getIdleTimeCounter().getCountLocked(which) != 0
   2667                 || counter.getRxTimeCounter().getCountLocked(which) != 0
   2668                 || counter.getPowerCounter().getCountLocked(which) != 0) {
   2669             return true;
   2670         }
   2671 
   2672         for (LongCounter c : counter.getTxTimeCounters()) {
   2673             if (c.getCountLocked(which) != 0) {
   2674                 return true;
   2675             }
   2676         }
   2677         return false;
   2678     }
   2679 
   2680     /**
   2681      * Dumps the ControllerActivityCounter if it has any data worth dumping.
   2682      * The order of the arguments in the final check in line is:
   2683      *
   2684      * idle, rx, power, tx...
   2685      *
   2686      * where tx... is one or more transmit level times.
   2687      */
   2688     private static final void dumpControllerActivityLine(PrintWriter pw, int uid, String category,
   2689                                                          String type,
   2690                                                          ControllerActivityCounter counter,
   2691                                                          int which) {
   2692         if (!controllerActivityHasData(counter, which)) {
   2693             return;
   2694         }
   2695 
   2696         dumpLineHeader(pw, uid, category, type);
   2697         pw.print(",");
   2698         pw.print(counter.getIdleTimeCounter().getCountLocked(which));
   2699         pw.print(",");
   2700         pw.print(counter.getRxTimeCounter().getCountLocked(which));
   2701         pw.print(",");
   2702         pw.print(counter.getPowerCounter().getCountLocked(which) / (1000 * 60 * 60));
   2703         for (LongCounter c : counter.getTxTimeCounters()) {
   2704             pw.print(",");
   2705             pw.print(c.getCountLocked(which));
   2706         }
   2707         pw.println();
   2708     }
   2709 
   2710     private final void printControllerActivityIfInteresting(PrintWriter pw, StringBuilder sb,
   2711                                                             String prefix, String controllerName,
   2712                                                             ControllerActivityCounter counter,
   2713                                                             int which) {
   2714         if (controllerActivityHasData(counter, which)) {
   2715             printControllerActivity(pw, sb, prefix, controllerName, counter, which);
   2716         }
   2717     }
   2718 
   2719     private final void printControllerActivity(PrintWriter pw, StringBuilder sb, String prefix,
   2720                                                String controllerName,
   2721                                                ControllerActivityCounter counter, int which) {
   2722         final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
   2723         final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
   2724         final long powerDrainMaMs = counter.getPowerCounter().getCountLocked(which);
   2725         long totalTxTimeMs = 0;
   2726         for (LongCounter txState : counter.getTxTimeCounters()) {
   2727             totalTxTimeMs += txState.getCountLocked(which);
   2728         }
   2729 
   2730         final long totalTimeMs = idleTimeMs + rxTimeMs + totalTxTimeMs;
   2731 
   2732         sb.setLength(0);
   2733         sb.append(prefix);
   2734         sb.append("  ");
   2735         sb.append(controllerName);
   2736         sb.append(" Idle time:   ");
   2737         formatTimeMs(sb, idleTimeMs);
   2738         sb.append("(");
   2739         sb.append(formatRatioLocked(idleTimeMs, totalTimeMs));
   2740         sb.append(")");
   2741         pw.println(sb.toString());
   2742 
   2743         sb.setLength(0);
   2744         sb.append(prefix);
   2745         sb.append("  ");
   2746         sb.append(controllerName);
   2747         sb.append(" Rx time:     ");
   2748         formatTimeMs(sb, rxTimeMs);
   2749         sb.append("(");
   2750         sb.append(formatRatioLocked(rxTimeMs, totalTimeMs));
   2751         sb.append(")");
   2752         pw.println(sb.toString());
   2753 
   2754         sb.setLength(0);
   2755         sb.append(prefix);
   2756         sb.append("  ");
   2757         sb.append(controllerName);
   2758         sb.append(" Tx time:     ");
   2759         formatTimeMs(sb, totalTxTimeMs);
   2760         sb.append("(");
   2761         sb.append(formatRatioLocked(totalTxTimeMs, totalTimeMs));
   2762         sb.append(")");
   2763         pw.println(sb.toString());
   2764 
   2765         final int numTxLvls = counter.getTxTimeCounters().length;
   2766         if (numTxLvls > 1) {
   2767             for (int lvl = 0; lvl < numTxLvls; lvl++) {
   2768                 final long txLvlTimeMs = counter.getTxTimeCounters()[lvl].getCountLocked(which);
   2769                 sb.setLength(0);
   2770                 sb.append(prefix);
   2771                 sb.append("    [");
   2772                 sb.append(lvl);
   2773                 sb.append("] ");
   2774                 formatTimeMs(sb, txLvlTimeMs);
   2775                 sb.append("(");
   2776                 sb.append(formatRatioLocked(txLvlTimeMs, totalTxTimeMs));
   2777                 sb.append(")");
   2778                 pw.println(sb.toString());
   2779             }
   2780         }
   2781 
   2782         sb.setLength(0);
   2783         sb.append(prefix);
   2784         sb.append("  ");
   2785         sb.append(controllerName);
   2786         sb.append(" Power drain: ").append(
   2787                 BatteryStatsHelper.makemAh(powerDrainMaMs / (double) (1000*60*60)));
   2788         sb.append("mAh");
   2789         pw.println(sb.toString());
   2790     }
   2791 
   2792     /**
   2793      * Temporary for settings.
   2794      */
   2795     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
   2796         dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
   2797     }
   2798 
   2799     /**
   2800      * Checkin server version of dump to produce more compact, computer-readable log.
   2801      *
   2802      * NOTE: all times are expressed in 'ms'.
   2803      */
   2804     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
   2805             boolean wifiOnly) {
   2806         final long rawUptime = SystemClock.uptimeMillis() * 1000;
   2807         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
   2808         final long batteryUptime = getBatteryUptime(rawUptime);
   2809         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
   2810         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
   2811         final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
   2812         final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
   2813                 which);
   2814         final long totalRealtime = computeRealtime(rawRealtime, which);
   2815         final long totalUptime = computeUptime(rawUptime, which);
   2816         final long screenOnTime = getScreenOnTime(rawRealtime, which);
   2817         final long interactiveTime = getInteractiveTime(rawRealtime, which);
   2818         final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
   2819         final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT,
   2820                 rawRealtime, which);
   2821         final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP,
   2822                 rawRealtime, which);
   2823         final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT,
   2824                 rawRealtime, which);
   2825         final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP,
   2826                 rawRealtime, which);
   2827         final int connChanges = getNumConnectivityChange(which);
   2828         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
   2829         final long dischargeCount = getDischargeCoulombCounter().getCountLocked(which);
   2830         final long dischargeScreenOffCount = getDischargeScreenOffCoulombCounter()
   2831                 .getCountLocked(which);
   2832 
   2833         final StringBuilder sb = new StringBuilder(128);
   2834 
   2835         final SparseArray<? extends Uid> uidStats = getUidStats();
   2836         final int NU = uidStats.size();
   2837 
   2838         final String category = STAT_NAMES[which];
   2839 
   2840         // Dump "battery" stat
   2841         dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
   2842                 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
   2843                 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
   2844                 totalRealtime / 1000, totalUptime / 1000,
   2845                 getStartClockTime(),
   2846                 whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000,
   2847                 getEstimatedBatteryCapacity());
   2848 
   2849 
   2850         // Calculate wakelock times across all uids.
   2851         long fullWakeLockTimeTotal = 0;
   2852         long partialWakeLockTimeTotal = 0;
   2853 
   2854         for (int iu = 0; iu < NU; iu++) {
   2855             final Uid u = uidStats.valueAt(iu);
   2856 
   2857             final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
   2858                     = u.getWakelockStats();
   2859             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
   2860                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
   2861 
   2862                 final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
   2863                 if (fullWakeTimer != null) {
   2864                     fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
   2865                             which);
   2866                 }
   2867 
   2868                 final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
   2869                 if (partialWakeTimer != null) {
   2870                     partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
   2871                         rawRealtime, which);
   2872                 }
   2873             }
   2874         }
   2875 
   2876         // Dump network stats
   2877         final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
   2878         final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
   2879         final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
   2880         final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
   2881         final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
   2882         final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
   2883         final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
   2884         final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
   2885         final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
   2886         final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
   2887         dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
   2888                 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
   2889                 mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets,
   2890                 btRxTotalBytes, btTxTotalBytes);
   2891 
   2892         // Dump Modem controller stats
   2893         dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_MODEM_CONTROLLER_DATA,
   2894                 getModemControllerActivity(), which);
   2895 
   2896         // Dump Wifi controller stats
   2897         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
   2898         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
   2899         dumpLine(pw, 0 /* uid */, category, GLOBAL_WIFI_DATA, wifiOnTime / 1000,
   2900                 wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */ 0, 0, 0);
   2901 
   2902         dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_WIFI_CONTROLLER_DATA,
   2903                 getWifiControllerActivity(), which);
   2904 
   2905         // Dump Bluetooth controller stats
   2906         dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_BLUETOOTH_CONTROLLER_DATA,
   2907                 getBluetoothControllerActivity(), which);
   2908 
   2909         // Dump misc stats
   2910         dumpLine(pw, 0 /* uid */, category, MISC_DATA,
   2911                 screenOnTime / 1000, phoneOnTime / 1000,
   2912                 fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000,
   2913                 getMobileRadioActiveTime(rawRealtime, which) / 1000,
   2914                 getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000,
   2915                 powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeFullTime / 1000,
   2916                 getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which), deviceIdlingTime / 1000,
   2917                 getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which),
   2918                 getMobileRadioActiveCount(which),
   2919                 getMobileRadioActiveUnknownTime(which) / 1000, deviceIdleModeLightTime / 1000,
   2920                 getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which), deviceLightIdlingTime / 1000,
   2921                 getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which),
   2922                 getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT),
   2923                 getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
   2924 
   2925         // Dump screen brightness stats
   2926         Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
   2927         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
   2928             args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
   2929         }
   2930         dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
   2931 
   2932         // Dump signal strength stats
   2933         args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
   2934         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
   2935             args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
   2936         }
   2937         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
   2938         dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
   2939                 getPhoneSignalScanningTime(rawRealtime, which) / 1000);
   2940         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
   2941             args[i] = getPhoneSignalStrengthCount(i, which);
   2942         }
   2943         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
   2944 
   2945         // Dump network type stats
   2946         args = new Object[NUM_DATA_CONNECTION_TYPES];
   2947         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
   2948             args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
   2949         }
   2950         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
   2951         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
   2952             args[i] = getPhoneDataConnectionCount(i, which);
   2953         }
   2954         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
   2955 
   2956         // Dump wifi state stats
   2957         args = new Object[NUM_WIFI_STATES];
   2958         for (int i=0; i<NUM_WIFI_STATES; i++) {
   2959             args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
   2960         }
   2961         dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args);
   2962         for (int i=0; i<NUM_WIFI_STATES; i++) {
   2963             args[i] = getWifiStateCount(i, which);
   2964         }
   2965         dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args);
   2966 
   2967         // Dump wifi suppl state stats
   2968         args = new Object[NUM_WIFI_SUPPL_STATES];
   2969         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
   2970             args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
   2971         }
   2972         dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_TIME_DATA, args);
   2973         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
   2974             args[i] = getWifiSupplStateCount(i, which);
   2975         }
   2976         dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_COUNT_DATA, args);
   2977 
   2978         // Dump wifi signal strength stats
   2979         args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
   2980         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
   2981             args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
   2982         }
   2983         dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
   2984         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
   2985             args[i] = getWifiSignalStrengthCount(i, which);
   2986         }
   2987         dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
   2988 
   2989         if (which == STATS_SINCE_UNPLUGGED) {
   2990             dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
   2991                     getDischargeCurrentLevel());
   2992         }
   2993 
   2994         if (which == STATS_SINCE_UNPLUGGED) {
   2995             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
   2996                     getDischargeStartLevel()-getDischargeCurrentLevel(),
   2997                     getDischargeStartLevel()-getDischargeCurrentLevel(),
   2998                     getDischargeAmountScreenOn(), getDischargeAmountScreenOff(),
   2999                     dischargeCount / 1000, dischargeScreenOffCount / 1000);
   3000         } else {
   3001             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
   3002                     getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
   3003                     getDischargeAmountScreenOnSinceCharge(),
   3004                     getDischargeAmountScreenOffSinceCharge(),
   3005                     dischargeCount / 1000, dischargeScreenOffCount / 1000);
   3006         }
   3007 
   3008         if (reqUid < 0) {
   3009             final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
   3010             if (kernelWakelocks.size() > 0) {
   3011                 for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
   3012                     sb.setLength(0);
   3013                     printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
   3014                     dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
   3015                             sb.toString());
   3016                 }
   3017             }
   3018             final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
   3019             if (wakeupReasons.size() > 0) {
   3020                 for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
   3021                     // Not doing the regular wake lock formatting to remain compatible
   3022                     // with the old checkin format.
   3023                     long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which);
   3024                     int count = ent.getValue().getCountLocked(which);
   3025                     dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA,
   3026                             "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count);
   3027                 }
   3028             }
   3029         }
   3030 
   3031         final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
   3032         helper.create(this);
   3033         helper.refreshStats(which, UserHandle.USER_ALL);
   3034         final List<BatterySipper> sippers = helper.getUsageList();
   3035         if (sippers != null && sippers.size() > 0) {
   3036             dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
   3037                     BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
   3038                     BatteryStatsHelper.makemAh(helper.getComputedPower()),
   3039                     BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
   3040                     BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
   3041             for (int i=0; i<sippers.size(); i++) {
   3042                 final BatterySipper bs = sippers.get(i);
   3043                 int uid = 0;
   3044                 String label;
   3045                 switch (bs.drainType) {
   3046                     case IDLE:
   3047                         label="idle";
   3048                         break;
   3049                     case CELL:
   3050                         label="cell";
   3051                         break;
   3052                     case PHONE:
   3053                         label="phone";
   3054                         break;
   3055                     case WIFI:
   3056                         label="wifi";
   3057                         break;
   3058                     case BLUETOOTH:
   3059                         label="blue";
   3060                         break;
   3061                     case SCREEN:
   3062                         label="scrn";
   3063                         break;
   3064                     case FLASHLIGHT:
   3065                         label="flashlight";
   3066                         break;
   3067                     case APP:
   3068                         uid = bs.uidObj.getUid();
   3069                         label = "uid";
   3070                         break;
   3071                     case USER:
   3072                         uid = UserHandle.getUid(bs.userId, 0);
   3073                         label = "user";
   3074                         break;
   3075                     case UNACCOUNTED:
   3076                         label = "unacc";
   3077                         break;
   3078                     case OVERCOUNTED:
   3079                         label = "over";
   3080                         break;
   3081                     case CAMERA:
   3082                         label = "camera";
   3083                         break;
   3084                     default:
   3085                         label = "???";
   3086                 }
   3087                 dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
   3088                         BatteryStatsHelper.makemAh(bs.totalPowerMah));
   3089             }
   3090         }
   3091 
   3092         for (int iu = 0; iu < NU; iu++) {
   3093             final int uid = uidStats.keyAt(iu);
   3094             if (reqUid >= 0 && uid != reqUid) {
   3095                 continue;
   3096             }
   3097             final Uid u = uidStats.valueAt(iu);
   3098 
   3099             // Dump Network stats per uid, if any
   3100             final long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
   3101             final long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
   3102             final long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
   3103             final long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
   3104             final long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
   3105             final long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
   3106             final long mobileActiveTime = u.getMobileRadioActiveTime(which);
   3107             final int mobileActiveCount = u.getMobileRadioActiveCount(which);
   3108             final long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
   3109             final long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
   3110             final long btBytesRx = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
   3111             final long btBytesTx = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
   3112             if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
   3113                     || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
   3114                     || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0
   3115                     || btBytesRx > 0 || btBytesTx > 0) {
   3116                 dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
   3117                         wifiBytesRx, wifiBytesTx,
   3118                         mobilePacketsRx, mobilePacketsTx,
   3119                         wifiPacketsRx, wifiPacketsTx,
   3120                         mobileActiveTime, mobileActiveCount,
   3121                         btBytesRx, btBytesTx);
   3122             }
   3123 
   3124             // Dump modem controller data, per UID.
   3125             dumpControllerActivityLine(pw, uid, category, MODEM_CONTROLLER_DATA,
   3126                     u.getModemControllerActivity(), which);
   3127 
   3128             // Dump Wifi controller data, per UID.
   3129             final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
   3130             final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
   3131             final int wifiScanCount = u.getWifiScanCount(which);
   3132             final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
   3133             if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
   3134                     || uidWifiRunningTime != 0) {
   3135                 dumpLine(pw, uid, category, WIFI_DATA, fullWifiLockOnTime, wifiScanTime,
   3136                         uidWifiRunningTime, wifiScanCount,
   3137                         /* legacy fields follow, keep at 0 */ 0, 0, 0);
   3138             }
   3139 
   3140             dumpControllerActivityLine(pw, uid, category, WIFI_CONTROLLER_DATA,
   3141                     u.getWifiControllerActivity(), which);
   3142 
   3143             dumpTimer(pw, uid, category, BLUETOOTH_MISC_DATA, u.getBluetoothScanTimer(),
   3144                     rawRealtime, which);
   3145 
   3146             dumpControllerActivityLine(pw, uid, category, BLUETOOTH_CONTROLLER_DATA,
   3147                     u.getBluetoothControllerActivity(), which);
   3148 
   3149             if (u.hasUserActivity()) {
   3150                 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
   3151                 boolean hasData = false;
   3152                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
   3153                     int val = u.getUserActivityCount(i, which);
   3154                     args[i] = val;
   3155                     if (val != 0) hasData = true;
   3156                 }
   3157                 if (hasData) {
   3158                     dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args);
   3159                 }
   3160             }
   3161 
   3162             final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
   3163             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
   3164                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
   3165                 String linePrefix = "";
   3166                 sb.setLength(0);
   3167                 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
   3168                         rawRealtime, "f", which, linePrefix);
   3169                 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
   3170                         rawRealtime, "p", which, linePrefix);
   3171                 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
   3172                         rawRealtime, "w", which, linePrefix);
   3173 
   3174                 // Only log if we had at lease one wakelock...
   3175                 if (sb.length() > 0) {
   3176                     String name = wakelocks.keyAt(iw);
   3177                     if (name.indexOf(',') >= 0) {
   3178                         name = name.replace(',', '_');
   3179                     }
   3180                     dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
   3181                 }
   3182             }
   3183 
   3184             final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
   3185             for (int isy=syncs.size()-1; isy>=0; isy--) {
   3186                 final Timer timer = syncs.valueAt(isy);
   3187                 // Convert from microseconds to milliseconds with rounding
   3188                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   3189                 final int count = timer.getCountLocked(which);
   3190                 if (totalTime != 0) {
   3191                     dumpLine(pw, uid, category, SYNC_DATA, syncs.keyAt(isy), totalTime, count);
   3192                 }
   3193             }
   3194 
   3195             final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
   3196             for (int ij=jobs.size()-1; ij>=0; ij--) {
   3197                 final Timer timer = jobs.valueAt(ij);
   3198                 // Convert from microseconds to milliseconds with rounding
   3199                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   3200                 final int count = timer.getCountLocked(which);
   3201                 if (totalTime != 0) {
   3202                     dumpLine(pw, uid, category, JOB_DATA, jobs.keyAt(ij), totalTime, count);
   3203                 }
   3204             }
   3205 
   3206             dumpTimer(pw, uid, category, FLASHLIGHT_DATA, u.getFlashlightTurnedOnTimer(),
   3207                     rawRealtime, which);
   3208             dumpTimer(pw, uid, category, CAMERA_DATA, u.getCameraTurnedOnTimer(),
   3209                     rawRealtime, which);
   3210             dumpTimer(pw, uid, category, VIDEO_DATA, u.getVideoTurnedOnTimer(),
   3211                     rawRealtime, which);
   3212             dumpTimer(pw, uid, category, AUDIO_DATA, u.getAudioTurnedOnTimer(),
   3213                     rawRealtime, which);
   3214 
   3215             final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
   3216             final int NSE = sensors.size();
   3217             for (int ise=0; ise<NSE; ise++) {
   3218                 final Uid.Sensor se = sensors.valueAt(ise);
   3219                 final int sensorNumber = sensors.keyAt(ise);
   3220                 final Timer timer = se.getSensorTime();
   3221                 if (timer != null) {
   3222                     // Convert from microseconds to milliseconds with rounding
   3223                     final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
   3224                             / 1000;
   3225                     final int count = timer.getCountLocked(which);
   3226                     if (totalTime != 0) {
   3227                         dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
   3228                     }
   3229                 }
   3230             }
   3231 
   3232             dumpTimer(pw, uid, category, VIBRATOR_DATA, u.getVibratorOnTimer(),
   3233                     rawRealtime, which);
   3234 
   3235             dumpTimer(pw, uid, category, FOREGROUND_DATA, u.getForegroundActivityTimer(),
   3236                     rawRealtime, which);
   3237 
   3238             final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
   3239             long totalStateTime = 0;
   3240             for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
   3241                 final long time = u.getProcessStateTime(ips, rawRealtime, which);
   3242                 totalStateTime += time;
   3243                 stateTimes[ips] = (time + 500) / 1000;
   3244             }
   3245             if (totalStateTime > 0) {
   3246                 dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
   3247             }
   3248 
   3249             final long userCpuTimeUs = u.getUserCpuTimeUs(which);
   3250             final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
   3251             final long powerCpuMaUs = u.getCpuPowerMaUs(which);
   3252             if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
   3253                 dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000,
   3254                         powerCpuMaUs / 1000);
   3255             }
   3256 
   3257             final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
   3258                     = u.getProcessStats();
   3259             for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
   3260                 final Uid.Proc ps = processStats.valueAt(ipr);
   3261 
   3262                 final long userMillis = ps.getUserTime(which);
   3263                 final long systemMillis = ps.getSystemTime(which);
   3264                 final long foregroundMillis = ps.getForegroundTime(which);
   3265                 final int starts = ps.getStarts(which);
   3266                 final int numCrashes = ps.getNumCrashes(which);
   3267                 final int numAnrs = ps.getNumAnrs(which);
   3268 
   3269                 if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
   3270                         || starts != 0 || numAnrs != 0 || numCrashes != 0) {
   3271                     dumpLine(pw, uid, category, PROCESS_DATA, processStats.keyAt(ipr), userMillis,
   3272                             systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
   3273                 }
   3274             }
   3275 
   3276             final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
   3277                     = u.getPackageStats();
   3278             for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
   3279                 final Uid.Pkg ps = packageStats.valueAt(ipkg);
   3280                 int wakeups = 0;
   3281                 final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
   3282                 for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
   3283                     int count = alarms.valueAt(iwa).getCountLocked(which);
   3284                     wakeups += count;
   3285                     String name = alarms.keyAt(iwa).replace(',', '_');
   3286                     dumpLine(pw, uid, category, WAKEUP_ALARM_DATA, name, count);
   3287                 }
   3288                 final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
   3289                 for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
   3290                     final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
   3291                     final long startTime = ss.getStartTime(batteryUptime, which);
   3292                     final int starts = ss.getStarts(which);
   3293                     final int launches = ss.getLaunches(which);
   3294                     if (startTime != 0 || starts != 0 || launches != 0) {
   3295                         dumpLine(pw, uid, category, APK_DATA,
   3296                                 wakeups, // wakeup alarms
   3297                                 packageStats.keyAt(ipkg), // Apk
   3298                                 serviceStats.keyAt(isvc), // service
   3299                                 startTime / 1000, // time spent started, in ms
   3300                                 starts,
   3301                                 launches);
   3302                     }
   3303                 }
   3304             }
   3305         }
   3306     }
   3307 
   3308     static final class TimerEntry {
   3309         final String mName;
   3310         final int mId;
   3311         final BatteryStats.Timer mTimer;
   3312         final long mTime;
   3313         TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
   3314             mName = name;
   3315             mId = id;
   3316             mTimer = timer;
   3317             mTime = time;
   3318         }
   3319     }
   3320 
   3321     private void printmAh(PrintWriter printer, double power) {
   3322         printer.print(BatteryStatsHelper.makemAh(power));
   3323     }
   3324 
   3325     private void printmAh(StringBuilder sb, double power) {
   3326         sb.append(BatteryStatsHelper.makemAh(power));
   3327     }
   3328 
   3329     /**
   3330      * Temporary for settings.
   3331      */
   3332     public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which,
   3333             int reqUid) {
   3334         dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
   3335     }
   3336 
   3337     @SuppressWarnings("unused")
   3338     public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
   3339             int reqUid, boolean wifiOnly) {
   3340         final long rawUptime = SystemClock.uptimeMillis() * 1000;
   3341         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
   3342         final long batteryUptime = getBatteryUptime(rawUptime);
   3343 
   3344         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
   3345         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
   3346         final long totalRealtime = computeRealtime(rawRealtime, which);
   3347         final long totalUptime = computeUptime(rawUptime, which);
   3348         final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
   3349         final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
   3350                 which);
   3351         final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
   3352         final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
   3353 
   3354         final StringBuilder sb = new StringBuilder(128);
   3355 
   3356         final SparseArray<? extends Uid> uidStats = getUidStats();
   3357         final int NU = uidStats.size();
   3358 
   3359         final int estimatedBatteryCapacity = getEstimatedBatteryCapacity();
   3360         if (estimatedBatteryCapacity > 0) {
   3361             sb.setLength(0);
   3362             sb.append(prefix);
   3363                 sb.append("  Estimated battery capacity: ");
   3364                 sb.append(BatteryStatsHelper.makemAh(estimatedBatteryCapacity));
   3365                 sb.append(" mAh");
   3366             pw.println(sb.toString());
   3367         }
   3368 
   3369         sb.setLength(0);
   3370         sb.append(prefix);
   3371                 sb.append("  Time on battery: ");
   3372                 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
   3373                 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
   3374                 sb.append(") realtime, ");
   3375                 formatTimeMs(sb, whichBatteryUptime / 1000);
   3376                 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
   3377                 sb.append(") uptime");
   3378         pw.println(sb.toString());
   3379         sb.setLength(0);
   3380         sb.append(prefix);
   3381                 sb.append("  Time on battery screen off: ");
   3382                 formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("(");
   3383                 sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime));
   3384                 sb.append(") realtime, ");
   3385                 formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
   3386                 sb.append("(");
   3387                 sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime));
   3388                 sb.append(") uptime");
   3389         pw.println(sb.toString());
   3390         sb.setLength(0);
   3391         sb.append(prefix);
   3392                 sb.append("  Total run time: ");
   3393                 formatTimeMs(sb, totalRealtime / 1000);
   3394                 sb.append("realtime, ");
   3395                 formatTimeMs(sb, totalUptime / 1000);
   3396                 sb.append("uptime");
   3397         pw.println(sb.toString());
   3398         if (batteryTimeRemaining >= 0) {
   3399             sb.setLength(0);
   3400             sb.append(prefix);
   3401                     sb.append("  Battery time remaining: ");
   3402                     formatTimeMs(sb, batteryTimeRemaining / 1000);
   3403             pw.println(sb.toString());
   3404         }
   3405         if (chargeTimeRemaining >= 0) {
   3406             sb.setLength(0);
   3407             sb.append(prefix);
   3408                     sb.append("  Charge time remaining: ");
   3409                     formatTimeMs(sb, chargeTimeRemaining / 1000);
   3410             pw.println(sb.toString());
   3411         }
   3412 
   3413         final LongCounter dischargeCounter = getDischargeCoulombCounter();
   3414         final long dischargeCount = dischargeCounter.getCountLocked(which);
   3415         if (dischargeCount >= 0) {
   3416             sb.setLength(0);
   3417             sb.append(prefix);
   3418                 sb.append("  Discharge: ");
   3419                 sb.append(BatteryStatsHelper.makemAh(dischargeCount / 1000.0));
   3420                 sb.append(" mAh");
   3421             pw.println(sb.toString());
   3422         }
   3423 
   3424         final LongCounter dischargeScreenOffCounter = getDischargeScreenOffCoulombCounter();
   3425         final long dischargeScreenOffCount = dischargeScreenOffCounter.getCountLocked(which);
   3426         if (dischargeScreenOffCount >= 0) {
   3427             sb.setLength(0);
   3428             sb.append(prefix);
   3429                 sb.append("  Screen off discharge: ");
   3430                 sb.append(BatteryStatsHelper.makemAh(dischargeScreenOffCount / 1000.0));
   3431                 sb.append(" mAh");
   3432             pw.println(sb.toString());
   3433         }
   3434 
   3435         final long dischargeScreenOnCount = dischargeCount - dischargeScreenOffCount;
   3436         if (dischargeScreenOnCount >= 0) {
   3437             sb.setLength(0);
   3438             sb.append(prefix);
   3439                 sb.append("  Screen on discharge: ");
   3440                 sb.append(BatteryStatsHelper.makemAh(dischargeScreenOnCount / 1000.0));
   3441                 sb.append(" mAh");
   3442             pw.println(sb.toString());
   3443         }
   3444 
   3445         pw.print("  Start clock time: ");
   3446         pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
   3447 
   3448         final long screenOnTime = getScreenOnTime(rawRealtime, which);
   3449         final long interactiveTime = getInteractiveTime(rawRealtime, which);
   3450         final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
   3451         final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT,
   3452                 rawRealtime, which);
   3453         final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP,
   3454                 rawRealtime, which);
   3455         final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT,
   3456                 rawRealtime, which);
   3457         final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP,
   3458                 rawRealtime, which);
   3459         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
   3460         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
   3461         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
   3462         sb.setLength(0);
   3463         sb.append(prefix);
   3464                 sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
   3465                 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
   3466                 sb.append(") "); sb.append(getScreenOnCount(which));
   3467                 sb.append("x, Interactive: "); formatTimeMs(sb, interactiveTime / 1000);
   3468                 sb.append("("); sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime));
   3469                 sb.append(")");
   3470         pw.println(sb.toString());
   3471         sb.setLength(0);
   3472         sb.append(prefix);
   3473         sb.append("  Screen brightnesses:");
   3474         boolean didOne = false;
   3475         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
   3476             final long time = getScreenBrightnessTime(i, rawRealtime, which);
   3477             if (time == 0) {
   3478                 continue;
   3479             }
   3480             sb.append("\n    ");
   3481             sb.append(prefix);
   3482             didOne = true;
   3483             sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
   3484             sb.append(" ");
   3485             formatTimeMs(sb, time/1000);
   3486             sb.append("(");
   3487             sb.append(formatRatioLocked(time, screenOnTime));
   3488             sb.append(")");
   3489         }
   3490         if (!didOne) sb.append(" (no activity)");
   3491         pw.println(sb.toString());
   3492         if (powerSaveModeEnabledTime != 0) {
   3493             sb.setLength(0);
   3494             sb.append(prefix);
   3495                     sb.append("  Power save mode enabled: ");
   3496                     formatTimeMs(sb, powerSaveModeEnabledTime / 1000);
   3497                     sb.append("(");
   3498                     sb.append(formatRatioLocked(powerSaveModeEnabledTime, whichBatteryRealtime));
   3499                     sb.append(")");
   3500             pw.println(sb.toString());
   3501         }
   3502         if (deviceLightIdlingTime != 0) {
   3503             sb.setLength(0);
   3504             sb.append(prefix);
   3505                     sb.append("  Device light idling: ");
   3506                     formatTimeMs(sb, deviceLightIdlingTime / 1000);
   3507                     sb.append("(");
   3508                     sb.append(formatRatioLocked(deviceLightIdlingTime, whichBatteryRealtime));
   3509                     sb.append(") "); sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which));
   3510                     sb.append("x");
   3511             pw.println(sb.toString());
   3512         }
   3513         if (deviceIdleModeLightTime != 0) {
   3514             sb.setLength(0);
   3515             sb.append(prefix);
   3516                     sb.append("  Idle mode light time: ");
   3517                     formatTimeMs(sb, deviceIdleModeLightTime / 1000);
   3518                     sb.append("(");
   3519                     sb.append(formatRatioLocked(deviceIdleModeLightTime, whichBatteryRealtime));
   3520                     sb.append(") ");
   3521                     sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which));
   3522                     sb.append("x");
   3523                     sb.append(" -- longest ");
   3524                     formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
   3525             pw.println(sb.toString());
   3526         }
   3527         if (deviceIdlingTime != 0) {
   3528             sb.setLength(0);
   3529             sb.append(prefix);
   3530                     sb.append("  Device full idling: ");
   3531                     formatTimeMs(sb, deviceIdlingTime / 1000);
   3532                     sb.append("(");
   3533                     sb.append(formatRatioLocked(deviceIdlingTime, whichBatteryRealtime));
   3534                     sb.append(") "); sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which));
   3535                     sb.append("x");
   3536             pw.println(sb.toString());
   3537         }
   3538         if (deviceIdleModeFullTime != 0) {
   3539             sb.setLength(0);
   3540             sb.append(prefix);
   3541                     sb.append("  Idle mode full time: ");
   3542                     formatTimeMs(sb, deviceIdleModeFullTime / 1000);
   3543                     sb.append("(");
   3544                     sb.append(formatRatioLocked(deviceIdleModeFullTime, whichBatteryRealtime));
   3545                     sb.append(") ");
   3546                     sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which));
   3547                     sb.append("x");
   3548                     sb.append(" -- longest ");
   3549                     formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
   3550             pw.println(sb.toString());
   3551         }
   3552         if (phoneOnTime != 0) {
   3553             sb.setLength(0);
   3554             sb.append(prefix);
   3555                     sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
   3556                     sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
   3557                     sb.append(") "); sb.append(getPhoneOnCount(which)); sb.append("x");
   3558         }
   3559         final int connChanges = getNumConnectivityChange(which);
   3560         if (connChanges != 0) {
   3561             pw.print(prefix);
   3562             pw.print("  Connectivity changes: "); pw.println(connChanges);
   3563         }
   3564 
   3565         // Calculate wakelock times across all uids.
   3566         long fullWakeLockTimeTotalMicros = 0;
   3567         long partialWakeLockTimeTotalMicros = 0;
   3568 
   3569         final ArrayList<TimerEntry> timers = new ArrayList<>();
   3570 
   3571         for (int iu = 0; iu < NU; iu++) {
   3572             final Uid u = uidStats.valueAt(iu);
   3573 
   3574             final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
   3575                     = u.getWakelockStats();
   3576             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
   3577                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
   3578 
   3579                 final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
   3580                 if (fullWakeTimer != null) {
   3581                     fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
   3582                             rawRealtime, which);
   3583                 }
   3584 
   3585                 final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
   3586                 if (partialWakeTimer != null) {
   3587                     final long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
   3588                             rawRealtime, which);
   3589                     if (totalTimeMicros > 0) {
   3590                         if (reqUid < 0) {
   3591                             // Only show the ordered list of all wake
   3592                             // locks if the caller is not asking for data
   3593                             // about a specific uid.
   3594                             timers.add(new TimerEntry(wakelocks.keyAt(iw), u.getUid(),
   3595                                     partialWakeTimer, totalTimeMicros));
   3596                         }
   3597                         partialWakeLockTimeTotalMicros += totalTimeMicros;
   3598                     }
   3599                 }
   3600             }
   3601         }
   3602 
   3603         final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
   3604         final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
   3605         final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
   3606         final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
   3607         final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
   3608         final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
   3609         final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
   3610         final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
   3611         final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
   3612         final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
   3613 
   3614         if (fullWakeLockTimeTotalMicros != 0) {
   3615             sb.setLength(0);
   3616             sb.append(prefix);
   3617                     sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
   3618                             (fullWakeLockTimeTotalMicros + 500) / 1000);
   3619             pw.println(sb.toString());
   3620         }
   3621 
   3622         if (partialWakeLockTimeTotalMicros != 0) {
   3623             sb.setLength(0);
   3624             sb.append(prefix);
   3625                     sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
   3626                             (partialWakeLockTimeTotalMicros + 500) / 1000);
   3627             pw.println(sb.toString());
   3628         }
   3629 
   3630         pw.print(prefix);
   3631                 pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
   3632                 pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
   3633                 pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
   3634                 pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
   3635         sb.setLength(0);
   3636         sb.append(prefix);
   3637         sb.append("  Phone signal levels:");
   3638         didOne = false;
   3639         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
   3640             final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
   3641             if (time == 0) {
   3642                 continue;
   3643             }
   3644             sb.append("\n    ");
   3645             sb.append(prefix);
   3646             didOne = true;
   3647             sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
   3648             sb.append(" ");
   3649             formatTimeMs(sb, time/1000);
   3650             sb.append("(");
   3651             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   3652             sb.append(") ");
   3653             sb.append(getPhoneSignalStrengthCount(i, which));
   3654             sb.append("x");
   3655         }
   3656         if (!didOne) sb.append(" (no activity)");
   3657         pw.println(sb.toString());
   3658 
   3659         sb.setLength(0);
   3660         sb.append(prefix);
   3661         sb.append("  Signal scanning time: ");
   3662         formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
   3663         pw.println(sb.toString());
   3664 
   3665         sb.setLength(0);
   3666         sb.append(prefix);
   3667         sb.append("  Radio types:");
   3668         didOne = false;
   3669         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
   3670             final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
   3671             if (time == 0) {
   3672                 continue;
   3673             }
   3674             sb.append("\n    ");
   3675             sb.append(prefix);
   3676             didOne = true;
   3677             sb.append(DATA_CONNECTION_NAMES[i]);
   3678             sb.append(" ");
   3679             formatTimeMs(sb, time/1000);
   3680             sb.append("(");
   3681             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   3682             sb.append(") ");
   3683             sb.append(getPhoneDataConnectionCount(i, which));
   3684             sb.append("x");
   3685         }
   3686         if (!didOne) sb.append(" (no activity)");
   3687         pw.println(sb.toString());
   3688 
   3689         sb.setLength(0);
   3690         sb.append(prefix);
   3691         sb.append("  Mobile radio active time: ");
   3692         final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
   3693         formatTimeMs(sb, mobileActiveTime / 1000);
   3694         sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
   3695         sb.append(") "); sb.append(getMobileRadioActiveCount(which));
   3696         sb.append("x");
   3697         pw.println(sb.toString());
   3698 
   3699         final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
   3700         if (mobileActiveUnknownTime != 0) {
   3701             sb.setLength(0);
   3702             sb.append(prefix);
   3703             sb.append("  Mobile radio active unknown time: ");
   3704             formatTimeMs(sb, mobileActiveUnknownTime / 1000);
   3705             sb.append("(");
   3706             sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
   3707             sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which));
   3708             sb.append("x");
   3709             pw.println(sb.toString());
   3710         }
   3711 
   3712         final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which);
   3713         if (mobileActiveAdjustedTime != 0) {
   3714             sb.setLength(0);
   3715             sb.append(prefix);
   3716             sb.append("  Mobile radio active adjusted time: ");
   3717             formatTimeMs(sb, mobileActiveAdjustedTime / 1000);
   3718             sb.append("(");
   3719             sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime));
   3720             sb.append(")");
   3721             pw.println(sb.toString());
   3722         }
   3723 
   3724         printControllerActivity(pw, sb, prefix, "Radio", getModemControllerActivity(), which);
   3725 
   3726         pw.print(prefix);
   3727                 pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
   3728                 pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
   3729                 pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
   3730                 pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
   3731         sb.setLength(0);
   3732         sb.append(prefix);
   3733                 sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
   3734                 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
   3735                 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
   3736                 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
   3737                 sb.append(")");
   3738         pw.println(sb.toString());
   3739 
   3740         sb.setLength(0);
   3741         sb.append(prefix);
   3742         sb.append("  Wifi states:");
   3743         didOne = false;
   3744         for (int i=0; i<NUM_WIFI_STATES; i++) {
   3745             final long time = getWifiStateTime(i, rawRealtime, which);
   3746             if (time == 0) {
   3747                 continue;
   3748             }
   3749             sb.append("\n    ");
   3750             didOne = true;
   3751             sb.append(WIFI_STATE_NAMES[i]);
   3752             sb.append(" ");
   3753             formatTimeMs(sb, time/1000);
   3754             sb.append("(");
   3755             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   3756             sb.append(") ");
   3757             sb.append(getWifiStateCount(i, which));
   3758             sb.append("x");
   3759         }
   3760         if (!didOne) sb.append(" (no activity)");
   3761         pw.println(sb.toString());
   3762 
   3763         sb.setLength(0);
   3764         sb.append(prefix);
   3765         sb.append("  Wifi supplicant states:");
   3766         didOne = false;
   3767         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
   3768             final long time = getWifiSupplStateTime(i, rawRealtime, which);
   3769             if (time == 0) {
   3770                 continue;
   3771             }
   3772             sb.append("\n    ");
   3773             didOne = true;
   3774             sb.append(WIFI_SUPPL_STATE_NAMES[i]);
   3775             sb.append(" ");
   3776             formatTimeMs(sb, time/1000);
   3777             sb.append("(");
   3778             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   3779             sb.append(") ");
   3780             sb.append(getWifiSupplStateCount(i, which));
   3781             sb.append("x");
   3782         }
   3783         if (!didOne) sb.append(" (no activity)");
   3784         pw.println(sb.toString());
   3785 
   3786         sb.setLength(0);
   3787         sb.append(prefix);
   3788         sb.append("  Wifi signal levels:");
   3789         didOne = false;
   3790         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
   3791             final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
   3792             if (time == 0) {
   3793                 continue;
   3794             }
   3795             sb.append("\n    ");
   3796             sb.append(prefix);
   3797             didOne = true;
   3798             sb.append("level(");
   3799             sb.append(i);
   3800             sb.append(") ");
   3801             formatTimeMs(sb, time/1000);
   3802             sb.append("(");
   3803             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   3804             sb.append(") ");
   3805             sb.append(getWifiSignalStrengthCount(i, which));
   3806             sb.append("x");
   3807         }
   3808         if (!didOne) sb.append(" (no activity)");
   3809         pw.println(sb.toString());
   3810 
   3811         printControllerActivity(pw, sb, prefix, "WiFi", getWifiControllerActivity(), which);
   3812 
   3813         pw.print(prefix);
   3814         pw.print("  Bluetooth total received: "); pw.print(formatBytesLocked(btRxTotalBytes));
   3815         pw.print(", sent: "); pw.println(formatBytesLocked(btTxTotalBytes));
   3816 
   3817         final long bluetoothScanTimeMs = getBluetoothScanTime(rawRealtime, which) / 1000;
   3818         sb.setLength(0);
   3819         sb.append(prefix);
   3820         sb.append("  Bluetooth scan time: "); formatTimeMs(sb, bluetoothScanTimeMs);
   3821         pw.println(sb.toString());
   3822 
   3823         printControllerActivity(pw, sb, prefix, "Bluetooth", getBluetoothControllerActivity(),
   3824                 which);
   3825 
   3826         pw.println();
   3827 
   3828         if (which == STATS_SINCE_UNPLUGGED) {
   3829             if (getIsOnBattery()) {
   3830                 pw.print(prefix); pw.println("  Device is currently unplugged");
   3831                 pw.print(prefix); pw.print("    Discharge cycle start level: ");
   3832                         pw.println(getDischargeStartLevel());
   3833                 pw.print(prefix); pw.print("    Discharge cycle current level: ");
   3834                         pw.println(getDischargeCurrentLevel());
   3835             } else {
   3836                 pw.print(prefix); pw.println("  Device is currently plugged into power");
   3837                 pw.print(prefix); pw.print("    Last discharge cycle start level: ");
   3838                         pw.println(getDischargeStartLevel());
   3839                 pw.print(prefix); pw.print("    Last discharge cycle end level: ");
   3840                         pw.println(getDischargeCurrentLevel());
   3841             }
   3842             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
   3843                     pw.println(getDischargeAmountScreenOn());
   3844             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
   3845                     pw.println(getDischargeAmountScreenOff());
   3846             pw.println(" ");
   3847         } else {
   3848             pw.print(prefix); pw.println("  Device battery use since last full charge");
   3849             pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
   3850                     pw.println(getLowDischargeAmountSinceCharge());
   3851             pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
   3852                     pw.println(getHighDischargeAmountSinceCharge());
   3853             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
   3854                     pw.println(getDischargeAmountScreenOnSinceCharge());
   3855             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
   3856                     pw.println(getDischargeAmountScreenOffSinceCharge());
   3857             pw.println();
   3858         }
   3859 
   3860         final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
   3861         helper.create(this);
   3862         helper.refreshStats(which, UserHandle.USER_ALL);
   3863         List<BatterySipper> sippers = helper.getUsageList();
   3864         if (sippers != null && sippers.size() > 0) {
   3865             pw.print(prefix); pw.println("  Estimated power use (mAh):");
   3866             pw.print(prefix); pw.print("    Capacity: ");
   3867                     printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
   3868                     pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
   3869                     pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower());
   3870                     if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
   3871                         pw.print("-"); printmAh(pw, helper.getMaxDrainedPower());
   3872                     }
   3873                     pw.println();
   3874             for (int i=0; i<sippers.size(); i++) {
   3875                 final BatterySipper bs = sippers.get(i);
   3876                 pw.print(prefix);
   3877                 switch (bs.drainType) {
   3878                     case IDLE:
   3879                         pw.print("    Idle: ");
   3880                         break;
   3881                     case CELL:
   3882                         pw.print("    Cell standby: ");
   3883                         break;
   3884                     case PHONE:
   3885                         pw.print("    Phone calls: ");
   3886                         break;
   3887                     case WIFI:
   3888                         pw.print("    Wifi: ");
   3889                         break;
   3890                     case BLUETOOTH:
   3891                         pw.print("    Bluetooth: ");
   3892                         break;
   3893                     case SCREEN:
   3894                         pw.print("    Screen: ");
   3895                         break;
   3896                     case FLASHLIGHT:
   3897                         pw.print("    Flashlight: ");
   3898                         break;
   3899                     case APP:
   3900                         pw.print("    Uid ");
   3901                         UserHandle.formatUid(pw, bs.uidObj.getUid());
   3902                         pw.print(": ");
   3903                         break;
   3904                     case USER:
   3905                         pw.print("    User "); pw.print(bs.userId);
   3906                         pw.print(": ");
   3907                         break;
   3908                     case UNACCOUNTED:
   3909                         pw.print("    Unaccounted: ");
   3910                         break;
   3911                     case OVERCOUNTED:
   3912                         pw.print("    Over-counted: ");
   3913                         break;
   3914                     case CAMERA:
   3915                         pw.print("    Camera: ");
   3916                         break;
   3917                     default:
   3918                         pw.print("    ???: ");
   3919                         break;
   3920                 }
   3921                 printmAh(pw, bs.totalPowerMah);
   3922 
   3923                 if (bs.usagePowerMah != bs.totalPowerMah) {
   3924                     // If the usage (generic power) isn't the whole amount, we list out
   3925                     // what components are involved in the calculation.
   3926 
   3927                     pw.print(" (");
   3928                     if (bs.usagePowerMah != 0) {
   3929                         pw.print(" usage=");
   3930                         printmAh(pw, bs.usagePowerMah);
   3931                     }
   3932                     if (bs.cpuPowerMah != 0) {
   3933                         pw.print(" cpu=");
   3934                         printmAh(pw, bs.cpuPowerMah);
   3935                     }
   3936                     if (bs.wakeLockPowerMah != 0) {
   3937                         pw.print(" wake=");
   3938                         printmAh(pw, bs.wakeLockPowerMah);
   3939                     }
   3940                     if (bs.mobileRadioPowerMah != 0) {
   3941                         pw.print(" radio=");
   3942                         printmAh(pw, bs.mobileRadioPowerMah);
   3943                     }
   3944                     if (bs.wifiPowerMah != 0) {
   3945                         pw.print(" wifi=");
   3946                         printmAh(pw, bs.wifiPowerMah);
   3947                     }
   3948                     if (bs.bluetoothPowerMah != 0) {
   3949                         pw.print(" bt=");
   3950                         printmAh(pw, bs.bluetoothPowerMah);
   3951                     }
   3952                     if (bs.gpsPowerMah != 0) {
   3953                         pw.print(" gps=");
   3954                         printmAh(pw, bs.gpsPowerMah);
   3955                     }
   3956                     if (bs.sensorPowerMah != 0) {
   3957                         pw.print(" sensor=");
   3958                         printmAh(pw, bs.sensorPowerMah);
   3959                     }
   3960                     if (bs.cameraPowerMah != 0) {
   3961                         pw.print(" camera=");
   3962                         printmAh(pw, bs.cameraPowerMah);
   3963                     }
   3964                     if (bs.flashlightPowerMah != 0) {
   3965                         pw.print(" flash=");
   3966                         printmAh(pw, bs.flashlightPowerMah);
   3967                     }
   3968                     pw.print(" )");
   3969                 }
   3970                 pw.println();
   3971             }
   3972             pw.println();
   3973         }
   3974 
   3975         sippers = helper.getMobilemsppList();
   3976         if (sippers != null && sippers.size() > 0) {
   3977             pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
   3978             long totalTime = 0;
   3979             for (int i=0; i<sippers.size(); i++) {
   3980                 final BatterySipper bs = sippers.get(i);
   3981                 sb.setLength(0);
   3982                 sb.append(prefix); sb.append("    Uid ");
   3983                 UserHandle.formatUid(sb, bs.uidObj.getUid());
   3984                 sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
   3985                 sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
   3986                 sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
   3987                 sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
   3988                 pw.println(sb.toString());
   3989                 totalTime += bs.mobileActive;
   3990             }
   3991             sb.setLength(0);
   3992             sb.append(prefix);
   3993             sb.append("    TOTAL TIME: ");
   3994             formatTimeMs(sb, totalTime);
   3995             sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
   3996             sb.append(")");
   3997             pw.println(sb.toString());
   3998             pw.println();
   3999         }
   4000 
   4001         final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
   4002             @Override
   4003             public int compare(TimerEntry lhs, TimerEntry rhs) {
   4004                 long lhsTime = lhs.mTime;
   4005                 long rhsTime = rhs.mTime;
   4006                 if (lhsTime < rhsTime) {
   4007                     return 1;
   4008                 }
   4009                 if (lhsTime > rhsTime) {
   4010                     return -1;
   4011                 }
   4012                 return 0;
   4013             }
   4014         };
   4015 
   4016         if (reqUid < 0) {
   4017             final Map<String, ? extends BatteryStats.Timer> kernelWakelocks
   4018                     = getKernelWakelockStats();
   4019             if (kernelWakelocks.size() > 0) {
   4020                 final ArrayList<TimerEntry> ktimers = new ArrayList<>();
   4021                 for (Map.Entry<String, ? extends BatteryStats.Timer> ent
   4022                         : kernelWakelocks.entrySet()) {
   4023                     final BatteryStats.Timer timer = ent.getValue();
   4024                     final long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
   4025                     if (totalTimeMillis > 0) {
   4026                         ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
   4027                     }
   4028                 }
   4029                 if (ktimers.size() > 0) {
   4030                     Collections.sort(ktimers, timerComparator);
   4031                     pw.print(prefix); pw.println("  All kernel wake locks:");
   4032                     for (int i=0; i<ktimers.size(); i++) {
   4033                         final TimerEntry timer = ktimers.get(i);
   4034                         String linePrefix = ": ";
   4035                         sb.setLength(0);
   4036                         sb.append(prefix);
   4037                         sb.append("  Kernel Wake lock ");
   4038                         sb.append(timer.mName);
   4039                         linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null,
   4040                                 which, linePrefix);
   4041                         if (!linePrefix.equals(": ")) {
   4042                             sb.append(" realtime");
   4043                             // Only print out wake locks that were held
   4044                             pw.println(sb.toString());
   4045                         }
   4046                     }
   4047                     pw.println();
   4048                 }
   4049             }
   4050 
   4051             if (timers.size() > 0) {
   4052                 Collections.sort(timers, timerComparator);
   4053                 pw.print(prefix); pw.println("  All partial wake locks:");
   4054                 for (int i=0; i<timers.size(); i++) {
   4055                     TimerEntry timer = timers.get(i);
   4056                     sb.setLength(0);
   4057                     sb.append("  Wake lock ");
   4058                     UserHandle.formatUid(sb, timer.mId);
   4059                     sb.append(" ");
   4060                     sb.append(timer.mName);
   4061                     printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
   4062                     sb.append(" realtime");
   4063                     pw.println(sb.toString());
   4064                 }
   4065                 timers.clear();
   4066                 pw.println();
   4067             }
   4068 
   4069             final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
   4070             if (wakeupReasons.size() > 0) {
   4071                 pw.print(prefix); pw.println("  All wakeup reasons:");
   4072                 final ArrayList<TimerEntry> reasons = new ArrayList<>();
   4073                 for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
   4074                     final Timer timer = ent.getValue();
   4075                     reasons.add(new TimerEntry(ent.getKey(), 0, timer,
   4076                             timer.getCountLocked(which)));
   4077                 }
   4078                 Collections.sort(reasons, timerComparator);
   4079                 for (int i=0; i<reasons.size(); i++) {
   4080                     TimerEntry timer = reasons.get(i);
   4081                     String linePrefix = ": ";
   4082                     sb.setLength(0);
   4083                     sb.append(prefix);
   4084                     sb.append("  Wakeup reason ");
   4085                     sb.append(timer.mName);
   4086                     printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
   4087                     sb.append(" realtime");
   4088                     pw.println(sb.toString());
   4089                 }
   4090                 pw.println();
   4091             }
   4092         }
   4093 
   4094         for (int iu=0; iu<NU; iu++) {
   4095             final int uid = uidStats.keyAt(iu);
   4096             if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
   4097                 continue;
   4098             }
   4099 
   4100             final Uid u = uidStats.valueAt(iu);
   4101 
   4102             pw.print(prefix);
   4103             pw.print("  ");
   4104             UserHandle.formatUid(pw, uid);
   4105             pw.println(":");
   4106             boolean uidActivity = false;
   4107 
   4108             final long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
   4109             final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
   4110             final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
   4111             final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
   4112             final long btRxBytes = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
   4113             final long btTxBytes = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
   4114 
   4115             final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
   4116             final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
   4117             final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
   4118             final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
   4119 
   4120             final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
   4121             final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
   4122 
   4123             final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
   4124             final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
   4125             final int wifiScanCount = u.getWifiScanCount(which);
   4126             final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
   4127 
   4128             if (mobileRxBytes > 0 || mobileTxBytes > 0
   4129                     || mobileRxPackets > 0 || mobileTxPackets > 0) {
   4130                 pw.print(prefix); pw.print("    Mobile network: ");
   4131                         pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
   4132                         pw.print(formatBytesLocked(mobileTxBytes));
   4133                         pw.print(" sent (packets "); pw.print(mobileRxPackets);
   4134                         pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
   4135             }
   4136             if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
   4137                 sb.setLength(0);
   4138                 sb.append(prefix); sb.append("    Mobile radio active: ");
   4139                 formatTimeMs(sb, uidMobileActiveTime / 1000);
   4140                 sb.append("(");
   4141                 sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
   4142                 sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
   4143                 long packets = mobileRxPackets + mobileTxPackets;
   4144                 if (packets == 0) {
   4145                     packets = 1;
   4146                 }
   4147                 sb.append(" @ ");
   4148                 sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
   4149                 sb.append(" mspp");
   4150                 pw.println(sb.toString());
   4151             }
   4152 
   4153             printControllerActivityIfInteresting(pw, sb, prefix + "  ", "Modem",
   4154                     u.getModemControllerActivity(), which);
   4155 
   4156             if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
   4157                 pw.print(prefix); pw.print("    Wi-Fi network: ");
   4158                         pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
   4159                         pw.print(formatBytesLocked(wifiTxBytes));
   4160                         pw.print(" sent (packets "); pw.print(wifiRxPackets);
   4161                         pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
   4162             }
   4163 
   4164             if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
   4165                     || uidWifiRunningTime != 0) {
   4166                 sb.setLength(0);
   4167                 sb.append(prefix); sb.append("    Wifi Running: ");
   4168                         formatTimeMs(sb, uidWifiRunningTime / 1000);
   4169                         sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
   4170                                 whichBatteryRealtime)); sb.append(")\n");
   4171                 sb.append(prefix); sb.append("    Full Wifi Lock: ");
   4172                         formatTimeMs(sb, fullWifiLockOnTime / 1000);
   4173                         sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
   4174                                 whichBatteryRealtime)); sb.append(")\n");
   4175                 sb.append(prefix); sb.append("    Wifi Scan: ");
   4176                         formatTimeMs(sb, wifiScanTime / 1000);
   4177                         sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
   4178                                 whichBatteryRealtime)); sb.append(") ");
   4179                                 sb.append(wifiScanCount);
   4180                                 sb.append("x");
   4181                 pw.println(sb.toString());
   4182             }
   4183 
   4184             printControllerActivityIfInteresting(pw, sb, prefix + "  ", "WiFi",
   4185                     u.getWifiControllerActivity(), which);
   4186 
   4187             if (btRxBytes > 0 || btTxBytes > 0) {
   4188                 pw.print(prefix); pw.print("    Bluetooth network: ");
   4189                 pw.print(formatBytesLocked(btRxBytes)); pw.print(" received, ");
   4190                 pw.print(formatBytesLocked(btTxBytes));
   4191                 pw.println(" sent");
   4192             }
   4193 
   4194             uidActivity |= printTimer(pw, sb, u.getBluetoothScanTimer(), rawRealtime, which, prefix,
   4195                     "Bluetooth Scan");
   4196 
   4197             if (u.hasUserActivity()) {
   4198                 boolean hasData = false;
   4199                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
   4200                     final int val = u.getUserActivityCount(i, which);
   4201                     if (val != 0) {
   4202                         if (!hasData) {
   4203                             sb.setLength(0);
   4204                             sb.append("    User activity: ");
   4205                             hasData = true;
   4206                         } else {
   4207                             sb.append(", ");
   4208                         }
   4209                         sb.append(val);
   4210                         sb.append(" ");
   4211                         sb.append(Uid.USER_ACTIVITY_TYPES[i]);
   4212                     }
   4213                 }
   4214                 if (hasData) {
   4215                     pw.println(sb.toString());
   4216                 }
   4217             }
   4218 
   4219             final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
   4220                     = u.getWakelockStats();
   4221             long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
   4222             long totalDrawWakelock = 0;
   4223             int countWakelock = 0;
   4224             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
   4225                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
   4226                 String linePrefix = ": ";
   4227                 sb.setLength(0);
   4228                 sb.append(prefix);
   4229                 sb.append("    Wake lock ");
   4230                 sb.append(wakelocks.keyAt(iw));
   4231                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
   4232                         "full", which, linePrefix);
   4233                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
   4234                         "partial", which, linePrefix);
   4235                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
   4236                         "window", which, linePrefix);
   4237                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
   4238                         "draw", which, linePrefix);
   4239                 sb.append(" realtime");
   4240                 pw.println(sb.toString());
   4241                 uidActivity = true;
   4242                 countWakelock++;
   4243 
   4244                 totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
   4245                         rawRealtime, which);
   4246                 totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
   4247                         rawRealtime, which);
   4248                 totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
   4249                         rawRealtime, which);
   4250                 totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW),
   4251                         rawRealtime, which);
   4252             }
   4253             if (countWakelock > 1) {
   4254                 if (totalFullWakelock != 0 || totalPartialWakelock != 0
   4255                         || totalWindowWakelock != 0) {
   4256                     sb.setLength(0);
   4257                     sb.append(prefix);
   4258                     sb.append("    TOTAL wake: ");
   4259                     boolean needComma = false;
   4260                     if (totalFullWakelock != 0) {
   4261                         needComma = true;
   4262                         formatTimeMs(sb, totalFullWakelock);
   4263                         sb.append("full");
   4264                     }
   4265                     if (totalPartialWakelock != 0) {
   4266                         if (needComma) {
   4267                             sb.append(", ");
   4268                         }
   4269                         needComma = true;
   4270                         formatTimeMs(sb, totalPartialWakelock);
   4271                         sb.append("partial");
   4272                     }
   4273                     if (totalWindowWakelock != 0) {
   4274                         if (needComma) {
   4275                             sb.append(", ");
   4276                         }
   4277                         needComma = true;
   4278                         formatTimeMs(sb, totalWindowWakelock);
   4279                         sb.append("window");
   4280                     }
   4281                     if (totalDrawWakelock != 0) {
   4282                         if (needComma) {
   4283                             sb.append(",");
   4284                         }
   4285                         needComma = true;
   4286                         formatTimeMs(sb, totalDrawWakelock);
   4287                         sb.append("draw");
   4288                     }
   4289                     sb.append(" realtime");
   4290                     pw.println(sb.toString());
   4291                 }
   4292             }
   4293 
   4294             final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
   4295             for (int isy=syncs.size()-1; isy>=0; isy--) {
   4296                 final Timer timer = syncs.valueAt(isy);
   4297                 // Convert from microseconds to milliseconds with rounding
   4298                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   4299                 final int count = timer.getCountLocked(which);
   4300                 sb.setLength(0);
   4301                 sb.append(prefix);
   4302                 sb.append("    Sync ");
   4303                 sb.append(syncs.keyAt(isy));
   4304                 sb.append(": ");
   4305                 if (totalTime != 0) {
   4306                     formatTimeMs(sb, totalTime);
   4307                     sb.append("realtime (");
   4308                     sb.append(count);
   4309                     sb.append(" times)");
   4310                 } else {
   4311                     sb.append("(not used)");
   4312                 }
   4313                 pw.println(sb.toString());
   4314                 uidActivity = true;
   4315             }
   4316 
   4317             final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
   4318             for (int ij=jobs.size()-1; ij>=0; ij--) {
   4319                 final Timer timer = jobs.valueAt(ij);
   4320                 // Convert from microseconds to milliseconds with rounding
   4321                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   4322                 final int count = timer.getCountLocked(which);
   4323                 sb.setLength(0);
   4324                 sb.append(prefix);
   4325                 sb.append("    Job ");
   4326                 sb.append(jobs.keyAt(ij));
   4327                 sb.append(": ");
   4328                 if (totalTime != 0) {
   4329                     formatTimeMs(sb, totalTime);
   4330                     sb.append("realtime (");
   4331                     sb.append(count);
   4332                     sb.append(" times)");
   4333                 } else {
   4334                     sb.append("(not used)");
   4335                 }
   4336                 pw.println(sb.toString());
   4337                 uidActivity = true;
   4338             }
   4339 
   4340             uidActivity |= printTimer(pw, sb, u.getFlashlightTurnedOnTimer(), rawRealtime, which,
   4341                     prefix, "Flashlight");
   4342             uidActivity |= printTimer(pw, sb, u.getCameraTurnedOnTimer(), rawRealtime, which,
   4343                     prefix, "Camera");
   4344             uidActivity |= printTimer(pw, sb, u.getVideoTurnedOnTimer(), rawRealtime, which,
   4345                     prefix, "Video");
   4346             uidActivity |= printTimer(pw, sb, u.getAudioTurnedOnTimer(), rawRealtime, which,
   4347                     prefix, "Audio");
   4348 
   4349             final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
   4350             final int NSE = sensors.size();
   4351             for (int ise=0; ise<NSE; ise++) {
   4352                 final Uid.Sensor se = sensors.valueAt(ise);
   4353                 final int sensorNumber = sensors.keyAt(ise);
   4354                 sb.setLength(0);
   4355                 sb.append(prefix);
   4356                 sb.append("    Sensor ");
   4357                 int handle = se.getHandle();
   4358                 if (handle == Uid.Sensor.GPS) {
   4359                     sb.append("GPS");
   4360                 } else {
   4361                     sb.append(handle);
   4362                 }
   4363                 sb.append(": ");
   4364 
   4365                 final Timer timer = se.getSensorTime();
   4366                 if (timer != null) {
   4367                     // Convert from microseconds to milliseconds with rounding
   4368                     final long totalTime = (timer.getTotalTimeLocked(
   4369                             rawRealtime, which) + 500) / 1000;
   4370                     final int count = timer.getCountLocked(which);
   4371                     //timer.logState();
   4372                     if (totalTime != 0) {
   4373                         formatTimeMs(sb, totalTime);
   4374                         sb.append("realtime (");
   4375                         sb.append(count);
   4376                         sb.append(" times)");
   4377                     } else {
   4378                         sb.append("(not used)");
   4379                     }
   4380                 } else {
   4381                     sb.append("(not used)");
   4382                 }
   4383 
   4384                 pw.println(sb.toString());
   4385                 uidActivity = true;
   4386             }
   4387 
   4388             uidActivity |= printTimer(pw, sb, u.getVibratorOnTimer(), rawRealtime, which, prefix,
   4389                     "Vibrator");
   4390             uidActivity |= printTimer(pw, sb, u.getForegroundActivityTimer(), rawRealtime, which,
   4391                     prefix, "Foreground activities");
   4392 
   4393             long totalStateTime = 0;
   4394             for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
   4395                 long time = u.getProcessStateTime(ips, rawRealtime, which);
   4396                 if (time > 0) {
   4397                     totalStateTime += time;
   4398                     sb.setLength(0);
   4399                     sb.append(prefix);
   4400                     sb.append("    ");
   4401                     sb.append(Uid.PROCESS_STATE_NAMES[ips]);
   4402                     sb.append(" for: ");
   4403                     formatTimeMs(sb, (time + 500) / 1000);
   4404                     pw.println(sb.toString());
   4405                     uidActivity = true;
   4406                 }
   4407             }
   4408             if (totalStateTime > 0) {
   4409                 sb.setLength(0);
   4410                 sb.append(prefix);
   4411                 sb.append("    Total running: ");
   4412                 formatTimeMs(sb, (totalStateTime + 500) / 1000);
   4413                 pw.println(sb.toString());
   4414             }
   4415 
   4416             final long userCpuTimeUs = u.getUserCpuTimeUs(which);
   4417             final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
   4418             final long powerCpuMaUs = u.getCpuPowerMaUs(which);
   4419             if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
   4420                 sb.setLength(0);
   4421                 sb.append(prefix);
   4422                 sb.append("    Total cpu time: u=");
   4423                 formatTimeMs(sb, userCpuTimeUs / 1000);
   4424                 sb.append("s=");
   4425                 formatTimeMs(sb, systemCpuTimeUs / 1000);
   4426                 sb.append("p=");
   4427                 printmAh(sb, powerCpuMaUs / (1000.0 * 1000.0 * 60.0 * 60.0));
   4428                 sb.append("mAh");
   4429                 pw.println(sb.toString());
   4430             }
   4431 
   4432             final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
   4433                     = u.getProcessStats();
   4434             for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
   4435                 final Uid.Proc ps = processStats.valueAt(ipr);
   4436                 long userTime;
   4437                 long systemTime;
   4438                 long foregroundTime;
   4439                 int starts;
   4440                 int numExcessive;
   4441 
   4442                 userTime = ps.getUserTime(which);
   4443                 systemTime = ps.getSystemTime(which);
   4444                 foregroundTime = ps.getForegroundTime(which);
   4445                 starts = ps.getStarts(which);
   4446                 final int numCrashes = ps.getNumCrashes(which);
   4447                 final int numAnrs = ps.getNumAnrs(which);
   4448                 numExcessive = which == STATS_SINCE_CHARGED
   4449                         ? ps.countExcessivePowers() : 0;
   4450 
   4451                 if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
   4452                         || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
   4453                     sb.setLength(0);
   4454                     sb.append(prefix); sb.append("    Proc ");
   4455                             sb.append(processStats.keyAt(ipr)); sb.append(":\n");
   4456                     sb.append(prefix); sb.append("      CPU: ");
   4457                             formatTimeMs(sb, userTime); sb.append("usr + ");
   4458                             formatTimeMs(sb, systemTime); sb.append("krn ; ");
   4459                             formatTimeMs(sb, foregroundTime); sb.append("fg");
   4460                     if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
   4461                         sb.append("\n"); sb.append(prefix); sb.append("      ");
   4462                         boolean hasOne = false;
   4463                         if (starts != 0) {
   4464                             hasOne = true;
   4465                             sb.append(starts); sb.append(" starts");
   4466                         }
   4467                         if (numCrashes != 0) {
   4468                             if (hasOne) {
   4469                                 sb.append(", ");
   4470                             }
   4471                             hasOne = true;
   4472                             sb.append(numCrashes); sb.append(" crashes");
   4473                         }
   4474                         if (numAnrs != 0) {
   4475                             if (hasOne) {
   4476                                 sb.append(", ");
   4477                             }
   4478                             sb.append(numAnrs); sb.append(" anrs");
   4479                         }
   4480                     }
   4481                     pw.println(sb.toString());
   4482                     for (int e=0; e<numExcessive; e++) {
   4483                         Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
   4484                         if (ew != null) {
   4485                             pw.print(prefix); pw.print("      * Killed for ");
   4486                                     if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
   4487                                         pw.print("wake lock");
   4488                                     } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
   4489                                         pw.print("cpu");
   4490                                     } else {
   4491                                         pw.print("unknown");
   4492                                     }
   4493                                     pw.print(" use: ");
   4494                                     TimeUtils.formatDuration(ew.usedTime, pw);
   4495                                     pw.print(" over ");
   4496                                     TimeUtils.formatDuration(ew.overTime, pw);
   4497                                     if (ew.overTime != 0) {
   4498                                         pw.print(" (");
   4499                                         pw.print((ew.usedTime*100)/ew.overTime);
   4500                                         pw.println("%)");
   4501                                     }
   4502                         }
   4503                     }
   4504                     uidActivity = true;
   4505                 }
   4506             }
   4507 
   4508             final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
   4509                     = u.getPackageStats();
   4510             for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
   4511                 pw.print(prefix); pw.print("    Apk "); pw.print(packageStats.keyAt(ipkg));
   4512                 pw.println(":");
   4513                 boolean apkActivity = false;
   4514                 final Uid.Pkg ps = packageStats.valueAt(ipkg);
   4515                 final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
   4516                 for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
   4517                     pw.print(prefix); pw.print("      Wakeup alarm ");
   4518                             pw.print(alarms.keyAt(iwa)); pw.print(": ");
   4519                             pw.print(alarms.valueAt(iwa).getCountLocked(which));
   4520                             pw.println(" times");
   4521                     apkActivity = true;
   4522                 }
   4523                 final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
   4524                 for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
   4525                     final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
   4526                     final long startTime = ss.getStartTime(batteryUptime, which);
   4527                     final int starts = ss.getStarts(which);
   4528                     final int launches = ss.getLaunches(which);
   4529                     if (startTime != 0 || starts != 0 || launches != 0) {
   4530                         sb.setLength(0);
   4531                         sb.append(prefix); sb.append("      Service ");
   4532                                 sb.append(serviceStats.keyAt(isvc)); sb.append(":\n");
   4533                         sb.append(prefix); sb.append("        Created for: ");
   4534                                 formatTimeMs(sb, startTime / 1000);
   4535                                 sb.append("uptime\n");
   4536                         sb.append(prefix); sb.append("        Starts: ");
   4537                                 sb.append(starts);
   4538                                 sb.append(", launches: "); sb.append(launches);
   4539                         pw.println(sb.toString());
   4540                         apkActivity = true;
   4541                     }
   4542                 }
   4543                 if (!apkActivity) {
   4544                     pw.print(prefix); pw.println("      (nothing executed)");
   4545                 }
   4546                 uidActivity = true;
   4547             }
   4548             if (!uidActivity) {
   4549                 pw.print(prefix); pw.println("    (nothing executed)");
   4550             }
   4551         }
   4552     }
   4553 
   4554     static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag,
   4555             BitDescription[] descriptions, boolean longNames) {
   4556         int diff = oldval ^ newval;
   4557         if (diff == 0) return;
   4558         boolean didWake = false;
   4559         for (int i=0; i<descriptions.length; i++) {
   4560             BitDescription bd = descriptions[i];
   4561             if ((diff&bd.mask) != 0) {
   4562                 pw.print(longNames ? " " : ",");
   4563                 if (bd.shift < 0) {
   4564                     pw.print((newval&bd.mask) != 0 ? "+" : "-");
   4565                     pw.print(longNames ? bd.name : bd.shortName);
   4566                     if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
   4567                         didWake = true;
   4568                         pw.print("=");
   4569                         if (longNames) {
   4570                             UserHandle.formatUid(pw, wakelockTag.uid);
   4571                             pw.print(":\"");
   4572                             pw.print(wakelockTag.string);
   4573                             pw.print("\"");
   4574                         } else {
   4575                             pw.print(wakelockTag.poolIdx);
   4576                         }
   4577                     }
   4578                 } else {
   4579                     pw.print(longNames ? bd.name : bd.shortName);
   4580                     pw.print("=");
   4581                     int val = (newval&bd.mask)>>bd.shift;
   4582                     if (bd.values != null && val >= 0 && val < bd.values.length) {
   4583                         pw.print(longNames? bd.values[val] : bd.shortValues[val]);
   4584                     } else {
   4585                         pw.print(val);
   4586                     }
   4587                 }
   4588             }
   4589         }
   4590         if (!didWake && wakelockTag != null) {
   4591             pw.print(longNames ? " wake_lock=" : ",w=");
   4592             if (longNames) {
   4593                 UserHandle.formatUid(pw, wakelockTag.uid);
   4594                 pw.print(":\"");
   4595                 pw.print(wakelockTag.string);
   4596                 pw.print("\"");
   4597             } else {
   4598                 pw.print(wakelockTag.poolIdx);
   4599             }
   4600         }
   4601     }
   4602 
   4603     public void prepareForDumpLocked() {
   4604     }
   4605 
   4606     public static class HistoryPrinter {
   4607         int oldState = 0;
   4608         int oldState2 = 0;
   4609         int oldLevel = -1;
   4610         int oldStatus = -1;
   4611         int oldHealth = -1;
   4612         int oldPlug = -1;
   4613         int oldTemp = -1;
   4614         int oldVolt = -1;
   4615         int oldChargeMAh = -1;
   4616         long lastTime = -1;
   4617 
   4618         void reset() {
   4619             oldState = oldState2 = 0;
   4620             oldLevel = -1;
   4621             oldStatus = -1;
   4622             oldHealth = -1;
   4623             oldPlug = -1;
   4624             oldTemp = -1;
   4625             oldVolt = -1;
   4626             oldChargeMAh = -1;
   4627         }
   4628 
   4629         public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
   4630                 boolean verbose) {
   4631             if (!checkin) {
   4632                 pw.print("  ");
   4633                 TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
   4634                 pw.print(" (");
   4635                 pw.print(rec.numReadInts);
   4636                 pw.print(") ");
   4637             } else {
   4638                 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
   4639                 pw.print(HISTORY_DATA); pw.print(',');
   4640                 if (lastTime < 0) {
   4641                     pw.print(rec.time - baseTime);
   4642                 } else {
   4643                     pw.print(rec.time - lastTime);
   4644                 }
   4645                 lastTime = rec.time;
   4646             }
   4647             if (rec.cmd == HistoryItem.CMD_START) {
   4648                 if (checkin) {
   4649                     pw.print(":");
   4650                 }
   4651                 pw.println("START");
   4652                 reset();
   4653             } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
   4654                     || rec.cmd == HistoryItem.CMD_RESET) {
   4655                 if (checkin) {
   4656                     pw.print(":");
   4657                 }
   4658                 if (rec.cmd == HistoryItem.CMD_RESET) {
   4659                     pw.print("RESET:");
   4660                     reset();
   4661                 }
   4662                 pw.print("TIME:");
   4663                 if (checkin) {
   4664                     pw.println(rec.currentTime);
   4665                 } else {
   4666                     pw.print(" ");
   4667                     pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
   4668                             rec.currentTime).toString());
   4669                 }
   4670             } else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) {
   4671                 if (checkin) {
   4672                     pw.print(":");
   4673                 }
   4674                 pw.println("SHUTDOWN");
   4675             } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
   4676                 if (checkin) {
   4677                     pw.print(":");
   4678                 }
   4679                 pw.println("*OVERFLOW*");
   4680             } else {
   4681                 if (!checkin) {
   4682                     if (rec.batteryLevel < 10) pw.print("00");
   4683                     else if (rec.batteryLevel < 100) pw.print("0");
   4684                     pw.print(rec.batteryLevel);
   4685                     if (verbose) {
   4686                         pw.print(" ");
   4687                         if (rec.states < 0) ;
   4688                         else if (rec.states < 0x10) pw.print("0000000");
   4689                         else if (rec.states < 0x100) pw.print("000000");
   4690                         else if (rec.states < 0x1000) pw.print("00000");
   4691                         else if (rec.states < 0x10000) pw.print("0000");
   4692                         else if (rec.states < 0x100000) pw.print("000");
   4693                         else if (rec.states < 0x1000000) pw.print("00");
   4694                         else if (rec.states < 0x10000000) pw.print("0");
   4695                         pw.print(Integer.toHexString(rec.states));
   4696                     }
   4697                 } else {
   4698                     if (oldLevel != rec.batteryLevel) {
   4699                         oldLevel = rec.batteryLevel;
   4700                         pw.print(",Bl="); pw.print(rec.batteryLevel);
   4701                     }
   4702                 }
   4703                 if (oldStatus != rec.batteryStatus) {
   4704                     oldStatus = rec.batteryStatus;
   4705                     pw.print(checkin ? ",Bs=" : " status=");
   4706                     switch (oldStatus) {
   4707                         case BatteryManager.BATTERY_STATUS_UNKNOWN:
   4708                             pw.print(checkin ? "?" : "unknown");
   4709                             break;
   4710                         case BatteryManager.BATTERY_STATUS_CHARGING:
   4711                             pw.print(checkin ? "c" : "charging");
   4712                             break;
   4713                         case BatteryManager.BATTERY_STATUS_DISCHARGING:
   4714                             pw.print(checkin ? "d" : "discharging");
   4715                             break;
   4716                         case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
   4717                             pw.print(checkin ? "n" : "not-charging");
   4718                             break;
   4719                         case BatteryManager.BATTERY_STATUS_FULL:
   4720                             pw.print(checkin ? "f" : "full");
   4721                             break;
   4722                         default:
   4723                             pw.print(oldStatus);
   4724                             break;
   4725                     }
   4726                 }
   4727                 if (oldHealth != rec.batteryHealth) {
   4728                     oldHealth = rec.batteryHealth;
   4729                     pw.print(checkin ? ",Bh=" : " health=");
   4730                     switch (oldHealth) {
   4731                         case BatteryManager.BATTERY_HEALTH_UNKNOWN:
   4732                             pw.print(checkin ? "?" : "unknown");
   4733                             break;
   4734                         case BatteryManager.BATTERY_HEALTH_GOOD:
   4735                             pw.print(checkin ? "g" : "good");
   4736                             break;
   4737                         case BatteryManager.BATTERY_HEALTH_OVERHEAT:
   4738                             pw.print(checkin ? "h" : "overheat");
   4739                             break;
   4740                         case BatteryManager.BATTERY_HEALTH_DEAD:
   4741                             pw.print(checkin ? "d" : "dead");
   4742                             break;
   4743                         case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
   4744                             pw.print(checkin ? "v" : "over-voltage");
   4745                             break;
   4746                         case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
   4747                             pw.print(checkin ? "f" : "failure");
   4748                             break;
   4749                         case BatteryManager.BATTERY_HEALTH_COLD:
   4750                             pw.print(checkin ? "c" : "cold");
   4751                             break;
   4752                         default:
   4753                             pw.print(oldHealth);
   4754                             break;
   4755                     }
   4756                 }
   4757                 if (oldPlug != rec.batteryPlugType) {
   4758                     oldPlug = rec.batteryPlugType;
   4759                     pw.print(checkin ? ",Bp=" : " plug=");
   4760                     switch (oldPlug) {
   4761                         case 0:
   4762                             pw.print(checkin ? "n" : "none");
   4763                             break;
   4764                         case BatteryManager.BATTERY_PLUGGED_AC:
   4765                             pw.print(checkin ? "a" : "ac");
   4766                             break;
   4767                         case BatteryManager.BATTERY_PLUGGED_USB:
   4768                             pw.print(checkin ? "u" : "usb");
   4769                             break;
   4770                         case BatteryManager.BATTERY_PLUGGED_WIRELESS:
   4771                             pw.print(checkin ? "w" : "wireless");
   4772                             break;
   4773                         default:
   4774                             pw.print(oldPlug);
   4775                             break;
   4776                     }
   4777                 }
   4778                 if (oldTemp != rec.batteryTemperature) {
   4779                     oldTemp = rec.batteryTemperature;
   4780                     pw.print(checkin ? ",Bt=" : " temp=");
   4781                     pw.print(oldTemp);
   4782                 }
   4783                 if (oldVolt != rec.batteryVoltage) {
   4784                     oldVolt = rec.batteryVoltage;
   4785                     pw.print(checkin ? ",Bv=" : " volt=");
   4786                     pw.print(oldVolt);
   4787                 }
   4788                 final int chargeMAh = rec.batteryChargeUAh / 1000;
   4789                 if (oldChargeMAh != chargeMAh) {
   4790                     oldChargeMAh = chargeMAh;
   4791                     pw.print(checkin ? ",Bcc=" : " charge=");
   4792                     pw.print(oldChargeMAh);
   4793                 }
   4794                 printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
   4795                         HISTORY_STATE_DESCRIPTIONS, !checkin);
   4796                 printBitDescriptions(pw, oldState2, rec.states2, null,
   4797                         HISTORY_STATE2_DESCRIPTIONS, !checkin);
   4798                 if (rec.wakeReasonTag != null) {
   4799                     if (checkin) {
   4800                         pw.print(",wr=");
   4801                         pw.print(rec.wakeReasonTag.poolIdx);
   4802                     } else {
   4803                         pw.print(" wake_reason=");
   4804                         pw.print(rec.wakeReasonTag.uid);
   4805                         pw.print(":\"");
   4806                         pw.print(rec.wakeReasonTag.string);
   4807                         pw.print("\"");
   4808                     }
   4809                 }
   4810                 if (rec.eventCode != HistoryItem.EVENT_NONE) {
   4811                     pw.print(checkin ? "," : " ");
   4812                     if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
   4813                         pw.print("+");
   4814                     } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
   4815                         pw.print("-");
   4816                     }
   4817                     String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
   4818                             : HISTORY_EVENT_NAMES;
   4819                     int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
   4820                             | HistoryItem.EVENT_FLAG_FINISH);
   4821                     if (idx >= 0 && idx < eventNames.length) {
   4822                         pw.print(eventNames[idx]);
   4823                     } else {
   4824                         pw.print(checkin ? "Ev" : "event");
   4825                         pw.print(idx);
   4826                     }
   4827                     pw.print("=");
   4828                     if (checkin) {
   4829                         pw.print(rec.eventTag.poolIdx);
   4830                     } else {
   4831                         UserHandle.formatUid(pw, rec.eventTag.uid);
   4832                         pw.print(":\"");
   4833                         pw.print(rec.eventTag.string);
   4834                         pw.print("\"");
   4835                     }
   4836                 }
   4837                 pw.println();
   4838                 if (rec.stepDetails != null) {
   4839                     if (!checkin) {
   4840                         pw.print("                 Details: cpu=");
   4841                         pw.print(rec.stepDetails.userTime);
   4842                         pw.print("u+");
   4843                         pw.print(rec.stepDetails.systemTime);
   4844                         pw.print("s");
   4845                         if (rec.stepDetails.appCpuUid1 >= 0) {
   4846                             pw.print(" (");
   4847                             printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid1,
   4848                                     rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
   4849                             if (rec.stepDetails.appCpuUid2 >= 0) {
   4850                                 pw.print(", ");
   4851                                 printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid2,
   4852                                         rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
   4853                             }
   4854                             if (rec.stepDetails.appCpuUid3 >= 0) {
   4855                                 pw.print(", ");
   4856                                 printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid3,
   4857                                         rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
   4858                             }
   4859                             pw.print(')');
   4860                         }
   4861                         pw.println();
   4862                         pw.print("                          /proc/stat=");
   4863                         pw.print(rec.stepDetails.statUserTime);
   4864                         pw.print(" usr, ");
   4865                         pw.print(rec.stepDetails.statSystemTime);
   4866                         pw.print(" sys, ");
   4867                         pw.print(rec.stepDetails.statIOWaitTime);
   4868                         pw.print(" io, ");
   4869                         pw.print(rec.stepDetails.statIrqTime);
   4870                         pw.print(" irq, ");
   4871                         pw.print(rec.stepDetails.statSoftIrqTime);
   4872                         pw.print(" sirq, ");
   4873                         pw.print(rec.stepDetails.statIdlTime);
   4874                         pw.print(" idle");
   4875                         int totalRun = rec.stepDetails.statUserTime + rec.stepDetails.statSystemTime
   4876                                 + rec.stepDetails.statIOWaitTime + rec.stepDetails.statIrqTime
   4877                                 + rec.stepDetails.statSoftIrqTime;
   4878                         int total = totalRun + rec.stepDetails.statIdlTime;
   4879                         if (total > 0) {
   4880                             pw.print(" (");
   4881                             float perc = ((float)totalRun) / ((float)total) * 100;
   4882                             pw.print(String.format("%.1f%%", perc));
   4883                             pw.print(" of ");
   4884                             StringBuilder sb = new StringBuilder(64);
   4885                             formatTimeMsNoSpace(sb, total*10);
   4886                             pw.print(sb);
   4887                             pw.print(")");
   4888                         }
   4889                         pw.print(", PlatformIdleStat ");
   4890                         pw.print(rec.stepDetails.statPlatformIdleState);
   4891                         pw.println();
   4892                     } else {
   4893                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
   4894                         pw.print(HISTORY_DATA); pw.print(",0,Dcpu=");
   4895                         pw.print(rec.stepDetails.userTime);
   4896                         pw.print(":");
   4897                         pw.print(rec.stepDetails.systemTime);
   4898                         if (rec.stepDetails.appCpuUid1 >= 0) {
   4899                             printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid1,
   4900                                     rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
   4901                             if (rec.stepDetails.appCpuUid2 >= 0) {
   4902                                 printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid2,
   4903                                         rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
   4904                             }
   4905                             if (rec.stepDetails.appCpuUid3 >= 0) {
   4906                                 printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid3,
   4907                                         rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
   4908                             }
   4909                         }
   4910                         pw.println();
   4911                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
   4912                         pw.print(HISTORY_DATA); pw.print(",0,Dpst=");
   4913                         pw.print(rec.stepDetails.statUserTime);
   4914                         pw.print(',');
   4915                         pw.print(rec.stepDetails.statSystemTime);
   4916                         pw.print(',');
   4917                         pw.print(rec.stepDetails.statIOWaitTime);
   4918                         pw.print(',');
   4919                         pw.print(rec.stepDetails.statIrqTime);
   4920                         pw.print(',');
   4921                         pw.print(rec.stepDetails.statSoftIrqTime);
   4922                         pw.print(',');
   4923                         pw.print(rec.stepDetails.statIdlTime);
   4924                         pw.print(',');
   4925                         pw.print(rec.stepDetails.statPlatformIdleState);
   4926                         pw.println();
   4927                     }
   4928                 }
   4929                 oldState = rec.states;
   4930                 oldState2 = rec.states2;
   4931             }
   4932         }
   4933 
   4934         private void printStepCpuUidDetails(PrintWriter pw, int uid, int utime, int stime) {
   4935             UserHandle.formatUid(pw, uid);
   4936             pw.print("=");
   4937             pw.print(utime);
   4938             pw.print("u+");
   4939             pw.print(stime);
   4940             pw.print("s");
   4941         }
   4942 
   4943         private void printStepCpuUidCheckinDetails(PrintWriter pw, int uid, int utime, int stime) {
   4944             pw.print('/');
   4945             pw.print(uid);
   4946             pw.print(":");
   4947             pw.print(utime);
   4948             pw.print(":");
   4949             pw.print(stime);
   4950         }
   4951     }
   4952 
   4953     private void printSizeValue(PrintWriter pw, long size) {
   4954         float result = size;
   4955         String suffix = "";
   4956         if (result >= 10*1024) {
   4957             suffix = "KB";
   4958             result = result / 1024;
   4959         }
   4960         if (result >= 10*1024) {
   4961             suffix = "MB";
   4962             result = result / 1024;
   4963         }
   4964         if (result >= 10*1024) {
   4965             suffix = "GB";
   4966             result = result / 1024;
   4967         }
   4968         if (result >= 10*1024) {
   4969             suffix = "TB";
   4970             result = result / 1024;
   4971         }
   4972         if (result >= 10*1024) {
   4973             suffix = "PB";
   4974             result = result / 1024;
   4975         }
   4976         pw.print((int)result);
   4977         pw.print(suffix);
   4978     }
   4979 
   4980     private static boolean dumpTimeEstimate(PrintWriter pw, String label1, String label2,
   4981             String label3, long estimatedTime) {
   4982         if (estimatedTime < 0) {
   4983             return false;
   4984         }
   4985         pw.print(label1);
   4986         pw.print(label2);
   4987         pw.print(label3);
   4988         StringBuilder sb = new StringBuilder(64);
   4989         formatTimeMs(sb, estimatedTime);
   4990         pw.print(sb);
   4991         pw.println();
   4992         return true;
   4993     }
   4994 
   4995     private static boolean dumpDurationSteps(PrintWriter pw, String prefix, String header,
   4996             LevelStepTracker steps, boolean checkin) {
   4997         if (steps == null) {
   4998             return false;
   4999         }
   5000         int count = steps.mNumStepDurations;
   5001         if (count <= 0) {
   5002             return false;
   5003         }
   5004         if (!checkin) {
   5005             pw.println(header);
   5006         }
   5007         String[] lineArgs = new String[5];
   5008         for (int i=0; i<count; i++) {
   5009             long duration = steps.getDurationAt(i);
   5010             int level = steps.getLevelAt(i);
   5011             long initMode = steps.getInitModeAt(i);
   5012             long modMode = steps.getModModeAt(i);
   5013             if (checkin) {
   5014                 lineArgs[0] = Long.toString(duration);
   5015                 lineArgs[1] = Integer.toString(level);
   5016                 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
   5017                     switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
   5018                         case Display.STATE_OFF: lineArgs[2] = "s-"; break;
   5019                         case Display.STATE_ON: lineArgs[2] = "s+"; break;
   5020                         case Display.STATE_DOZE: lineArgs[2] = "sd"; break;
   5021                         case Display.STATE_DOZE_SUSPEND: lineArgs[2] = "sds"; break;
   5022                         default: lineArgs[2] = "?"; break;
   5023                     }
   5024                 } else {
   5025                     lineArgs[2] = "";
   5026                 }
   5027                 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
   5028                     lineArgs[3] = (initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 ? "p+" : "p-";
   5029                 } else {
   5030                     lineArgs[3] = "";
   5031                 }
   5032                 if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
   5033                     lineArgs[4] = (initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0 ? "i+" : "i-";
   5034                 } else {
   5035                     lineArgs[4] = "";
   5036                 }
   5037                 dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs);
   5038             } else {
   5039                 pw.print(prefix);
   5040                 pw.print("#"); pw.print(i); pw.print(": ");
   5041                 TimeUtils.formatDuration(duration, pw);
   5042                 pw.print(" to "); pw.print(level);
   5043                 boolean haveModes = false;
   5044                 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
   5045                     pw.print(" (");
   5046                     switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
   5047                         case Display.STATE_OFF: pw.print("screen-off"); break;
   5048                         case Display.STATE_ON: pw.print("screen-on"); break;
   5049                         case Display.STATE_DOZE: pw.print("screen-doze"); break;
   5050                         case Display.STATE_DOZE_SUSPEND: pw.print("screen-doze-suspend"); break;
   5051                         default: pw.print("screen-?"); break;
   5052                     }
   5053                     haveModes = true;
   5054                 }
   5055                 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
   5056                     pw.print(haveModes ? ", " : " (");
   5057                     pw.print((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0
   5058                             ? "power-save-on" : "power-save-off");
   5059                     haveModes = true;
   5060                 }
   5061                 if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
   5062                     pw.print(haveModes ? ", " : " (");
   5063                     pw.print((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0
   5064                             ? "device-idle-on" : "device-idle-off");
   5065                     haveModes = true;
   5066                 }
   5067                 if (haveModes) {
   5068                     pw.print(")");
   5069                 }
   5070                 pw.println();
   5071             }
   5072         }
   5073         return true;
   5074     }
   5075 
   5076     public static final int DUMP_CHARGED_ONLY = 1<<1;
   5077     public static final int DUMP_DAILY_ONLY = 1<<2;
   5078     public static final int DUMP_HISTORY_ONLY = 1<<3;
   5079     public static final int DUMP_INCLUDE_HISTORY = 1<<4;
   5080     public static final int DUMP_VERBOSE = 1<<5;
   5081     public static final int DUMP_DEVICE_WIFI_ONLY = 1<<6;
   5082 
   5083     private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
   5084         final HistoryPrinter hprinter = new HistoryPrinter();
   5085         final HistoryItem rec = new HistoryItem();
   5086         long lastTime = -1;
   5087         long baseTime = -1;
   5088         boolean printed = false;
   5089         HistoryEventTracker tracker = null;
   5090         while (getNextHistoryLocked(rec)) {
   5091             lastTime = rec.time;
   5092             if (baseTime < 0) {
   5093                 baseTime = lastTime;
   5094             }
   5095             if (rec.time >= histStart) {
   5096                 if (histStart >= 0 && !printed) {
   5097                     if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
   5098                             || rec.cmd == HistoryItem.CMD_RESET
   5099                             || rec.cmd == HistoryItem.CMD_START
   5100                             || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
   5101                         printed = true;
   5102                         hprinter.printNextItem(pw, rec, baseTime, checkin,
   5103                                 (flags&DUMP_VERBOSE) != 0);
   5104                         rec.cmd = HistoryItem.CMD_UPDATE;
   5105                     } else if (rec.currentTime != 0) {
   5106                         printed = true;
   5107                         byte cmd = rec.cmd;
   5108                         rec.cmd = HistoryItem.CMD_CURRENT_TIME;
   5109                         hprinter.printNextItem(pw, rec, baseTime, checkin,
   5110                                 (flags&DUMP_VERBOSE) != 0);
   5111                         rec.cmd = cmd;
   5112                     }
   5113                     if (tracker != null) {
   5114                         if (rec.cmd != HistoryItem.CMD_UPDATE) {
   5115                             hprinter.printNextItem(pw, rec, baseTime, checkin,
   5116                                     (flags&DUMP_VERBOSE) != 0);
   5117                             rec.cmd = HistoryItem.CMD_UPDATE;
   5118                         }
   5119                         int oldEventCode = rec.eventCode;
   5120                         HistoryTag oldEventTag = rec.eventTag;
   5121                         rec.eventTag = new HistoryTag();
   5122                         for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
   5123                             HashMap<String, SparseIntArray> active
   5124                                     = tracker.getStateForEvent(i);
   5125                             if (active == null) {
   5126                                 continue;
   5127                             }
   5128                             for (HashMap.Entry<String, SparseIntArray> ent
   5129                                     : active.entrySet()) {
   5130                                 SparseIntArray uids = ent.getValue();
   5131                                 for (int j=0; j<uids.size(); j++) {
   5132                                     rec.eventCode = i;
   5133                                     rec.eventTag.string = ent.getKey();
   5134                                     rec.eventTag.uid = uids.keyAt(j);
   5135                                     rec.eventTag.poolIdx = uids.valueAt(j);
   5136                                     hprinter.printNextItem(pw, rec, baseTime, checkin,
   5137                                             (flags&DUMP_VERBOSE) != 0);
   5138                                     rec.wakeReasonTag = null;
   5139                                     rec.wakelockTag = null;
   5140                                 }
   5141                             }
   5142                         }
   5143                         rec.eventCode = oldEventCode;
   5144                         rec.eventTag = oldEventTag;
   5145                         tracker = null;
   5146                     }
   5147                 }
   5148                 hprinter.printNextItem(pw, rec, baseTime, checkin,
   5149                         (flags&DUMP_VERBOSE) != 0);
   5150             } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) {
   5151                 // This is an attempt to aggregate the previous state and generate
   5152                 //fake events to reflect that state at the point where we start
   5153                 // printing real events.  It doesn't really work right, so is turned off.
   5154                 if (tracker == null) {
   5155                     tracker = new HistoryEventTracker();
   5156                 }
   5157                 tracker.updateState(rec.eventCode, rec.eventTag.string,
   5158                         rec.eventTag.uid, rec.eventTag.poolIdx);
   5159             }
   5160         }
   5161         if (histStart >= 0) {
   5162             commitCurrentHistoryBatchLocked();
   5163             pw.print(checkin ? "NEXT: " : "  NEXT: "); pw.println(lastTime+1);
   5164         }
   5165     }
   5166 
   5167     private void dumpDailyLevelStepSummary(PrintWriter pw, String prefix, String label,
   5168             LevelStepTracker steps, StringBuilder tmpSb, int[] tmpOutInt) {
   5169         if (steps == null) {
   5170             return;
   5171         }
   5172         long timeRemaining = steps.computeTimeEstimate(0, 0, tmpOutInt);
   5173         if (timeRemaining >= 0) {
   5174             pw.print(prefix); pw.print(label); pw.print(" total time: ");
   5175             tmpSb.setLength(0);
   5176             formatTimeMs(tmpSb, timeRemaining);
   5177             pw.print(tmpSb);
   5178             pw.print(" (from "); pw.print(tmpOutInt[0]);
   5179             pw.println(" steps)");
   5180         }
   5181         for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
   5182             long estimatedTime = steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
   5183                     STEP_LEVEL_MODE_VALUES[i], tmpOutInt);
   5184             if (estimatedTime > 0) {
   5185                 pw.print(prefix); pw.print(label); pw.print(" ");
   5186                 pw.print(STEP_LEVEL_MODE_LABELS[i]);
   5187                 pw.print(" time: ");
   5188                 tmpSb.setLength(0);
   5189                 formatTimeMs(tmpSb, estimatedTime);
   5190                 pw.print(tmpSb);
   5191                 pw.print(" (from "); pw.print(tmpOutInt[0]);
   5192                 pw.println(" steps)");
   5193             }
   5194         }
   5195     }
   5196 
   5197     private void dumpDailyPackageChanges(PrintWriter pw, String prefix,
   5198             ArrayList<PackageChange> changes) {
   5199         if (changes == null) {
   5200             return;
   5201         }
   5202         pw.print(prefix); pw.println("Package changes:");
   5203         for (int i=0; i<changes.size(); i++) {
   5204             PackageChange pc = changes.get(i);
   5205             if (pc.mUpdate) {
   5206                 pw.print(prefix); pw.print("  Update "); pw.print(pc.mPackageName);
   5207                 pw.print(" vers="); pw.println(pc.mVersionCode);
   5208             } else {
   5209                 pw.print(prefix); pw.print("  Uninstall "); pw.println(pc.mPackageName);
   5210             }
   5211         }
   5212     }
   5213 
   5214     /**
   5215      * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
   5216      *
   5217      * @param pw a Printer to receive the dump output.
   5218      */
   5219     @SuppressWarnings("unused")
   5220     public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
   5221         prepareForDumpLocked();
   5222 
   5223         final boolean filtering = (flags
   5224                 & (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
   5225 
   5226         if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
   5227             final long historyTotalSize = getHistoryTotalSize();
   5228             final long historyUsedSize = getHistoryUsedSize();
   5229             if (startIteratingHistoryLocked()) {
   5230                 try {
   5231                     pw.print("Battery History (");
   5232                     pw.print((100*historyUsedSize)/historyTotalSize);
   5233                     pw.print("% used, ");
   5234                     printSizeValue(pw, historyUsedSize);
   5235                     pw.print(" used of ");
   5236                     printSizeValue(pw, historyTotalSize);
   5237                     pw.print(", ");
   5238                     pw.print(getHistoryStringPoolSize());
   5239                     pw.print(" strings using ");
   5240                     printSizeValue(pw, getHistoryStringPoolBytes());
   5241                     pw.println("):");
   5242                     dumpHistoryLocked(pw, flags, histStart, false);
   5243                     pw.println();
   5244                 } finally {
   5245                     finishIteratingHistoryLocked();
   5246                 }
   5247             }
   5248 
   5249             if (startIteratingOldHistoryLocked()) {
   5250                 try {
   5251                     final HistoryItem rec = new HistoryItem();
   5252                     pw.println("Old battery History:");
   5253                     HistoryPrinter hprinter = new HistoryPrinter();
   5254                     long baseTime = -1;
   5255                     while (getNextOldHistoryLocked(rec)) {
   5256                         if (baseTime < 0) {
   5257                             baseTime = rec.time;
   5258                         }
   5259                         hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0);
   5260                     }
   5261                     pw.println();
   5262                 } finally {
   5263                     finishIteratingOldHistoryLocked();
   5264                 }
   5265             }
   5266         }
   5267 
   5268         if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
   5269             return;
   5270         }
   5271 
   5272         if (!filtering) {
   5273             SparseArray<? extends Uid> uidStats = getUidStats();
   5274             final int NU = uidStats.size();
   5275             boolean didPid = false;
   5276             long nowRealtime = SystemClock.elapsedRealtime();
   5277             for (int i=0; i<NU; i++) {
   5278                 Uid uid = uidStats.valueAt(i);
   5279                 SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
   5280                 if (pids != null) {
   5281                     for (int j=0; j<pids.size(); j++) {
   5282                         Uid.Pid pid = pids.valueAt(j);
   5283                         if (!didPid) {
   5284                             pw.println("Per-PID Stats:");
   5285                             didPid = true;
   5286                         }
   5287                         long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
   5288                                 ? (nowRealtime - pid.mWakeStartMs) : 0);
   5289                         pw.print("  PID "); pw.print(pids.keyAt(j));
   5290                                 pw.print(" wake time: ");
   5291                                 TimeUtils.formatDuration(time, pw);
   5292                                 pw.println("");
   5293                     }
   5294                 }
   5295             }
   5296             if (didPid) {
   5297                 pw.println();
   5298             }
   5299         }
   5300 
   5301         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
   5302             if (dumpDurationSteps(pw, "  ", "Discharge step durations:",
   5303                     getDischargeLevelStepTracker(), false)) {
   5304                 long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
   5305                 if (timeRemaining >= 0) {
   5306                     pw.print("  Estimated discharge time remaining: ");
   5307                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
   5308                     pw.println();
   5309                 }
   5310                 final LevelStepTracker steps = getDischargeLevelStepTracker();
   5311                 for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
   5312                     dumpTimeEstimate(pw, "  Estimated ", STEP_LEVEL_MODE_LABELS[i], " time: ",
   5313                             steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
   5314                                     STEP_LEVEL_MODE_VALUES[i], null));
   5315                 }
   5316                 pw.println();
   5317             }
   5318             if (dumpDurationSteps(pw, "  ", "Charge step durations:",
   5319                     getChargeLevelStepTracker(), false)) {
   5320                 long timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
   5321                 if (timeRemaining >= 0) {
   5322                     pw.print("  Estimated charge time remaining: ");
   5323                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
   5324                     pw.println();
   5325                 }
   5326                 pw.println();
   5327             }
   5328         }
   5329         if (!filtering || (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0) {
   5330             pw.println("Daily stats:");
   5331             pw.print("  Current start time: ");
   5332             pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
   5333                     getCurrentDailyStartTime()).toString());
   5334             pw.print("  Next min deadline: ");
   5335             pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
   5336                     getNextMinDailyDeadline()).toString());
   5337             pw.print("  Next max deadline: ");
   5338             pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
   5339                     getNextMaxDailyDeadline()).toString());
   5340             StringBuilder sb = new StringBuilder(64);
   5341             int[] outInt = new int[1];
   5342             LevelStepTracker dsteps = getDailyDischargeLevelStepTracker();
   5343             LevelStepTracker csteps = getDailyChargeLevelStepTracker();
   5344             ArrayList<PackageChange> pkgc = getDailyPackageChanges();
   5345             if (dsteps.mNumStepDurations > 0 || csteps.mNumStepDurations > 0 || pkgc != null) {
   5346                 if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
   5347                     if (dumpDurationSteps(pw, "    ", "  Current daily discharge step durations:",
   5348                             dsteps, false)) {
   5349                         dumpDailyLevelStepSummary(pw, "      ", "Discharge", dsteps,
   5350                                 sb, outInt);
   5351                     }
   5352                     if (dumpDurationSteps(pw, "    ", "  Current daily charge step durations:",
   5353                             csteps, false)) {
   5354                         dumpDailyLevelStepSummary(pw, "      ", "Charge", csteps,
   5355                                 sb, outInt);
   5356                     }
   5357                     dumpDailyPackageChanges(pw, "    ", pkgc);
   5358                 } else {
   5359                     pw.println("  Current daily steps:");
   5360                     dumpDailyLevelStepSummary(pw, "    ", "Discharge", dsteps,
   5361                             sb, outInt);
   5362                     dumpDailyLevelStepSummary(pw, "    ", "Charge", csteps,
   5363                             sb, outInt);
   5364                 }
   5365             }
   5366             DailyItem dit;
   5367             int curIndex = 0;
   5368             while ((dit=getDailyItemLocked(curIndex)) != null) {
   5369                 curIndex++;
   5370                 if ((flags&DUMP_DAILY_ONLY) != 0) {
   5371                     pw.println();
   5372                 }
   5373                 pw.print("  Daily from ");
   5374                 pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mStartTime).toString());
   5375                 pw.print(" to ");
   5376                 pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mEndTime).toString());
   5377                 pw.println(":");
   5378                 if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
   5379                     if (dumpDurationSteps(pw, "      ",
   5380                             "    Discharge step durations:", dit.mDischargeSteps, false)) {
   5381                         dumpDailyLevelStepSummary(pw, "        ", "Discharge", dit.mDischargeSteps,
   5382                                 sb, outInt);
   5383                     }
   5384                     if (dumpDurationSteps(pw, "      ",
   5385                             "    Charge step durations:", dit.mChargeSteps, false)) {
   5386                         dumpDailyLevelStepSummary(pw, "        ", "Charge", dit.mChargeSteps,
   5387                                 sb, outInt);
   5388                     }
   5389                     dumpDailyPackageChanges(pw, "    ", dit.mPackageChanges);
   5390                 } else {
   5391                     dumpDailyLevelStepSummary(pw, "    ", "Discharge", dit.mDischargeSteps,
   5392                             sb, outInt);
   5393                     dumpDailyLevelStepSummary(pw, "    ", "Charge", dit.mChargeSteps,
   5394                             sb, outInt);
   5395                 }
   5396             }
   5397             pw.println();
   5398         }
   5399         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
   5400             pw.println("Statistics since last charge:");
   5401             pw.println("  System starts: " + getStartCount()
   5402                     + ", currently on battery: " + getIsOnBattery());
   5403             dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
   5404                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
   5405             pw.println();
   5406         }
   5407     }
   5408 
   5409     @SuppressWarnings("unused")
   5410     public void dumpCheckinLocked(Context context, PrintWriter pw,
   5411             List<ApplicationInfo> apps, int flags, long histStart) {
   5412         prepareForDumpLocked();
   5413 
   5414         dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
   5415                 CHECKIN_VERSION, getParcelVersion(), getStartPlatformVersion(),
   5416                 getEndPlatformVersion());
   5417 
   5418         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
   5419 
   5420         final boolean filtering = (flags &
   5421                 (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
   5422 
   5423         if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) {
   5424             if (startIteratingHistoryLocked()) {
   5425                 try {
   5426                     for (int i=0; i<getHistoryStringPoolSize(); i++) {
   5427                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
   5428                         pw.print(HISTORY_STRING_POOL); pw.print(',');
   5429                         pw.print(i);
   5430                         pw.print(",");
   5431                         pw.print(getHistoryTagPoolUid(i));
   5432                         pw.print(",\"");
   5433                         String str = getHistoryTagPoolString(i);
   5434                         str = str.replace("\\", "\\\\");
   5435                         str = str.replace("\"", "\\\"");
   5436                         pw.print(str);
   5437                         pw.print("\"");
   5438                         pw.println();
   5439                     }
   5440                     dumpHistoryLocked(pw, flags, histStart, true);
   5441                 } finally {
   5442                     finishIteratingHistoryLocked();
   5443                 }
   5444             }
   5445         }
   5446 
   5447         if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
   5448             return;
   5449         }
   5450 
   5451         if (apps != null) {
   5452             SparseArray<Pair<ArrayList<String>, MutableBoolean>> uids = new SparseArray<>();
   5453             for (int i=0; i<apps.size(); i++) {
   5454                 ApplicationInfo ai = apps.get(i);
   5455                 Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(
   5456                         UserHandle.getAppId(ai.uid));
   5457                 if (pkgs == null) {
   5458                     pkgs = new Pair<>(new ArrayList<String>(), new MutableBoolean(false));
   5459                     uids.put(UserHandle.getAppId(ai.uid), pkgs);
   5460                 }
   5461                 pkgs.first.add(ai.packageName);
   5462             }
   5463             SparseArray<? extends Uid> uidStats = getUidStats();
   5464             final int NU = uidStats.size();
   5465             String[] lineArgs = new String[2];
   5466             for (int i=0; i<NU; i++) {
   5467                 int uid = UserHandle.getAppId(uidStats.keyAt(i));
   5468                 Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(uid);
   5469                 if (pkgs != null && !pkgs.second.value) {
   5470                     pkgs.second.value = true;
   5471                     for (int j=0; j<pkgs.first.size(); j++) {
   5472                         lineArgs[0] = Integer.toString(uid);
   5473                         lineArgs[1] = pkgs.first.get(j);
   5474                         dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
   5475                                 (Object[])lineArgs);
   5476                     }
   5477                 }
   5478             }
   5479         }
   5480         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
   5481             dumpDurationSteps(pw, "", DISCHARGE_STEP_DATA, getDischargeLevelStepTracker(), true);
   5482             String[] lineArgs = new String[1];
   5483             long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
   5484             if (timeRemaining >= 0) {
   5485                 lineArgs[0] = Long.toString(timeRemaining);
   5486                 dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA,
   5487                         (Object[])lineArgs);
   5488             }
   5489             dumpDurationSteps(pw, "", CHARGE_STEP_DATA, getChargeLevelStepTracker(), true);
   5490             timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
   5491             if (timeRemaining >= 0) {
   5492                 lineArgs[0] = Long.toString(timeRemaining);
   5493                 dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA,
   5494                         (Object[])lineArgs);
   5495             }
   5496             dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
   5497                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
   5498         }
   5499     }
   5500 }
   5501