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