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