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