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