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