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