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