• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import static android.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 time in microseconds that power save mode has been enabled while the device was
2307      * running on battery.
2308      *
2309      * {@hide}
2310      */
getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)2311     public abstract long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which);
2312 
2313     /**
2314      * Returns the number of times that power save mode was enabled.
2315      *
2316      * {@hide}
2317      */
getPowerSaveModeEnabledCount(int which)2318     public abstract int getPowerSaveModeEnabledCount(int which);
2319 
2320     /**
2321      * Constant for device idle mode: not active.
2322      */
2323     public static final int DEVICE_IDLE_MODE_OFF = ServerProtoEnums.DEVICE_IDLE_MODE_OFF; // 0
2324 
2325     /**
2326      * Constant for device idle mode: active in lightweight mode.
2327      */
2328     public static final int DEVICE_IDLE_MODE_LIGHT = ServerProtoEnums.DEVICE_IDLE_MODE_LIGHT; // 1
2329 
2330     /**
2331      * Constant for device idle mode: active in full mode.
2332      */
2333     public static final int DEVICE_IDLE_MODE_DEEP = ServerProtoEnums.DEVICE_IDLE_MODE_DEEP; // 2
2334 
2335     /**
2336      * Returns the time in microseconds that device has been in idle mode while
2337      * running on battery.
2338      *
2339      * {@hide}
2340      */
getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)2341     public abstract long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which);
2342 
2343     /**
2344      * Returns the number of times that the devie has gone in to idle mode.
2345      *
2346      * {@hide}
2347      */
getDeviceIdleModeCount(int mode, int which)2348     public abstract int getDeviceIdleModeCount(int mode, int which);
2349 
2350     /**
2351      * Return the longest duration we spent in a particular device idle mode (fully in the
2352      * mode, not in idle maintenance etc).
2353      */
getLongestDeviceIdleModeTime(int mode)2354     public abstract long getLongestDeviceIdleModeTime(int mode);
2355 
2356     /**
2357      * Returns the time in microseconds that device has been in idling while on
2358      * battery.  This is broader than {@link #getDeviceIdleModeTime} -- it
2359      * counts all of the time that we consider the device to be idle, whether or not
2360      * it is currently in the actual device idle mode.
2361      *
2362      * {@hide}
2363      */
getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)2364     public abstract long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which);
2365 
2366     /**
2367      * Returns the number of times that the device has started idling.
2368      *
2369      * {@hide}
2370      */
getDeviceIdlingCount(int mode, int which)2371     public abstract int getDeviceIdlingCount(int mode, int which);
2372 
2373     /**
2374      * Returns the number of times that connectivity state changed.
2375      *
2376      * {@hide}
2377      */
getNumConnectivityChange(int which)2378     public abstract int getNumConnectivityChange(int which);
2379 
2380 
2381     /**
2382      * Returns the time in microseconds that the phone has been running with
2383      * the given GPS signal quality level
2384      *
2385      * {@hide}
2386      */
getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)2387     public abstract long getGpsSignalQualityTime(int strengthBin,
2388         long elapsedRealtimeUs, int which);
2389 
2390     /**
2391      * Returns the GPS battery drain in mA-ms
2392      *
2393      * {@hide}
2394      */
getGpsBatteryDrainMaMs()2395     public abstract long getGpsBatteryDrainMaMs();
2396 
2397     /**
2398      * Returns the time in microseconds that the phone has been on while the device was
2399      * running on battery.
2400      *
2401      * {@hide}
2402      */
2403     @UnsupportedAppUsage
getPhoneOnTime(long elapsedRealtimeUs, int which)2404     public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
2405 
2406     /**
2407      * Returns the number of times a phone call was activated.
2408      *
2409      * {@hide}
2410      */
getPhoneOnCount(int which)2411     public abstract int getPhoneOnCount(int which);
2412 
2413     /**
2414      * Returns the time in microseconds that the phone has been running with
2415      * the given signal strength.
2416      *
2417      * {@hide}
2418      */
2419     @UnsupportedAppUsage
getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)2420     public abstract long getPhoneSignalStrengthTime(int strengthBin,
2421             long elapsedRealtimeUs, int which);
2422 
2423     /**
2424      * Returns the time in microseconds that the phone has been trying to
2425      * acquire a signal.
2426      *
2427      * {@hide}
2428      */
getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)2429     public abstract long getPhoneSignalScanningTime(
2430             long elapsedRealtimeUs, int which);
2431 
2432     /**
2433      * Returns the {@link Timer} object that tracks how much the phone has been trying to
2434      * acquire a signal.
2435      *
2436      * {@hide}
2437      */
getPhoneSignalScanningTimer()2438     public abstract Timer getPhoneSignalScanningTimer();
2439 
2440     /**
2441      * Returns the number of times the phone has entered the given signal strength.
2442      *
2443      * {@hide}
2444      */
getPhoneSignalStrengthCount(int strengthBin, int which)2445     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
2446 
2447     /**
2448      * Return the {@link Timer} object used to track the given signal strength's duration and
2449      * counts.
2450      */
getPhoneSignalStrengthTimer(int strengthBin)2451     protected abstract Timer getPhoneSignalStrengthTimer(int strengthBin);
2452 
2453     /**
2454      * Returns the time in microseconds that the mobile network has been active
2455      * (in a high power state).
2456      *
2457      * {@hide}
2458      */
2459     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
getMobileRadioActiveTime(long elapsedRealtimeUs, int which)2460     public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which);
2461 
2462     /**
2463      * Returns the number of times that the mobile network has transitioned to the
2464      * active state.
2465      *
2466      * {@hide}
2467      */
getMobileRadioActiveCount(int which)2468     public abstract int getMobileRadioActiveCount(int which);
2469 
2470     /**
2471      * Returns the time in microseconds that is the difference between the mobile radio
2472      * time we saw based on the elapsed timestamp when going down vs. the given time stamp
2473      * from the radio.
2474      *
2475      * {@hide}
2476      */
getMobileRadioActiveAdjustedTime(int which)2477     public abstract long getMobileRadioActiveAdjustedTime(int which);
2478 
2479     /**
2480      * Returns the time in microseconds that the mobile network has been active
2481      * (in a high power state) but not being able to blame on an app.
2482      *
2483      * {@hide}
2484      */
getMobileRadioActiveUnknownTime(int which)2485     public abstract long getMobileRadioActiveUnknownTime(int which);
2486 
2487     /**
2488      * Return count of number of times radio was up that could not be blamed on apps.
2489      *
2490      * {@hide}
2491      */
getMobileRadioActiveUnknownCount(int which)2492     public abstract int getMobileRadioActiveUnknownCount(int which);
2493 
2494     public static final int DATA_CONNECTION_OUT_OF_SERVICE = 0;
2495     public static final int DATA_CONNECTION_EMERGENCY_SERVICE =
2496             TelephonyManager.getAllNetworkTypes().length + 1;
2497     public static final int DATA_CONNECTION_OTHER = DATA_CONNECTION_EMERGENCY_SERVICE + 1;
2498 
2499 
2500     static final String[] DATA_CONNECTION_NAMES = {
2501         "oos", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
2502         "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
2503         "ehrpd", "hspap", "gsm", "td_scdma", "iwlan", "lte_ca", "nr",
2504         "emngcy", "other"
2505     };
2506 
2507     @UnsupportedAppUsage
2508     public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER + 1;
2509 
2510     /**
2511      * Returns the time in microseconds that the phone has been running with
2512      * the given data connection.
2513      *
2514      * {@hide}
2515      */
getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)2516     public abstract long getPhoneDataConnectionTime(int dataType,
2517             long elapsedRealtimeUs, int which);
2518 
2519     /**
2520      * Returns the number of times the phone has entered the given data
2521      * connection type.
2522      *
2523      * {@hide}
2524      */
getPhoneDataConnectionCount(int dataType, int which)2525     public abstract int getPhoneDataConnectionCount(int dataType, int which);
2526 
2527     /**
2528      * Returns the {@link Timer} object that tracks the phone's data connection type stats.
2529      */
getPhoneDataConnectionTimer(int dataType)2530     public abstract Timer getPhoneDataConnectionTimer(int dataType);
2531 
2532     static final String[] WIFI_SUPPL_STATE_NAMES = {
2533         "invalid", "disconn", "disabled", "inactive", "scanning",
2534         "authenticating", "associating", "associated", "4-way-handshake",
2535         "group-handshake", "completed", "dormant", "uninit"
2536     };
2537 
2538     static final String[] WIFI_SUPPL_STATE_SHORT_NAMES = {
2539         "inv", "dsc", "dis", "inact", "scan",
2540         "auth", "ascing", "asced", "4-way",
2541         "group", "compl", "dorm", "uninit"
2542     };
2543 
2544     /**
2545      * Returned value if power data is unavailable.
2546      *
2547      * {@hide}
2548      */
2549     public static final long POWER_DATA_UNAVAILABLE = -1L;
2550 
2551     /**
2552      * Returns the battery consumption (in microcoulombs) of bluetooth, derived from on
2553      * device power measurement data.
2554      * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
2555      *
2556      * {@hide}
2557      */
getBluetoothMeasuredBatteryConsumptionUC()2558     public abstract long getBluetoothMeasuredBatteryConsumptionUC();
2559 
2560     /**
2561      * Returns the battery consumption (in microcoulombs) of the cpu, derived from on device power
2562      * measurement data.
2563      * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
2564      *
2565      * {@hide}
2566      */
getCpuMeasuredBatteryConsumptionUC()2567     public abstract long getCpuMeasuredBatteryConsumptionUC();
2568 
2569     /**
2570      * Returns the battery consumption (in microcoulombs) of the GNSS, derived from on device power
2571      * measurement data.
2572      * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
2573      *
2574      * {@hide}
2575      */
getGnssMeasuredBatteryConsumptionUC()2576     public abstract long getGnssMeasuredBatteryConsumptionUC();
2577 
2578     /**
2579      * Returns the battery consumption (in microcoulombs) of the radio, derived from on device power
2580      * measurement data.
2581      * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
2582      *
2583      * {@hide}
2584      */
getMobileRadioMeasuredBatteryConsumptionUC()2585     public abstract long getMobileRadioMeasuredBatteryConsumptionUC();
2586 
2587     /**
2588      * Returns the battery consumption (in microcoulombs) of the screen while on, derived from on
2589      * device power measurement data.
2590      * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
2591      *
2592      * {@hide}
2593      */
getScreenOnMeasuredBatteryConsumptionUC()2594     public abstract long getScreenOnMeasuredBatteryConsumptionUC();
2595 
2596     /**
2597      * Returns the battery consumption (in microcoulombs) of the screen in doze, derived from on
2598      * device power measurement data.
2599      * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
2600      *
2601      * {@hide}
2602      */
getScreenDozeMeasuredBatteryConsumptionUC()2603     public abstract long getScreenDozeMeasuredBatteryConsumptionUC();
2604 
2605     /**
2606      * Returns the battery consumption (in microcoulombs) of wifi, derived from on
2607      * device power measurement data.
2608      * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
2609      *
2610      * {@hide}
2611      */
getWifiMeasuredBatteryConsumptionUC()2612     public abstract long getWifiMeasuredBatteryConsumptionUC();
2613 
2614     /**
2615      * Returns the battery consumption (in microcoulombs) that each
2616      * {@link android.hardware.power.stats.EnergyConsumer.ordinal} of (custom) energy consumer
2617      * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}) consumed.
2618      *
2619      * @return charge (in microcoulombs) used by each (custom) energy consumer of type OTHER,
2620      * indexed by their ordinal. Returns null if no energy reporting is supported.
2621      *
2622      * {@hide}
2623      */
getCustomConsumerMeasuredBatteryConsumptionUC()2624     public abstract @Nullable long[] getCustomConsumerMeasuredBatteryConsumptionUC();
2625 
2626     /**
2627      * Returns the names of all {@link android.hardware.power.stats.EnergyConsumer}'s
2628      * of (custom) energy consumer type
2629      * {@link android.hardware.power.stats.EnergyConsumerType#OTHER}).
2630      *
2631      * {@hide}
2632      */
getCustomEnergyConsumerNames()2633     public abstract @NonNull String[] getCustomEnergyConsumerNames();
2634 
2635     public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS = new BitDescription[] {
2636         new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
2637         new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
2638         new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
2639         new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
2640         new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
2641         new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
2642         new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
2643         new BitDescription(HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG, "wifi_radio", "Wr"),
2644         new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
2645         new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
2646         new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
2647         new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
2648         new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
2649         new BitDescription(HistoryItem.STATE_SCREEN_DOZE_FLAG, "screen_doze", "Sd"),
2650         new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
2651                 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
2652                 DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
2653         new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
2654                 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
2655                 new String[] {"in", "out", "emergency", "off"},
2656                 new String[] {"in", "out", "em", "off"}),
2657         new BitDescription(HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK,
2658                 HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT, "phone_signal_strength", "Pss",
2659                 new String[] { "none", "poor", "moderate", "good", "great" },
2660                 new String[] { "0", "1", "2", "3", "4" }),
2661         new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
2662                 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
2663                 SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
2664     };
2665 
2666     public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS = new BitDescription[] {
2667         new BitDescription(HistoryItem.STATE2_POWER_SAVE_FLAG, "power_save", "ps"),
2668         new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
2669         new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Ww"),
2670         new BitDescription(HistoryItem.STATE2_WIFI_ON_FLAG, "wifi", "W"),
2671         new BitDescription(HistoryItem.STATE2_FLASHLIGHT_FLAG, "flashlight", "fl"),
2672         new BitDescription(HistoryItem.STATE2_DEVICE_IDLE_MASK,
2673                 HistoryItem.STATE2_DEVICE_IDLE_SHIFT, "device_idle", "di",
2674                 new String[] { "off", "light", "full", "???" },
2675                 new String[] { "off", "light", "full", "???" }),
2676         new BitDescription(HistoryItem.STATE2_CHARGING_FLAG, "charging", "ch"),
2677         new BitDescription(HistoryItem.STATE2_USB_DATA_LINK_FLAG, "usb_data", "Ud"),
2678         new BitDescription(HistoryItem.STATE2_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
2679         new BitDescription(HistoryItem.STATE2_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
2680         new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
2681                 HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT, "wifi_signal_strength", "Wss",
2682                 new String[] { "0", "1", "2", "3", "4" },
2683                 new String[] { "0", "1", "2", "3", "4" }),
2684         new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK,
2685                 HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp",
2686                 WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES),
2687         new BitDescription(HistoryItem.STATE2_CAMERA_FLAG, "camera", "ca"),
2688         new BitDescription(HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG, "ble_scan", "bles"),
2689         new BitDescription(HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG,
2690                 "cellular_high_tx_power", "Chtp"),
2691         new BitDescription(HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK,
2692             HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT, "gps_signal_quality", "Gss",
2693             new String[] { "poor", "good"}, new String[] { "poor", "good"})
2694     };
2695 
2696     public static final String[] HISTORY_EVENT_NAMES = new String[] {
2697             "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
2698             "active", "pkginst", "pkgunin", "alarm", "stats", "pkginactive", "pkgactive",
2699             "tmpwhitelist", "screenwake", "wakeupap", "longwake", "est_capacity"
2700     };
2701 
2702     public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
2703             "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
2704             "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa", "Etw",
2705             "Esw", "Ewa", "Elw", "Eec"
2706     };
2707 
2708     @FunctionalInterface
2709     public interface IntToString {
applyAsString(int val)2710         String applyAsString(int val);
2711     }
2712 
2713     private static final IntToString sUidToString = UserHandle::formatUid;
2714     private static final IntToString sIntToString = Integer::toString;
2715 
2716     public static final IntToString[] HISTORY_EVENT_INT_FORMATTERS = new IntToString[] {
2717             sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sUidToString,
2718             sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sIntToString,
2719             sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sUidToString,
2720             sUidToString, sUidToString, sUidToString, sIntToString
2721     };
2722 
2723     /**
2724      * Returns total time for WiFi Multicast Wakelock timer.
2725      * Note that this may be different from the sum of per uid timer values.
2726      *
2727      *  {@hide}
2728      */
getWifiMulticastWakelockTime(long elapsedRealtimeUs, int which)2729     public abstract long getWifiMulticastWakelockTime(long elapsedRealtimeUs, int which);
2730 
2731     /**
2732      * Returns total time for WiFi Multicast Wakelock timer
2733      * Note that this may be different from the sum of per uid timer values.
2734      *
2735      * {@hide}
2736      */
getWifiMulticastWakelockCount(int which)2737     public abstract int getWifiMulticastWakelockCount(int which);
2738 
2739     /**
2740      * Returns the time in microseconds that wifi has been on while the device was
2741      * running on battery.
2742      *
2743      * {@hide}
2744      */
2745     @UnsupportedAppUsage
getWifiOnTime(long elapsedRealtimeUs, int which)2746     public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
2747 
2748     /**
2749      * Returns the time in microseconds that wifi has been active while the device was
2750      * running on battery.
2751      *
2752      * {@hide}
2753      */
getWifiActiveTime(long elapsedRealtimeUs, int which)2754     public abstract long getWifiActiveTime(long elapsedRealtimeUs, int which);
2755 
2756     /**
2757      * Returns the time in microseconds that wifi has been on and the driver has
2758      * been in the running state while the device was running on battery.
2759      *
2760      * {@hide}
2761      */
2762     @UnsupportedAppUsage
getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)2763     public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
2764 
2765     static final String[] WIFI_STATE_NAMES = {
2766         "off", "scanning", "no_net", "disconn",
2767         "sta", "p2p", "sta_p2p", "soft_ap"
2768     };
2769 
2770     /**
2771      * Returns the time in microseconds that WiFi has been running in the given state.
2772      *
2773      * {@hide}
2774      */
getWifiStateTime(@ifiState int wifiState, long elapsedRealtimeUs, @StatName int which)2775     public abstract long getWifiStateTime(@WifiState int wifiState,
2776             long elapsedRealtimeUs, @StatName int which);
2777 
2778     /**
2779      * Returns the number of times that WiFi has entered the given state.
2780      *
2781      * {@hide}
2782      */
getWifiStateCount(@ifiState int wifiState, @StatName int which)2783     public abstract int getWifiStateCount(@WifiState int wifiState, @StatName int which);
2784 
2785     /**
2786      * Returns the {@link Timer} object that tracks the given WiFi state.
2787      *
2788      * {@hide}
2789      */
getWifiStateTimer(@ifiState int wifiState)2790     public abstract Timer getWifiStateTimer(@WifiState int wifiState);
2791 
2792     /**
2793      * Returns the time in microseconds that the wifi supplicant has been
2794      * in a given state.
2795      *
2796      * {@hide}
2797      */
getWifiSupplStateTime(@ifiSupplState int state, long elapsedRealtimeUs, @StatName int which)2798     public abstract long getWifiSupplStateTime(@WifiSupplState int state, long elapsedRealtimeUs,
2799             @StatName int which);
2800 
2801     /**
2802      * Returns the number of times that the wifi supplicant has transitioned
2803      * to a given state.
2804      *
2805      * {@hide}
2806      */
getWifiSupplStateCount(@ifiSupplState int state, @StatName int which)2807     public abstract int getWifiSupplStateCount(@WifiSupplState int state, @StatName int which);
2808 
2809     /**
2810      * Returns the {@link Timer} object that tracks the given wifi supplicant state.
2811      *
2812      * {@hide}
2813      */
getWifiSupplStateTimer(@ifiSupplState int state)2814     public abstract Timer getWifiSupplStateTimer(@WifiSupplState int state);
2815 
2816     public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5;
2817 
2818     /**
2819      * Returns the time in microseconds that WIFI has been running with
2820      * the given signal strength.
2821      *
2822      * {@hide}
2823      */
getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)2824     public abstract long getWifiSignalStrengthTime(int strengthBin,
2825             long elapsedRealtimeUs, int which);
2826 
2827     /**
2828      * Returns the number of times WIFI has entered the given signal strength.
2829      *
2830      * {@hide}
2831      */
getWifiSignalStrengthCount(int strengthBin, int which)2832     public abstract int getWifiSignalStrengthCount(int strengthBin, int which);
2833 
2834     /**
2835      * Returns the {@link Timer} object that tracks the given WIFI signal strength.
2836      *
2837      * {@hide}
2838      */
getWifiSignalStrengthTimer(int strengthBin)2839     public abstract Timer getWifiSignalStrengthTimer(int strengthBin);
2840 
2841     /**
2842      * Returns the time in microseconds that the flashlight has been on while the device was
2843      * running on battery.
2844      *
2845      * {@hide}
2846      */
getFlashlightOnTime(long elapsedRealtimeUs, int which)2847     public abstract long getFlashlightOnTime(long elapsedRealtimeUs, int which);
2848 
2849     /**
2850      * Returns the number of times that the flashlight has been turned on while the device was
2851      * running on battery.
2852      *
2853      * {@hide}
2854      */
getFlashlightOnCount(int which)2855     public abstract long getFlashlightOnCount(int which);
2856 
2857     /**
2858      * Returns the time in microseconds that the camera has been on while the device was
2859      * running on battery.
2860      *
2861      * {@hide}
2862      */
getCameraOnTime(long elapsedRealtimeUs, int which)2863     public abstract long getCameraOnTime(long elapsedRealtimeUs, int which);
2864 
2865     /**
2866      * Returns the time in microseconds that bluetooth scans were running while the device was
2867      * on battery.
2868      *
2869      * {@hide}
2870      */
getBluetoothScanTime(long elapsedRealtimeUs, int which)2871     public abstract long getBluetoothScanTime(long elapsedRealtimeUs, int which);
2872 
2873     public static final int NETWORK_MOBILE_RX_DATA = 0;
2874     public static final int NETWORK_MOBILE_TX_DATA = 1;
2875     public static final int NETWORK_WIFI_RX_DATA = 2;
2876     public static final int NETWORK_WIFI_TX_DATA = 3;
2877     public static final int NETWORK_BT_RX_DATA = 4;
2878     public static final int NETWORK_BT_TX_DATA = 5;
2879     public static final int NETWORK_MOBILE_BG_RX_DATA = 6;
2880     public static final int NETWORK_MOBILE_BG_TX_DATA = 7;
2881     public static final int NETWORK_WIFI_BG_RX_DATA = 8;
2882     public static final int NETWORK_WIFI_BG_TX_DATA = 9;
2883     public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_BG_TX_DATA + 1;
2884 
2885     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
getNetworkActivityBytes(int type, int which)2886     public abstract long getNetworkActivityBytes(int type, int which);
getNetworkActivityPackets(int type, int which)2887     public abstract long getNetworkActivityPackets(int type, int which);
2888 
2889     /**
2890      * Returns true if the BatteryStats object has detailed WiFi power reports.
2891      * When true, calling {@link #getWifiControllerActivity()} will yield the
2892      * actual power data.
2893      */
hasWifiActivityReporting()2894     public abstract boolean hasWifiActivityReporting();
2895 
2896     /**
2897      * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
2898      * in various radio controller states, such as transmit, receive, and idle.
2899      * @return non-null {@link ControllerActivityCounter}
2900      */
getWifiControllerActivity()2901     public abstract ControllerActivityCounter getWifiControllerActivity();
2902 
2903     /**
2904      * Returns true if the BatteryStats object has detailed bluetooth power reports.
2905      * When true, calling {@link #getBluetoothControllerActivity()} will yield the
2906      * actual power data.
2907      */
hasBluetoothActivityReporting()2908     public abstract boolean hasBluetoothActivityReporting();
2909 
2910     /**
2911      * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
2912      * in various radio controller states, such as transmit, receive, and idle.
2913      * @return non-null {@link ControllerActivityCounter}
2914      */
getBluetoothControllerActivity()2915     public abstract ControllerActivityCounter getBluetoothControllerActivity();
2916 
2917     /**
2918      * Returns true if the BatteryStats object has detailed modem power reports.
2919      * When true, calling {@link #getModemControllerActivity()} will yield the
2920      * actual power data.
2921      */
hasModemActivityReporting()2922     public abstract boolean hasModemActivityReporting();
2923 
2924     /**
2925      * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
2926      * in various radio controller states, such as transmit, receive, and idle.
2927      * @return non-null {@link ControllerActivityCounter}
2928      */
getModemControllerActivity()2929     public abstract ControllerActivityCounter getModemControllerActivity();
2930 
2931     /**
2932      * Return the wall clock time when battery stats data collection started.
2933      */
getStartClockTime()2934     public abstract long getStartClockTime();
2935 
2936     /**
2937      * Return platform version tag that we were running in when the battery stats started.
2938      */
getStartPlatformVersion()2939     public abstract String getStartPlatformVersion();
2940 
2941     /**
2942      * Return platform version tag that we were running in when the battery stats ended.
2943      */
getEndPlatformVersion()2944     public abstract String getEndPlatformVersion();
2945 
2946     /**
2947      * Return the internal version code of the parcelled format.
2948      */
getParcelVersion()2949     public abstract int getParcelVersion();
2950 
2951     /**
2952      * Return whether we are currently running on battery.
2953      */
getIsOnBattery()2954     public abstract boolean getIsOnBattery();
2955 
2956     /**
2957      * Returns the timestamp of when battery stats collection started, in microseconds.
2958      */
getStatsStartRealtime()2959     public abstract long getStatsStartRealtime();
2960 
2961     /**
2962      * Returns a SparseArray containing the statistics for each uid.
2963      */
2964     @UnsupportedAppUsage
getUidStats()2965     public abstract SparseArray<? extends Uid> getUidStats();
2966 
2967     /**
2968      * Returns the current battery uptime in microseconds.
2969      *
2970      * @param curTime the amount of elapsed realtime in microseconds.
2971      */
2972     @UnsupportedAppUsage
getBatteryUptime(long curTime)2973     public abstract long getBatteryUptime(long curTime);
2974 
2975     /**
2976      * Returns the current battery realtime in microseconds.
2977      *
2978      * @param curTime the amount of elapsed realtime in microseconds.
2979      */
getBatteryRealtime(long curTime)2980     public abstract long getBatteryRealtime(long curTime);
2981 
2982     /**
2983      * Returns the battery percentage level at the last time the device was unplugged from power, or
2984      * the last time it booted on battery power.
2985      */
getDischargeStartLevel()2986     public abstract int getDischargeStartLevel();
2987 
2988     /**
2989      * Returns the current battery percentage level if we are in a discharge cycle, otherwise
2990      * returns the level at the last plug event.
2991      */
getDischargeCurrentLevel()2992     public abstract int getDischargeCurrentLevel();
2993 
2994     /**
2995      * Get the amount the battery has discharged since the stats were
2996      * last reset after charging, as a lower-end approximation.
2997      */
getLowDischargeAmountSinceCharge()2998     public abstract int getLowDischargeAmountSinceCharge();
2999 
3000     /**
3001      * Get the amount the battery has discharged since the stats were
3002      * last reset after charging, as an upper-end approximation.
3003      */
getHighDischargeAmountSinceCharge()3004     public abstract int getHighDischargeAmountSinceCharge();
3005 
3006     /**
3007      * Retrieve the discharge amount over the selected discharge period <var>which</var>.
3008      */
getDischargeAmount(int which)3009     public abstract int getDischargeAmount(int which);
3010 
3011     /**
3012      * Get the amount the battery has discharged while the screen was on,
3013      * since the last time power was unplugged.
3014      */
getDischargeAmountScreenOn()3015     public abstract int getDischargeAmountScreenOn();
3016 
3017     /**
3018      * Get the amount the battery has discharged while the screen was on,
3019      * since the last time the device was charged.
3020      */
getDischargeAmountScreenOnSinceCharge()3021     public abstract int getDischargeAmountScreenOnSinceCharge();
3022 
3023     /**
3024      * Get the amount the battery has discharged while the screen was off,
3025      * since the last time power was unplugged.
3026      */
getDischargeAmountScreenOff()3027     public abstract int getDischargeAmountScreenOff();
3028 
3029     /**
3030      * Get the amount the battery has discharged while the screen was off,
3031      * since the last time the device was charged.
3032      */
getDischargeAmountScreenOffSinceCharge()3033     public abstract int getDischargeAmountScreenOffSinceCharge();
3034 
3035     /**
3036      * Get the amount the battery has discharged while the screen was dozing,
3037      * since the last time power was unplugged.
3038      */
getDischargeAmountScreenDoze()3039     public abstract int getDischargeAmountScreenDoze();
3040 
3041     /**
3042      * Get the amount the battery has discharged while the screen was dozing,
3043      * since the last time the device was charged.
3044      */
getDischargeAmountScreenDozeSinceCharge()3045     public abstract int getDischargeAmountScreenDozeSinceCharge();
3046 
3047     /**
3048      * Returns the approximate CPU time (in microseconds) spent by the system server handling
3049      * incoming service calls from apps.  The result is returned as an array of longs,
3050      * organized as a sequence like this:
3051      * <pre>
3052      *     cluster1-speeed1, cluster1-speed2, ..., cluster2-speed1, cluster2-speed2, ...
3053      * </pre>
3054      *
3055      * @see com.android.internal.os.PowerProfile#getNumCpuClusters()
3056      * @see com.android.internal.os.PowerProfile#getNumSpeedStepsInCpuCluster(int)
3057      */
3058     @Nullable
getSystemServiceTimeAtCpuSpeeds()3059     public abstract long[] getSystemServiceTimeAtCpuSpeeds();
3060 
3061     /**
3062      * Returns the total, last, or current battery uptime in microseconds.
3063      *
3064      * @param curTime the elapsed realtime in microseconds.
3065      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3066      */
3067     @UnsupportedAppUsage
computeBatteryUptime(long curTime, int which)3068     public abstract long computeBatteryUptime(long curTime, int which);
3069 
3070     /**
3071      * Returns the total, last, or current battery realtime in microseconds.
3072      *
3073      * @param curTime the current elapsed realtime in microseconds.
3074      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3075      */
3076     @UnsupportedAppUsage
computeBatteryRealtime(long curTime, int which)3077     public abstract long computeBatteryRealtime(long curTime, int which);
3078 
3079     /**
3080      * Returns the total, last, or current battery screen off/doze uptime in microseconds.
3081      *
3082      * @param curTime the elapsed realtime in microseconds.
3083      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3084      */
computeBatteryScreenOffUptime(long curTime, int which)3085     public abstract long computeBatteryScreenOffUptime(long curTime, int which);
3086 
3087     /**
3088      * Returns the total, last, or current battery screen off/doze realtime in microseconds.
3089      *
3090      * @param curTime the current elapsed realtime in microseconds.
3091      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3092      */
computeBatteryScreenOffRealtime(long curTime, int which)3093     public abstract long computeBatteryScreenOffRealtime(long curTime, int which);
3094 
3095     /**
3096      * Returns the total, last, or current uptime in microseconds.
3097      *
3098      * @param curTime the current elapsed realtime in microseconds.
3099      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3100      */
computeUptime(long curTime, int which)3101     public abstract long computeUptime(long curTime, int which);
3102 
3103     /**
3104      * Returns the total, last, or current realtime in microseconds.
3105      *
3106      * @param curTime the current elapsed realtime in microseconds.
3107      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3108      */
computeRealtime(long curTime, int which)3109     public abstract long computeRealtime(long curTime, int which);
3110 
3111     /**
3112      * Compute an approximation for how much run time (in microseconds) is remaining on
3113      * the battery.  Returns -1 if no time can be computed: either there is not
3114      * enough current data to make a decision, or the battery is currently
3115      * charging.
3116      *
3117      * @param curTime The current elapsed realtime in microseconds.
3118      */
3119     @UnsupportedAppUsage
computeBatteryTimeRemaining(long curTime)3120     public abstract long computeBatteryTimeRemaining(long curTime);
3121 
3122     // The part of a step duration that is the actual time.
3123     public static final long STEP_LEVEL_TIME_MASK = 0x000000ffffffffffL;
3124 
3125     // Bits in a step duration that are the new battery level we are at.
3126     public static final long STEP_LEVEL_LEVEL_MASK = 0x0000ff0000000000L;
3127     public static final int STEP_LEVEL_LEVEL_SHIFT = 40;
3128 
3129     // Bits in a step duration that are the initial mode we were in at that step.
3130     public static final long STEP_LEVEL_INITIAL_MODE_MASK = 0x00ff000000000000L;
3131     public static final int STEP_LEVEL_INITIAL_MODE_SHIFT = 48;
3132 
3133     // Bits in a step duration that indicate which modes changed during that step.
3134     public static final long STEP_LEVEL_MODIFIED_MODE_MASK = 0xff00000000000000L;
3135     public static final int STEP_LEVEL_MODIFIED_MODE_SHIFT = 56;
3136 
3137     // Step duration mode: the screen is on, off, dozed, etc; value is Display.STATE_* - 1.
3138     public static final int STEP_LEVEL_MODE_SCREEN_STATE = 0x03;
3139 
3140     // The largest value for screen state that is tracked in battery states. Any values above
3141     // this should be mapped back to one of the tracked values before being tracked here.
3142     public static final int MAX_TRACKED_SCREEN_STATE = Display.STATE_DOZE_SUSPEND;
3143 
3144     // Step duration mode: power save is on.
3145     public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04;
3146 
3147     // Step duration mode: device is currently in idle mode.
3148     public static final int STEP_LEVEL_MODE_DEVICE_IDLE = 0x08;
3149 
3150     public static final int[] STEP_LEVEL_MODES_OF_INTEREST = new int[] {
3151             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
3152             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE,
3153             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
3154             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
3155             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
3156             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
3157             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
3158             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
3159             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE,
3160             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
3161     };
3162     public static final int[] STEP_LEVEL_MODE_VALUES = new int[] {
3163             (Display.STATE_OFF-1),
3164             (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE,
3165             (Display.STATE_OFF-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
3166             (Display.STATE_ON-1),
3167             (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE,
3168             (Display.STATE_DOZE-1),
3169             (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE,
3170             (Display.STATE_DOZE_SUSPEND-1),
3171             (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE,
3172             (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
3173     };
3174     public static final String[] STEP_LEVEL_MODE_LABELS = new String[] {
3175             "screen off",
3176             "screen off power save",
3177             "screen off device idle",
3178             "screen on",
3179             "screen on power save",
3180             "screen doze",
3181             "screen doze power save",
3182             "screen doze-suspend",
3183             "screen doze-suspend power save",
3184             "screen doze-suspend device idle",
3185     };
3186 
3187     /**
3188      * Return the amount of battery discharge while the screen was off, measured in
3189      * micro-Ampere-hours. This will be non-zero only if the device's battery has
3190      * a coulomb counter.
3191      */
getUahDischargeScreenOff(int which)3192     public abstract long getUahDischargeScreenOff(int which);
3193 
3194     /**
3195      * Return the amount of battery discharge while the screen was in doze mode, measured in
3196      * micro-Ampere-hours. This will be non-zero only if the device's battery has
3197      * a coulomb counter.
3198      */
getUahDischargeScreenDoze(int which)3199     public abstract long getUahDischargeScreenDoze(int which);
3200 
3201     /**
3202      * Return the amount of battery discharge  measured in micro-Ampere-hours. This will be
3203      * non-zero only if the device's battery has a coulomb counter.
3204      */
getUahDischarge(int which)3205     public abstract long getUahDischarge(int which);
3206 
3207     /**
3208      * @return the amount of battery discharge while the device is in light idle mode, measured in
3209      * micro-Ampere-hours.
3210      */
getUahDischargeLightDoze(int which)3211     public abstract long getUahDischargeLightDoze(int which);
3212 
3213     /**
3214      * @return the amount of battery discharge while the device is in deep idle mode, measured in
3215      * micro-Ampere-hours.
3216      */
getUahDischargeDeepDoze(int which)3217     public abstract long getUahDischargeDeepDoze(int which);
3218 
3219     /**
3220      * Returns the estimated real battery capacity, which may be less than the capacity
3221      * declared by the PowerProfile.
3222      * @return The estimated battery capacity in mAh.
3223      */
getEstimatedBatteryCapacity()3224     public abstract int getEstimatedBatteryCapacity();
3225 
3226     /**
3227      * @return The minimum learned battery capacity in uAh.
3228      */
getMinLearnedBatteryCapacity()3229     public abstract int getMinLearnedBatteryCapacity();
3230 
3231     /**
3232      * @return The maximum learned battery capacity in uAh.
3233      */
getMaxLearnedBatteryCapacity()3234     public abstract int getMaxLearnedBatteryCapacity() ;
3235 
3236     /**
3237      * @return The latest learned battery capacity in uAh.
3238      */
getLearnedBatteryCapacity()3239     public abstract int getLearnedBatteryCapacity();
3240 
3241     /**
3242      * Return the array of discharge step durations.
3243      */
getDischargeLevelStepTracker()3244     public abstract LevelStepTracker getDischargeLevelStepTracker();
3245 
3246     /**
3247      * Return the array of daily discharge step durations.
3248      */
getDailyDischargeLevelStepTracker()3249     public abstract LevelStepTracker getDailyDischargeLevelStepTracker();
3250 
3251     /**
3252      * Compute an approximation for how much time (in microseconds) remains until the battery
3253      * is fully charged.  Returns -1 if no time can be computed: either there is not
3254      * enough current data to make a decision, or the battery is currently
3255      * discharging.
3256      *
3257      * @param curTime The current elepsed realtime in microseconds.
3258      */
3259     @UnsupportedAppUsage
computeChargeTimeRemaining(long curTime)3260     public abstract long computeChargeTimeRemaining(long curTime);
3261 
3262     /**
3263      * Return the array of charge step durations.
3264      */
getChargeLevelStepTracker()3265     public abstract LevelStepTracker getChargeLevelStepTracker();
3266 
3267     /**
3268      * Return the array of daily charge step durations.
3269      */
getDailyChargeLevelStepTracker()3270     public abstract LevelStepTracker getDailyChargeLevelStepTracker();
3271 
getDailyPackageChanges()3272     public abstract ArrayList<PackageChange> getDailyPackageChanges();
3273 
getWakeupReasonStats()3274     public abstract Map<String, ? extends Timer> getWakeupReasonStats();
3275 
getKernelWakelockStats()3276     public abstract Map<String, ? extends Timer> getKernelWakelockStats();
3277 
3278     /**
3279      * Returns Timers tracking the total time of each Resource Power Manager state and voter.
3280      */
getRpmStats()3281     public abstract Map<String, ? extends Timer> getRpmStats();
3282     /**
3283      * Returns Timers tracking the screen-off time of each Resource Power Manager state and voter.
3284      */
getScreenOffRpmStats()3285     public abstract Map<String, ? extends Timer> getScreenOffRpmStats();
3286 
3287 
getKernelMemoryStats()3288     public abstract LongSparseArray<? extends Timer> getKernelMemoryStats();
3289 
writeToParcelWithoutUids(Parcel out, int flags)3290     public abstract void writeToParcelWithoutUids(Parcel out, int flags);
3291 
formatTimeRaw(StringBuilder out, long seconds)3292     private final static void formatTimeRaw(StringBuilder out, long seconds) {
3293         long days = seconds / (60 * 60 * 24);
3294         if (days != 0) {
3295             out.append(days);
3296             out.append("d ");
3297         }
3298         long used = days * 60 * 60 * 24;
3299 
3300         long hours = (seconds - used) / (60 * 60);
3301         if (hours != 0 || used != 0) {
3302             out.append(hours);
3303             out.append("h ");
3304         }
3305         used += hours * 60 * 60;
3306 
3307         long mins = (seconds-used) / 60;
3308         if (mins != 0 || used != 0) {
3309             out.append(mins);
3310             out.append("m ");
3311         }
3312         used += mins * 60;
3313 
3314         if (seconds != 0 || used != 0) {
3315             out.append(seconds-used);
3316             out.append("s ");
3317         }
3318     }
3319 
formatTimeMs(StringBuilder sb, long time)3320     public final static void formatTimeMs(StringBuilder sb, long time) {
3321         long sec = time / 1000;
3322         formatTimeRaw(sb, sec);
3323         sb.append(time - (sec * 1000));
3324         sb.append("ms ");
3325     }
3326 
formatTimeMsNoSpace(StringBuilder sb, long time)3327     public final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
3328         long sec = time / 1000;
3329         formatTimeRaw(sb, sec);
3330         sb.append(time - (sec * 1000));
3331         sb.append("ms");
3332     }
3333 
formatRatioLocked(long num, long den)3334     public final String formatRatioLocked(long num, long den) {
3335         if (den == 0L) {
3336             return "--%";
3337         }
3338         float perc = ((float)num) / ((float)den) * 100;
3339         mFormatBuilder.setLength(0);
3340         mFormatter.format("%.1f%%", perc);
3341         return mFormatBuilder.toString();
3342     }
3343 
formatBytesLocked(long bytes)3344     final String formatBytesLocked(long bytes) {
3345         mFormatBuilder.setLength(0);
3346 
3347         if (bytes < BYTES_PER_KB) {
3348             return bytes + "B";
3349         } else if (bytes < BYTES_PER_MB) {
3350             mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
3351             return mFormatBuilder.toString();
3352         } else if (bytes < BYTES_PER_GB){
3353             mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
3354             return mFormatBuilder.toString();
3355         } else {
3356             mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
3357             return mFormatBuilder.toString();
3358         }
3359     }
3360 
roundUsToMs(long timeUs)3361     private static long roundUsToMs(long timeUs) {
3362         return (timeUs + 500) / 1000;
3363     }
3364 
computeWakeLock(Timer timer, long elapsedRealtimeUs, int which)3365     private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) {
3366         if (timer != null) {
3367             // Convert from microseconds to milliseconds with rounding
3368             long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
3369             long totalTimeMillis = (totalTimeMicros + 500) / 1000;
3370             return totalTimeMillis;
3371         }
3372         return 0;
3373     }
3374 
3375     /**
3376      *
3377      * @param sb a StringBuilder object.
3378      * @param timer a Timer object contining the wakelock times.
3379      * @param elapsedRealtimeUs the current on-battery time in microseconds.
3380      * @param name the name of the wakelock.
3381      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3382      * @param linePrefix a String to be prepended to each line of output.
3383      * @return the line prefix
3384      */
printWakeLock(StringBuilder sb, Timer timer, long elapsedRealtimeUs, String name, int which, String linePrefix)3385     private static final String printWakeLock(StringBuilder sb, Timer timer,
3386             long elapsedRealtimeUs, String name, int which, String linePrefix) {
3387 
3388         if (timer != null) {
3389             long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which);
3390 
3391             int count = timer.getCountLocked(which);
3392             if (totalTimeMillis != 0) {
3393                 sb.append(linePrefix);
3394                 formatTimeMs(sb, totalTimeMillis);
3395                 if (name != null) {
3396                     sb.append(name);
3397                     sb.append(' ');
3398                 }
3399                 sb.append('(');
3400                 sb.append(count);
3401                 sb.append(" times)");
3402                 final long maxDurationMs = timer.getMaxDurationMsLocked(elapsedRealtimeUs/1000);
3403                 if (maxDurationMs >= 0) {
3404                     sb.append(" max=");
3405                     sb.append(maxDurationMs);
3406                 }
3407                 // Put actual time if it is available and different from totalTimeMillis.
3408                 final long totalDurMs = timer.getTotalDurationMsLocked(elapsedRealtimeUs/1000);
3409                 if (totalDurMs > totalTimeMillis) {
3410                     sb.append(" actual=");
3411                     sb.append(totalDurMs);
3412                 }
3413                 if (timer.isRunningLocked()) {
3414                     final long currentMs = timer.getCurrentDurationMsLocked(elapsedRealtimeUs/1000);
3415                     if (currentMs >= 0) {
3416                         sb.append(" (running for ");
3417                         sb.append(currentMs);
3418                         sb.append("ms)");
3419                     } else {
3420                         sb.append(" (running)");
3421                     }
3422                 }
3423 
3424                 return ", ";
3425             }
3426         }
3427         return linePrefix;
3428     }
3429 
3430     /**
3431      * Prints details about a timer, if its total time was greater than 0.
3432      *
3433      * @param pw a PrintWriter object to print to.
3434      * @param sb a StringBuilder object.
3435      * @param timer a Timer object contining the wakelock times.
3436      * @param rawRealtimeUs the current on-battery time in microseconds.
3437      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3438      * @param prefix a String to be prepended to each line of output.
3439      * @param type the name of the timer.
3440      * @return true if anything was printed.
3441      */
printTimer(PrintWriter pw, StringBuilder sb, Timer timer, long rawRealtimeUs, int which, String prefix, String type)3442     private static final boolean printTimer(PrintWriter pw, StringBuilder sb, Timer timer,
3443             long rawRealtimeUs, int which, String prefix, String type) {
3444         if (timer != null) {
3445             // Convert from microseconds to milliseconds with rounding
3446             final long totalTimeMs = (timer.getTotalTimeLocked(
3447                     rawRealtimeUs, which) + 500) / 1000;
3448             final int count = timer.getCountLocked(which);
3449             if (totalTimeMs != 0) {
3450                 sb.setLength(0);
3451                 sb.append(prefix);
3452                 sb.append("    ");
3453                 sb.append(type);
3454                 sb.append(": ");
3455                 formatTimeMs(sb, totalTimeMs);
3456                 sb.append("realtime (");
3457                 sb.append(count);
3458                 sb.append(" times)");
3459                 final long maxDurationMs = timer.getMaxDurationMsLocked(rawRealtimeUs/1000);
3460                 if (maxDurationMs >= 0) {
3461                     sb.append(" max=");
3462                     sb.append(maxDurationMs);
3463                 }
3464                 if (timer.isRunningLocked()) {
3465                     final long currentMs = timer.getCurrentDurationMsLocked(rawRealtimeUs/1000);
3466                     if (currentMs >= 0) {
3467                         sb.append(" (running for ");
3468                         sb.append(currentMs);
3469                         sb.append("ms)");
3470                     } else {
3471                         sb.append(" (running)");
3472                     }
3473                 }
3474                 pw.println(sb.toString());
3475                 return true;
3476             }
3477         }
3478         return false;
3479     }
3480 
3481     /**
3482      * Checkin version of wakelock printer. Prints simple comma-separated list.
3483      *
3484      * @param sb a StringBuilder object.
3485      * @param timer a Timer object contining the wakelock times.
3486      * @param elapsedRealtimeUs the current time in microseconds.
3487      * @param name the name of the wakelock.
3488      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3489      * @param linePrefix a String to be prepended to each line of output.
3490      * @return the line prefix
3491      */
printWakeLockCheckin(StringBuilder sb, Timer timer, long elapsedRealtimeUs, String name, int which, String linePrefix)3492     private static final String printWakeLockCheckin(StringBuilder sb, Timer timer,
3493             long elapsedRealtimeUs, String name, int which, String linePrefix) {
3494         long totalTimeMicros = 0;
3495         int count = 0;
3496         long max = 0;
3497         long current = 0;
3498         long totalDuration = 0;
3499         if (timer != null) {
3500             totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
3501             count = timer.getCountLocked(which);
3502             current = timer.getCurrentDurationMsLocked(elapsedRealtimeUs/1000);
3503             max = timer.getMaxDurationMsLocked(elapsedRealtimeUs/1000);
3504             totalDuration = timer.getTotalDurationMsLocked(elapsedRealtimeUs/1000);
3505         }
3506         sb.append(linePrefix);
3507         sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
3508         sb.append(',');
3509         sb.append(name != null ? name + "," : "");
3510         sb.append(count);
3511         sb.append(',');
3512         sb.append(current);
3513         sb.append(',');
3514         sb.append(max);
3515         // Partial, full, and window wakelocks are pooled, so totalDuration is meaningful (albeit
3516         // not always tracked). Kernel wakelocks (which have name == null) have no notion of
3517         // totalDuration independent of totalTimeMicros (since they are not pooled).
3518         if (name != null) {
3519             sb.append(',');
3520             sb.append(totalDuration);
3521         }
3522         return ",";
3523     }
3524 
dumpLineHeader(PrintWriter pw, int uid, String category, String type)3525     private static final void dumpLineHeader(PrintWriter pw, int uid, String category,
3526                                              String type) {
3527         pw.print(BATTERY_STATS_CHECKIN_VERSION);
3528         pw.print(',');
3529         pw.print(uid);
3530         pw.print(',');
3531         pw.print(category);
3532         pw.print(',');
3533         pw.print(type);
3534     }
3535 
3536     /**
3537      * Dump a comma-separated line of values for terse checkin mode.
3538      *
3539      * @param pw the PageWriter to dump log to
3540      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
3541      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
3542      * @param args type-dependent data arguments
3543      */
3544     @UnsupportedAppUsage
dumpLine(PrintWriter pw, int uid, String category, String type, Object... args )3545     private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
3546            Object... args ) {
3547         dumpLineHeader(pw, uid, category, type);
3548         for (Object arg : args) {
3549             pw.print(',');
3550             pw.print(arg);
3551         }
3552         pw.println();
3553     }
3554 
3555     /**
3556      * Dump a given timer stat for terse checkin mode.
3557      *
3558      * @param pw the PageWriter to dump log to
3559      * @param uid the UID to log
3560      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
3561      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
3562      * @param timer a {@link Timer} to dump stats for
3563      * @param rawRealtime the current elapsed realtime of the system in microseconds
3564      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
3565      */
dumpTimer(PrintWriter pw, int uid, String category, String type, Timer timer, long rawRealtime, int which)3566     private static final void dumpTimer(PrintWriter pw, int uid, String category, String type,
3567                                         Timer timer, long rawRealtime, int which) {
3568         if (timer != null) {
3569             // Convert from microseconds to milliseconds with rounding
3570             final long totalTime = roundUsToMs(timer.getTotalTimeLocked(rawRealtime, which));
3571             final int count = timer.getCountLocked(which);
3572             if (totalTime != 0 || count != 0) {
3573                 dumpLine(pw, uid, category, type, totalTime, count);
3574             }
3575         }
3576     }
3577 
3578     /**
3579      * Dump a given timer stat to the proto stream.
3580      *
3581      * @param proto the ProtoOutputStream to log to
3582      * @param fieldId type of data, the field to save to (e.g. AggregatedBatteryStats.WAKELOCK)
3583      * @param timer a {@link Timer} to dump stats for
3584      * @param rawRealtimeUs the current elapsed realtime of the system in microseconds
3585      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
3586      */
dumpTimer(ProtoOutputStream proto, long fieldId, Timer timer, long rawRealtimeUs, int which)3587     private static void dumpTimer(ProtoOutputStream proto, long fieldId,
3588                                         Timer timer, long rawRealtimeUs, int which) {
3589         if (timer == null) {
3590             return;
3591         }
3592         // Convert from microseconds to milliseconds with rounding
3593         final long timeMs = roundUsToMs(timer.getTotalTimeLocked(rawRealtimeUs, which));
3594         final int count = timer.getCountLocked(which);
3595         final long maxDurationMs = timer.getMaxDurationMsLocked(rawRealtimeUs / 1000);
3596         final long curDurationMs = timer.getCurrentDurationMsLocked(rawRealtimeUs / 1000);
3597         final long totalDurationMs = timer.getTotalDurationMsLocked(rawRealtimeUs / 1000);
3598         if (timeMs != 0 || count != 0 || maxDurationMs != -1 || curDurationMs != -1
3599                 || totalDurationMs != -1) {
3600             final long token = proto.start(fieldId);
3601             proto.write(TimerProto.DURATION_MS, timeMs);
3602             proto.write(TimerProto.COUNT, count);
3603             // These values will be -1 for timers that don't implement the functionality.
3604             if (maxDurationMs != -1) {
3605                 proto.write(TimerProto.MAX_DURATION_MS, maxDurationMs);
3606             }
3607             if (curDurationMs != -1) {
3608                 proto.write(TimerProto.CURRENT_DURATION_MS, curDurationMs);
3609             }
3610             if (totalDurationMs != -1) {
3611                 proto.write(TimerProto.TOTAL_DURATION_MS, totalDurationMs);
3612             }
3613             proto.end(token);
3614         }
3615     }
3616 
3617     /**
3618      * Checks if the ControllerActivityCounter has any data worth dumping.
3619      */
controllerActivityHasData(ControllerActivityCounter counter, int which)3620     private static boolean controllerActivityHasData(ControllerActivityCounter counter, int which) {
3621         if (counter == null) {
3622             return false;
3623         }
3624 
3625         if (counter.getIdleTimeCounter().getCountLocked(which) != 0
3626                 || counter.getRxTimeCounter().getCountLocked(which) != 0
3627                 || counter.getPowerCounter().getCountLocked(which) != 0
3628                 || counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which) != 0) {
3629             return true;
3630         }
3631 
3632         for (LongCounter c : counter.getTxTimeCounters()) {
3633             if (c.getCountLocked(which) != 0) {
3634                 return true;
3635             }
3636         }
3637         return false;
3638     }
3639 
3640     /**
3641      * Dumps the ControllerActivityCounter if it has any data worth dumping.
3642      * The order of the arguments in the final check in line is:
3643      *
3644      * idle, rx, power, tx...
3645      *
3646      * where tx... is one or more transmit level times.
3647      */
dumpControllerActivityLine(PrintWriter pw, int uid, String category, String type, ControllerActivityCounter counter, int which)3648     private static final void dumpControllerActivityLine(PrintWriter pw, int uid, String category,
3649                                                          String type,
3650                                                          ControllerActivityCounter counter,
3651                                                          int which) {
3652         if (!controllerActivityHasData(counter, which)) {
3653             return;
3654         }
3655 
3656         dumpLineHeader(pw, uid, category, type);
3657         pw.print(",");
3658         pw.print(counter.getIdleTimeCounter().getCountLocked(which));
3659         pw.print(",");
3660         pw.print(counter.getRxTimeCounter().getCountLocked(which));
3661         pw.print(",");
3662         pw.print(counter.getPowerCounter().getCountLocked(which) / (MILLISECONDS_IN_HOUR));
3663         pw.print(",");
3664         pw.print(counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which)
3665                 / (MILLISECONDS_IN_HOUR));
3666         for (LongCounter c : counter.getTxTimeCounters()) {
3667             pw.print(",");
3668             pw.print(c.getCountLocked(which));
3669         }
3670         pw.println();
3671     }
3672 
3673     /**
3674      * Dumps the ControllerActivityCounter if it has any data worth dumping.
3675      */
dumpControllerActivityProto(ProtoOutputStream proto, long fieldId, ControllerActivityCounter counter, int which)3676     private static void dumpControllerActivityProto(ProtoOutputStream proto, long fieldId,
3677                                                     ControllerActivityCounter counter,
3678                                                     int which) {
3679         if (!controllerActivityHasData(counter, which)) {
3680             return;
3681         }
3682 
3683         final long cToken = proto.start(fieldId);
3684 
3685         proto.write(ControllerActivityProto.IDLE_DURATION_MS,
3686                 counter.getIdleTimeCounter().getCountLocked(which));
3687         proto.write(ControllerActivityProto.RX_DURATION_MS,
3688                 counter.getRxTimeCounter().getCountLocked(which));
3689         proto.write(ControllerActivityProto.POWER_MAH,
3690                 counter.getPowerCounter().getCountLocked(which) / (MILLISECONDS_IN_HOUR));
3691         proto.write(ControllerActivityProto.MONITORED_RAIL_CHARGE_MAH,
3692                 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which)
3693                         / (MILLISECONDS_IN_HOUR));
3694 
3695         long tToken;
3696         LongCounter[] txCounters = counter.getTxTimeCounters();
3697         for (int i = 0; i < txCounters.length; ++i) {
3698             LongCounter c = txCounters[i];
3699             tToken = proto.start(ControllerActivityProto.TX);
3700             proto.write(ControllerActivityProto.TxLevel.LEVEL, i);
3701             proto.write(ControllerActivityProto.TxLevel.DURATION_MS, c.getCountLocked(which));
3702             proto.end(tToken);
3703         }
3704 
3705         proto.end(cToken);
3706     }
3707 
printControllerActivityIfInteresting(PrintWriter pw, StringBuilder sb, String prefix, String controllerName, ControllerActivityCounter counter, int which)3708     private final void printControllerActivityIfInteresting(PrintWriter pw, StringBuilder sb,
3709                                                             String prefix, String controllerName,
3710                                                             ControllerActivityCounter counter,
3711                                                             int which) {
3712         if (controllerActivityHasData(counter, which)) {
3713             printControllerActivity(pw, sb, prefix, controllerName, counter, which);
3714         }
3715     }
3716 
printControllerActivity(PrintWriter pw, StringBuilder sb, String prefix, String controllerName, ControllerActivityCounter counter, int which)3717     private final void printControllerActivity(PrintWriter pw, StringBuilder sb, String prefix,
3718                                                String controllerName,
3719                                                ControllerActivityCounter counter, int which) {
3720         final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
3721         final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
3722         final long powerDrainMaMs = counter.getPowerCounter().getCountLocked(which);
3723         final long monitoredRailChargeConsumedMaMs =
3724                 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which);
3725         // Battery real time
3726         final long totalControllerActivityTimeMs
3727             = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
3728         long totalTxTimeMs = 0;
3729         for (LongCounter txState : counter.getTxTimeCounters()) {
3730             totalTxTimeMs += txState.getCountLocked(which);
3731         }
3732 
3733         if (controllerName.equals(WIFI_CONTROLLER_NAME)) {
3734             final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which);
3735             sb.setLength(0);
3736             sb.append(prefix);
3737             sb.append("     ");
3738             sb.append(controllerName);
3739             sb.append(" Scan time:  ");
3740             formatTimeMs(sb, scanTimeMs);
3741             sb.append("(");
3742             sb.append(formatRatioLocked(scanTimeMs, totalControllerActivityTimeMs));
3743             sb.append(")");
3744             pw.println(sb.toString());
3745 
3746             final long sleepTimeMs
3747                 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + totalTxTimeMs);
3748             sb.setLength(0);
3749             sb.append(prefix);
3750             sb.append("     ");
3751             sb.append(controllerName);
3752             sb.append(" Sleep time:  ");
3753             formatTimeMs(sb, sleepTimeMs);
3754             sb.append("(");
3755             sb.append(formatRatioLocked(sleepTimeMs, totalControllerActivityTimeMs));
3756             sb.append(")");
3757             pw.println(sb.toString());
3758         }
3759 
3760         if (controllerName.equals(CELLULAR_CONTROLLER_NAME)) {
3761             final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which);
3762             sb.setLength(0);
3763             sb.append(prefix);
3764             sb.append("     ");
3765             sb.append(controllerName);
3766             sb.append(" Sleep time:  ");
3767             formatTimeMs(sb, sleepTimeMs);
3768             sb.append("(");
3769             sb.append(formatRatioLocked(sleepTimeMs, totalControllerActivityTimeMs));
3770             sb.append(")");
3771             pw.println(sb.toString());
3772         }
3773 
3774         sb.setLength(0);
3775         sb.append(prefix);
3776         sb.append("     ");
3777         sb.append(controllerName);
3778         sb.append(" Idle time:   ");
3779         formatTimeMs(sb, idleTimeMs);
3780         sb.append("(");
3781         sb.append(formatRatioLocked(idleTimeMs, totalControllerActivityTimeMs));
3782         sb.append(")");
3783         pw.println(sb.toString());
3784 
3785         sb.setLength(0);
3786         sb.append(prefix);
3787         sb.append("     ");
3788         sb.append(controllerName);
3789         sb.append(" Rx time:     ");
3790         formatTimeMs(sb, rxTimeMs);
3791         sb.append("(");
3792         sb.append(formatRatioLocked(rxTimeMs, totalControllerActivityTimeMs));
3793         sb.append(")");
3794         pw.println(sb.toString());
3795 
3796         sb.setLength(0);
3797         sb.append(prefix);
3798         sb.append("     ");
3799         sb.append(controllerName);
3800         sb.append(" Tx time:     ");
3801 
3802         String [] powerLevel;
3803         switch(controllerName) {
3804             case CELLULAR_CONTROLLER_NAME:
3805                 powerLevel = new String[] {
3806                     "   less than 0dBm: ",
3807                     "   0dBm to 8dBm: ",
3808                     "   8dBm to 15dBm: ",
3809                     "   15dBm to 20dBm: ",
3810                     "   above 20dBm: "};
3811                 break;
3812             default:
3813                 powerLevel = new String[] {"[0]", "[1]", "[2]", "[3]", "[4]"};
3814                 break;
3815         }
3816         final int numTxLvls = Math.min(counter.getTxTimeCounters().length, powerLevel.length);
3817         if (numTxLvls > 1) {
3818             pw.println(sb.toString());
3819             for (int lvl = 0; lvl < numTxLvls; lvl++) {
3820                 final long txLvlTimeMs = counter.getTxTimeCounters()[lvl].getCountLocked(which);
3821                 sb.setLength(0);
3822                 sb.append(prefix);
3823                 sb.append("    ");
3824                 sb.append(powerLevel[lvl]);
3825                 sb.append(" ");
3826                 formatTimeMs(sb, txLvlTimeMs);
3827                 sb.append("(");
3828                 sb.append(formatRatioLocked(txLvlTimeMs, totalControllerActivityTimeMs));
3829                 sb.append(")");
3830                 pw.println(sb.toString());
3831             }
3832         } else {
3833             final long txLvlTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which);
3834             formatTimeMs(sb, txLvlTimeMs);
3835             sb.append("(");
3836             sb.append(formatRatioLocked(txLvlTimeMs, totalControllerActivityTimeMs));
3837             sb.append(")");
3838             pw.println(sb.toString());
3839         }
3840 
3841         if (powerDrainMaMs > 0) {
3842             sb.setLength(0);
3843             sb.append(prefix);
3844             sb.append("     ");
3845             sb.append(controllerName);
3846             sb.append(" Battery drain: ").append(
3847                     BatteryStatsHelper.makemAh(powerDrainMaMs / MILLISECONDS_IN_HOUR));
3848             sb.append("mAh");
3849             pw.println(sb.toString());
3850         }
3851 
3852         if (monitoredRailChargeConsumedMaMs > 0) {
3853             sb.setLength(0);
3854             sb.append(prefix);
3855             sb.append("     ");
3856             sb.append(controllerName);
3857             sb.append(" Monitored rail energy drain: ").append(
3858                     new DecimalFormat("#.##").format(
3859                             monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR));
3860             sb.append(" mAh");
3861             pw.println(sb.toString());
3862         }
3863     }
3864 
3865     /**
3866      * Temporary for settings.
3867      */
dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid)3868     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
3869         dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
3870     }
3871 
3872     /**
3873      * Checkin server version of dump to produce more compact, computer-readable log.
3874      *
3875      * NOTE: all times are expressed in microseconds, unless specified otherwise.
3876      */
dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid, boolean wifiOnly)3877     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
3878             boolean wifiOnly) {
3879 
3880         if (which != BatteryStats.STATS_SINCE_CHARGED) {
3881             dumpLine(pw, 0, STAT_NAMES[which], "err",
3882                     "ERROR: BatteryStats.dumpCheckin called for which type " + which
3883                     + " but only STATS_SINCE_CHARGED is supported.");
3884             return;
3885         }
3886 
3887         final long rawUptime = SystemClock.uptimeMillis() * 1000;
3888         final long rawRealtimeMs = SystemClock.elapsedRealtime();
3889         final long rawRealtime = rawRealtimeMs * 1000;
3890         final long batteryUptime = getBatteryUptime(rawUptime);
3891         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
3892         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
3893         final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
3894         final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
3895                 which);
3896         final long totalRealtime = computeRealtime(rawRealtime, which);
3897         final long totalUptime = computeUptime(rawUptime, which);
3898         final long screenOnTime = getScreenOnTime(rawRealtime, which);
3899         final long screenDozeTime = getScreenDozeTime(rawRealtime, which);
3900         final long interactiveTime = getInteractiveTime(rawRealtime, which);
3901         final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
3902         final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT,
3903                 rawRealtime, which);
3904         final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP,
3905                 rawRealtime, which);
3906         final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT,
3907                 rawRealtime, which);
3908         final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP,
3909                 rawRealtime, which);
3910         final int connChanges = getNumConnectivityChange(which);
3911         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
3912         final long dischargeCount = getUahDischarge(which);
3913         final long dischargeScreenOffCount = getUahDischargeScreenOff(which);
3914         final long dischargeScreenDozeCount = getUahDischargeScreenDoze(which);
3915         final long dischargeLightDozeCount = getUahDischargeLightDoze(which);
3916         final long dischargeDeepDozeCount = getUahDischargeDeepDoze(which);
3917 
3918         final StringBuilder sb = new StringBuilder(128);
3919 
3920         final SparseArray<? extends Uid> uidStats = getUidStats();
3921         final int NU = uidStats.size();
3922 
3923         final String category = STAT_NAMES[which];
3924 
3925         // Dump "battery" stat
3926         dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
3927                 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
3928                 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
3929                 totalRealtime / 1000, totalUptime / 1000,
3930                 getStartClockTime(),
3931                 whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000,
3932                 getEstimatedBatteryCapacity(),
3933                 getMinLearnedBatteryCapacity(),
3934                 getMaxLearnedBatteryCapacity(),
3935                 screenDozeTime / 1000);
3936 
3937 
3938         // Calculate wakelock times across all uids.
3939         long fullWakeLockTimeTotal = 0;
3940         long partialWakeLockTimeTotal = 0;
3941 
3942         for (int iu = 0; iu < NU; iu++) {
3943             final Uid u = uidStats.valueAt(iu);
3944 
3945             final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
3946                     = u.getWakelockStats();
3947             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
3948                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
3949 
3950                 final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
3951                 if (fullWakeTimer != null) {
3952                     fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
3953                             which);
3954                 }
3955 
3956                 final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
3957                 if (partialWakeTimer != null) {
3958                     partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
3959                         rawRealtime, which);
3960                 }
3961             }
3962         }
3963 
3964         // Dump network stats
3965         final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
3966         final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
3967         final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
3968         final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
3969         final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
3970         final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
3971         final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
3972         final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
3973         final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
3974         final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
3975         dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
3976                 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
3977                 mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets,
3978                 btRxTotalBytes, btTxTotalBytes);
3979 
3980         // Dump Modem controller stats
3981         dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_MODEM_CONTROLLER_DATA,
3982                 getModemControllerActivity(), which);
3983 
3984         // Dump Wifi controller stats
3985         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
3986         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
3987         dumpLine(pw, 0 /* uid */, category, GLOBAL_WIFI_DATA, wifiOnTime / 1000,
3988                 wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */ 0, 0, 0);
3989 
3990         dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_WIFI_CONTROLLER_DATA,
3991                 getWifiControllerActivity(), which);
3992 
3993         // Dump Bluetooth controller stats
3994         dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_BLUETOOTH_CONTROLLER_DATA,
3995                 getBluetoothControllerActivity(), which);
3996 
3997         // Dump misc stats
3998         dumpLine(pw, 0 /* uid */, category, MISC_DATA,
3999                 screenOnTime / 1000, phoneOnTime / 1000,
4000                 fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000,
4001                 getMobileRadioActiveTime(rawRealtime, which) / 1000,
4002                 getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000,
4003                 powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeFullTime / 1000,
4004                 getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which), deviceIdlingTime / 1000,
4005                 getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which),
4006                 getMobileRadioActiveCount(which),
4007                 getMobileRadioActiveUnknownTime(which) / 1000, deviceIdleModeLightTime / 1000,
4008                 getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which), deviceLightIdlingTime / 1000,
4009                 getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which),
4010                 getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT),
4011                 getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
4012 
4013         // Dump screen brightness stats
4014         Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
4015         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4016             args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
4017         }
4018         dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
4019 
4020         // Dump signal strength stats
4021         args = new Object[CellSignalStrength.getNumSignalStrengthLevels()];
4022         for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) {
4023             args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
4024         }
4025         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
4026         dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
4027                 getPhoneSignalScanningTime(rawRealtime, which) / 1000);
4028         for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) {
4029             args[i] = getPhoneSignalStrengthCount(i, which);
4030         }
4031         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
4032 
4033         // Dump network type stats
4034         args = new Object[NUM_DATA_CONNECTION_TYPES];
4035         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4036             args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
4037         }
4038         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
4039         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4040             args[i] = getPhoneDataConnectionCount(i, which);
4041         }
4042         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
4043 
4044         // Dump wifi state stats
4045         args = new Object[NUM_WIFI_STATES];
4046         for (int i=0; i<NUM_WIFI_STATES; i++) {
4047             args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
4048         }
4049         dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args);
4050         for (int i=0; i<NUM_WIFI_STATES; i++) {
4051             args[i] = getWifiStateCount(i, which);
4052         }
4053         dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args);
4054 
4055         // Dump wifi suppl state stats
4056         args = new Object[NUM_WIFI_SUPPL_STATES];
4057         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
4058             args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
4059         }
4060         dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_TIME_DATA, args);
4061         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
4062             args[i] = getWifiSupplStateCount(i, which);
4063         }
4064         dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_COUNT_DATA, args);
4065 
4066         // Dump wifi signal strength stats
4067         args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
4068         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
4069             args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
4070         }
4071         dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
4072         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
4073             args[i] = getWifiSignalStrengthCount(i, which);
4074         }
4075         dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
4076 
4077         // Dump Multicast total stats
4078         final long multicastWakeLockTimeTotalMicros =
4079                 getWifiMulticastWakelockTime(rawRealtime, which);
4080         final int multicastWakeLockCountTotal = getWifiMulticastWakelockCount(which);
4081         dumpLine(pw, 0 /* uid */, category, WIFI_MULTICAST_TOTAL_DATA,
4082                 multicastWakeLockTimeTotalMicros / 1000,
4083                 multicastWakeLockCountTotal);
4084 
4085         dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
4086                 getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
4087                 getDischargeAmountScreenOnSinceCharge(),
4088                 getDischargeAmountScreenOffSinceCharge(),
4089                 dischargeCount / 1000, dischargeScreenOffCount / 1000,
4090                 getDischargeAmountScreenDozeSinceCharge(), dischargeScreenDozeCount / 1000,
4091                 dischargeLightDozeCount / 1000, dischargeDeepDozeCount / 1000);
4092 
4093         if (reqUid < 0) {
4094             final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
4095             if (kernelWakelocks.size() > 0) {
4096                 for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
4097                     sb.setLength(0);
4098                     printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
4099                     dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA,
4100                             "\"" + ent.getKey() + "\"", sb.toString());
4101                 }
4102             }
4103             final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
4104             if (wakeupReasons.size() > 0) {
4105                 for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
4106                     // Not doing the regular wake lock formatting to remain compatible
4107                     // with the old checkin format.
4108                     long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which);
4109                     int count = ent.getValue().getCountLocked(which);
4110                     dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA,
4111                             "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count);
4112                 }
4113             }
4114         }
4115 
4116         final Map<String, ? extends Timer> rpmStats = getRpmStats();
4117         final Map<String, ? extends Timer> screenOffRpmStats = getScreenOffRpmStats();
4118         if (rpmStats.size() > 0) {
4119             for (Map.Entry<String, ? extends Timer> ent : rpmStats.entrySet()) {
4120                 sb.setLength(0);
4121                 Timer totalTimer = ent.getValue();
4122                 long timeMs = (totalTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
4123                 int count = totalTimer.getCountLocked(which);
4124                 Timer screenOffTimer = screenOffRpmStats.get(ent.getKey());
4125                 long screenOffTimeMs = screenOffTimer != null
4126                         ? (screenOffTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
4127                 int screenOffCount = screenOffTimer != null
4128                         ? screenOffTimer.getCountLocked(which) : 0;
4129                 if (SCREEN_OFF_RPM_STATS_ENABLED) {
4130                     dumpLine(pw, 0 /* uid */, category, RESOURCE_POWER_MANAGER_DATA,
4131                             "\"" + ent.getKey() + "\"", timeMs, count, screenOffTimeMs,
4132                             screenOffCount);
4133                 } else {
4134                     dumpLine(pw, 0 /* uid */, category, RESOURCE_POWER_MANAGER_DATA,
4135                             "\"" + ent.getKey() + "\"", timeMs, count);
4136                 }
4137             }
4138         }
4139 
4140         final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
4141         helper.create(this);
4142         helper.refreshStats(which, UserHandle.USER_ALL);
4143         final List<BatterySipper> sippers = helper.getUsageList();
4144         if (sippers != null && sippers.size() > 0) {
4145             dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
4146                     BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
4147                     BatteryStatsHelper.makemAh(helper.getComputedPower()),
4148                     BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
4149                     BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
4150             int uid = 0;
4151             for (int i=0; i<sippers.size(); i++) {
4152                 final BatterySipper bs = sippers.get(i);
4153                 String label;
4154                 switch (bs.drainType) {
4155                     case AMBIENT_DISPLAY:
4156                         label = "ambi";
4157                         break;
4158                     case IDLE:
4159                         label="idle";
4160                         break;
4161                     case CELL:
4162                         label="cell";
4163                         break;
4164                     case PHONE:
4165                         label="phone";
4166                         break;
4167                     case WIFI:
4168                         label="wifi";
4169                         break;
4170                     case BLUETOOTH:
4171                         label="blue";
4172                         break;
4173                     case SCREEN:
4174                         label="scrn";
4175                         break;
4176                     case FLASHLIGHT:
4177                         label="flashlight";
4178                         break;
4179                     case APP:
4180                         uid = bs.uidObj.getUid();
4181                         label = "uid";
4182                         break;
4183                     case USER:
4184                         uid = UserHandle.getUid(bs.userId, 0);
4185                         label = "user";
4186                         break;
4187                     case UNACCOUNTED:
4188                         label = "unacc";
4189                         break;
4190                     case OVERCOUNTED:
4191                         label = "over";
4192                         break;
4193                     case CAMERA:
4194                         label = "camera";
4195                         break;
4196                     case MEMORY:
4197                         label = "memory";
4198                         break;
4199                     default:
4200                         label = "???";
4201                 }
4202                 dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
4203                         BatteryStatsHelper.makemAh(bs.totalPowerMah),
4204                         bs.shouldHide ? 1 : 0,
4205                         BatteryStatsHelper.makemAh(bs.screenPowerMah),
4206                         BatteryStatsHelper.makemAh(bs.proportionalSmearMah));
4207             }
4208         }
4209 
4210         final long[] cpuFreqs = getCpuFreqs();
4211         if (cpuFreqs != null) {
4212             sb.setLength(0);
4213             for (int i = 0; i < cpuFreqs.length; ++i) {
4214                 if (i != 0) sb.append(',');
4215                 sb.append(cpuFreqs[i]);
4216             }
4217             dumpLine(pw, 0 /* uid */, category, GLOBAL_CPU_FREQ_DATA, sb.toString());
4218         }
4219 
4220         // Dump stats per UID.
4221         for (int iu = 0; iu < NU; iu++) {
4222             final int uid = uidStats.keyAt(iu);
4223             if (reqUid >= 0 && uid != reqUid) {
4224                 continue;
4225             }
4226             final Uid u = uidStats.valueAt(iu);
4227 
4228             // Dump Network stats per uid, if any
4229             final long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
4230             final long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
4231             final long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
4232             final long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
4233             final long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
4234             final long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
4235             final long mobileActiveTime = u.getMobileRadioActiveTime(which);
4236             final int mobileActiveCount = u.getMobileRadioActiveCount(which);
4237             final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
4238             final long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
4239             final long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
4240             final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
4241             final long btBytesRx = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
4242             final long btBytesTx = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
4243             // Background data transfers
4244             final long mobileBytesBgRx = u.getNetworkActivityBytes(NETWORK_MOBILE_BG_RX_DATA,
4245                     which);
4246             final long mobileBytesBgTx = u.getNetworkActivityBytes(NETWORK_MOBILE_BG_TX_DATA,
4247                     which);
4248             final long wifiBytesBgRx = u.getNetworkActivityBytes(NETWORK_WIFI_BG_RX_DATA, which);
4249             final long wifiBytesBgTx = u.getNetworkActivityBytes(NETWORK_WIFI_BG_TX_DATA, which);
4250             final long mobilePacketsBgRx = u.getNetworkActivityPackets(NETWORK_MOBILE_BG_RX_DATA,
4251                     which);
4252             final long mobilePacketsBgTx = u.getNetworkActivityPackets(NETWORK_MOBILE_BG_TX_DATA,
4253                     which);
4254             final long wifiPacketsBgRx = u.getNetworkActivityPackets(NETWORK_WIFI_BG_RX_DATA,
4255                     which);
4256             final long wifiPacketsBgTx = u.getNetworkActivityPackets(NETWORK_WIFI_BG_TX_DATA,
4257                     which);
4258 
4259             if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
4260                     || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
4261                     || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0
4262                     || btBytesRx > 0 || btBytesTx > 0 || mobileWakeup > 0 || wifiWakeup > 0
4263                     || mobileBytesBgRx > 0 || mobileBytesBgTx > 0 || wifiBytesBgRx > 0
4264                     || wifiBytesBgTx > 0
4265                     || mobilePacketsBgRx > 0 || mobilePacketsBgTx > 0 || wifiPacketsBgRx > 0
4266                     || wifiPacketsBgTx > 0) {
4267                 dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
4268                         wifiBytesRx, wifiBytesTx,
4269                         mobilePacketsRx, mobilePacketsTx,
4270                         wifiPacketsRx, wifiPacketsTx,
4271                         mobileActiveTime, mobileActiveCount,
4272                         btBytesRx, btBytesTx, mobileWakeup, wifiWakeup,
4273                         mobileBytesBgRx, mobileBytesBgTx, wifiBytesBgRx, wifiBytesBgTx,
4274                         mobilePacketsBgRx, mobilePacketsBgTx, wifiPacketsBgRx, wifiPacketsBgTx
4275                         );
4276             }
4277 
4278             // Dump modem controller data, per UID.
4279             dumpControllerActivityLine(pw, uid, category, MODEM_CONTROLLER_DATA,
4280                     u.getModemControllerActivity(), which);
4281 
4282             // Dump Wifi controller data, per UID.
4283             final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
4284             final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
4285             final int wifiScanCount = u.getWifiScanCount(which);
4286             final int wifiScanCountBg = u.getWifiScanBackgroundCount(which);
4287             // Note that 'ActualTime' are unpooled and always since reset (regardless of 'which')
4288             final long wifiScanActualTimeMs = (u.getWifiScanActualTime(rawRealtime) + 500) / 1000;
4289             final long wifiScanActualTimeMsBg = (u.getWifiScanBackgroundTime(rawRealtime) + 500)
4290                     / 1000;
4291             final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
4292             if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
4293                     || wifiScanCountBg != 0 || wifiScanActualTimeMs != 0
4294                     || wifiScanActualTimeMsBg != 0 || uidWifiRunningTime != 0) {
4295                 dumpLine(pw, uid, category, WIFI_DATA, fullWifiLockOnTime, wifiScanTime,
4296                         uidWifiRunningTime, wifiScanCount,
4297                         /* legacy fields follow, keep at 0 */ 0, 0, 0,
4298                         wifiScanCountBg, wifiScanActualTimeMs, wifiScanActualTimeMsBg);
4299             }
4300 
4301             dumpControllerActivityLine(pw, uid, category, WIFI_CONTROLLER_DATA,
4302                     u.getWifiControllerActivity(), which);
4303 
4304             final Timer bleTimer = u.getBluetoothScanTimer();
4305             if (bleTimer != null) {
4306                 // Convert from microseconds to milliseconds with rounding
4307                 final long totalTime = (bleTimer.getTotalTimeLocked(rawRealtime, which) + 500)
4308                         / 1000;
4309                 if (totalTime != 0) {
4310                     final int count = bleTimer.getCountLocked(which);
4311                     final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
4312                     final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
4313                     // 'actualTime' are unpooled and always since reset (regardless of 'which')
4314                     final long actualTime = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
4315                     final long actualTimeBg = bleTimerBg != null ?
4316                             bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4317                     // Result counters
4318                     final int resultCount = u.getBluetoothScanResultCounter() != null ?
4319                             u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
4320                     final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
4321                             u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
4322                     // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
4323                     final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
4324                     final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
4325                             unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4326                     final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
4327                             unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
4328                     // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
4329                     final Timer unoptimizedScanTimerBg =
4330                             u.getBluetoothUnoptimizedScanBackgroundTimer();
4331                     final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
4332                             unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4333                     final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
4334                             unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
4335 
4336                     dumpLine(pw, uid, category, BLUETOOTH_MISC_DATA, totalTime, count,
4337                             countBg, actualTime, actualTimeBg, resultCount, resultCountBg,
4338                             unoptimizedScanTotalTime, unoptimizedScanTotalTimeBg,
4339                             unoptimizedScanMaxTime, unoptimizedScanMaxTimeBg);
4340                 }
4341             }
4342 
4343             dumpControllerActivityLine(pw, uid, category, BLUETOOTH_CONTROLLER_DATA,
4344                     u.getBluetoothControllerActivity(), which);
4345 
4346             if (u.hasUserActivity()) {
4347                 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
4348                 boolean hasData = false;
4349                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
4350                     int val = u.getUserActivityCount(i, which);
4351                     args[i] = val;
4352                     if (val != 0) hasData = true;
4353                 }
4354                 if (hasData) {
4355                     dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args);
4356                 }
4357             }
4358 
4359             if (u.getAggregatedPartialWakelockTimer() != null) {
4360                 final Timer timer = u.getAggregatedPartialWakelockTimer();
4361                 // Times are since reset (regardless of 'which')
4362                 final long totTimeMs = timer.getTotalDurationMsLocked(rawRealtimeMs);
4363                 final Timer bgTimer = timer.getSubTimer();
4364                 final long bgTimeMs = bgTimer != null ?
4365                         bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4366                 dumpLine(pw, uid, category, AGGREGATED_WAKELOCK_DATA, totTimeMs, bgTimeMs);
4367             }
4368 
4369             final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
4370             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
4371                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
4372                 String linePrefix = "";
4373                 sb.setLength(0);
4374                 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
4375                         rawRealtime, "f", which, linePrefix);
4376                 final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
4377                 linePrefix = printWakeLockCheckin(sb, pTimer,
4378                         rawRealtime, "p", which, linePrefix);
4379                 linePrefix = printWakeLockCheckin(sb, pTimer != null ? pTimer.getSubTimer() : null,
4380                         rawRealtime, "bp", which, linePrefix);
4381                 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
4382                         rawRealtime, "w", which, linePrefix);
4383 
4384                 // Only log if we had at least one wakelock...
4385                 if (sb.length() > 0) {
4386                     String name = wakelocks.keyAt(iw);
4387                     if (name.indexOf(',') >= 0) {
4388                         name = name.replace(',', '_');
4389                     }
4390                     if (name.indexOf('\n') >= 0) {
4391                         name = name.replace('\n', '_');
4392                     }
4393                     if (name.indexOf('\r') >= 0) {
4394                         name = name.replace('\r', '_');
4395                     }
4396                     dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
4397                 }
4398             }
4399 
4400             // WiFi Multicast Wakelock Statistics
4401             final Timer mcTimer = u.getMulticastWakelockStats();
4402             if (mcTimer != null) {
4403                 final long totalMcWakelockTimeMs =
4404                         mcTimer.getTotalTimeLocked(rawRealtime, which) / 1000 ;
4405                 final int countMcWakelock = mcTimer.getCountLocked(which);
4406                 if(totalMcWakelockTimeMs > 0) {
4407                     dumpLine(pw, uid, category, WIFI_MULTICAST_DATA,
4408                             totalMcWakelockTimeMs, countMcWakelock);
4409                 }
4410             }
4411 
4412             final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
4413             for (int isy=syncs.size()-1; isy>=0; isy--) {
4414                 final Timer timer = syncs.valueAt(isy);
4415                 // Convert from microseconds to milliseconds with rounding
4416                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
4417                 final int count = timer.getCountLocked(which);
4418                 final Timer bgTimer = timer.getSubTimer();
4419                 final long bgTime = bgTimer != null ?
4420                         bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
4421                 final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
4422                 if (totalTime != 0) {
4423                     dumpLine(pw, uid, category, SYNC_DATA, "\"" + syncs.keyAt(isy) + "\"",
4424                             totalTime, count, bgTime, bgCount);
4425                 }
4426             }
4427 
4428             final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
4429             for (int ij=jobs.size()-1; ij>=0; ij--) {
4430                 final Timer timer = jobs.valueAt(ij);
4431                 // Convert from microseconds to milliseconds with rounding
4432                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
4433                 final int count = timer.getCountLocked(which);
4434                 final Timer bgTimer = timer.getSubTimer();
4435                 final long bgTime = bgTimer != null ?
4436                         bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
4437                 final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
4438                 if (totalTime != 0) {
4439                     dumpLine(pw, uid, category, JOB_DATA, "\"" + jobs.keyAt(ij) + "\"",
4440                             totalTime, count, bgTime, bgCount);
4441                 }
4442             }
4443 
4444             final int[] jobStopReasonCodes = JobParameters.getJobStopReasonCodes();
4445             final Object[] jobCompletionArgs = new Object[jobStopReasonCodes.length + 1];
4446 
4447             final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
4448             for (int ic=completions.size()-1; ic>=0; ic--) {
4449                 SparseIntArray types = completions.valueAt(ic);
4450                 if (types != null) {
4451                     jobCompletionArgs[0] = "\"" + completions.keyAt(ic) + "\"";
4452                     for (int i = 0; i < jobStopReasonCodes.length; i++) {
4453                         jobCompletionArgs[i + 1] = types.get(jobStopReasonCodes[i], 0);
4454                     }
4455 
4456                     dumpLine(pw, uid, category, JOB_COMPLETION_DATA, jobCompletionArgs);
4457                 }
4458             }
4459 
4460             // Dump deferred jobs stats
4461             u.getDeferredJobsCheckinLineLocked(sb, which);
4462             if (sb.length() > 0) {
4463                 dumpLine(pw, uid, category, JOBS_DEFERRED_DATA, sb.toString());
4464             }
4465 
4466             dumpTimer(pw, uid, category, FLASHLIGHT_DATA, u.getFlashlightTurnedOnTimer(),
4467                     rawRealtime, which);
4468             dumpTimer(pw, uid, category, CAMERA_DATA, u.getCameraTurnedOnTimer(),
4469                     rawRealtime, which);
4470             dumpTimer(pw, uid, category, VIDEO_DATA, u.getVideoTurnedOnTimer(),
4471                     rawRealtime, which);
4472             dumpTimer(pw, uid, category, AUDIO_DATA, u.getAudioTurnedOnTimer(),
4473                     rawRealtime, which);
4474 
4475             final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
4476             final int NSE = sensors.size();
4477             for (int ise=0; ise<NSE; ise++) {
4478                 final Uid.Sensor se = sensors.valueAt(ise);
4479                 final int sensorNumber = sensors.keyAt(ise);
4480                 final Timer timer = se.getSensorTime();
4481                 if (timer != null) {
4482                     // Convert from microseconds to milliseconds with rounding
4483                     final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
4484                             / 1000;
4485                     if (totalTime != 0) {
4486                         final int count = timer.getCountLocked(which);
4487                         final Timer bgTimer = se.getSensorBackgroundTime();
4488                         final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
4489                         // 'actualTime' are unpooled and always since reset (regardless of 'which')
4490                         final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
4491                         final long bgActualTime = bgTimer != null ?
4492                                 bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4493                         dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime,
4494                                 count, bgCount, actualTime, bgActualTime);
4495                     }
4496                 }
4497             }
4498 
4499             dumpTimer(pw, uid, category, VIBRATOR_DATA, u.getVibratorOnTimer(),
4500                     rawRealtime, which);
4501 
4502             dumpTimer(pw, uid, category, FOREGROUND_ACTIVITY_DATA, u.getForegroundActivityTimer(),
4503                     rawRealtime, which);
4504 
4505             dumpTimer(pw, uid, category, FOREGROUND_SERVICE_DATA, u.getForegroundServiceTimer(),
4506                     rawRealtime, which);
4507 
4508             final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
4509             long totalStateTime = 0;
4510             for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
4511                 final long time = u.getProcessStateTime(ips, rawRealtime, which);
4512                 totalStateTime += time;
4513                 stateTimes[ips] = (time + 500) / 1000;
4514             }
4515             if (totalStateTime > 0) {
4516                 dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
4517             }
4518 
4519             final long userCpuTimeUs = u.getUserCpuTimeUs(which);
4520             final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
4521             if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
4522                 dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000,
4523                         0 /* old cpu power, keep for compatibility */);
4524             }
4525 
4526             // If the cpuFreqs is null, then don't bother checking for cpu freq times.
4527             if (cpuFreqs != null) {
4528                 final long[] cpuFreqTimeMs = u.getCpuFreqTimes(which);
4529                 // If total cpuFreqTimes is null, then we don't need to check for
4530                 // screenOffCpuFreqTimes.
4531                 if (cpuFreqTimeMs != null && cpuFreqTimeMs.length == cpuFreqs.length) {
4532                     sb.setLength(0);
4533                     for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
4534                         if (i != 0) sb.append(',');
4535                         sb.append(cpuFreqTimeMs[i]);
4536                     }
4537                     final long[] screenOffCpuFreqTimeMs = u.getScreenOffCpuFreqTimes(which);
4538                     if (screenOffCpuFreqTimeMs != null) {
4539                         for (int i = 0; i < screenOffCpuFreqTimeMs.length; ++i) {
4540                             sb.append(',').append(screenOffCpuFreqTimeMs[i]);
4541                         }
4542                     } else {
4543                         for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
4544                             sb.append(",0");
4545                         }
4546                     }
4547                     dumpLine(pw, uid, category, CPU_TIMES_AT_FREQ_DATA, UID_TIMES_TYPE_ALL,
4548                             cpuFreqTimeMs.length, sb.toString());
4549                 }
4550 
4551                 for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
4552                     final long[] timesMs = u.getCpuFreqTimes(which, procState);
4553                     if (timesMs != null && timesMs.length == cpuFreqs.length) {
4554                         sb.setLength(0);
4555                         for (int i = 0; i < timesMs.length; ++i) {
4556                             if (i != 0) sb.append(',');
4557                             sb.append(timesMs[i]);
4558                         }
4559                         final long[] screenOffTimesMs = u.getScreenOffCpuFreqTimes(
4560                                 which, procState);
4561                         if (screenOffTimesMs != null) {
4562                             for (int i = 0; i < screenOffTimesMs.length; ++i) {
4563                                 sb.append(',').append(screenOffTimesMs[i]);
4564                             }
4565                         } else {
4566                             for (int i = 0; i < timesMs.length; ++i) {
4567                                 sb.append(",0");
4568                             }
4569                         }
4570                         dumpLine(pw, uid, category, CPU_TIMES_AT_FREQ_DATA,
4571                                 Uid.UID_PROCESS_TYPES[procState], timesMs.length, sb.toString());
4572                     }
4573                 }
4574             }
4575 
4576             final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
4577                     = u.getProcessStats();
4578             for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
4579                 final Uid.Proc ps = processStats.valueAt(ipr);
4580 
4581                 final long userMillis = ps.getUserTime(which);
4582                 final long systemMillis = ps.getSystemTime(which);
4583                 final long foregroundMillis = ps.getForegroundTime(which);
4584                 final int starts = ps.getStarts(which);
4585                 final int numCrashes = ps.getNumCrashes(which);
4586                 final int numAnrs = ps.getNumAnrs(which);
4587 
4588                 if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
4589                         || starts != 0 || numAnrs != 0 || numCrashes != 0) {
4590                     dumpLine(pw, uid, category, PROCESS_DATA, "\"" + processStats.keyAt(ipr) + "\"",
4591                             userMillis, systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
4592                 }
4593             }
4594 
4595             final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
4596                     = u.getPackageStats();
4597             for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
4598                 final Uid.Pkg ps = packageStats.valueAt(ipkg);
4599                 int wakeups = 0;
4600                 final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
4601                 for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
4602                     int count = alarms.valueAt(iwa).getCountLocked(which);
4603                     wakeups += count;
4604                     String name = alarms.keyAt(iwa).replace(',', '_');
4605                     dumpLine(pw, uid, category, WAKEUP_ALARM_DATA, name, count);
4606                 }
4607                 final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
4608                 for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
4609                     final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
4610                     final long startTime = ss.getStartTime(batteryUptime, which);
4611                     final int starts = ss.getStarts(which);
4612                     final int launches = ss.getLaunches(which);
4613                     if (startTime != 0 || starts != 0 || launches != 0) {
4614                         dumpLine(pw, uid, category, APK_DATA,
4615                                 wakeups, // wakeup alarms
4616                                 packageStats.keyAt(ipkg), // Apk
4617                                 serviceStats.keyAt(isvc), // service
4618                                 startTime / 1000, // time spent started, in ms
4619                                 starts,
4620                                 launches);
4621                     }
4622                 }
4623             }
4624         }
4625     }
4626 
4627     static final class TimerEntry {
4628         final String mName;
4629         final int mId;
4630         final BatteryStats.Timer mTimer;
4631         final long mTime;
TimerEntry(String name, int id, BatteryStats.Timer timer, long time)4632         TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
4633             mName = name;
4634             mId = id;
4635             mTimer = timer;
4636             mTime = time;
4637         }
4638     }
4639 
printmAh(PrintWriter printer, double power)4640     private void printmAh(PrintWriter printer, double power) {
4641         printer.print(BatteryStatsHelper.makemAh(power));
4642     }
4643 
printmAh(StringBuilder sb, double power)4644     private void printmAh(StringBuilder sb, double power) {
4645         sb.append(BatteryStatsHelper.makemAh(power));
4646     }
4647 
4648     /**
4649      * Temporary for settings.
4650      */
dumpLocked(Context context, PrintWriter pw, String prefix, int which, int reqUid)4651     public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which,
4652             int reqUid) {
4653         dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
4654     }
4655 
4656     @SuppressWarnings("unused")
dumpLocked(Context context, PrintWriter pw, String prefix, final int which, int reqUid, boolean wifiOnly)4657     public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
4658             int reqUid, boolean wifiOnly) {
4659 
4660         if (which != BatteryStats.STATS_SINCE_CHARGED) {
4661             pw.println("ERROR: BatteryStats.dump called for which type " + which
4662                     + " but only STATS_SINCE_CHARGED is supported");
4663             return;
4664         }
4665 
4666         final long rawUptime = SystemClock.uptimeMillis() * 1000;
4667         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
4668         final long rawRealtimeMs = (rawRealtime + 500) / 1000;
4669         final long batteryUptime = getBatteryUptime(rawUptime);
4670 
4671         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
4672         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
4673         final long totalRealtime = computeRealtime(rawRealtime, which);
4674         final long totalUptime = computeUptime(rawUptime, which);
4675         final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
4676         final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
4677                 which);
4678         final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
4679         final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
4680         final long screenDozeTime = getScreenDozeTime(rawRealtime, which);
4681 
4682         final StringBuilder sb = new StringBuilder(128);
4683 
4684         final SparseArray<? extends Uid> uidStats = getUidStats();
4685         final int NU = uidStats.size();
4686 
4687         final int estimatedBatteryCapacity = getEstimatedBatteryCapacity();
4688         if (estimatedBatteryCapacity > 0) {
4689             sb.setLength(0);
4690             sb.append(prefix);
4691                 sb.append("  Estimated battery capacity: ");
4692                 sb.append(BatteryStatsHelper.makemAh(estimatedBatteryCapacity));
4693                 sb.append(" mAh");
4694             pw.println(sb.toString());
4695         }
4696 
4697         final int lastLearnedBatteryCapacity = getLearnedBatteryCapacity();
4698         if (lastLearnedBatteryCapacity > 0) {
4699             sb.setLength(0);
4700             sb.append(prefix);
4701             sb.append("  Last learned battery capacity: ");
4702             sb.append(BatteryStatsHelper.makemAh(lastLearnedBatteryCapacity / 1000));
4703             sb.append(" mAh");
4704             pw.println(sb.toString());
4705         }
4706         final int minLearnedBatteryCapacity = getMinLearnedBatteryCapacity();
4707         if (minLearnedBatteryCapacity > 0) {
4708             sb.setLength(0);
4709             sb.append(prefix);
4710             sb.append("  Min learned battery capacity: ");
4711             sb.append(BatteryStatsHelper.makemAh(minLearnedBatteryCapacity / 1000));
4712             sb.append(" mAh");
4713             pw.println(sb.toString());
4714         }
4715         final int maxLearnedBatteryCapacity = getMaxLearnedBatteryCapacity();
4716         if (maxLearnedBatteryCapacity > 0) {
4717             sb.setLength(0);
4718             sb.append(prefix);
4719             sb.append("  Max learned battery capacity: ");
4720             sb.append(BatteryStatsHelper.makemAh(maxLearnedBatteryCapacity / 1000));
4721             sb.append(" mAh");
4722             pw.println(sb.toString());
4723         }
4724 
4725         sb.setLength(0);
4726         sb.append(prefix);
4727         sb.append("  Time on battery: ");
4728         formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
4729         sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
4730         sb.append(") realtime, ");
4731         formatTimeMs(sb, whichBatteryUptime / 1000);
4732         sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, whichBatteryRealtime));
4733         sb.append(") uptime");
4734         pw.println(sb.toString());
4735 
4736         sb.setLength(0);
4737         sb.append(prefix);
4738         sb.append("  Time on battery screen off: ");
4739         formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("(");
4740         sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, whichBatteryRealtime));
4741         sb.append(") realtime, ");
4742         formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
4743         sb.append("(");
4744         sb.append(formatRatioLocked(whichBatteryScreenOffUptime, whichBatteryRealtime));
4745         sb.append(") uptime");
4746         pw.println(sb.toString());
4747 
4748         sb.setLength(0);
4749         sb.append(prefix);
4750         sb.append("  Time on battery screen doze: ");
4751         formatTimeMs(sb, screenDozeTime / 1000); sb.append("(");
4752         sb.append(formatRatioLocked(screenDozeTime, whichBatteryRealtime));
4753         sb.append(")");
4754         pw.println(sb.toString());
4755 
4756         sb.setLength(0);
4757         sb.append(prefix);
4758                 sb.append("  Total run time: ");
4759                 formatTimeMs(sb, totalRealtime / 1000);
4760                 sb.append("realtime, ");
4761                 formatTimeMs(sb, totalUptime / 1000);
4762                 sb.append("uptime");
4763         pw.println(sb.toString());
4764         if (batteryTimeRemaining >= 0) {
4765             sb.setLength(0);
4766             sb.append(prefix);
4767                     sb.append("  Battery time remaining: ");
4768                     formatTimeMs(sb, batteryTimeRemaining / 1000);
4769             pw.println(sb.toString());
4770         }
4771         if (chargeTimeRemaining >= 0) {
4772             sb.setLength(0);
4773             sb.append(prefix);
4774                     sb.append("  Charge time remaining: ");
4775                     formatTimeMs(sb, chargeTimeRemaining / 1000);
4776             pw.println(sb.toString());
4777         }
4778 
4779         final long dischargeCount = getUahDischarge(which);
4780         if (dischargeCount >= 0) {
4781             sb.setLength(0);
4782             sb.append(prefix);
4783                 sb.append("  Discharge: ");
4784                 sb.append(BatteryStatsHelper.makemAh(dischargeCount / 1000.0));
4785                 sb.append(" mAh");
4786             pw.println(sb.toString());
4787         }
4788 
4789         final long dischargeScreenOffCount = getUahDischargeScreenOff(which);
4790         if (dischargeScreenOffCount >= 0) {
4791             sb.setLength(0);
4792             sb.append(prefix);
4793                 sb.append("  Screen off discharge: ");
4794                 sb.append(BatteryStatsHelper.makemAh(dischargeScreenOffCount / 1000.0));
4795                 sb.append(" mAh");
4796             pw.println(sb.toString());
4797         }
4798 
4799         final long dischargeScreenDozeCount = getUahDischargeScreenDoze(which);
4800         if (dischargeScreenDozeCount >= 0) {
4801             sb.setLength(0);
4802             sb.append(prefix);
4803             sb.append("  Screen doze discharge: ");
4804             sb.append(BatteryStatsHelper.makemAh(dischargeScreenDozeCount / 1000.0));
4805             sb.append(" mAh");
4806             pw.println(sb.toString());
4807         }
4808 
4809         final long dischargeScreenOnCount = dischargeCount - dischargeScreenOffCount;
4810         if (dischargeScreenOnCount >= 0) {
4811             sb.setLength(0);
4812             sb.append(prefix);
4813                 sb.append("  Screen on discharge: ");
4814                 sb.append(BatteryStatsHelper.makemAh(dischargeScreenOnCount / 1000.0));
4815                 sb.append(" mAh");
4816             pw.println(sb.toString());
4817         }
4818 
4819         final long dischargeLightDozeCount = getUahDischargeLightDoze(which);
4820         if (dischargeLightDozeCount >= 0) {
4821             sb.setLength(0);
4822             sb.append(prefix);
4823             sb.append("  Device light doze discharge: ");
4824             sb.append(BatteryStatsHelper.makemAh(dischargeLightDozeCount / 1000.0));
4825             sb.append(" mAh");
4826             pw.println(sb.toString());
4827         }
4828 
4829         final long dischargeDeepDozeCount = getUahDischargeDeepDoze(which);
4830         if (dischargeDeepDozeCount >= 0) {
4831             sb.setLength(0);
4832             sb.append(prefix);
4833             sb.append("  Device deep doze discharge: ");
4834             sb.append(BatteryStatsHelper.makemAh(dischargeDeepDozeCount / 1000.0));
4835             sb.append(" mAh");
4836             pw.println(sb.toString());
4837         }
4838 
4839         pw.print("  Start clock time: ");
4840         pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
4841 
4842         final long screenOnTime = getScreenOnTime(rawRealtime, which);
4843         final long interactiveTime = getInteractiveTime(rawRealtime, which);
4844         final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
4845         final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT,
4846                 rawRealtime, which);
4847         final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP,
4848                 rawRealtime, which);
4849         final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT,
4850                 rawRealtime, which);
4851         final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP,
4852                 rawRealtime, which);
4853         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
4854         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
4855         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
4856         sb.setLength(0);
4857         sb.append(prefix);
4858                 sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
4859                 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
4860                 sb.append(") "); sb.append(getScreenOnCount(which));
4861                 sb.append("x, Interactive: "); formatTimeMs(sb, interactiveTime / 1000);
4862                 sb.append("("); sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime));
4863                 sb.append(")");
4864         pw.println(sb.toString());
4865         sb.setLength(0);
4866         sb.append(prefix);
4867         sb.append("  Screen brightnesses:");
4868         boolean didOne = false;
4869         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4870             final long time = getScreenBrightnessTime(i, rawRealtime, which);
4871             if (time == 0) {
4872                 continue;
4873             }
4874             sb.append("\n    ");
4875             sb.append(prefix);
4876             didOne = true;
4877             sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
4878             sb.append(" ");
4879             formatTimeMs(sb, time/1000);
4880             sb.append("(");
4881             sb.append(formatRatioLocked(time, screenOnTime));
4882             sb.append(")");
4883         }
4884         if (!didOne) sb.append(" (no activity)");
4885         pw.println(sb.toString());
4886         if (powerSaveModeEnabledTime != 0) {
4887             sb.setLength(0);
4888             sb.append(prefix);
4889                     sb.append("  Power save mode enabled: ");
4890                     formatTimeMs(sb, powerSaveModeEnabledTime / 1000);
4891                     sb.append("(");
4892                     sb.append(formatRatioLocked(powerSaveModeEnabledTime, whichBatteryRealtime));
4893                     sb.append(")");
4894             pw.println(sb.toString());
4895         }
4896         if (deviceLightIdlingTime != 0) {
4897             sb.setLength(0);
4898             sb.append(prefix);
4899                     sb.append("  Device light idling: ");
4900                     formatTimeMs(sb, deviceLightIdlingTime / 1000);
4901                     sb.append("(");
4902                     sb.append(formatRatioLocked(deviceLightIdlingTime, whichBatteryRealtime));
4903                     sb.append(") "); sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which));
4904                     sb.append("x");
4905             pw.println(sb.toString());
4906         }
4907         if (deviceIdleModeLightTime != 0) {
4908             sb.setLength(0);
4909             sb.append(prefix);
4910                     sb.append("  Idle mode light time: ");
4911                     formatTimeMs(sb, deviceIdleModeLightTime / 1000);
4912                     sb.append("(");
4913                     sb.append(formatRatioLocked(deviceIdleModeLightTime, whichBatteryRealtime));
4914                     sb.append(") ");
4915                     sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which));
4916                     sb.append("x");
4917                     sb.append(" -- longest ");
4918                     formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
4919             pw.println(sb.toString());
4920         }
4921         if (deviceIdlingTime != 0) {
4922             sb.setLength(0);
4923             sb.append(prefix);
4924                     sb.append("  Device full idling: ");
4925                     formatTimeMs(sb, deviceIdlingTime / 1000);
4926                     sb.append("(");
4927                     sb.append(formatRatioLocked(deviceIdlingTime, whichBatteryRealtime));
4928                     sb.append(") "); sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which));
4929                     sb.append("x");
4930             pw.println(sb.toString());
4931         }
4932         if (deviceIdleModeFullTime != 0) {
4933             sb.setLength(0);
4934             sb.append(prefix);
4935                     sb.append("  Idle mode full time: ");
4936                     formatTimeMs(sb, deviceIdleModeFullTime / 1000);
4937                     sb.append("(");
4938                     sb.append(formatRatioLocked(deviceIdleModeFullTime, whichBatteryRealtime));
4939                     sb.append(") ");
4940                     sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which));
4941                     sb.append("x");
4942                     sb.append(" -- longest ");
4943                     formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
4944             pw.println(sb.toString());
4945         }
4946         if (phoneOnTime != 0) {
4947             sb.setLength(0);
4948             sb.append(prefix);
4949                     sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
4950                     sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
4951                     sb.append(") "); sb.append(getPhoneOnCount(which)); sb.append("x");
4952         }
4953         final int connChanges = getNumConnectivityChange(which);
4954         if (connChanges != 0) {
4955             pw.print(prefix);
4956             pw.print("  Connectivity changes: "); pw.println(connChanges);
4957         }
4958 
4959         // Calculate wakelock times across all uids.
4960         long fullWakeLockTimeTotalMicros = 0;
4961         long partialWakeLockTimeTotalMicros = 0;
4962 
4963         final ArrayList<TimerEntry> timers = new ArrayList<>();
4964 
4965         for (int iu = 0; iu < NU; iu++) {
4966             final Uid u = uidStats.valueAt(iu);
4967 
4968             final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
4969                     = u.getWakelockStats();
4970             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
4971                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
4972 
4973                 final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
4974                 if (fullWakeTimer != null) {
4975                     fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
4976                             rawRealtime, which);
4977                 }
4978 
4979                 final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
4980                 if (partialWakeTimer != null) {
4981                     final long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
4982                             rawRealtime, which);
4983                     if (totalTimeMicros > 0) {
4984                         if (reqUid < 0) {
4985                             // Only show the ordered list of all wake
4986                             // locks if the caller is not asking for data
4987                             // about a specific uid.
4988                             timers.add(new TimerEntry(wakelocks.keyAt(iw), u.getUid(),
4989                                     partialWakeTimer, totalTimeMicros));
4990                         }
4991                         partialWakeLockTimeTotalMicros += totalTimeMicros;
4992                     }
4993                 }
4994             }
4995         }
4996 
4997         final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
4998         final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
4999         final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
5000         final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
5001         final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
5002         final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
5003         final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
5004         final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
5005         final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
5006         final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
5007 
5008         if (fullWakeLockTimeTotalMicros != 0) {
5009             sb.setLength(0);
5010             sb.append(prefix);
5011                     sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
5012                             (fullWakeLockTimeTotalMicros + 500) / 1000);
5013             pw.println(sb.toString());
5014         }
5015 
5016         if (partialWakeLockTimeTotalMicros != 0) {
5017             sb.setLength(0);
5018             sb.append(prefix);
5019                     sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
5020                             (partialWakeLockTimeTotalMicros + 500) / 1000);
5021             pw.println(sb.toString());
5022         }
5023 
5024         final long multicastWakeLockTimeTotalMicros =
5025                 getWifiMulticastWakelockTime(rawRealtime, which);
5026         final int multicastWakeLockCountTotal = getWifiMulticastWakelockCount(which);
5027         if (multicastWakeLockTimeTotalMicros != 0) {
5028             sb.setLength(0);
5029             sb.append(prefix);
5030             sb.append("  Total WiFi Multicast wakelock Count: ");
5031             sb.append(multicastWakeLockCountTotal);
5032             pw.println(sb.toString());
5033 
5034             sb.setLength(0);
5035             sb.append(prefix);
5036             sb.append("  Total WiFi Multicast wakelock time: ");
5037             formatTimeMsNoSpace(sb, (multicastWakeLockTimeTotalMicros + 500) / 1000);
5038             pw.println(sb.toString());
5039         }
5040 
5041         pw.println("");
5042         pw.print(prefix);
5043         sb.setLength(0);
5044         sb.append(prefix);
5045         sb.append("  CONNECTIVITY POWER SUMMARY START");
5046         pw.println(sb.toString());
5047 
5048         pw.print(prefix);
5049         sb.setLength(0);
5050         sb.append(prefix);
5051         sb.append("  Logging duration for connectivity statistics: ");
5052         formatTimeMs(sb, whichBatteryRealtime / 1000);
5053         pw.println(sb.toString());
5054 
5055         sb.setLength(0);
5056         sb.append(prefix);
5057         sb.append("  Cellular Statistics:");
5058         pw.println(sb.toString());
5059 
5060         pw.print(prefix);
5061         sb.setLength(0);
5062         sb.append(prefix);
5063         sb.append("     Cellular kernel active time: ");
5064         final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
5065         formatTimeMs(sb, mobileActiveTime / 1000);
5066         sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
5067         sb.append(")");
5068         pw.println(sb.toString());
5069 
5070         printControllerActivity(pw, sb, prefix, CELLULAR_CONTROLLER_NAME,
5071                 getModemControllerActivity(), which);
5072 
5073         pw.print("     Cellular data received: "); pw.println(formatBytesLocked(mobileRxTotalBytes));
5074         pw.print("     Cellular data sent: "); pw.println(formatBytesLocked(mobileTxTotalBytes));
5075         pw.print("     Cellular packets received: "); pw.println(mobileRxTotalPackets);
5076         pw.print("     Cellular packets sent: "); pw.println(mobileTxTotalPackets);
5077 
5078         sb.setLength(0);
5079         sb.append(prefix);
5080         sb.append("     Cellular Radio Access Technology:");
5081         didOne = false;
5082         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5083             final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
5084             if (time == 0) {
5085                 continue;
5086             }
5087             sb.append("\n       ");
5088             sb.append(prefix);
5089             didOne = true;
5090             sb.append(i < DATA_CONNECTION_NAMES.length ? DATA_CONNECTION_NAMES[i] : "ERROR");
5091             sb.append(" ");
5092             formatTimeMs(sb, time/1000);
5093             sb.append("(");
5094             sb.append(formatRatioLocked(time, whichBatteryRealtime));
5095             sb.append(") ");
5096         }
5097         if (!didOne) sb.append(" (no activity)");
5098         pw.println(sb.toString());
5099 
5100         sb.setLength(0);
5101         sb.append(prefix);
5102         sb.append("     Cellular Rx signal strength (RSRP):");
5103         final String[] cellularRxSignalStrengthDescription = new String[]{
5104             "very poor (less than -128dBm): ",
5105             "poor (-128dBm to -118dBm): ",
5106             "moderate (-118dBm to -108dBm): ",
5107             "good (-108dBm to -98dBm): ",
5108             "great (greater than -98dBm): "};
5109         didOne = false;
5110         final int numCellularRxBins = Math.min(CellSignalStrength.getNumSignalStrengthLevels(),
5111             cellularRxSignalStrengthDescription.length);
5112         for (int i=0; i<numCellularRxBins; i++) {
5113             final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
5114             if (time == 0) {
5115                 continue;
5116             }
5117             sb.append("\n       ");
5118             sb.append(prefix);
5119             didOne = true;
5120             sb.append(cellularRxSignalStrengthDescription[i]);
5121             sb.append(" ");
5122             formatTimeMs(sb, time/1000);
5123             sb.append("(");
5124             sb.append(formatRatioLocked(time, whichBatteryRealtime));
5125             sb.append(") ");
5126         }
5127         if (!didOne) sb.append(" (no activity)");
5128         pw.println(sb.toString());
5129 
5130         pw.print(prefix);
5131         sb.setLength(0);
5132         sb.append(prefix);
5133         sb.append("  Wifi Statistics:");
5134         pw.println(sb.toString());
5135 
5136         pw.print(prefix);
5137         sb.setLength(0);
5138         sb.append(prefix);
5139         sb.append("     Wifi kernel active time: ");
5140         final long wifiActiveTime = getWifiActiveTime(rawRealtime, which);
5141         formatTimeMs(sb, wifiActiveTime / 1000);
5142         sb.append("("); sb.append(formatRatioLocked(wifiActiveTime, whichBatteryRealtime));
5143         sb.append(")");
5144         pw.println(sb.toString());
5145 
5146         printControllerActivity(pw, sb, prefix, WIFI_CONTROLLER_NAME,
5147                 getWifiControllerActivity(), which);
5148 
5149         pw.print("     Wifi data received: "); pw.println(formatBytesLocked(wifiRxTotalBytes));
5150         pw.print("     Wifi data sent: "); pw.println(formatBytesLocked(wifiTxTotalBytes));
5151         pw.print("     Wifi packets received: "); pw.println(wifiRxTotalPackets);
5152         pw.print("     Wifi packets sent: "); pw.println(wifiTxTotalPackets);
5153 
5154         sb.setLength(0);
5155         sb.append(prefix);
5156         sb.append("     Wifi states:");
5157         didOne = false;
5158         for (int i=0; i<NUM_WIFI_STATES; i++) {
5159             final long time = getWifiStateTime(i, rawRealtime, which);
5160             if (time == 0) {
5161                 continue;
5162             }
5163             sb.append("\n       ");
5164             didOne = true;
5165             sb.append(WIFI_STATE_NAMES[i]);
5166             sb.append(" ");
5167             formatTimeMs(sb, time/1000);
5168             sb.append("(");
5169             sb.append(formatRatioLocked(time, whichBatteryRealtime));
5170             sb.append(") ");
5171         }
5172         if (!didOne) sb.append(" (no activity)");
5173         pw.println(sb.toString());
5174 
5175         sb.setLength(0);
5176         sb.append(prefix);
5177         sb.append("     Wifi supplicant states:");
5178         didOne = false;
5179         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
5180             final long time = getWifiSupplStateTime(i, rawRealtime, which);
5181             if (time == 0) {
5182                 continue;
5183             }
5184             sb.append("\n       ");
5185             didOne = true;
5186             sb.append(WIFI_SUPPL_STATE_NAMES[i]);
5187             sb.append(" ");
5188             formatTimeMs(sb, time/1000);
5189             sb.append("(");
5190             sb.append(formatRatioLocked(time, whichBatteryRealtime));
5191             sb.append(") ");
5192         }
5193         if (!didOne) sb.append(" (no activity)");
5194         pw.println(sb.toString());
5195 
5196         sb.setLength(0);
5197         sb.append(prefix);
5198         sb.append("     Wifi Rx signal strength (RSSI):");
5199         final String[] wifiRxSignalStrengthDescription = new String[]{
5200             "very poor (less than -88.75dBm): ",
5201             "poor (-88.75 to -77.5dBm): ",
5202             "moderate (-77.5dBm to -66.25dBm): ",
5203             "good (-66.25dBm to -55dBm): ",
5204             "great (greater than -55dBm): "};
5205         didOne = false;
5206         final int numWifiRxBins = Math.min(NUM_WIFI_SIGNAL_STRENGTH_BINS,
5207             wifiRxSignalStrengthDescription.length);
5208         for (int i=0; i<numWifiRxBins; i++) {
5209             final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
5210             if (time == 0) {
5211                 continue;
5212             }
5213             sb.append("\n    ");
5214             sb.append(prefix);
5215             didOne = true;
5216             sb.append("     ");
5217             sb.append(wifiRxSignalStrengthDescription[i]);
5218             formatTimeMs(sb, time/1000);
5219             sb.append("(");
5220             sb.append(formatRatioLocked(time, whichBatteryRealtime));
5221             sb.append(") ");
5222         }
5223         if (!didOne) sb.append(" (no activity)");
5224         pw.println(sb.toString());
5225 
5226         pw.print(prefix);
5227         sb.setLength(0);
5228         sb.append(prefix);
5229         sb.append("  GPS Statistics:");
5230         pw.println(sb.toString());
5231 
5232         sb.setLength(0);
5233         sb.append(prefix);
5234         sb.append("     GPS signal quality (Top 4 Average CN0):");
5235         final String[] gpsSignalQualityDescription = new String[]{
5236             "poor (less than 20 dBHz): ",
5237             "good (greater than 20 dBHz): "};
5238         final int numGpsSignalQualityBins = Math.min(
5239                 GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS,
5240                 gpsSignalQualityDescription.length);
5241         for (int i=0; i<numGpsSignalQualityBins; i++) {
5242             final long time = getGpsSignalQualityTime(i, rawRealtime, which);
5243             sb.append("\n    ");
5244             sb.append(prefix);
5245             sb.append("  ");
5246             sb.append(gpsSignalQualityDescription[i]);
5247             formatTimeMs(sb, time/1000);
5248             sb.append("(");
5249             sb.append(formatRatioLocked(time, whichBatteryRealtime));
5250             sb.append(") ");
5251         }
5252         pw.println(sb.toString());
5253 
5254         final long gpsBatteryDrainMaMs = getGpsBatteryDrainMaMs();
5255         if (gpsBatteryDrainMaMs > 0) {
5256             pw.print(prefix);
5257             sb.setLength(0);
5258             sb.append(prefix);
5259             sb.append("     GPS Battery Drain: ");
5260             sb.append(new DecimalFormat("#.##").format(
5261                     ((double) gpsBatteryDrainMaMs) / (3600 * 1000)));
5262             sb.append("mAh");
5263             pw.println(sb.toString());
5264         }
5265 
5266         pw.print(prefix);
5267         sb.setLength(0);
5268         sb.append(prefix);
5269         sb.append("  CONNECTIVITY POWER SUMMARY END");
5270         pw.println(sb.toString());
5271         pw.println("");
5272 
5273         pw.print(prefix);
5274         pw.print("  Bluetooth total received: "); pw.print(formatBytesLocked(btRxTotalBytes));
5275         pw.print(", sent: "); pw.println(formatBytesLocked(btTxTotalBytes));
5276 
5277         final long bluetoothScanTimeMs = getBluetoothScanTime(rawRealtime, which) / 1000;
5278         sb.setLength(0);
5279         sb.append(prefix);
5280         sb.append("  Bluetooth scan time: "); formatTimeMs(sb, bluetoothScanTimeMs);
5281         pw.println(sb.toString());
5282 
5283         printControllerActivity(pw, sb, prefix, "Bluetooth", getBluetoothControllerActivity(),
5284                 which);
5285 
5286         pw.println();
5287 
5288         pw.print(prefix); pw.println("  Device battery use since last full charge");
5289         pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
5290         pw.println(getLowDischargeAmountSinceCharge());
5291         pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
5292         pw.println(getHighDischargeAmountSinceCharge());
5293         pw.print(prefix); pw.print("    Amount discharged while screen on: ");
5294         pw.println(getDischargeAmountScreenOnSinceCharge());
5295         pw.print(prefix); pw.print("    Amount discharged while screen off: ");
5296         pw.println(getDischargeAmountScreenOffSinceCharge());
5297         pw.print(prefix); pw.print("    Amount discharged while screen doze: ");
5298         pw.println(getDischargeAmountScreenDozeSinceCharge());
5299         pw.println();
5300 
5301         final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this);
5302         final BatteryUsageStats stats = provider.getBatteryUsageStats(
5303                 new BatteryUsageStatsQuery.Builder()
5304                         .setMaxStatsAgeMs(0)
5305                         .includePowerModels()
5306                         .build());
5307         stats.dump(pw, prefix);
5308 
5309         final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
5310         helper.create(this);
5311         helper.refreshStats(which, UserHandle.USER_ALL);
5312 
5313         final List<BatterySipper> sippers = helper.getMobilemsppList();
5314         if (sippers != null && sippers.size() > 0) {
5315             pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
5316             long totalTime = 0;
5317             for (int i=0; i<sippers.size(); i++) {
5318                 final BatterySipper bs = sippers.get(i);
5319                 sb.setLength(0);
5320                 sb.append(prefix); sb.append("    Uid ");
5321                 UserHandle.formatUid(sb, bs.uidObj.getUid());
5322                 sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
5323                 sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
5324                 sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
5325                 sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
5326                 pw.println(sb.toString());
5327                 totalTime += bs.mobileActive;
5328             }
5329             sb.setLength(0);
5330             sb.append(prefix);
5331             sb.append("    TOTAL TIME: ");
5332             formatTimeMs(sb, totalTime);
5333             sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
5334             sb.append(")");
5335             pw.println(sb.toString());
5336             pw.println();
5337         }
5338 
5339         final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
5340             @Override
5341             public int compare(TimerEntry lhs, TimerEntry rhs) {
5342                 long lhsTime = lhs.mTime;
5343                 long rhsTime = rhs.mTime;
5344                 if (lhsTime < rhsTime) {
5345                     return 1;
5346                 }
5347                 if (lhsTime > rhsTime) {
5348                     return -1;
5349                 }
5350                 return 0;
5351             }
5352         };
5353 
5354         if (reqUid < 0) {
5355             final Map<String, ? extends BatteryStats.Timer> kernelWakelocks
5356                     = getKernelWakelockStats();
5357             if (kernelWakelocks.size() > 0) {
5358                 final ArrayList<TimerEntry> ktimers = new ArrayList<>();
5359                 for (Map.Entry<String, ? extends BatteryStats.Timer> ent
5360                         : kernelWakelocks.entrySet()) {
5361                     final BatteryStats.Timer timer = ent.getValue();
5362                     final long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
5363                     if (totalTimeMillis > 0) {
5364                         ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
5365                     }
5366                 }
5367                 if (ktimers.size() > 0) {
5368                     Collections.sort(ktimers, timerComparator);
5369                     pw.print(prefix); pw.println("  All kernel wake locks:");
5370                     for (int i=0; i<ktimers.size(); i++) {
5371                         final TimerEntry timer = ktimers.get(i);
5372                         String linePrefix = ": ";
5373                         sb.setLength(0);
5374                         sb.append(prefix);
5375                         sb.append("  Kernel Wake lock ");
5376                         sb.append(timer.mName);
5377                         linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null,
5378                                 which, linePrefix);
5379                         if (!linePrefix.equals(": ")) {
5380                             sb.append(" realtime");
5381                             // Only print out wake locks that were held
5382                             pw.println(sb.toString());
5383                         }
5384                     }
5385                     pw.println();
5386                 }
5387             }
5388 
5389             if (timers.size() > 0) {
5390                 Collections.sort(timers, timerComparator);
5391                 pw.print(prefix); pw.println("  All partial wake locks:");
5392                 for (int i=0; i<timers.size(); i++) {
5393                     TimerEntry timer = timers.get(i);
5394                     sb.setLength(0);
5395                     sb.append("  Wake lock ");
5396                     UserHandle.formatUid(sb, timer.mId);
5397                     sb.append(" ");
5398                     sb.append(timer.mName);
5399                     printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
5400                     sb.append(" realtime");
5401                     pw.println(sb.toString());
5402                 }
5403                 timers.clear();
5404                 pw.println();
5405             }
5406 
5407             final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
5408             if (wakeupReasons.size() > 0) {
5409                 pw.print(prefix); pw.println("  All wakeup reasons:");
5410                 final ArrayList<TimerEntry> reasons = new ArrayList<>();
5411                 for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
5412                     final Timer timer = ent.getValue();
5413                     reasons.add(new TimerEntry(ent.getKey(), 0, timer,
5414                             timer.getCountLocked(which)));
5415                 }
5416                 Collections.sort(reasons, timerComparator);
5417                 for (int i=0; i<reasons.size(); i++) {
5418                     TimerEntry timer = reasons.get(i);
5419                     String linePrefix = ": ";
5420                     sb.setLength(0);
5421                     sb.append(prefix);
5422                     sb.append("  Wakeup reason ");
5423                     sb.append(timer.mName);
5424                     printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
5425                     sb.append(" realtime");
5426                     pw.println(sb.toString());
5427                 }
5428                 pw.println();
5429             }
5430         }
5431 
5432         final LongSparseArray<? extends Timer> mMemoryStats = getKernelMemoryStats();
5433         if (mMemoryStats.size() > 0) {
5434             pw.println("  Memory Stats");
5435             for (int i = 0; i < mMemoryStats.size(); i++) {
5436                 sb.setLength(0);
5437                 sb.append("  Bandwidth ");
5438                 sb.append(mMemoryStats.keyAt(i));
5439                 sb.append(" Time ");
5440                 sb.append(mMemoryStats.valueAt(i).getTotalTimeLocked(rawRealtime, which));
5441                 pw.println(sb.toString());
5442             }
5443             pw.println();
5444         }
5445 
5446         final Map<String, ? extends Timer> rpmStats = getRpmStats();
5447         if (rpmStats.size() > 0) {
5448             pw.print(prefix); pw.println("  Resource Power Manager Stats");
5449             if (rpmStats.size() > 0) {
5450                 for (Map.Entry<String, ? extends Timer> ent : rpmStats.entrySet()) {
5451                     final String timerName = ent.getKey();
5452                     final Timer timer = ent.getValue();
5453                     printTimer(pw, sb, timer, rawRealtime, which, prefix, timerName);
5454                 }
5455             }
5456             pw.println();
5457         }
5458         if (SCREEN_OFF_RPM_STATS_ENABLED) {
5459             final Map<String, ? extends Timer> screenOffRpmStats = getScreenOffRpmStats();
5460             if (screenOffRpmStats.size() > 0) {
5461                 pw.print(prefix);
5462                 pw.println("  Resource Power Manager Stats for when screen was off");
5463                 if (screenOffRpmStats.size() > 0) {
5464                     for (Map.Entry<String, ? extends Timer> ent : screenOffRpmStats.entrySet()) {
5465                         final String timerName = ent.getKey();
5466                         final Timer timer = ent.getValue();
5467                         printTimer(pw, sb, timer, rawRealtime, which, prefix, timerName);
5468                     }
5469                 }
5470                 pw.println();
5471             }
5472         }
5473 
5474         final long[] cpuFreqs = getCpuFreqs();
5475         if (cpuFreqs != null) {
5476             sb.setLength(0);
5477             sb.append("  CPU freqs:");
5478             for (int i = 0; i < cpuFreqs.length; ++i) {
5479                 sb.append(' ').append(cpuFreqs[i]);
5480             }
5481             pw.println(sb.toString());
5482             pw.println();
5483         }
5484 
5485         for (int iu=0; iu<NU; iu++) {
5486             final int uid = uidStats.keyAt(iu);
5487             if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
5488                 continue;
5489             }
5490 
5491             final Uid u = uidStats.valueAt(iu);
5492 
5493             pw.print(prefix);
5494             pw.print("  ");
5495             UserHandle.formatUid(pw, uid);
5496             pw.println(":");
5497             boolean uidActivity = false;
5498 
5499             final long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
5500             final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
5501             final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
5502             final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
5503             final long btRxBytes = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
5504             final long btTxBytes = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
5505 
5506             final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
5507             final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
5508             final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
5509             final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
5510 
5511             final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
5512             final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
5513 
5514             final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
5515             final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
5516             final int wifiScanCount = u.getWifiScanCount(which);
5517             final int wifiScanCountBg = u.getWifiScanBackgroundCount(which);
5518             // 'actualTime' are unpooled and always since reset (regardless of 'which')
5519             final long wifiScanActualTime = u.getWifiScanActualTime(rawRealtime);
5520             final long wifiScanActualTimeBg = u.getWifiScanBackgroundTime(rawRealtime);
5521             final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
5522 
5523             final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
5524             final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
5525 
5526             if (mobileRxBytes > 0 || mobileTxBytes > 0
5527                     || mobileRxPackets > 0 || mobileTxPackets > 0) {
5528                 pw.print(prefix); pw.print("    Mobile network: ");
5529                         pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
5530                         pw.print(formatBytesLocked(mobileTxBytes));
5531                         pw.print(" sent (packets "); pw.print(mobileRxPackets);
5532                         pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
5533             }
5534             if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
5535                 sb.setLength(0);
5536                 sb.append(prefix); sb.append("    Mobile radio active: ");
5537                 formatTimeMs(sb, uidMobileActiveTime / 1000);
5538                 sb.append("(");
5539                 sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
5540                 sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
5541                 long packets = mobileRxPackets + mobileTxPackets;
5542                 if (packets == 0) {
5543                     packets = 1;
5544                 }
5545                 sb.append(" @ ");
5546                 sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
5547                 sb.append(" mspp");
5548                 pw.println(sb.toString());
5549             }
5550 
5551             if (mobileWakeup > 0) {
5552                 sb.setLength(0);
5553                 sb.append(prefix);
5554                 sb.append("    Mobile radio AP wakeups: ");
5555                 sb.append(mobileWakeup);
5556                 pw.println(sb.toString());
5557             }
5558 
5559             printControllerActivityIfInteresting(pw, sb, prefix + "  ",
5560                 CELLULAR_CONTROLLER_NAME, u.getModemControllerActivity(), which);
5561 
5562             if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
5563                 pw.print(prefix); pw.print("    Wi-Fi network: ");
5564                         pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
5565                         pw.print(formatBytesLocked(wifiTxBytes));
5566                         pw.print(" sent (packets "); pw.print(wifiRxPackets);
5567                         pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
5568             }
5569 
5570             if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
5571                     || wifiScanCountBg != 0 || wifiScanActualTime != 0 || wifiScanActualTimeBg != 0
5572                     || uidWifiRunningTime != 0) {
5573                 sb.setLength(0);
5574                 sb.append(prefix); sb.append("    Wifi Running: ");
5575                         formatTimeMs(sb, uidWifiRunningTime / 1000);
5576                         sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
5577                                 whichBatteryRealtime)); sb.append(")\n");
5578                 sb.append(prefix); sb.append("    Full Wifi Lock: ");
5579                         formatTimeMs(sb, fullWifiLockOnTime / 1000);
5580                         sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
5581                                 whichBatteryRealtime)); sb.append(")\n");
5582                 sb.append(prefix); sb.append("    Wifi Scan (blamed): ");
5583                         formatTimeMs(sb, wifiScanTime / 1000);
5584                         sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
5585                                 whichBatteryRealtime)); sb.append(") ");
5586                                 sb.append(wifiScanCount);
5587                                 sb.append("x\n");
5588                 // actual and background times are unpooled and since reset (regardless of 'which')
5589                 sb.append(prefix); sb.append("    Wifi Scan (actual): ");
5590                         formatTimeMs(sb, wifiScanActualTime / 1000);
5591                         sb.append("("); sb.append(formatRatioLocked(wifiScanActualTime,
5592                                 computeBatteryRealtime(rawRealtime, STATS_SINCE_CHARGED)));
5593                                 sb.append(") ");
5594                                 sb.append(wifiScanCount);
5595                                 sb.append("x\n");
5596                 sb.append(prefix); sb.append("    Background Wifi Scan: ");
5597                         formatTimeMs(sb, wifiScanActualTimeBg / 1000);
5598                         sb.append("("); sb.append(formatRatioLocked(wifiScanActualTimeBg,
5599                                 computeBatteryRealtime(rawRealtime, STATS_SINCE_CHARGED)));
5600                                 sb.append(") ");
5601                                 sb.append(wifiScanCountBg);
5602                                 sb.append("x");
5603                 pw.println(sb.toString());
5604             }
5605 
5606             if (wifiWakeup > 0) {
5607                 sb.setLength(0);
5608                 sb.append(prefix);
5609                 sb.append("    WiFi AP wakeups: ");
5610                 sb.append(wifiWakeup);
5611                 pw.println(sb.toString());
5612             }
5613 
5614             printControllerActivityIfInteresting(pw, sb, prefix + "  ", WIFI_CONTROLLER_NAME,
5615                     u.getWifiControllerActivity(), which);
5616 
5617             if (btRxBytes > 0 || btTxBytes > 0) {
5618                 pw.print(prefix); pw.print("    Bluetooth network: ");
5619                 pw.print(formatBytesLocked(btRxBytes)); pw.print(" received, ");
5620                 pw.print(formatBytesLocked(btTxBytes));
5621                 pw.println(" sent");
5622             }
5623 
5624             final Timer bleTimer = u.getBluetoothScanTimer();
5625             if (bleTimer != null) {
5626                 // Convert from microseconds to milliseconds with rounding
5627                 final long totalTimeMs = (bleTimer.getTotalTimeLocked(rawRealtime, which) + 500)
5628                         / 1000;
5629                 if (totalTimeMs != 0) {
5630                     final int count = bleTimer.getCountLocked(which);
5631                     final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
5632                     final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
5633                     // 'actualTime' are unpooled and always since reset (regardless of 'which')
5634                     final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
5635                     final long actualTimeMsBg = bleTimerBg != null ?
5636                             bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5637                     // Result counters
5638                     final int resultCount = u.getBluetoothScanResultCounter() != null ?
5639                             u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
5640                     final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
5641                             u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
5642                     // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
5643                     final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
5644                     final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
5645                             unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5646                     final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
5647                             unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
5648                     // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
5649                     final Timer unoptimizedScanTimerBg =
5650                             u.getBluetoothUnoptimizedScanBackgroundTimer();
5651                     final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
5652                             unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5653                     final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
5654                             unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
5655 
5656                     sb.setLength(0);
5657                     if (actualTimeMs != totalTimeMs) {
5658                         sb.append(prefix);
5659                         sb.append("    Bluetooth Scan (total blamed realtime): ");
5660                         formatTimeMs(sb, totalTimeMs);
5661                         sb.append(" (");
5662                         sb.append(count);
5663                         sb.append(" times)");
5664                         if (bleTimer.isRunningLocked()) {
5665                             sb.append(" (currently running)");
5666                         }
5667                         sb.append("\n");
5668                     }
5669 
5670                     sb.append(prefix);
5671                     sb.append("    Bluetooth Scan (total actual realtime): ");
5672                     formatTimeMs(sb, actualTimeMs); // since reset, ignores 'which'
5673                     sb.append(" (");
5674                     sb.append(count);
5675                     sb.append(" times)");
5676                     if (bleTimer.isRunningLocked()) {
5677                             sb.append(" (currently running)");
5678                     }
5679                     sb.append("\n");
5680                     if (actualTimeMsBg > 0 || countBg > 0) {
5681                         sb.append(prefix);
5682                         sb.append("    Bluetooth Scan (background realtime): ");
5683                         formatTimeMs(sb, actualTimeMsBg); // since reset, ignores 'which'
5684                         sb.append(" (");
5685                         sb.append(countBg);
5686                         sb.append(" times)");
5687                         if (bleTimerBg != null && bleTimerBg.isRunningLocked()) {
5688                             sb.append(" (currently running in background)");
5689                         }
5690                         sb.append("\n");
5691                     }
5692 
5693                     sb.append(prefix);
5694                     sb.append("    Bluetooth Scan Results: ");
5695                     sb.append(resultCount);
5696                     sb.append(" (");
5697                     sb.append(resultCountBg);
5698                     sb.append(" in background)");
5699 
5700                     if (unoptimizedScanTotalTime > 0 || unoptimizedScanTotalTimeBg > 0) {
5701                         sb.append("\n");
5702                         sb.append(prefix);
5703                         sb.append("    Unoptimized Bluetooth Scan (realtime): ");
5704                         formatTimeMs(sb, unoptimizedScanTotalTime); // since reset, ignores 'which'
5705                         sb.append(" (max ");
5706                         formatTimeMs(sb, unoptimizedScanMaxTime); // since reset, ignores 'which'
5707                         sb.append(")");
5708                         if (unoptimizedScanTimer != null
5709                                 && unoptimizedScanTimer.isRunningLocked()) {
5710                             sb.append(" (currently running unoptimized)");
5711                         }
5712                         if (unoptimizedScanTimerBg != null && unoptimizedScanTotalTimeBg > 0) {
5713                             sb.append("\n");
5714                             sb.append(prefix);
5715                             sb.append("    Unoptimized Bluetooth Scan (background realtime): ");
5716                             formatTimeMs(sb, unoptimizedScanTotalTimeBg); // since reset
5717                             sb.append(" (max ");
5718                             formatTimeMs(sb, unoptimizedScanMaxTimeBg); // since reset
5719                             sb.append(")");
5720                             if (unoptimizedScanTimerBg.isRunningLocked()) {
5721                                 sb.append(" (currently running unoptimized in background)");
5722                             }
5723                         }
5724                     }
5725                     pw.println(sb.toString());
5726                     uidActivity = true;
5727                 }
5728             }
5729 
5730 
5731 
5732             if (u.hasUserActivity()) {
5733                 boolean hasData = false;
5734                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5735                     final int val = u.getUserActivityCount(i, which);
5736                     if (val != 0) {
5737                         if (!hasData) {
5738                             sb.setLength(0);
5739                             sb.append("    User activity: ");
5740                             hasData = true;
5741                         } else {
5742                             sb.append(", ");
5743                         }
5744                         sb.append(val);
5745                         sb.append(" ");
5746                         sb.append(Uid.USER_ACTIVITY_TYPES[i]);
5747                     }
5748                 }
5749                 if (hasData) {
5750                     pw.println(sb.toString());
5751                 }
5752             }
5753 
5754             final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
5755                     = u.getWakelockStats();
5756             long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
5757             long totalDrawWakelock = 0;
5758             int countWakelock = 0;
5759             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
5760                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
5761                 String linePrefix = ": ";
5762                 sb.setLength(0);
5763                 sb.append(prefix);
5764                 sb.append("    Wake lock ");
5765                 sb.append(wakelocks.keyAt(iw));
5766                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
5767                         "full", which, linePrefix);
5768                 final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
5769                 linePrefix = printWakeLock(sb, pTimer, rawRealtime,
5770                         "partial", which, linePrefix);
5771                 linePrefix = printWakeLock(sb, pTimer != null ? pTimer.getSubTimer() : null,
5772                         rawRealtime, "background partial", which, linePrefix);
5773                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
5774                         "window", which, linePrefix);
5775                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
5776                         "draw", which, linePrefix);
5777                 sb.append(" realtime");
5778                 pw.println(sb.toString());
5779                 uidActivity = true;
5780                 countWakelock++;
5781 
5782                 totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
5783                         rawRealtime, which);
5784                 totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
5785                         rawRealtime, which);
5786                 totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
5787                         rawRealtime, which);
5788                 totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW),
5789                         rawRealtime, which);
5790             }
5791             if (countWakelock > 1) {
5792                 // get unpooled partial wakelock quantities (unlike totalPartialWakelock, which is
5793                 // pooled and therefore just a lower bound)
5794                 long actualTotalPartialWakelock = 0;
5795                 long actualBgPartialWakelock = 0;
5796                 if (u.getAggregatedPartialWakelockTimer() != null) {
5797                     final Timer aggTimer = u.getAggregatedPartialWakelockTimer();
5798                     // Convert from microseconds to milliseconds with rounding
5799                     actualTotalPartialWakelock =
5800                             aggTimer.getTotalDurationMsLocked(rawRealtimeMs);
5801                     final Timer bgAggTimer = aggTimer.getSubTimer();
5802                     actualBgPartialWakelock = bgAggTimer != null ?
5803                             bgAggTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5804                 }
5805 
5806                 if (actualTotalPartialWakelock != 0 || actualBgPartialWakelock != 0 ||
5807                         totalFullWakelock != 0 || totalPartialWakelock != 0 ||
5808                         totalWindowWakelock != 0) {
5809                     sb.setLength(0);
5810                     sb.append(prefix);
5811                     sb.append("    TOTAL wake: ");
5812                     boolean needComma = false;
5813                     if (totalFullWakelock != 0) {
5814                         needComma = true;
5815                         formatTimeMs(sb, totalFullWakelock);
5816                         sb.append("full");
5817                     }
5818                     if (totalPartialWakelock != 0) {
5819                         if (needComma) {
5820                             sb.append(", ");
5821                         }
5822                         needComma = true;
5823                         formatTimeMs(sb, totalPartialWakelock);
5824                         sb.append("blamed partial");
5825                     }
5826                     if (actualTotalPartialWakelock != 0) {
5827                         if (needComma) {
5828                             sb.append(", ");
5829                         }
5830                         needComma = true;
5831                         formatTimeMs(sb, actualTotalPartialWakelock);
5832                         sb.append("actual partial");
5833                     }
5834                     if (actualBgPartialWakelock != 0) {
5835                         if (needComma) {
5836                             sb.append(", ");
5837                         }
5838                         needComma = true;
5839                         formatTimeMs(sb, actualBgPartialWakelock);
5840                         sb.append("actual background partial");
5841                     }
5842                     if (totalWindowWakelock != 0) {
5843                         if (needComma) {
5844                             sb.append(", ");
5845                         }
5846                         needComma = true;
5847                         formatTimeMs(sb, totalWindowWakelock);
5848                         sb.append("window");
5849                     }
5850                     if (totalDrawWakelock != 0) {
5851                         if (needComma) {
5852                             sb.append(",");
5853                         }
5854                         needComma = true;
5855                         formatTimeMs(sb, totalDrawWakelock);
5856                         sb.append("draw");
5857                     }
5858                     sb.append(" realtime");
5859                     pw.println(sb.toString());
5860                 }
5861             }
5862 
5863             // Calculate multicast wakelock stats
5864             final Timer mcTimer = u.getMulticastWakelockStats();
5865             if (mcTimer != null) {
5866                 final long multicastWakeLockTimeMicros = mcTimer.getTotalTimeLocked(rawRealtime, which);
5867                 final int multicastWakeLockCount = mcTimer.getCountLocked(which);
5868 
5869                 if (multicastWakeLockTimeMicros > 0) {
5870                     sb.setLength(0);
5871                     sb.append(prefix);
5872                     sb.append("    WiFi Multicast Wakelock");
5873                     sb.append(" count = ");
5874                     sb.append(multicastWakeLockCount);
5875                     sb.append(" time = ");
5876                     formatTimeMsNoSpace(sb, (multicastWakeLockTimeMicros + 500) / 1000);
5877                     pw.println(sb.toString());
5878                 }
5879             }
5880 
5881             final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
5882             for (int isy=syncs.size()-1; isy>=0; isy--) {
5883                 final Timer timer = syncs.valueAt(isy);
5884                 // Convert from microseconds to milliseconds with rounding
5885                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
5886                 final int count = timer.getCountLocked(which);
5887                 final Timer bgTimer = timer.getSubTimer();
5888                 final long bgTime = bgTimer != null ?
5889                         bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
5890                 final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
5891                 sb.setLength(0);
5892                 sb.append(prefix);
5893                 sb.append("    Sync ");
5894                 sb.append(syncs.keyAt(isy));
5895                 sb.append(": ");
5896                 if (totalTime != 0) {
5897                     formatTimeMs(sb, totalTime);
5898                     sb.append("realtime (");
5899                     sb.append(count);
5900                     sb.append(" times)");
5901                     if (bgTime > 0) {
5902                         sb.append(", ");
5903                         formatTimeMs(sb, bgTime);
5904                         sb.append("background (");
5905                         sb.append(bgCount);
5906                         sb.append(" times)");
5907                     }
5908                 } else {
5909                     sb.append("(not used)");
5910                 }
5911                 pw.println(sb.toString());
5912                 uidActivity = true;
5913             }
5914 
5915             final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
5916             for (int ij=jobs.size()-1; ij>=0; ij--) {
5917                 final Timer timer = jobs.valueAt(ij);
5918                 // Convert from microseconds to milliseconds with rounding
5919                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
5920                 final int count = timer.getCountLocked(which);
5921                 final Timer bgTimer = timer.getSubTimer();
5922                 final long bgTime = bgTimer != null ?
5923                         bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
5924                 final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
5925                 sb.setLength(0);
5926                 sb.append(prefix);
5927                 sb.append("    Job ");
5928                 sb.append(jobs.keyAt(ij));
5929                 sb.append(": ");
5930                 if (totalTime != 0) {
5931                     formatTimeMs(sb, totalTime);
5932                     sb.append("realtime (");
5933                     sb.append(count);
5934                     sb.append(" times)");
5935                     if (bgTime > 0) {
5936                         sb.append(", ");
5937                         formatTimeMs(sb, bgTime);
5938                         sb.append("background (");
5939                         sb.append(bgCount);
5940                         sb.append(" times)");
5941                     }
5942                 } else {
5943                     sb.append("(not used)");
5944                 }
5945                 pw.println(sb.toString());
5946                 uidActivity = true;
5947             }
5948 
5949             final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
5950             for (int ic=completions.size()-1; ic>=0; ic--) {
5951                 SparseIntArray types = completions.valueAt(ic);
5952                 if (types != null) {
5953                     pw.print(prefix);
5954                     pw.print("    Job Completions ");
5955                     pw.print(completions.keyAt(ic));
5956                     pw.print(":");
5957                     for (int it=0; it<types.size(); it++) {
5958                         pw.print(" ");
5959                         pw.print(JobParameters.getInternalReasonCodeDescription(types.keyAt(it)));
5960                         pw.print("(");
5961                         pw.print(types.valueAt(it));
5962                         pw.print("x)");
5963                     }
5964                     pw.println();
5965                 }
5966             }
5967 
5968             u.getDeferredJobsLineLocked(sb, which);
5969             if (sb.length() > 0) {
5970                 pw.print("    Jobs deferred on launch "); pw.println(sb.toString());
5971             }
5972 
5973             uidActivity |= printTimer(pw, sb, u.getFlashlightTurnedOnTimer(), rawRealtime, which,
5974                     prefix, "Flashlight");
5975             uidActivity |= printTimer(pw, sb, u.getCameraTurnedOnTimer(), rawRealtime, which,
5976                     prefix, "Camera");
5977             uidActivity |= printTimer(pw, sb, u.getVideoTurnedOnTimer(), rawRealtime, which,
5978                     prefix, "Video");
5979             uidActivity |= printTimer(pw, sb, u.getAudioTurnedOnTimer(), rawRealtime, which,
5980                     prefix, "Audio");
5981 
5982             final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
5983             final int NSE = sensors.size();
5984             for (int ise=0; ise<NSE; ise++) {
5985                 final Uid.Sensor se = sensors.valueAt(ise);
5986                 final int sensorNumber = sensors.keyAt(ise);
5987                 sb.setLength(0);
5988                 sb.append(prefix);
5989                 sb.append("    Sensor ");
5990                 int handle = se.getHandle();
5991                 if (handle == Uid.Sensor.GPS) {
5992                     sb.append("GPS");
5993                 } else {
5994                     sb.append(handle);
5995                 }
5996                 sb.append(": ");
5997 
5998                 final Timer timer = se.getSensorTime();
5999                 if (timer != null) {
6000                     // Convert from microseconds to milliseconds with rounding
6001                     final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
6002                             / 1000;
6003                     final int count = timer.getCountLocked(which);
6004                     final Timer bgTimer = se.getSensorBackgroundTime();
6005                     final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
6006                     // 'actualTime' are unpooled and always since reset (regardless of 'which')
6007                     final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
6008                     final long bgActualTime = bgTimer != null ?
6009                             bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
6010 
6011                     //timer.logState();
6012                     if (totalTime != 0) {
6013                         if (actualTime != totalTime) {
6014                             formatTimeMs(sb, totalTime);
6015                             sb.append("blamed realtime, ");
6016                         }
6017 
6018                         formatTimeMs(sb, actualTime); // since reset, regardless of 'which'
6019                         sb.append("realtime (");
6020                         sb.append(count);
6021                         sb.append(" times)");
6022 
6023                         if (bgActualTime != 0 || bgCount > 0) {
6024                             sb.append(", ");
6025                             formatTimeMs(sb, bgActualTime); // since reset, regardless of 'which'
6026                             sb.append("background (");
6027                             sb.append(bgCount);
6028                             sb.append(" times)");
6029                         }
6030                     } else {
6031                         sb.append("(not used)");
6032                     }
6033                 } else {
6034                     sb.append("(not used)");
6035                 }
6036 
6037                 pw.println(sb.toString());
6038                 uidActivity = true;
6039             }
6040 
6041             uidActivity |= printTimer(pw, sb, u.getVibratorOnTimer(), rawRealtime, which, prefix,
6042                     "Vibrator");
6043             uidActivity |= printTimer(pw, sb, u.getForegroundActivityTimer(), rawRealtime, which,
6044                     prefix, "Foreground activities");
6045             uidActivity |= printTimer(pw, sb, u.getForegroundServiceTimer(), rawRealtime, which,
6046                     prefix, "Foreground services");
6047 
6048             long totalStateTime = 0;
6049             for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
6050                 long time = u.getProcessStateTime(ips, rawRealtime, which);
6051                 if (time > 0) {
6052                     totalStateTime += time;
6053                     sb.setLength(0);
6054                     sb.append(prefix);
6055                     sb.append("    ");
6056                     sb.append(Uid.PROCESS_STATE_NAMES[ips]);
6057                     sb.append(" for: ");
6058                     formatTimeMs(sb, (time + 500) / 1000);
6059                     pw.println(sb.toString());
6060                     uidActivity = true;
6061                 }
6062             }
6063             if (totalStateTime > 0) {
6064                 sb.setLength(0);
6065                 sb.append(prefix);
6066                 sb.append("    Total running: ");
6067                 formatTimeMs(sb, (totalStateTime + 500) / 1000);
6068                 pw.println(sb.toString());
6069             }
6070 
6071             final long userCpuTimeUs = u.getUserCpuTimeUs(which);
6072             final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
6073             if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
6074                 sb.setLength(0);
6075                 sb.append(prefix);
6076                 sb.append("    Total cpu time: u=");
6077                 formatTimeMs(sb, userCpuTimeUs / 1000);
6078                 sb.append("s=");
6079                 formatTimeMs(sb, systemCpuTimeUs / 1000);
6080                 pw.println(sb.toString());
6081             }
6082 
6083             final long[] cpuFreqTimes = u.getCpuFreqTimes(which);
6084             if (cpuFreqTimes != null) {
6085                 sb.setLength(0);
6086                 sb.append("    Total cpu time per freq:");
6087                 for (int i = 0; i < cpuFreqTimes.length; ++i) {
6088                     sb.append(' ').append(cpuFreqTimes[i]);
6089                 }
6090                 pw.println(sb.toString());
6091             }
6092             final long[] screenOffCpuFreqTimes = u.getScreenOffCpuFreqTimes(which);
6093             if (screenOffCpuFreqTimes != null) {
6094                 sb.setLength(0);
6095                 sb.append("    Total screen-off cpu time per freq:");
6096                 for (int i = 0; i < screenOffCpuFreqTimes.length; ++i) {
6097                     sb.append(' ').append(screenOffCpuFreqTimes[i]);
6098                 }
6099                 pw.println(sb.toString());
6100             }
6101 
6102             for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
6103                 final long[] cpuTimes = u.getCpuFreqTimes(which, procState);
6104                 if (cpuTimes != null) {
6105                     sb.setLength(0);
6106                     sb.append("    Cpu times per freq at state ")
6107                             .append(Uid.PROCESS_STATE_NAMES[procState]).append(':');
6108                     for (int i = 0; i < cpuTimes.length; ++i) {
6109                         sb.append(" " + cpuTimes[i]);
6110                     }
6111                     pw.println(sb.toString());
6112                 }
6113 
6114                 final long[] screenOffCpuTimes = u.getScreenOffCpuFreqTimes(which, procState);
6115                 if (screenOffCpuTimes != null) {
6116                     sb.setLength(0);
6117                     sb.append("   Screen-off cpu times per freq at state ")
6118                             .append(Uid.PROCESS_STATE_NAMES[procState]).append(':');
6119                     for (int i = 0; i < screenOffCpuTimes.length; ++i) {
6120                         sb.append(" " + screenOffCpuTimes[i]);
6121                     }
6122                     pw.println(sb.toString());
6123                 }
6124             }
6125 
6126             final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
6127                     = u.getProcessStats();
6128             for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
6129                 final Uid.Proc ps = processStats.valueAt(ipr);
6130                 long userTime;
6131                 long systemTime;
6132                 long foregroundTime;
6133                 int starts;
6134                 int numExcessive;
6135 
6136                 userTime = ps.getUserTime(which);
6137                 systemTime = ps.getSystemTime(which);
6138                 foregroundTime = ps.getForegroundTime(which);
6139                 starts = ps.getStarts(which);
6140                 final int numCrashes = ps.getNumCrashes(which);
6141                 final int numAnrs = ps.getNumAnrs(which);
6142                 numExcessive = which == STATS_SINCE_CHARGED
6143                         ? ps.countExcessivePowers() : 0;
6144 
6145                 if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
6146                         || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
6147                     sb.setLength(0);
6148                     sb.append(prefix); sb.append("    Proc ");
6149                             sb.append(processStats.keyAt(ipr)); sb.append(":\n");
6150                     sb.append(prefix); sb.append("      CPU: ");
6151                             formatTimeMs(sb, userTime); sb.append("usr + ");
6152                             formatTimeMs(sb, systemTime); sb.append("krn ; ");
6153                             formatTimeMs(sb, foregroundTime); sb.append("fg");
6154                     if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
6155                         sb.append("\n"); sb.append(prefix); sb.append("      ");
6156                         boolean hasOne = false;
6157                         if (starts != 0) {
6158                             hasOne = true;
6159                             sb.append(starts); sb.append(" starts");
6160                         }
6161                         if (numCrashes != 0) {
6162                             if (hasOne) {
6163                                 sb.append(", ");
6164                             }
6165                             hasOne = true;
6166                             sb.append(numCrashes); sb.append(" crashes");
6167                         }
6168                         if (numAnrs != 0) {
6169                             if (hasOne) {
6170                                 sb.append(", ");
6171                             }
6172                             sb.append(numAnrs); sb.append(" anrs");
6173                         }
6174                     }
6175                     pw.println(sb.toString());
6176                     for (int e=0; e<numExcessive; e++) {
6177                         Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
6178                         if (ew != null) {
6179                             pw.print(prefix); pw.print("      * Killed for ");
6180                                     if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
6181                                         pw.print("cpu");
6182                                     } else {
6183                                         pw.print("unknown");
6184                                     }
6185                                     pw.print(" use: ");
6186                                     TimeUtils.formatDuration(ew.usedTime, pw);
6187                                     pw.print(" over ");
6188                                     TimeUtils.formatDuration(ew.overTime, pw);
6189                                     if (ew.overTime != 0) {
6190                                         pw.print(" (");
6191                                         pw.print((ew.usedTime*100)/ew.overTime);
6192                                         pw.println("%)");
6193                                     }
6194                         }
6195                     }
6196                     uidActivity = true;
6197                 }
6198             }
6199 
6200             final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
6201                     = u.getPackageStats();
6202             for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
6203                 pw.print(prefix); pw.print("    Apk "); pw.print(packageStats.keyAt(ipkg));
6204                 pw.println(":");
6205                 boolean apkActivity = false;
6206                 final Uid.Pkg ps = packageStats.valueAt(ipkg);
6207                 final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
6208                 for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
6209                     pw.print(prefix); pw.print("      Wakeup alarm ");
6210                             pw.print(alarms.keyAt(iwa)); pw.print(": ");
6211                             pw.print(alarms.valueAt(iwa).getCountLocked(which));
6212                             pw.println(" times");
6213                     apkActivity = true;
6214                 }
6215                 final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
6216                 for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
6217                     final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
6218                     final long startTime = ss.getStartTime(batteryUptime, which);
6219                     final int starts = ss.getStarts(which);
6220                     final int launches = ss.getLaunches(which);
6221                     if (startTime != 0 || starts != 0 || launches != 0) {
6222                         sb.setLength(0);
6223                         sb.append(prefix); sb.append("      Service ");
6224                                 sb.append(serviceStats.keyAt(isvc)); sb.append(":\n");
6225                         sb.append(prefix); sb.append("        Created for: ");
6226                                 formatTimeMs(sb, startTime / 1000);
6227                                 sb.append("uptime\n");
6228                         sb.append(prefix); sb.append("        Starts: ");
6229                                 sb.append(starts);
6230                                 sb.append(", launches: "); sb.append(launches);
6231                         pw.println(sb.toString());
6232                         apkActivity = true;
6233                     }
6234                 }
6235                 if (!apkActivity) {
6236                     pw.print(prefix); pw.println("      (nothing executed)");
6237                 }
6238                 uidActivity = true;
6239             }
6240             if (!uidActivity) {
6241                 pw.print(prefix); pw.println("    (nothing executed)");
6242             }
6243         }
6244     }
6245 
printBitDescriptions(StringBuilder sb, int oldval, int newval, HistoryTag wakelockTag, BitDescription[] descriptions, boolean longNames)6246     static void printBitDescriptions(StringBuilder sb, int oldval, int newval,
6247             HistoryTag wakelockTag, BitDescription[] descriptions, boolean longNames) {
6248         int diff = oldval ^ newval;
6249         if (diff == 0) return;
6250         boolean didWake = false;
6251         for (int i=0; i<descriptions.length; i++) {
6252             BitDescription bd = descriptions[i];
6253             if ((diff&bd.mask) != 0) {
6254                 sb.append(longNames ? " " : ",");
6255                 if (bd.shift < 0) {
6256                     sb.append((newval & bd.mask) != 0 ? "+" : "-");
6257                     sb.append(longNames ? bd.name : bd.shortName);
6258                     if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
6259                         didWake = true;
6260                         sb.append("=");
6261                         if (longNames) {
6262                             UserHandle.formatUid(sb, wakelockTag.uid);
6263                             sb.append(":\"");
6264                             sb.append(wakelockTag.string);
6265                             sb.append("\"");
6266                         } else {
6267                             sb.append(wakelockTag.poolIdx);
6268                         }
6269                     }
6270                 } else {
6271                     sb.append(longNames ? bd.name : bd.shortName);
6272                     sb.append("=");
6273                     int val = (newval&bd.mask)>>bd.shift;
6274                     if (bd.values != null && val >= 0 && val < bd.values.length) {
6275                         sb.append(longNames ? bd.values[val] : bd.shortValues[val]);
6276                     } else {
6277                         sb.append(val);
6278                     }
6279                 }
6280             }
6281         }
6282         if (!didWake && wakelockTag != null) {
6283             sb.append(longNames ? " wake_lock=" : ",w=");
6284             if (longNames) {
6285                 UserHandle.formatUid(sb, wakelockTag.uid);
6286                 sb.append(":\"");
6287                 sb.append(wakelockTag.string);
6288                 sb.append("\"");
6289             } else {
6290                 sb.append(wakelockTag.poolIdx);
6291             }
6292         }
6293     }
6294 
prepareForDumpLocked()6295     public void prepareForDumpLocked() {
6296         // We don't need to require subclasses implement this.
6297     }
6298 
6299     public static class HistoryPrinter {
6300         int oldState = 0;
6301         int oldState2 = 0;
6302         int oldLevel = -1;
6303         int oldStatus = -1;
6304         int oldHealth = -1;
6305         int oldPlug = -1;
6306         int oldTemp = -1;
6307         int oldVolt = -1;
6308         int oldChargeMAh = -1;
6309         double oldModemRailChargeMah = -1;
6310         double oldWifiRailChargeMah = -1;
6311         long lastTime = -1;
6312 
reset()6313         void reset() {
6314             oldState = oldState2 = 0;
6315             oldLevel = -1;
6316             oldStatus = -1;
6317             oldHealth = -1;
6318             oldPlug = -1;
6319             oldTemp = -1;
6320             oldVolt = -1;
6321             oldChargeMAh = -1;
6322             oldModemRailChargeMah = -1;
6323             oldWifiRailChargeMah = -1;
6324         }
6325 
printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin, boolean verbose)6326         public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
6327                 boolean verbose) {
6328             pw.print(printNextItem(rec, baseTime, checkin, verbose));
6329         }
6330 
6331         /** Print the next history item to proto. */
printNextItem(ProtoOutputStream proto, HistoryItem rec, long baseTime, boolean verbose)6332         public void printNextItem(ProtoOutputStream proto, HistoryItem rec, long baseTime,
6333                 boolean verbose) {
6334             String item = printNextItem(rec, baseTime, true, verbose);
6335             for (String line : item.split("\n")) {
6336                 proto.write(BatteryStatsServiceDumpHistoryProto.CSV_LINES, line);
6337             }
6338         }
6339 
printNextItem(HistoryItem rec, long baseTime, boolean checkin, boolean verbose)6340         private String printNextItem(HistoryItem rec, long baseTime, boolean checkin,
6341                 boolean verbose) {
6342             StringBuilder item = new StringBuilder();
6343             if (!checkin) {
6344                 item.append("  ");
6345                 TimeUtils.formatDuration(
6346                         rec.time - baseTime, item, TimeUtils.HUNDRED_DAY_FIELD_LEN);
6347                 item.append(" (");
6348                 item.append(rec.numReadInts);
6349                 item.append(") ");
6350             } else {
6351                 item.append(BATTERY_STATS_CHECKIN_VERSION); item.append(',');
6352                 item.append(HISTORY_DATA); item.append(',');
6353                 if (lastTime < 0) {
6354                     item.append(rec.time - baseTime);
6355                 } else {
6356                     item.append(rec.time - lastTime);
6357                 }
6358                 lastTime = rec.time;
6359             }
6360             if (rec.cmd == HistoryItem.CMD_START) {
6361                 if (checkin) {
6362                     item.append(":");
6363                 }
6364                 item.append("START\n");
6365                 reset();
6366             } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
6367                     || rec.cmd == HistoryItem.CMD_RESET) {
6368                 if (checkin) {
6369                     item.append(":");
6370                 }
6371                 if (rec.cmd == HistoryItem.CMD_RESET) {
6372                     item.append("RESET:");
6373                     reset();
6374                 }
6375                 item.append("TIME:");
6376                 if (checkin) {
6377                     item.append(rec.currentTime);
6378                     item.append("\n");
6379                 } else {
6380                     item.append(" ");
6381                     item.append(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6382                             rec.currentTime).toString());
6383                     item.append("\n");
6384                 }
6385             } else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) {
6386                 if (checkin) {
6387                     item.append(":");
6388                 }
6389                 item.append("SHUTDOWN\n");
6390             } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
6391                 if (checkin) {
6392                     item.append(":");
6393                 }
6394                 item.append("*OVERFLOW*\n");
6395             } else {
6396                 if (!checkin) {
6397                     if (rec.batteryLevel < 10) item.append("00");
6398                     else if (rec.batteryLevel < 100) item.append("0");
6399                     item.append(rec.batteryLevel);
6400                     if (verbose) {
6401                         item.append(" ");
6402                         if (rec.states < 0) ;
6403                         else if (rec.states < 0x10) item.append("0000000");
6404                         else if (rec.states < 0x100) item.append("000000");
6405                         else if (rec.states < 0x1000) item.append("00000");
6406                         else if (rec.states < 0x10000) item.append("0000");
6407                         else if (rec.states < 0x100000) item.append("000");
6408                         else if (rec.states < 0x1000000) item.append("00");
6409                         else if (rec.states < 0x10000000) item.append("0");
6410                         item.append(Integer.toHexString(rec.states));
6411                     }
6412                 } else {
6413                     if (oldLevel != rec.batteryLevel) {
6414                         oldLevel = rec.batteryLevel;
6415                         item.append(",Bl="); item.append(rec.batteryLevel);
6416                     }
6417                 }
6418                 if (oldStatus != rec.batteryStatus) {
6419                     oldStatus = rec.batteryStatus;
6420                     item.append(checkin ? ",Bs=" : " status=");
6421                     switch (oldStatus) {
6422                         case BatteryManager.BATTERY_STATUS_UNKNOWN:
6423                             item.append(checkin ? "?" : "unknown");
6424                             break;
6425                         case BatteryManager.BATTERY_STATUS_CHARGING:
6426                             item.append(checkin ? "c" : "charging");
6427                             break;
6428                         case BatteryManager.BATTERY_STATUS_DISCHARGING:
6429                             item.append(checkin ? "d" : "discharging");
6430                             break;
6431                         case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
6432                             item.append(checkin ? "n" : "not-charging");
6433                             break;
6434                         case BatteryManager.BATTERY_STATUS_FULL:
6435                             item.append(checkin ? "f" : "full");
6436                             break;
6437                         default:
6438                             item.append(oldStatus);
6439                             break;
6440                     }
6441                 }
6442                 if (oldHealth != rec.batteryHealth) {
6443                     oldHealth = rec.batteryHealth;
6444                     item.append(checkin ? ",Bh=" : " health=");
6445                     switch (oldHealth) {
6446                         case BatteryManager.BATTERY_HEALTH_UNKNOWN:
6447                             item.append(checkin ? "?" : "unknown");
6448                             break;
6449                         case BatteryManager.BATTERY_HEALTH_GOOD:
6450                             item.append(checkin ? "g" : "good");
6451                             break;
6452                         case BatteryManager.BATTERY_HEALTH_OVERHEAT:
6453                             item.append(checkin ? "h" : "overheat");
6454                             break;
6455                         case BatteryManager.BATTERY_HEALTH_DEAD:
6456                             item.append(checkin ? "d" : "dead");
6457                             break;
6458                         case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
6459                             item.append(checkin ? "v" : "over-voltage");
6460                             break;
6461                         case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
6462                             item.append(checkin ? "f" : "failure");
6463                             break;
6464                         case BatteryManager.BATTERY_HEALTH_COLD:
6465                             item.append(checkin ? "c" : "cold");
6466                             break;
6467                         default:
6468                             item.append(oldHealth);
6469                             break;
6470                     }
6471                 }
6472                 if (oldPlug != rec.batteryPlugType) {
6473                     oldPlug = rec.batteryPlugType;
6474                     item.append(checkin ? ",Bp=" : " plug=");
6475                     switch (oldPlug) {
6476                         case 0:
6477                             item.append(checkin ? "n" : "none");
6478                             break;
6479                         case BatteryManager.BATTERY_PLUGGED_AC:
6480                             item.append(checkin ? "a" : "ac");
6481                             break;
6482                         case BatteryManager.BATTERY_PLUGGED_USB:
6483                             item.append(checkin ? "u" : "usb");
6484                             break;
6485                         case BatteryManager.BATTERY_PLUGGED_WIRELESS:
6486                             item.append(checkin ? "w" : "wireless");
6487                             break;
6488                         default:
6489                             item.append(oldPlug);
6490                             break;
6491                     }
6492                 }
6493                 if (oldTemp != rec.batteryTemperature) {
6494                     oldTemp = rec.batteryTemperature;
6495                     item.append(checkin ? ",Bt=" : " temp=");
6496                     item.append(oldTemp);
6497                 }
6498                 if (oldVolt != rec.batteryVoltage) {
6499                     oldVolt = rec.batteryVoltage;
6500                     item.append(checkin ? ",Bv=" : " volt=");
6501                     item.append(oldVolt);
6502                 }
6503                 final int chargeMAh = rec.batteryChargeUah / 1000;
6504                 if (oldChargeMAh != chargeMAh) {
6505                     oldChargeMAh = chargeMAh;
6506                     item.append(checkin ? ",Bcc=" : " charge=");
6507                     item.append(oldChargeMAh);
6508                 }
6509                 if (oldModemRailChargeMah != rec.modemRailChargeMah) {
6510                     oldModemRailChargeMah = rec.modemRailChargeMah;
6511                     item.append(checkin ? ",Mrc=" : " modemRailChargemAh=");
6512                     item.append(new DecimalFormat("#.##").format(oldModemRailChargeMah));
6513                 }
6514                 if (oldWifiRailChargeMah != rec.wifiRailChargeMah) {
6515                     oldWifiRailChargeMah = rec.wifiRailChargeMah;
6516                     item.append(checkin ? ",Wrc=" : " wifiRailChargemAh=");
6517                     item.append(new DecimalFormat("#.##").format(oldWifiRailChargeMah));
6518                 }
6519                 printBitDescriptions(item, oldState, rec.states, rec.wakelockTag,
6520                         HISTORY_STATE_DESCRIPTIONS, !checkin);
6521                 printBitDescriptions(item, oldState2, rec.states2, null,
6522                         HISTORY_STATE2_DESCRIPTIONS, !checkin);
6523                 if (rec.wakeReasonTag != null) {
6524                     if (checkin) {
6525                         item.append(",wr=");
6526                         item.append(rec.wakeReasonTag.poolIdx);
6527                     } else {
6528                         item.append(" wake_reason=");
6529                         item.append(rec.wakeReasonTag.uid);
6530                         item.append(":\"");
6531                         item.append(rec.wakeReasonTag.string);
6532                         item.append("\"");
6533                     }
6534                 }
6535                 if (rec.eventCode != HistoryItem.EVENT_NONE) {
6536                     item.append(checkin ? "," : " ");
6537                     if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
6538                         item.append("+");
6539                     } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
6540                         item.append("-");
6541                     }
6542                     String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
6543                             : HISTORY_EVENT_NAMES;
6544                     int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
6545                             | HistoryItem.EVENT_FLAG_FINISH);
6546                     if (idx >= 0 && idx < eventNames.length) {
6547                         item.append(eventNames[idx]);
6548                     } else {
6549                         item.append(checkin ? "Ev" : "event");
6550                         item.append(idx);
6551                     }
6552                     item.append("=");
6553                     if (checkin) {
6554                         item.append(rec.eventTag.poolIdx);
6555                     } else {
6556                         item.append(HISTORY_EVENT_INT_FORMATTERS[idx]
6557                                 .applyAsString(rec.eventTag.uid));
6558                         item.append(":\"");
6559                         item.append(rec.eventTag.string);
6560                         item.append("\"");
6561                     }
6562                 }
6563                 item.append("\n");
6564                 if (rec.stepDetails != null) {
6565                     if (!checkin) {
6566                         item.append("                 Details: cpu=");
6567                         item.append(rec.stepDetails.userTime);
6568                         item.append("u+");
6569                         item.append(rec.stepDetails.systemTime);
6570                         item.append("s");
6571                         if (rec.stepDetails.appCpuUid1 >= 0) {
6572                             item.append(" (");
6573                             printStepCpuUidDetails(item, rec.stepDetails.appCpuUid1,
6574                                     rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
6575                             if (rec.stepDetails.appCpuUid2 >= 0) {
6576                                 item.append(", ");
6577                                 printStepCpuUidDetails(item, rec.stepDetails.appCpuUid2,
6578                                         rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
6579                             }
6580                             if (rec.stepDetails.appCpuUid3 >= 0) {
6581                                 item.append(", ");
6582                                 printStepCpuUidDetails(item, rec.stepDetails.appCpuUid3,
6583                                         rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
6584                             }
6585                             item.append(')');
6586                         }
6587                         item.append("\n");
6588                         item.append("                          /proc/stat=");
6589                         item.append(rec.stepDetails.statUserTime);
6590                         item.append(" usr, ");
6591                         item.append(rec.stepDetails.statSystemTime);
6592                         item.append(" sys, ");
6593                         item.append(rec.stepDetails.statIOWaitTime);
6594                         item.append(" io, ");
6595                         item.append(rec.stepDetails.statIrqTime);
6596                         item.append(" irq, ");
6597                         item.append(rec.stepDetails.statSoftIrqTime);
6598                         item.append(" sirq, ");
6599                         item.append(rec.stepDetails.statIdlTime);
6600                         item.append(" idle");
6601                         int totalRun = rec.stepDetails.statUserTime + rec.stepDetails.statSystemTime
6602                                 + rec.stepDetails.statIOWaitTime + rec.stepDetails.statIrqTime
6603                                 + rec.stepDetails.statSoftIrqTime;
6604                         int total = totalRun + rec.stepDetails.statIdlTime;
6605                         if (total > 0) {
6606                             item.append(" (");
6607                             float perc = ((float)totalRun) / ((float)total) * 100;
6608                             item.append(String.format("%.1f%%", perc));
6609                             item.append(" of ");
6610                             StringBuilder sb = new StringBuilder(64);
6611                             formatTimeMsNoSpace(sb, total*10);
6612                             item.append(sb);
6613                             item.append(")");
6614                         }
6615 
6616                         item.append(", SubsystemPowerState ");
6617                         item.append(rec.stepDetails.statSubsystemPowerState);
6618                         item.append("\n");
6619                     } else {
6620                         item.append(BATTERY_STATS_CHECKIN_VERSION); item.append(',');
6621                         item.append(HISTORY_DATA); item.append(",0,Dcpu=");
6622                         item.append(rec.stepDetails.userTime);
6623                         item.append(":");
6624                         item.append(rec.stepDetails.systemTime);
6625                         if (rec.stepDetails.appCpuUid1 >= 0) {
6626                             printStepCpuUidCheckinDetails(item, rec.stepDetails.appCpuUid1,
6627                                     rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
6628                             if (rec.stepDetails.appCpuUid2 >= 0) {
6629                                 printStepCpuUidCheckinDetails(item, rec.stepDetails.appCpuUid2,
6630                                         rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
6631                             }
6632                             if (rec.stepDetails.appCpuUid3 >= 0) {
6633                                 printStepCpuUidCheckinDetails(item, rec.stepDetails.appCpuUid3,
6634                                         rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
6635                             }
6636                         }
6637                         item.append("\n");
6638                         item.append(BATTERY_STATS_CHECKIN_VERSION); item.append(',');
6639                         item.append(HISTORY_DATA); item.append(",0,Dpst=");
6640                         item.append(rec.stepDetails.statUserTime);
6641                         item.append(',');
6642                         item.append(rec.stepDetails.statSystemTime);
6643                         item.append(',');
6644                         item.append(rec.stepDetails.statIOWaitTime);
6645                         item.append(',');
6646                         item.append(rec.stepDetails.statIrqTime);
6647                         item.append(',');
6648                         item.append(rec.stepDetails.statSoftIrqTime);
6649                         item.append(',');
6650                         item.append(rec.stepDetails.statIdlTime);
6651                         item.append(',');
6652 
6653                         if (rec.stepDetails.statSubsystemPowerState != null) {
6654                             item.append(rec.stepDetails.statSubsystemPowerState);
6655                         }
6656                         item.append("\n");
6657                     }
6658                 }
6659                 oldState = rec.states;
6660                 oldState2 = rec.states2;
6661                 // Clear High Tx Power Flag for volta positioning
6662                 if ((rec.states2 & HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG) != 0) {
6663                     rec.states2 &= ~HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
6664                 }
6665             }
6666 
6667             return item.toString();
6668         }
6669 
printStepCpuUidDetails(StringBuilder sb, int uid, int utime, int stime)6670         private void printStepCpuUidDetails(StringBuilder sb, int uid, int utime, int stime) {
6671             UserHandle.formatUid(sb, uid);
6672             sb.append("=");
6673             sb.append(utime);
6674             sb.append("u+");
6675             sb.append(stime);
6676             sb.append("s");
6677         }
6678 
printStepCpuUidCheckinDetails(StringBuilder sb, int uid, int utime, int stime)6679         private void printStepCpuUidCheckinDetails(StringBuilder sb, int uid, int utime,
6680                 int stime) {
6681             sb.append('/');
6682             sb.append(uid);
6683             sb.append(":");
6684             sb.append(utime);
6685             sb.append(":");
6686             sb.append(stime);
6687         }
6688     }
6689 
printSizeValue(PrintWriter pw, long size)6690     private void printSizeValue(PrintWriter pw, long size) {
6691         float result = size;
6692         String suffix = "";
6693         if (result >= 10*1024) {
6694             suffix = "KB";
6695             result = result / 1024;
6696         }
6697         if (result >= 10*1024) {
6698             suffix = "MB";
6699             result = result / 1024;
6700         }
6701         if (result >= 10*1024) {
6702             suffix = "GB";
6703             result = result / 1024;
6704         }
6705         if (result >= 10*1024) {
6706             suffix = "TB";
6707             result = result / 1024;
6708         }
6709         if (result >= 10*1024) {
6710             suffix = "PB";
6711             result = result / 1024;
6712         }
6713         pw.print((int)result);
6714         pw.print(suffix);
6715     }
6716 
dumpTimeEstimate(PrintWriter pw, String label1, String label2, String label3, long estimatedTime)6717     private static boolean dumpTimeEstimate(PrintWriter pw, String label1, String label2,
6718             String label3, long estimatedTime) {
6719         if (estimatedTime < 0) {
6720             return false;
6721         }
6722         pw.print(label1);
6723         pw.print(label2);
6724         pw.print(label3);
6725         StringBuilder sb = new StringBuilder(64);
6726         formatTimeMs(sb, estimatedTime);
6727         pw.print(sb);
6728         pw.println();
6729         return true;
6730     }
6731 
dumpDurationSteps(PrintWriter pw, String prefix, String header, LevelStepTracker steps, boolean checkin)6732     private static boolean dumpDurationSteps(PrintWriter pw, String prefix, String header,
6733             LevelStepTracker steps, boolean checkin) {
6734         if (steps == null) {
6735             return false;
6736         }
6737         int count = steps.mNumStepDurations;
6738         if (count <= 0) {
6739             return false;
6740         }
6741         if (!checkin) {
6742             pw.println(header);
6743         }
6744         String[] lineArgs = new String[5];
6745         for (int i=0; i<count; i++) {
6746             long duration = steps.getDurationAt(i);
6747             int level = steps.getLevelAt(i);
6748             long initMode = steps.getInitModeAt(i);
6749             long modMode = steps.getModModeAt(i);
6750             if (checkin) {
6751                 lineArgs[0] = Long.toString(duration);
6752                 lineArgs[1] = Integer.toString(level);
6753                 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
6754                     switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
6755                         case Display.STATE_OFF: lineArgs[2] = "s-"; break;
6756                         case Display.STATE_ON: lineArgs[2] = "s+"; break;
6757                         case Display.STATE_DOZE: lineArgs[2] = "sd"; break;
6758                         case Display.STATE_DOZE_SUSPEND: lineArgs[2] = "sds"; break;
6759                         default: lineArgs[2] = "?"; break;
6760                     }
6761                 } else {
6762                     lineArgs[2] = "";
6763                 }
6764                 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
6765                     lineArgs[3] = (initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 ? "p+" : "p-";
6766                 } else {
6767                     lineArgs[3] = "";
6768                 }
6769                 if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
6770                     lineArgs[4] = (initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0 ? "i+" : "i-";
6771                 } else {
6772                     lineArgs[4] = "";
6773                 }
6774                 dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs);
6775             } else {
6776                 pw.print(prefix);
6777                 pw.print("#"); pw.print(i); pw.print(": ");
6778                 TimeUtils.formatDuration(duration, pw);
6779                 pw.print(" to "); pw.print(level);
6780                 boolean haveModes = false;
6781                 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
6782                     pw.print(" (");
6783                     switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
6784                         case Display.STATE_OFF: pw.print("screen-off"); break;
6785                         case Display.STATE_ON: pw.print("screen-on"); break;
6786                         case Display.STATE_DOZE: pw.print("screen-doze"); break;
6787                         case Display.STATE_DOZE_SUSPEND: pw.print("screen-doze-suspend"); break;
6788                         default: pw.print("screen-?"); break;
6789                     }
6790                     haveModes = true;
6791                 }
6792                 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
6793                     pw.print(haveModes ? ", " : " (");
6794                     pw.print((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0
6795                             ? "power-save-on" : "power-save-off");
6796                     haveModes = true;
6797                 }
6798                 if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
6799                     pw.print(haveModes ? ", " : " (");
6800                     pw.print((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0
6801                             ? "device-idle-on" : "device-idle-off");
6802                     haveModes = true;
6803                 }
6804                 if (haveModes) {
6805                     pw.print(")");
6806                 }
6807                 pw.println();
6808             }
6809         }
6810         return true;
6811     }
6812 
dumpDurationSteps(ProtoOutputStream proto, long fieldId, LevelStepTracker steps)6813     private static void dumpDurationSteps(ProtoOutputStream proto, long fieldId,
6814             LevelStepTracker steps) {
6815         if (steps == null) {
6816             return;
6817         }
6818         int count = steps.mNumStepDurations;
6819         for (int i = 0; i < count; ++i) {
6820             long token = proto.start(fieldId);
6821             proto.write(SystemProto.BatteryLevelStep.DURATION_MS, steps.getDurationAt(i));
6822             proto.write(SystemProto.BatteryLevelStep.LEVEL, steps.getLevelAt(i));
6823 
6824             final long initMode = steps.getInitModeAt(i);
6825             final long modMode = steps.getModModeAt(i);
6826 
6827             int ds = SystemProto.BatteryLevelStep.DS_MIXED;
6828             if ((modMode & STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
6829                 switch ((int) (initMode & STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
6830                     case Display.STATE_OFF:
6831                         ds = SystemProto.BatteryLevelStep.DS_OFF;
6832                         break;
6833                     case Display.STATE_ON:
6834                         ds = SystemProto.BatteryLevelStep.DS_ON;
6835                         break;
6836                     case Display.STATE_DOZE:
6837                         ds = SystemProto.BatteryLevelStep.DS_DOZE;
6838                         break;
6839                     case Display.STATE_DOZE_SUSPEND:
6840                         ds = SystemProto.BatteryLevelStep.DS_DOZE_SUSPEND;
6841                         break;
6842                     default:
6843                         ds = SystemProto.BatteryLevelStep.DS_ERROR;
6844                         break;
6845                 }
6846             }
6847             proto.write(SystemProto.BatteryLevelStep.DISPLAY_STATE, ds);
6848 
6849             int psm = SystemProto.BatteryLevelStep.PSM_MIXED;
6850             if ((modMode & STEP_LEVEL_MODE_POWER_SAVE) == 0) {
6851                 psm = (initMode & STEP_LEVEL_MODE_POWER_SAVE) != 0
6852                     ? SystemProto.BatteryLevelStep.PSM_ON : SystemProto.BatteryLevelStep.PSM_OFF;
6853             }
6854             proto.write(SystemProto.BatteryLevelStep.POWER_SAVE_MODE, psm);
6855 
6856             int im = SystemProto.BatteryLevelStep.IM_MIXED;
6857             if ((modMode & STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
6858                 im = (initMode & STEP_LEVEL_MODE_DEVICE_IDLE) != 0
6859                     ? SystemProto.BatteryLevelStep.IM_ON : SystemProto.BatteryLevelStep.IM_OFF;
6860             }
6861             proto.write(SystemProto.BatteryLevelStep.IDLE_MODE, im);
6862 
6863             proto.end(token);
6864         }
6865     }
6866 
6867     public static final int DUMP_CHARGED_ONLY = 1<<1;
6868     public static final int DUMP_DAILY_ONLY = 1<<2;
6869     public static final int DUMP_HISTORY_ONLY = 1<<3;
6870     public static final int DUMP_INCLUDE_HISTORY = 1<<4;
6871     public static final int DUMP_VERBOSE = 1<<5;
6872     public static final int DUMP_DEVICE_WIFI_ONLY = 1<<6;
6873 
dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin)6874     private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
6875         final HistoryPrinter hprinter = new HistoryPrinter();
6876         final HistoryItem rec = new HistoryItem();
6877         long lastTime = -1;
6878         long baseTime = -1;
6879         boolean printed = false;
6880         HistoryEventTracker tracker = null;
6881         while (getNextHistoryLocked(rec)) {
6882             lastTime = rec.time;
6883             if (baseTime < 0) {
6884                 baseTime = lastTime;
6885             }
6886             if (rec.time >= histStart) {
6887                 if (histStart >= 0 && !printed) {
6888                     if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
6889                             || rec.cmd == HistoryItem.CMD_RESET
6890                             || rec.cmd == HistoryItem.CMD_START
6891                             || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
6892                         printed = true;
6893                         hprinter.printNextItem(pw, rec, baseTime, checkin,
6894                                 (flags&DUMP_VERBOSE) != 0);
6895                         rec.cmd = HistoryItem.CMD_UPDATE;
6896                     } else if (rec.currentTime != 0) {
6897                         printed = true;
6898                         byte cmd = rec.cmd;
6899                         rec.cmd = HistoryItem.CMD_CURRENT_TIME;
6900                         hprinter.printNextItem(pw, rec, baseTime, checkin,
6901                                 (flags&DUMP_VERBOSE) != 0);
6902                         rec.cmd = cmd;
6903                     }
6904                     if (tracker != null) {
6905                         if (rec.cmd != HistoryItem.CMD_UPDATE) {
6906                             hprinter.printNextItem(pw, rec, baseTime, checkin,
6907                                     (flags&DUMP_VERBOSE) != 0);
6908                             rec.cmd = HistoryItem.CMD_UPDATE;
6909                         }
6910                         int oldEventCode = rec.eventCode;
6911                         HistoryTag oldEventTag = rec.eventTag;
6912                         rec.eventTag = new HistoryTag();
6913                         for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
6914                             HashMap<String, SparseIntArray> active
6915                                     = tracker.getStateForEvent(i);
6916                             if (active == null) {
6917                                 continue;
6918                             }
6919                             for (HashMap.Entry<String, SparseIntArray> ent
6920                                     : active.entrySet()) {
6921                                 SparseIntArray uids = ent.getValue();
6922                                 for (int j=0; j<uids.size(); j++) {
6923                                     rec.eventCode = i;
6924                                     rec.eventTag.string = ent.getKey();
6925                                     rec.eventTag.uid = uids.keyAt(j);
6926                                     rec.eventTag.poolIdx = uids.valueAt(j);
6927                                     hprinter.printNextItem(pw, rec, baseTime, checkin,
6928                                             (flags&DUMP_VERBOSE) != 0);
6929                                     rec.wakeReasonTag = null;
6930                                     rec.wakelockTag = null;
6931                                 }
6932                             }
6933                         }
6934                         rec.eventCode = oldEventCode;
6935                         rec.eventTag = oldEventTag;
6936                         tracker = null;
6937                     }
6938                 }
6939                 hprinter.printNextItem(pw, rec, baseTime, checkin,
6940                         (flags&DUMP_VERBOSE) != 0);
6941             } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) {
6942                 // This is an attempt to aggregate the previous state and generate
6943                 // fake events to reflect that state at the point where we start
6944                 // printing real events.  It doesn't really work right, so is turned off.
6945                 if (tracker == null) {
6946                     tracker = new HistoryEventTracker();
6947                 }
6948                 tracker.updateState(rec.eventCode, rec.eventTag.string,
6949                         rec.eventTag.uid, rec.eventTag.poolIdx);
6950             }
6951         }
6952         if (histStart >= 0) {
6953             commitCurrentHistoryBatchLocked();
6954             pw.print(checkin ? "NEXT: " : "  NEXT: "); pw.println(lastTime+1);
6955         }
6956     }
6957 
dumpDailyLevelStepSummary(PrintWriter pw, String prefix, String label, LevelStepTracker steps, StringBuilder tmpSb, int[] tmpOutInt)6958     private void dumpDailyLevelStepSummary(PrintWriter pw, String prefix, String label,
6959             LevelStepTracker steps, StringBuilder tmpSb, int[] tmpOutInt) {
6960         if (steps == null) {
6961             return;
6962         }
6963         long timeRemaining = steps.computeTimeEstimate(0, 0, tmpOutInt);
6964         if (timeRemaining >= 0) {
6965             pw.print(prefix); pw.print(label); pw.print(" total time: ");
6966             tmpSb.setLength(0);
6967             formatTimeMs(tmpSb, timeRemaining);
6968             pw.print(tmpSb);
6969             pw.print(" (from "); pw.print(tmpOutInt[0]);
6970             pw.println(" steps)");
6971         }
6972         for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
6973             long estimatedTime = steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
6974                     STEP_LEVEL_MODE_VALUES[i], tmpOutInt);
6975             if (estimatedTime > 0) {
6976                 pw.print(prefix); pw.print(label); pw.print(" ");
6977                 pw.print(STEP_LEVEL_MODE_LABELS[i]);
6978                 pw.print(" time: ");
6979                 tmpSb.setLength(0);
6980                 formatTimeMs(tmpSb, estimatedTime);
6981                 pw.print(tmpSb);
6982                 pw.print(" (from "); pw.print(tmpOutInt[0]);
6983                 pw.println(" steps)");
6984             }
6985         }
6986     }
6987 
dumpDailyPackageChanges(PrintWriter pw, String prefix, ArrayList<PackageChange> changes)6988     private void dumpDailyPackageChanges(PrintWriter pw, String prefix,
6989             ArrayList<PackageChange> changes) {
6990         if (changes == null) {
6991             return;
6992         }
6993         pw.print(prefix); pw.println("Package changes:");
6994         for (int i=0; i<changes.size(); i++) {
6995             PackageChange pc = changes.get(i);
6996             if (pc.mUpdate) {
6997                 pw.print(prefix); pw.print("  Update "); pw.print(pc.mPackageName);
6998                 pw.print(" vers="); pw.println(pc.mVersionCode);
6999             } else {
7000                 pw.print(prefix); pw.print("  Uninstall "); pw.println(pc.mPackageName);
7001             }
7002         }
7003     }
7004 
7005     /**
7006      * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
7007      *
7008      * @param pw a Printer to receive the dump output.
7009      */
7010     @SuppressWarnings("unused")
dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart)7011     public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
7012         prepareForDumpLocked();
7013 
7014         final boolean filtering = (flags
7015                 & (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
7016 
7017         if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
7018             final long historyTotalSize = getHistoryTotalSize();
7019             final long historyUsedSize = getHistoryUsedSize();
7020             if (startIteratingHistoryLocked()) {
7021                 try {
7022                     pw.print("Battery History (");
7023                     pw.print((100*historyUsedSize)/historyTotalSize);
7024                     pw.print("% used, ");
7025                     printSizeValue(pw, historyUsedSize);
7026                     pw.print(" used of ");
7027                     printSizeValue(pw, historyTotalSize);
7028                     pw.print(", ");
7029                     pw.print(getHistoryStringPoolSize());
7030                     pw.print(" strings using ");
7031                     printSizeValue(pw, getHistoryStringPoolBytes());
7032                     pw.println("):");
7033                     dumpHistoryLocked(pw, flags, histStart, false);
7034                     pw.println();
7035                 } finally {
7036                     finishIteratingHistoryLocked();
7037                 }
7038             }
7039         }
7040 
7041         if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
7042             return;
7043         }
7044 
7045         if (!filtering) {
7046             SparseArray<? extends Uid> uidStats = getUidStats();
7047             final int NU = uidStats.size();
7048             boolean didPid = false;
7049             long nowRealtime = SystemClock.elapsedRealtime();
7050             for (int i=0; i<NU; i++) {
7051                 Uid uid = uidStats.valueAt(i);
7052                 SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
7053                 if (pids != null) {
7054                     for (int j=0; j<pids.size(); j++) {
7055                         Uid.Pid pid = pids.valueAt(j);
7056                         if (!didPid) {
7057                             pw.println("Per-PID Stats:");
7058                             didPid = true;
7059                         }
7060                         long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
7061                                 ? (nowRealtime - pid.mWakeStartMs) : 0);
7062                         pw.print("  PID "); pw.print(pids.keyAt(j));
7063                                 pw.print(" wake time: ");
7064                                 TimeUtils.formatDuration(time, pw);
7065                                 pw.println("");
7066                     }
7067                 }
7068             }
7069             if (didPid) {
7070                 pw.println();
7071             }
7072         }
7073 
7074         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
7075             if (dumpDurationSteps(pw, "  ", "Discharge step durations:",
7076                     getDischargeLevelStepTracker(), false)) {
7077                 long timeRemaining = computeBatteryTimeRemaining(
7078                     SystemClock.elapsedRealtime() * 1000);
7079                 if (timeRemaining >= 0) {
7080                     pw.print("  Estimated discharge time remaining: ");
7081                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
7082                     pw.println();
7083                 }
7084                 final LevelStepTracker steps = getDischargeLevelStepTracker();
7085                 for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
7086                     dumpTimeEstimate(pw, "  Estimated ", STEP_LEVEL_MODE_LABELS[i], " time: ",
7087                             steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
7088                                     STEP_LEVEL_MODE_VALUES[i], null));
7089                 }
7090                 pw.println();
7091             }
7092             if (dumpDurationSteps(pw, "  ", "Charge step durations:",
7093                     getChargeLevelStepTracker(), false)) {
7094                 long timeRemaining = computeChargeTimeRemaining(
7095                     SystemClock.elapsedRealtime() * 1000);
7096                 if (timeRemaining >= 0) {
7097                     pw.print("  Estimated charge time remaining: ");
7098                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
7099                     pw.println();
7100                 }
7101                 pw.println();
7102             }
7103         }
7104         if (!filtering || (flags & DUMP_DAILY_ONLY) != 0) {
7105             pw.println("Daily stats:");
7106             pw.print("  Current start time: ");
7107             pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
7108                     getCurrentDailyStartTime()).toString());
7109             pw.print("  Next min deadline: ");
7110             pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
7111                     getNextMinDailyDeadline()).toString());
7112             pw.print("  Next max deadline: ");
7113             pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
7114                     getNextMaxDailyDeadline()).toString());
7115             StringBuilder sb = new StringBuilder(64);
7116             int[] outInt = new int[1];
7117             LevelStepTracker dsteps = getDailyDischargeLevelStepTracker();
7118             LevelStepTracker csteps = getDailyChargeLevelStepTracker();
7119             ArrayList<PackageChange> pkgc = getDailyPackageChanges();
7120             if (dsteps.mNumStepDurations > 0 || csteps.mNumStepDurations > 0 || pkgc != null) {
7121                 if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
7122                     if (dumpDurationSteps(pw, "    ", "  Current daily discharge step durations:",
7123                             dsteps, false)) {
7124                         dumpDailyLevelStepSummary(pw, "      ", "Discharge", dsteps,
7125                                 sb, outInt);
7126                     }
7127                     if (dumpDurationSteps(pw, "    ", "  Current daily charge step durations:",
7128                             csteps, false)) {
7129                         dumpDailyLevelStepSummary(pw, "      ", "Charge", csteps,
7130                                 sb, outInt);
7131                     }
7132                     dumpDailyPackageChanges(pw, "    ", pkgc);
7133                 } else {
7134                     pw.println("  Current daily steps:");
7135                     dumpDailyLevelStepSummary(pw, "    ", "Discharge", dsteps,
7136                             sb, outInt);
7137                     dumpDailyLevelStepSummary(pw, "    ", "Charge", csteps,
7138                             sb, outInt);
7139                 }
7140             }
7141             DailyItem dit;
7142             int curIndex = 0;
7143             while ((dit=getDailyItemLocked(curIndex)) != null) {
7144                 curIndex++;
7145                 if ((flags&DUMP_DAILY_ONLY) != 0) {
7146                     pw.println();
7147                 }
7148                 pw.print("  Daily from ");
7149                 pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mStartTime).toString());
7150                 pw.print(" to ");
7151                 pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mEndTime).toString());
7152                 pw.println(":");
7153                 if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
7154                     if (dumpDurationSteps(pw, "      ",
7155                             "    Discharge step durations:", dit.mDischargeSteps, false)) {
7156                         dumpDailyLevelStepSummary(pw, "        ", "Discharge", dit.mDischargeSteps,
7157                                 sb, outInt);
7158                     }
7159                     if (dumpDurationSteps(pw, "      ",
7160                             "    Charge step durations:", dit.mChargeSteps, false)) {
7161                         dumpDailyLevelStepSummary(pw, "        ", "Charge", dit.mChargeSteps,
7162                                 sb, outInt);
7163                     }
7164                     dumpDailyPackageChanges(pw, "    ", dit.mPackageChanges);
7165                 } else {
7166                     dumpDailyLevelStepSummary(pw, "    ", "Discharge", dit.mDischargeSteps,
7167                             sb, outInt);
7168                     dumpDailyLevelStepSummary(pw, "    ", "Charge", dit.mChargeSteps,
7169                             sb, outInt);
7170                 }
7171             }
7172             pw.println();
7173         }
7174         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
7175             pw.println("Statistics since last charge:");
7176             pw.println("  System starts: " + getStartCount()
7177                     + ", currently on battery: " + getIsOnBattery());
7178             dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
7179                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
7180             pw.println();
7181         }
7182     }
7183 
7184     // This is called from BatteryStatsService.
7185     @SuppressWarnings("unused")
dumpCheckinLocked(Context context, PrintWriter pw, List<ApplicationInfo> apps, int flags, long histStart)7186     public void dumpCheckinLocked(Context context, PrintWriter pw,
7187             List<ApplicationInfo> apps, int flags, long histStart) {
7188         prepareForDumpLocked();
7189 
7190         dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
7191                 CHECKIN_VERSION, getParcelVersion(), getStartPlatformVersion(),
7192                 getEndPlatformVersion());
7193 
7194         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
7195 
7196         if ((flags & (DUMP_INCLUDE_HISTORY | DUMP_HISTORY_ONLY)) != 0) {
7197             if (startIteratingHistoryLocked()) {
7198                 try {
7199                     for (int i=0; i<getHistoryStringPoolSize(); i++) {
7200                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
7201                         pw.print(HISTORY_STRING_POOL); pw.print(',');
7202                         pw.print(i);
7203                         pw.print(",");
7204                         pw.print(getHistoryTagPoolUid(i));
7205                         pw.print(",\"");
7206                         String str = getHistoryTagPoolString(i);
7207                         str = str.replace("\\", "\\\\");
7208                         str = str.replace("\"", "\\\"");
7209                         pw.print(str);
7210                         pw.print("\"");
7211                         pw.println();
7212                     }
7213                     dumpHistoryLocked(pw, flags, histStart, true);
7214                 } finally {
7215                     finishIteratingHistoryLocked();
7216                 }
7217             }
7218         }
7219 
7220         if ((flags & DUMP_HISTORY_ONLY) != 0) {
7221             return;
7222         }
7223 
7224         if (apps != null) {
7225             SparseArray<Pair<ArrayList<String>, MutableBoolean>> uids = new SparseArray<>();
7226             for (int i=0; i<apps.size(); i++) {
7227                 ApplicationInfo ai = apps.get(i);
7228                 Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(
7229                         UserHandle.getAppId(ai.uid));
7230                 if (pkgs == null) {
7231                     pkgs = new Pair<>(new ArrayList<String>(), new MutableBoolean(false));
7232                     uids.put(UserHandle.getAppId(ai.uid), pkgs);
7233                 }
7234                 pkgs.first.add(ai.packageName);
7235             }
7236             SparseArray<? extends Uid> uidStats = getUidStats();
7237             final int NU = uidStats.size();
7238             String[] lineArgs = new String[2];
7239             for (int i=0; i<NU; i++) {
7240                 int uid = UserHandle.getAppId(uidStats.keyAt(i));
7241                 Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(uid);
7242                 if (pkgs != null && !pkgs.second.value) {
7243                     pkgs.second.value = true;
7244                     for (int j=0; j<pkgs.first.size(); j++) {
7245                         lineArgs[0] = Integer.toString(uid);
7246                         lineArgs[1] = pkgs.first.get(j);
7247                         dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
7248                                 (Object[])lineArgs);
7249                     }
7250                 }
7251             }
7252         }
7253         if ((flags & DUMP_DAILY_ONLY) == 0) {
7254             dumpDurationSteps(pw, "", DISCHARGE_STEP_DATA, getDischargeLevelStepTracker(), true);
7255             String[] lineArgs = new String[1];
7256             long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime() * 1000);
7257             if (timeRemaining >= 0) {
7258                 lineArgs[0] = Long.toString(timeRemaining);
7259                 dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA,
7260                         (Object[])lineArgs);
7261             }
7262             dumpDurationSteps(pw, "", CHARGE_STEP_DATA, getChargeLevelStepTracker(), true);
7263             timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime() * 1000);
7264             if (timeRemaining >= 0) {
7265                 lineArgs[0] = Long.toString(timeRemaining);
7266                 dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA,
7267                         (Object[])lineArgs);
7268             }
7269             dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
7270                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
7271         }
7272     }
7273 
7274     /**
7275      * Dump #STATS_SINCE_CHARGED batterystats data to a proto. If the flags include
7276      * DUMP_INCLUDE_HISTORY or DUMP_HISTORY_ONLY, only the history will be dumped.
7277      * @hide
7278      */
dumpProtoLocked(Context context, FileDescriptor fd, List<ApplicationInfo> apps, int flags, long histStart)7279     public void dumpProtoLocked(Context context, FileDescriptor fd, List<ApplicationInfo> apps,
7280             int flags, long histStart) {
7281         final ProtoOutputStream proto = new ProtoOutputStream(fd);
7282         prepareForDumpLocked();
7283 
7284         if ((flags & (DUMP_INCLUDE_HISTORY | DUMP_HISTORY_ONLY)) != 0) {
7285             dumpProtoHistoryLocked(proto, flags, histStart);
7286             proto.flush();
7287             return;
7288         }
7289 
7290         final long bToken = proto.start(BatteryStatsServiceDumpProto.BATTERYSTATS);
7291 
7292         proto.write(BatteryStatsProto.REPORT_VERSION, CHECKIN_VERSION);
7293         proto.write(BatteryStatsProto.PARCEL_VERSION, getParcelVersion());
7294         proto.write(BatteryStatsProto.START_PLATFORM_VERSION, getStartPlatformVersion());
7295         proto.write(BatteryStatsProto.END_PLATFORM_VERSION, getEndPlatformVersion());
7296 
7297         if ((flags & DUMP_DAILY_ONLY) == 0) {
7298             final BatteryStatsHelper helper = new BatteryStatsHelper(context, false,
7299                     (flags & DUMP_DEVICE_WIFI_ONLY) != 0);
7300             helper.create(this);
7301             helper.refreshStats(STATS_SINCE_CHARGED, UserHandle.USER_ALL);
7302 
7303             dumpProtoAppsLocked(proto, helper, apps);
7304             dumpProtoSystemLocked(proto, helper);
7305         }
7306 
7307         proto.end(bToken);
7308         proto.flush();
7309     }
7310 
dumpProtoAppsLocked(ProtoOutputStream proto, BatteryStatsHelper helper, List<ApplicationInfo> apps)7311     private void dumpProtoAppsLocked(ProtoOutputStream proto, BatteryStatsHelper helper,
7312             List<ApplicationInfo> apps) {
7313         final int which = STATS_SINCE_CHARGED;
7314         final long rawUptimeUs = SystemClock.uptimeMillis() * 1000;
7315         final long rawRealtimeMs = SystemClock.elapsedRealtime();
7316         final long rawRealtimeUs = rawRealtimeMs * 1000;
7317         final long batteryUptimeUs = getBatteryUptime(rawUptimeUs);
7318 
7319         SparseArray<ArrayList<String>> aidToPackages = new SparseArray<>();
7320         if (apps != null) {
7321             for (int i = 0; i < apps.size(); ++i) {
7322                 ApplicationInfo ai = apps.get(i);
7323                 int aid = UserHandle.getAppId(ai.uid);
7324                 ArrayList<String> pkgs = aidToPackages.get(aid);
7325                 if (pkgs == null) {
7326                     pkgs = new ArrayList<String>();
7327                     aidToPackages.put(aid, pkgs);
7328                 }
7329                 pkgs.add(ai.packageName);
7330             }
7331         }
7332 
7333         SparseArray<BatterySipper> uidToSipper = new SparseArray<>();
7334         final List<BatterySipper> sippers = helper.getUsageList();
7335         if (sippers != null) {
7336             for (int i = 0; i < sippers.size(); ++i) {
7337                 final BatterySipper bs = sippers.get(i);
7338                 if (bs.drainType != BatterySipper.DrainType.APP) {
7339                     // Others are handled by dumpProtoSystemLocked()
7340                     continue;
7341                 }
7342                 uidToSipper.put(bs.uidObj.getUid(), bs);
7343             }
7344         }
7345 
7346         SparseArray<? extends Uid> uidStats = getUidStats();
7347         final int n = uidStats.size();
7348         for (int iu = 0; iu < n; ++iu) {
7349             final long uTkn = proto.start(BatteryStatsProto.UIDS);
7350             final Uid u = uidStats.valueAt(iu);
7351 
7352             final int uid = uidStats.keyAt(iu);
7353             proto.write(UidProto.UID, uid);
7354 
7355             // Print packages and apk stats (UID_DATA & APK_DATA)
7356             ArrayList<String> pkgs = aidToPackages.get(UserHandle.getAppId(uid));
7357             if (pkgs == null) {
7358                 pkgs = new ArrayList<String>();
7359             }
7360             final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats =
7361                     u.getPackageStats();
7362             for (int ipkg = packageStats.size() - 1; ipkg >= 0; --ipkg) {
7363                 String pkg = packageStats.keyAt(ipkg);
7364                 final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats =
7365                         packageStats.valueAt(ipkg).getServiceStats();
7366                 if (serviceStats.size() == 0) {
7367                     // Due to the way ActivityManagerService logs wakeup alarms, some packages (for
7368                     // example, "android") may be included in the packageStats that aren't part of
7369                     // the UID. If they don't have any services, then they shouldn't be listed here.
7370                     // These packages won't be a part in the pkgs List.
7371                     continue;
7372                 }
7373 
7374                 final long pToken = proto.start(UidProto.PACKAGES);
7375                 proto.write(UidProto.Package.NAME, pkg);
7376                 // Remove from the packages list since we're logging it here.
7377                 pkgs.remove(pkg);
7378 
7379                 for (int isvc = serviceStats.size() - 1; isvc >= 0; --isvc) {
7380                     final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
7381 
7382                     final long startTimeMs = roundUsToMs(ss.getStartTime(batteryUptimeUs, which));
7383                     final int starts = ss.getStarts(which);
7384                     final int launches = ss.getLaunches(which);
7385                     if (startTimeMs == 0 && starts == 0 && launches == 0) {
7386                         continue;
7387                     }
7388 
7389                     long sToken = proto.start(UidProto.Package.SERVICES);
7390 
7391                     proto.write(UidProto.Package.Service.NAME, serviceStats.keyAt(isvc));
7392                     proto.write(UidProto.Package.Service.START_DURATION_MS, startTimeMs);
7393                     proto.write(UidProto.Package.Service.START_COUNT, starts);
7394                     proto.write(UidProto.Package.Service.LAUNCH_COUNT, launches);
7395 
7396                     proto.end(sToken);
7397                 }
7398                 proto.end(pToken);
7399             }
7400             // Print any remaining packages that weren't in the packageStats map. pkgs is pulled
7401             // from PackageManager data. Packages are only included in packageStats if there was
7402             // specific data tracked for them (services and wakeup alarms, etc.).
7403             for (String p : pkgs) {
7404                 final long pToken = proto.start(UidProto.PACKAGES);
7405                 proto.write(UidProto.Package.NAME, p);
7406                 proto.end(pToken);
7407             }
7408 
7409             // Total wakelock data (AGGREGATED_WAKELOCK_DATA)
7410             if (u.getAggregatedPartialWakelockTimer() != null) {
7411                 final Timer timer = u.getAggregatedPartialWakelockTimer();
7412                 // Times are since reset (regardless of 'which')
7413                 final long totTimeMs = timer.getTotalDurationMsLocked(rawRealtimeMs);
7414                 final Timer bgTimer = timer.getSubTimer();
7415                 final long bgTimeMs = bgTimer != null
7416                         ? bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
7417                 final long awToken = proto.start(UidProto.AGGREGATED_WAKELOCK);
7418                 proto.write(UidProto.AggregatedWakelock.PARTIAL_DURATION_MS, totTimeMs);
7419                 proto.write(UidProto.AggregatedWakelock.BACKGROUND_PARTIAL_DURATION_MS, bgTimeMs);
7420                 proto.end(awToken);
7421             }
7422 
7423             // Audio (AUDIO_DATA)
7424             dumpTimer(proto, UidProto.AUDIO, u.getAudioTurnedOnTimer(), rawRealtimeUs, which);
7425 
7426             // Bluetooth Controller (BLUETOOTH_CONTROLLER_DATA)
7427             dumpControllerActivityProto(proto, UidProto.BLUETOOTH_CONTROLLER,
7428                     u.getBluetoothControllerActivity(), which);
7429 
7430             // BLE scans (BLUETOOTH_MISC_DATA) (uses totalDurationMsLocked and MaxDurationMsLocked)
7431             final Timer bleTimer = u.getBluetoothScanTimer();
7432             if (bleTimer != null) {
7433                 final long bmToken = proto.start(UidProto.BLUETOOTH_MISC);
7434 
7435                 dumpTimer(proto, UidProto.BluetoothMisc.APPORTIONED_BLE_SCAN, bleTimer,
7436                         rawRealtimeUs, which);
7437                 dumpTimer(proto, UidProto.BluetoothMisc.BACKGROUND_BLE_SCAN,
7438                         u.getBluetoothScanBackgroundTimer(), rawRealtimeUs, which);
7439                 // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
7440                 dumpTimer(proto, UidProto.BluetoothMisc.UNOPTIMIZED_BLE_SCAN,
7441                         u.getBluetoothUnoptimizedScanTimer(), rawRealtimeUs, which);
7442                 // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
7443                 dumpTimer(proto, UidProto.BluetoothMisc.BACKGROUND_UNOPTIMIZED_BLE_SCAN,
7444                         u.getBluetoothUnoptimizedScanBackgroundTimer(), rawRealtimeUs, which);
7445                 // Result counters
7446                 proto.write(UidProto.BluetoothMisc.BLE_SCAN_RESULT_COUNT,
7447                         u.getBluetoothScanResultCounter() != null
7448                             ? u.getBluetoothScanResultCounter().getCountLocked(which) : 0);
7449                 proto.write(UidProto.BluetoothMisc.BACKGROUND_BLE_SCAN_RESULT_COUNT,
7450                         u.getBluetoothScanResultBgCounter() != null
7451                             ? u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0);
7452 
7453                 proto.end(bmToken);
7454             }
7455 
7456             // Camera (CAMERA_DATA)
7457             dumpTimer(proto, UidProto.CAMERA, u.getCameraTurnedOnTimer(), rawRealtimeUs, which);
7458 
7459             // CPU stats (CPU_DATA & CPU_TIMES_AT_FREQ_DATA)
7460             final long cpuToken = proto.start(UidProto.CPU);
7461             proto.write(UidProto.Cpu.USER_DURATION_MS, roundUsToMs(u.getUserCpuTimeUs(which)));
7462             proto.write(UidProto.Cpu.SYSTEM_DURATION_MS, roundUsToMs(u.getSystemCpuTimeUs(which)));
7463 
7464             final long[] cpuFreqs = getCpuFreqs();
7465             if (cpuFreqs != null) {
7466                 final long[] cpuFreqTimeMs = u.getCpuFreqTimes(which);
7467                 // If total cpuFreqTimes is null, then we don't need to check for
7468                 // screenOffCpuFreqTimes.
7469                 if (cpuFreqTimeMs != null && cpuFreqTimeMs.length == cpuFreqs.length) {
7470                     long[] screenOffCpuFreqTimeMs = u.getScreenOffCpuFreqTimes(which);
7471                     if (screenOffCpuFreqTimeMs == null) {
7472                         screenOffCpuFreqTimeMs = new long[cpuFreqTimeMs.length];
7473                     }
7474                     for (int ic = 0; ic < cpuFreqTimeMs.length; ++ic) {
7475                         long cToken = proto.start(UidProto.Cpu.BY_FREQUENCY);
7476                         proto.write(UidProto.Cpu.ByFrequency.FREQUENCY_INDEX, ic + 1);
7477                         proto.write(UidProto.Cpu.ByFrequency.TOTAL_DURATION_MS,
7478                                 cpuFreqTimeMs[ic]);
7479                         proto.write(UidProto.Cpu.ByFrequency.SCREEN_OFF_DURATION_MS,
7480                                 screenOffCpuFreqTimeMs[ic]);
7481                         proto.end(cToken);
7482                     }
7483                 }
7484             }
7485 
7486             for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
7487                 final long[] timesMs = u.getCpuFreqTimes(which, procState);
7488                 if (timesMs != null && timesMs.length == cpuFreqs.length) {
7489                     long[] screenOffTimesMs = u.getScreenOffCpuFreqTimes(which, procState);
7490                     if (screenOffTimesMs == null) {
7491                         screenOffTimesMs = new long[timesMs.length];
7492                     }
7493                     final long procToken = proto.start(UidProto.Cpu.BY_PROCESS_STATE);
7494                     proto.write(UidProto.Cpu.ByProcessState.PROCESS_STATE, procState);
7495                     for (int ic = 0; ic < timesMs.length; ++ic) {
7496                         long cToken = proto.start(UidProto.Cpu.ByProcessState.BY_FREQUENCY);
7497                         proto.write(UidProto.Cpu.ByFrequency.FREQUENCY_INDEX, ic + 1);
7498                         proto.write(UidProto.Cpu.ByFrequency.TOTAL_DURATION_MS,
7499                                 timesMs[ic]);
7500                         proto.write(UidProto.Cpu.ByFrequency.SCREEN_OFF_DURATION_MS,
7501                                 screenOffTimesMs[ic]);
7502                         proto.end(cToken);
7503                     }
7504                     proto.end(procToken);
7505                 }
7506             }
7507             proto.end(cpuToken);
7508 
7509             // Flashlight (FLASHLIGHT_DATA)
7510             dumpTimer(proto, UidProto.FLASHLIGHT, u.getFlashlightTurnedOnTimer(),
7511                     rawRealtimeUs, which);
7512 
7513             // Foreground activity (FOREGROUND_ACTIVITY_DATA)
7514             dumpTimer(proto, UidProto.FOREGROUND_ACTIVITY, u.getForegroundActivityTimer(),
7515                     rawRealtimeUs, which);
7516 
7517             // Foreground service (FOREGROUND_SERVICE_DATA)
7518             dumpTimer(proto, UidProto.FOREGROUND_SERVICE, u.getForegroundServiceTimer(),
7519                     rawRealtimeUs, which);
7520 
7521             // Job completion (JOB_COMPLETION_DATA)
7522             final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
7523             for (int ic = 0; ic < completions.size(); ++ic) {
7524                 SparseIntArray types = completions.valueAt(ic);
7525                 if (types != null) {
7526                     final long jcToken = proto.start(UidProto.JOB_COMPLETION);
7527 
7528                     proto.write(UidProto.JobCompletion.NAME, completions.keyAt(ic));
7529 
7530                     for (int r : JobParameters.getJobStopReasonCodes()) {
7531                         long rToken = proto.start(UidProto.JobCompletion.REASON_COUNT);
7532                         proto.write(UidProto.JobCompletion.ReasonCount.NAME, r);
7533                         proto.write(UidProto.JobCompletion.ReasonCount.COUNT, types.get(r, 0));
7534                         proto.end(rToken);
7535                     }
7536 
7537                     proto.end(jcToken);
7538                 }
7539             }
7540 
7541             // Scheduled jobs (JOB_DATA)
7542             final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
7543             for (int ij = jobs.size() - 1; ij >= 0; --ij) {
7544                 final Timer timer = jobs.valueAt(ij);
7545                 final Timer bgTimer = timer.getSubTimer();
7546                 final long jToken = proto.start(UidProto.JOBS);
7547 
7548                 proto.write(UidProto.Job.NAME, jobs.keyAt(ij));
7549                 // Background uses totalDurationMsLocked, while total uses totalTimeLocked
7550                 dumpTimer(proto, UidProto.Job.TOTAL, timer, rawRealtimeUs, which);
7551                 dumpTimer(proto, UidProto.Job.BACKGROUND, bgTimer, rawRealtimeUs, which);
7552 
7553                 proto.end(jToken);
7554             }
7555 
7556             // Modem Controller (MODEM_CONTROLLER_DATA)
7557             dumpControllerActivityProto(proto, UidProto.MODEM_CONTROLLER,
7558                     u.getModemControllerActivity(), which);
7559 
7560             // Network stats (NETWORK_DATA)
7561             final long nToken = proto.start(UidProto.NETWORK);
7562             proto.write(UidProto.Network.MOBILE_BYTES_RX,
7563                     u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which));
7564             proto.write(UidProto.Network.MOBILE_BYTES_TX,
7565                     u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which));
7566             proto.write(UidProto.Network.WIFI_BYTES_RX,
7567                     u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
7568             proto.write(UidProto.Network.WIFI_BYTES_TX,
7569                     u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
7570             proto.write(UidProto.Network.BT_BYTES_RX,
7571                     u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which));
7572             proto.write(UidProto.Network.BT_BYTES_TX,
7573                     u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which));
7574             proto.write(UidProto.Network.MOBILE_PACKETS_RX,
7575                     u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which));
7576             proto.write(UidProto.Network.MOBILE_PACKETS_TX,
7577                     u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which));
7578             proto.write(UidProto.Network.WIFI_PACKETS_RX,
7579                     u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
7580             proto.write(UidProto.Network.WIFI_PACKETS_TX,
7581                     u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
7582             proto.write(UidProto.Network.MOBILE_ACTIVE_DURATION_MS,
7583                     roundUsToMs(u.getMobileRadioActiveTime(which)));
7584             proto.write(UidProto.Network.MOBILE_ACTIVE_COUNT,
7585                     u.getMobileRadioActiveCount(which));
7586             proto.write(UidProto.Network.MOBILE_WAKEUP_COUNT,
7587                     u.getMobileRadioApWakeupCount(which));
7588             proto.write(UidProto.Network.WIFI_WAKEUP_COUNT,
7589                     u.getWifiRadioApWakeupCount(which));
7590             proto.write(UidProto.Network.MOBILE_BYTES_BG_RX,
7591                     u.getNetworkActivityBytes(NETWORK_MOBILE_BG_RX_DATA, which));
7592             proto.write(UidProto.Network.MOBILE_BYTES_BG_TX,
7593                     u.getNetworkActivityBytes(NETWORK_MOBILE_BG_TX_DATA, which));
7594             proto.write(UidProto.Network.WIFI_BYTES_BG_RX,
7595                     u.getNetworkActivityBytes(NETWORK_WIFI_BG_RX_DATA, which));
7596             proto.write(UidProto.Network.WIFI_BYTES_BG_TX,
7597                     u.getNetworkActivityBytes(NETWORK_WIFI_BG_TX_DATA, which));
7598             proto.write(UidProto.Network.MOBILE_PACKETS_BG_RX,
7599                     u.getNetworkActivityPackets(NETWORK_MOBILE_BG_RX_DATA, which));
7600             proto.write(UidProto.Network.MOBILE_PACKETS_BG_TX,
7601                     u.getNetworkActivityPackets(NETWORK_MOBILE_BG_TX_DATA, which));
7602             proto.write(UidProto.Network.WIFI_PACKETS_BG_RX,
7603                     u.getNetworkActivityPackets(NETWORK_WIFI_BG_RX_DATA, which));
7604             proto.write(UidProto.Network.WIFI_PACKETS_BG_TX,
7605                     u.getNetworkActivityPackets(NETWORK_WIFI_BG_TX_DATA, which));
7606             proto.end(nToken);
7607 
7608             // Power use item (POWER_USE_ITEM_DATA)
7609             BatterySipper bs = uidToSipper.get(uid);
7610             if (bs != null) {
7611                 final long bsToken = proto.start(UidProto.POWER_USE_ITEM);
7612                 proto.write(UidProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah);
7613                 proto.write(UidProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide);
7614                 proto.write(UidProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah);
7615                 proto.write(UidProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH,
7616                         bs.proportionalSmearMah);
7617                 proto.end(bsToken);
7618             }
7619 
7620             // Processes (PROCESS_DATA)
7621             final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats =
7622                     u.getProcessStats();
7623             for (int ipr = processStats.size() - 1; ipr >= 0; --ipr) {
7624                 final Uid.Proc ps = processStats.valueAt(ipr);
7625                 final long prToken = proto.start(UidProto.PROCESS);
7626 
7627                 proto.write(UidProto.Process.NAME, processStats.keyAt(ipr));
7628                 proto.write(UidProto.Process.USER_DURATION_MS, ps.getUserTime(which));
7629                 proto.write(UidProto.Process.SYSTEM_DURATION_MS, ps.getSystemTime(which));
7630                 proto.write(UidProto.Process.FOREGROUND_DURATION_MS, ps.getForegroundTime(which));
7631                 proto.write(UidProto.Process.START_COUNT, ps.getStarts(which));
7632                 proto.write(UidProto.Process.ANR_COUNT, ps.getNumAnrs(which));
7633                 proto.write(UidProto.Process.CRASH_COUNT, ps.getNumCrashes(which));
7634 
7635                 proto.end(prToken);
7636             }
7637 
7638             // Sensors (SENSOR_DATA)
7639             final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
7640             for (int ise = 0; ise < sensors.size(); ++ise) {
7641                 final Uid.Sensor se = sensors.valueAt(ise);
7642                 final Timer timer = se.getSensorTime();
7643                 if (timer == null) {
7644                     continue;
7645                 }
7646                 final Timer bgTimer = se.getSensorBackgroundTime();
7647                 final int sensorNumber = sensors.keyAt(ise);
7648                 final long seToken = proto.start(UidProto.SENSORS);
7649 
7650                 proto.write(UidProto.Sensor.ID, sensorNumber);
7651                 // Background uses totalDurationMsLocked, while total uses totalTimeLocked
7652                 dumpTimer(proto, UidProto.Sensor.APPORTIONED, timer, rawRealtimeUs, which);
7653                 dumpTimer(proto, UidProto.Sensor.BACKGROUND, bgTimer, rawRealtimeUs, which);
7654 
7655                 proto.end(seToken);
7656             }
7657 
7658             // State times (STATE_TIME_DATA)
7659             for (int ips = 0; ips < Uid.NUM_PROCESS_STATE; ++ips) {
7660                 long durMs = roundUsToMs(u.getProcessStateTime(ips, rawRealtimeUs, which));
7661                 if (durMs == 0) {
7662                     continue;
7663                 }
7664                 final long stToken = proto.start(UidProto.STATES);
7665                 proto.write(UidProto.StateTime.STATE, ips);
7666                 proto.write(UidProto.StateTime.DURATION_MS, durMs);
7667                 proto.end(stToken);
7668             }
7669 
7670             // Syncs (SYNC_DATA)
7671             final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
7672             for (int isy = syncs.size() - 1; isy >= 0; --isy) {
7673                 final Timer timer = syncs.valueAt(isy);
7674                 final Timer bgTimer = timer.getSubTimer();
7675                 final long syToken = proto.start(UidProto.SYNCS);
7676 
7677                 proto.write(UidProto.Sync.NAME, syncs.keyAt(isy));
7678                 // Background uses totalDurationMsLocked, while total uses totalTimeLocked
7679                 dumpTimer(proto, UidProto.Sync.TOTAL, timer, rawRealtimeUs, which);
7680                 dumpTimer(proto, UidProto.Sync.BACKGROUND, bgTimer, rawRealtimeUs, which);
7681 
7682                 proto.end(syToken);
7683             }
7684 
7685             // User activity (USER_ACTIVITY_DATA)
7686             if (u.hasUserActivity()) {
7687                 for (int i = 0; i < Uid.NUM_USER_ACTIVITY_TYPES; ++i) {
7688                     int val = u.getUserActivityCount(i, which);
7689                     if (val != 0) {
7690                         final long uaToken = proto.start(UidProto.USER_ACTIVITY);
7691                         proto.write(UidProto.UserActivity.NAME, i);
7692                         proto.write(UidProto.UserActivity.COUNT, val);
7693                         proto.end(uaToken);
7694                     }
7695                 }
7696             }
7697 
7698             // Vibrator (VIBRATOR_DATA)
7699             dumpTimer(proto, UidProto.VIBRATOR, u.getVibratorOnTimer(), rawRealtimeUs, which);
7700 
7701             // Video (VIDEO_DATA)
7702             dumpTimer(proto, UidProto.VIDEO, u.getVideoTurnedOnTimer(), rawRealtimeUs, which);
7703 
7704             // Wakelocks (WAKELOCK_DATA)
7705             final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
7706             for (int iw = wakelocks.size() - 1; iw >= 0; --iw) {
7707                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
7708                 final long wToken = proto.start(UidProto.WAKELOCKS);
7709                 proto.write(UidProto.Wakelock.NAME, wakelocks.keyAt(iw));
7710                 dumpTimer(proto, UidProto.Wakelock.FULL, wl.getWakeTime(WAKE_TYPE_FULL),
7711                         rawRealtimeUs, which);
7712                 final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
7713                 if (pTimer != null) {
7714                     dumpTimer(proto, UidProto.Wakelock.PARTIAL, pTimer, rawRealtimeUs, which);
7715                     dumpTimer(proto, UidProto.Wakelock.BACKGROUND_PARTIAL, pTimer.getSubTimer(),
7716                             rawRealtimeUs, which);
7717                 }
7718                 dumpTimer(proto, UidProto.Wakelock.WINDOW, wl.getWakeTime(WAKE_TYPE_WINDOW),
7719                         rawRealtimeUs, which);
7720                 proto.end(wToken);
7721             }
7722 
7723             // Wifi Multicast Wakelock (WIFI_MULTICAST_WAKELOCK_DATA)
7724             dumpTimer(proto, UidProto.WIFI_MULTICAST_WAKELOCK, u.getMulticastWakelockStats(),
7725                     rawRealtimeUs, which);
7726 
7727             // Wakeup alarms (WAKEUP_ALARM_DATA)
7728             for (int ipkg = packageStats.size() - 1; ipkg >= 0; --ipkg) {
7729                 final Uid.Pkg ps = packageStats.valueAt(ipkg);
7730                 final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
7731                 for (int iwa = alarms.size() - 1; iwa >= 0; --iwa) {
7732                     final long waToken = proto.start(UidProto.WAKEUP_ALARM);
7733                     proto.write(UidProto.WakeupAlarm.NAME, alarms.keyAt(iwa));
7734                     proto.write(UidProto.WakeupAlarm.COUNT,
7735                             alarms.valueAt(iwa).getCountLocked(which));
7736                     proto.end(waToken);
7737                 }
7738             }
7739 
7740             // Wifi Controller (WIFI_CONTROLLER_DATA)
7741             dumpControllerActivityProto(proto, UidProto.WIFI_CONTROLLER,
7742                     u.getWifiControllerActivity(), which);
7743 
7744             // Wifi data (WIFI_DATA)
7745             final long wToken = proto.start(UidProto.WIFI);
7746             proto.write(UidProto.Wifi.FULL_WIFI_LOCK_DURATION_MS,
7747                     roundUsToMs(u.getFullWifiLockTime(rawRealtimeUs, which)));
7748             dumpTimer(proto, UidProto.Wifi.APPORTIONED_SCAN, u.getWifiScanTimer(),
7749                     rawRealtimeUs, which);
7750             proto.write(UidProto.Wifi.RUNNING_DURATION_MS,
7751                     roundUsToMs(u.getWifiRunningTime(rawRealtimeUs, which)));
7752             dumpTimer(proto, UidProto.Wifi.BACKGROUND_SCAN, u.getWifiScanBackgroundTimer(),
7753                     rawRealtimeUs, which);
7754             proto.end(wToken);
7755 
7756             proto.end(uTkn);
7757         }
7758     }
7759 
dumpProtoHistoryLocked(ProtoOutputStream proto, int flags, long histStart)7760     private void dumpProtoHistoryLocked(ProtoOutputStream proto, int flags, long histStart) {
7761         if (!startIteratingHistoryLocked()) {
7762             return;
7763         }
7764 
7765         proto.write(BatteryStatsServiceDumpHistoryProto.REPORT_VERSION, CHECKIN_VERSION);
7766         proto.write(BatteryStatsServiceDumpHistoryProto.PARCEL_VERSION, getParcelVersion());
7767         proto.write(BatteryStatsServiceDumpHistoryProto.START_PLATFORM_VERSION,
7768                 getStartPlatformVersion());
7769         proto.write(BatteryStatsServiceDumpHistoryProto.END_PLATFORM_VERSION,
7770                 getEndPlatformVersion());
7771         try {
7772             long token;
7773             // History string pool (HISTORY_STRING_POOL)
7774             for (int i = 0; i < getHistoryStringPoolSize(); ++i) {
7775                 token = proto.start(BatteryStatsServiceDumpHistoryProto.KEYS);
7776                 proto.write(BatteryStatsServiceDumpHistoryProto.Key.INDEX, i);
7777                 proto.write(BatteryStatsServiceDumpHistoryProto.Key.UID, getHistoryTagPoolUid(i));
7778                 proto.write(BatteryStatsServiceDumpHistoryProto.Key.TAG,
7779                         getHistoryTagPoolString(i));
7780                 proto.end(token);
7781             }
7782 
7783             // History data (HISTORY_DATA)
7784             final HistoryPrinter hprinter = new HistoryPrinter();
7785             final HistoryItem rec = new HistoryItem();
7786             long lastTime = -1;
7787             long baseTime = -1;
7788             boolean printed = false;
7789             HistoryEventTracker tracker = null;
7790             while (getNextHistoryLocked(rec)) {
7791                 lastTime = rec.time;
7792                 if (baseTime < 0) {
7793                     baseTime = lastTime;
7794                 }
7795                 if (rec.time >= histStart) {
7796                     if (histStart >= 0 && !printed) {
7797                         if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
7798                                 || rec.cmd == HistoryItem.CMD_RESET
7799                                 || rec.cmd == HistoryItem.CMD_START
7800                                 || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
7801                             printed = true;
7802                             hprinter.printNextItem(proto, rec, baseTime,
7803                                     (flags & DUMP_VERBOSE) != 0);
7804                             rec.cmd = HistoryItem.CMD_UPDATE;
7805                         } else if (rec.currentTime != 0) {
7806                             printed = true;
7807                             byte cmd = rec.cmd;
7808                             rec.cmd = HistoryItem.CMD_CURRENT_TIME;
7809                             hprinter.printNextItem(proto, rec, baseTime,
7810                                     (flags & DUMP_VERBOSE) != 0);
7811                             rec.cmd = cmd;
7812                         }
7813                         if (tracker != null) {
7814                             if (rec.cmd != HistoryItem.CMD_UPDATE) {
7815                                 hprinter.printNextItem(proto, rec, baseTime,
7816                                         (flags & DUMP_VERBOSE) != 0);
7817                                 rec.cmd = HistoryItem.CMD_UPDATE;
7818                             }
7819                             int oldEventCode = rec.eventCode;
7820                             HistoryTag oldEventTag = rec.eventTag;
7821                             rec.eventTag = new HistoryTag();
7822                             for (int i = 0; i < HistoryItem.EVENT_COUNT; i++) {
7823                                 HashMap<String, SparseIntArray> active =
7824                                         tracker.getStateForEvent(i);
7825                                 if (active == null) {
7826                                     continue;
7827                                 }
7828                                 for (HashMap.Entry<String, SparseIntArray> ent
7829                                         : active.entrySet()) {
7830                                     SparseIntArray uids = ent.getValue();
7831                                     for (int j = 0; j < uids.size(); j++) {
7832                                         rec.eventCode = i;
7833                                         rec.eventTag.string = ent.getKey();
7834                                         rec.eventTag.uid = uids.keyAt(j);
7835                                         rec.eventTag.poolIdx = uids.valueAt(j);
7836                                         hprinter.printNextItem(proto, rec, baseTime,
7837                                                 (flags & DUMP_VERBOSE) != 0);
7838                                         rec.wakeReasonTag = null;
7839                                         rec.wakelockTag = null;
7840                                     }
7841                                 }
7842                             }
7843                             rec.eventCode = oldEventCode;
7844                             rec.eventTag = oldEventTag;
7845                             tracker = null;
7846                         }
7847                     }
7848                     hprinter.printNextItem(proto, rec, baseTime,
7849                             (flags & DUMP_VERBOSE) != 0);
7850                 }
7851             }
7852             if (histStart >= 0) {
7853                 commitCurrentHistoryBatchLocked();
7854                 proto.write(BatteryStatsServiceDumpHistoryProto.CSV_LINES,
7855                         "NEXT: " + (lastTime + 1));
7856             }
7857         } finally {
7858             finishIteratingHistoryLocked();
7859         }
7860     }
7861 
dumpProtoSystemLocked(ProtoOutputStream proto, BatteryStatsHelper helper)7862     private void dumpProtoSystemLocked(ProtoOutputStream proto, BatteryStatsHelper helper) {
7863         final long sToken = proto.start(BatteryStatsProto.SYSTEM);
7864         final long rawUptimeUs = SystemClock.uptimeMillis() * 1000;
7865         final long rawRealtimeMs = SystemClock.elapsedRealtime();
7866         final long rawRealtimeUs = rawRealtimeMs * 1000;
7867         final int which = STATS_SINCE_CHARGED;
7868 
7869         // Battery data (BATTERY_DATA)
7870         final long bToken = proto.start(SystemProto.BATTERY);
7871         proto.write(SystemProto.Battery.START_CLOCK_TIME_MS, getStartClockTime());
7872         proto.write(SystemProto.Battery.START_COUNT, getStartCount());
7873         proto.write(SystemProto.Battery.TOTAL_REALTIME_MS,
7874                 computeRealtime(rawRealtimeUs, which) / 1000);
7875         proto.write(SystemProto.Battery.TOTAL_UPTIME_MS,
7876                 computeUptime(rawUptimeUs, which) / 1000);
7877         proto.write(SystemProto.Battery.BATTERY_REALTIME_MS,
7878                 computeBatteryRealtime(rawRealtimeUs, which) / 1000);
7879         proto.write(SystemProto.Battery.BATTERY_UPTIME_MS,
7880                 computeBatteryUptime(rawUptimeUs, which) / 1000);
7881         proto.write(SystemProto.Battery.SCREEN_OFF_REALTIME_MS,
7882                 computeBatteryScreenOffRealtime(rawRealtimeUs, which) / 1000);
7883         proto.write(SystemProto.Battery.SCREEN_OFF_UPTIME_MS,
7884                 computeBatteryScreenOffUptime(rawUptimeUs, which) / 1000);
7885         proto.write(SystemProto.Battery.SCREEN_DOZE_DURATION_MS,
7886                 getScreenDozeTime(rawRealtimeUs, which) / 1000);
7887         proto.write(SystemProto.Battery.ESTIMATED_BATTERY_CAPACITY_MAH,
7888                 getEstimatedBatteryCapacity());
7889         proto.write(SystemProto.Battery.MIN_LEARNED_BATTERY_CAPACITY_UAH,
7890                 getMinLearnedBatteryCapacity());
7891         proto.write(SystemProto.Battery.MAX_LEARNED_BATTERY_CAPACITY_UAH,
7892                 getMaxLearnedBatteryCapacity());
7893         proto.end(bToken);
7894 
7895         // Battery discharge (BATTERY_DISCHARGE_DATA)
7896         final long bdToken = proto.start(SystemProto.BATTERY_DISCHARGE);
7897         proto.write(SystemProto.BatteryDischarge.LOWER_BOUND_SINCE_CHARGE,
7898                 getLowDischargeAmountSinceCharge());
7899         proto.write(SystemProto.BatteryDischarge.UPPER_BOUND_SINCE_CHARGE,
7900                 getHighDischargeAmountSinceCharge());
7901         proto.write(SystemProto.BatteryDischarge.SCREEN_ON_SINCE_CHARGE,
7902                 getDischargeAmountScreenOnSinceCharge());
7903         proto.write(SystemProto.BatteryDischarge.SCREEN_OFF_SINCE_CHARGE,
7904                 getDischargeAmountScreenOffSinceCharge());
7905         proto.write(SystemProto.BatteryDischarge.SCREEN_DOZE_SINCE_CHARGE,
7906                 getDischargeAmountScreenDozeSinceCharge());
7907         proto.write(SystemProto.BatteryDischarge.TOTAL_MAH,
7908                 getUahDischarge(which) / 1000);
7909         proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_SCREEN_OFF,
7910                 getUahDischargeScreenOff(which) / 1000);
7911         proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_SCREEN_DOZE,
7912                 getUahDischargeScreenDoze(which) / 1000);
7913         proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_LIGHT_DOZE,
7914                 getUahDischargeLightDoze(which) / 1000);
7915         proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_DEEP_DOZE,
7916                 getUahDischargeDeepDoze(which) / 1000);
7917         proto.end(bdToken);
7918 
7919         // Time remaining
7920         long timeRemainingUs = computeChargeTimeRemaining(rawRealtimeUs);
7921         // These are part of a oneof, so we should only set one of them.
7922         if (timeRemainingUs >= 0) {
7923             // Charge time remaining (CHARGE_TIME_REMAIN_DATA)
7924             proto.write(SystemProto.CHARGE_TIME_REMAINING_MS, timeRemainingUs / 1000);
7925         } else {
7926             timeRemainingUs = computeBatteryTimeRemaining(rawRealtimeUs);
7927             // Discharge time remaining (DISCHARGE_TIME_REMAIN_DATA)
7928             if (timeRemainingUs >= 0) {
7929                 proto.write(SystemProto.DISCHARGE_TIME_REMAINING_MS, timeRemainingUs / 1000);
7930             } else {
7931                 proto.write(SystemProto.DISCHARGE_TIME_REMAINING_MS, -1);
7932             }
7933         }
7934 
7935         // Charge step (CHARGE_STEP_DATA)
7936         dumpDurationSteps(proto, SystemProto.CHARGE_STEP, getChargeLevelStepTracker());
7937 
7938         // Phone data connection (DATA_CONNECTION_TIME_DATA and DATA_CONNECTION_COUNT_DATA)
7939         for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; ++i) {
7940             // Map OTHER to TelephonyManager.NETWORK_TYPE_UNKNOWN and mark NONE as a boolean.
7941             boolean isNone = (i == DATA_CONNECTION_OUT_OF_SERVICE);
7942             int telephonyNetworkType = i;
7943             if (i == DATA_CONNECTION_OTHER || i == DATA_CONNECTION_EMERGENCY_SERVICE) {
7944                 telephonyNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
7945             }
7946             final long pdcToken = proto.start(SystemProto.DATA_CONNECTION);
7947             if (isNone) {
7948                 proto.write(SystemProto.DataConnection.IS_NONE, isNone);
7949             } else {
7950                 proto.write(SystemProto.DataConnection.NAME, telephonyNetworkType);
7951             }
7952             dumpTimer(proto, SystemProto.DataConnection.TOTAL, getPhoneDataConnectionTimer(i),
7953                     rawRealtimeUs, which);
7954             proto.end(pdcToken);
7955         }
7956 
7957         // Discharge step (DISCHARGE_STEP_DATA)
7958         dumpDurationSteps(proto, SystemProto.DISCHARGE_STEP, getDischargeLevelStepTracker());
7959 
7960         // CPU frequencies (GLOBAL_CPU_FREQ_DATA)
7961         final long[] cpuFreqs = getCpuFreqs();
7962         if (cpuFreqs != null) {
7963             for (long i : cpuFreqs) {
7964                 proto.write(SystemProto.CPU_FREQUENCY, i);
7965             }
7966         }
7967 
7968         // Bluetooth controller (GLOBAL_BLUETOOTH_CONTROLLER_DATA)
7969         dumpControllerActivityProto(proto, SystemProto.GLOBAL_BLUETOOTH_CONTROLLER,
7970                 getBluetoothControllerActivity(), which);
7971 
7972         // Modem controller (GLOBAL_MODEM_CONTROLLER_DATA)
7973         dumpControllerActivityProto(proto, SystemProto.GLOBAL_MODEM_CONTROLLER,
7974                 getModemControllerActivity(), which);
7975 
7976         // Global network data (GLOBAL_NETWORK_DATA)
7977         final long gnToken = proto.start(SystemProto.GLOBAL_NETWORK);
7978         proto.write(SystemProto.GlobalNetwork.MOBILE_BYTES_RX,
7979                 getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which));
7980         proto.write(SystemProto.GlobalNetwork.MOBILE_BYTES_TX,
7981                 getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which));
7982         proto.write(SystemProto.GlobalNetwork.MOBILE_PACKETS_RX,
7983                 getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which));
7984         proto.write(SystemProto.GlobalNetwork.MOBILE_PACKETS_TX,
7985                 getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which));
7986         proto.write(SystemProto.GlobalNetwork.WIFI_BYTES_RX,
7987                 getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
7988         proto.write(SystemProto.GlobalNetwork.WIFI_BYTES_TX,
7989                 getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
7990         proto.write(SystemProto.GlobalNetwork.WIFI_PACKETS_RX,
7991                 getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
7992         proto.write(SystemProto.GlobalNetwork.WIFI_PACKETS_TX,
7993                 getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
7994         proto.write(SystemProto.GlobalNetwork.BT_BYTES_RX,
7995                 getNetworkActivityBytes(NETWORK_BT_RX_DATA, which));
7996         proto.write(SystemProto.GlobalNetwork.BT_BYTES_TX,
7997                 getNetworkActivityBytes(NETWORK_BT_TX_DATA, which));
7998         proto.end(gnToken);
7999 
8000         // Wifi controller (GLOBAL_WIFI_CONTROLLER_DATA)
8001         dumpControllerActivityProto(proto, SystemProto.GLOBAL_WIFI_CONTROLLER,
8002                 getWifiControllerActivity(), which);
8003 
8004 
8005         // Global wifi (GLOBAL_WIFI_DATA)
8006         final long gwToken = proto.start(SystemProto.GLOBAL_WIFI);
8007         proto.write(SystemProto.GlobalWifi.ON_DURATION_MS,
8008                 getWifiOnTime(rawRealtimeUs, which) / 1000);
8009         proto.write(SystemProto.GlobalWifi.RUNNING_DURATION_MS,
8010                 getGlobalWifiRunningTime(rawRealtimeUs, which) / 1000);
8011         proto.end(gwToken);
8012 
8013         // Kernel wakelock (KERNEL_WAKELOCK_DATA)
8014         final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
8015         for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
8016             final long kwToken = proto.start(SystemProto.KERNEL_WAKELOCK);
8017             proto.write(SystemProto.KernelWakelock.NAME, ent.getKey());
8018             dumpTimer(proto, SystemProto.KernelWakelock.TOTAL, ent.getValue(),
8019                     rawRealtimeUs, which);
8020             proto.end(kwToken);
8021         }
8022 
8023         // Misc (MISC_DATA)
8024         // Calculate wakelock times across all uids.
8025         long fullWakeLockTimeTotalUs = 0;
8026         long partialWakeLockTimeTotalUs = 0;
8027 
8028         final SparseArray<? extends Uid> uidStats = getUidStats();
8029         for (int iu = 0; iu < uidStats.size(); iu++) {
8030             final Uid u = uidStats.valueAt(iu);
8031 
8032             final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks =
8033                     u.getWakelockStats();
8034             for (int iw = wakelocks.size() - 1; iw >= 0; --iw) {
8035                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
8036 
8037                 final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
8038                 if (fullWakeTimer != null) {
8039                     fullWakeLockTimeTotalUs += fullWakeTimer.getTotalTimeLocked(rawRealtimeUs,
8040                             which);
8041                 }
8042 
8043                 final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
8044                 if (partialWakeTimer != null) {
8045                     partialWakeLockTimeTotalUs += partialWakeTimer.getTotalTimeLocked(
8046                         rawRealtimeUs, which);
8047                 }
8048             }
8049         }
8050         final long mToken = proto.start(SystemProto.MISC);
8051         proto.write(SystemProto.Misc.SCREEN_ON_DURATION_MS,
8052                 getScreenOnTime(rawRealtimeUs, which) / 1000);
8053         proto.write(SystemProto.Misc.PHONE_ON_DURATION_MS,
8054                 getPhoneOnTime(rawRealtimeUs, which) / 1000);
8055         proto.write(SystemProto.Misc.FULL_WAKELOCK_TOTAL_DURATION_MS,
8056                 fullWakeLockTimeTotalUs / 1000);
8057         proto.write(SystemProto.Misc.PARTIAL_WAKELOCK_TOTAL_DURATION_MS,
8058                 partialWakeLockTimeTotalUs / 1000);
8059         proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_DURATION_MS,
8060                 getMobileRadioActiveTime(rawRealtimeUs, which) / 1000);
8061         proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_ADJUSTED_TIME_MS,
8062                 getMobileRadioActiveAdjustedTime(which) / 1000);
8063         proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_COUNT,
8064                 getMobileRadioActiveCount(which));
8065         proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_UNKNOWN_DURATION_MS,
8066                 getMobileRadioActiveUnknownTime(which) / 1000);
8067         proto.write(SystemProto.Misc.INTERACTIVE_DURATION_MS,
8068                 getInteractiveTime(rawRealtimeUs, which) / 1000);
8069         proto.write(SystemProto.Misc.BATTERY_SAVER_MODE_ENABLED_DURATION_MS,
8070                 getPowerSaveModeEnabledTime(rawRealtimeUs, which) / 1000);
8071         proto.write(SystemProto.Misc.NUM_CONNECTIVITY_CHANGES,
8072                 getNumConnectivityChange(which));
8073         proto.write(SystemProto.Misc.DEEP_DOZE_ENABLED_DURATION_MS,
8074                 getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP, rawRealtimeUs, which) / 1000);
8075         proto.write(SystemProto.Misc.DEEP_DOZE_COUNT,
8076                 getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which));
8077         proto.write(SystemProto.Misc.DEEP_DOZE_IDLING_DURATION_MS,
8078                 getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP, rawRealtimeUs, which) / 1000);
8079         proto.write(SystemProto.Misc.DEEP_DOZE_IDLING_COUNT,
8080                 getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which));
8081         proto.write(SystemProto.Misc.LONGEST_DEEP_DOZE_DURATION_MS,
8082                 getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
8083         proto.write(SystemProto.Misc.LIGHT_DOZE_ENABLED_DURATION_MS,
8084                 getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT, rawRealtimeUs, which) / 1000);
8085         proto.write(SystemProto.Misc.LIGHT_DOZE_COUNT,
8086                 getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which));
8087         proto.write(SystemProto.Misc.LIGHT_DOZE_IDLING_DURATION_MS,
8088                 getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT, rawRealtimeUs, which) / 1000);
8089         proto.write(SystemProto.Misc.LIGHT_DOZE_IDLING_COUNT,
8090                 getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which));
8091         proto.write(SystemProto.Misc.LONGEST_LIGHT_DOZE_DURATION_MS,
8092                 getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
8093         proto.end(mToken);
8094 
8095         // Wifi multicast wakelock total stats (WIFI_MULTICAST_WAKELOCK_TOTAL_DATA)
8096         final long multicastWakeLockTimeTotalUs =
8097                 getWifiMulticastWakelockTime(rawRealtimeUs, which);
8098         final int multicastWakeLockCountTotal = getWifiMulticastWakelockCount(which);
8099         final long wmctToken = proto.start(SystemProto.WIFI_MULTICAST_WAKELOCK_TOTAL);
8100         proto.write(SystemProto.WifiMulticastWakelockTotal.DURATION_MS,
8101                 multicastWakeLockTimeTotalUs / 1000);
8102         proto.write(SystemProto.WifiMulticastWakelockTotal.COUNT,
8103                 multicastWakeLockCountTotal);
8104         proto.end(wmctToken);
8105 
8106         // Power use item (POWER_USE_ITEM_DATA)
8107         final List<BatterySipper> sippers = helper.getUsageList();
8108         if (sippers != null) {
8109             for (int i = 0; i < sippers.size(); ++i) {
8110                 final BatterySipper bs = sippers.get(i);
8111                 int n = SystemProto.PowerUseItem.UNKNOWN_SIPPER;
8112                 int uid = 0;
8113                 switch (bs.drainType) {
8114                     case AMBIENT_DISPLAY:
8115                         n = SystemProto.PowerUseItem.AMBIENT_DISPLAY;
8116                         break;
8117                     case IDLE:
8118                         n = SystemProto.PowerUseItem.IDLE;
8119                         break;
8120                     case CELL:
8121                         n = SystemProto.PowerUseItem.CELL;
8122                         break;
8123                     case PHONE:
8124                         n = SystemProto.PowerUseItem.PHONE;
8125                         break;
8126                     case WIFI:
8127                         n = SystemProto.PowerUseItem.WIFI;
8128                         break;
8129                     case BLUETOOTH:
8130                         n = SystemProto.PowerUseItem.BLUETOOTH;
8131                         break;
8132                     case SCREEN:
8133                         n = SystemProto.PowerUseItem.SCREEN;
8134                         break;
8135                     case FLASHLIGHT:
8136                         n = SystemProto.PowerUseItem.FLASHLIGHT;
8137                         break;
8138                     case APP:
8139                         // dumpProtoAppsLocked will handle this.
8140                         continue;
8141                     case USER:
8142                         n = SystemProto.PowerUseItem.USER;
8143                         uid = UserHandle.getUid(bs.userId, 0);
8144                         break;
8145                     case UNACCOUNTED:
8146                         n = SystemProto.PowerUseItem.UNACCOUNTED;
8147                         break;
8148                     case OVERCOUNTED:
8149                         n = SystemProto.PowerUseItem.OVERCOUNTED;
8150                         break;
8151                     case CAMERA:
8152                         n = SystemProto.PowerUseItem.CAMERA;
8153                         break;
8154                     case MEMORY:
8155                         n = SystemProto.PowerUseItem.MEMORY;
8156                         break;
8157                 }
8158                 final long puiToken = proto.start(SystemProto.POWER_USE_ITEM);
8159                 proto.write(SystemProto.PowerUseItem.NAME, n);
8160                 proto.write(SystemProto.PowerUseItem.UID, uid);
8161                 proto.write(SystemProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah);
8162                 proto.write(SystemProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide);
8163                 proto.write(SystemProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah);
8164                 proto.write(SystemProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH,
8165                         bs.proportionalSmearMah);
8166                 proto.end(puiToken);
8167             }
8168         }
8169 
8170         // Power use summary (POWER_USE_SUMMARY_DATA)
8171         final long pusToken = proto.start(SystemProto.POWER_USE_SUMMARY);
8172         proto.write(SystemProto.PowerUseSummary.BATTERY_CAPACITY_MAH,
8173                 helper.getPowerProfile().getBatteryCapacity());
8174         proto.write(SystemProto.PowerUseSummary.COMPUTED_POWER_MAH, helper.getComputedPower());
8175         proto.write(SystemProto.PowerUseSummary.MIN_DRAINED_POWER_MAH, helper.getMinDrainedPower());
8176         proto.write(SystemProto.PowerUseSummary.MAX_DRAINED_POWER_MAH, helper.getMaxDrainedPower());
8177         proto.end(pusToken);
8178 
8179         // RPM stats (RESOURCE_POWER_MANAGER_DATA)
8180         final Map<String, ? extends Timer> rpmStats = getRpmStats();
8181         final Map<String, ? extends Timer> screenOffRpmStats = getScreenOffRpmStats();
8182         for (Map.Entry<String, ? extends Timer> ent : rpmStats.entrySet()) {
8183             final long rpmToken = proto.start(SystemProto.RESOURCE_POWER_MANAGER);
8184             proto.write(SystemProto.ResourcePowerManager.NAME, ent.getKey());
8185             dumpTimer(proto, SystemProto.ResourcePowerManager.TOTAL,
8186                     ent.getValue(), rawRealtimeUs, which);
8187             dumpTimer(proto, SystemProto.ResourcePowerManager.SCREEN_OFF,
8188                     screenOffRpmStats.get(ent.getKey()), rawRealtimeUs, which);
8189             proto.end(rpmToken);
8190         }
8191 
8192         // Screen brightness (SCREEN_BRIGHTNESS_DATA)
8193         for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; ++i) {
8194             final long sbToken = proto.start(SystemProto.SCREEN_BRIGHTNESS);
8195             proto.write(SystemProto.ScreenBrightness.NAME, i);
8196             dumpTimer(proto, SystemProto.ScreenBrightness.TOTAL, getScreenBrightnessTimer(i),
8197                     rawRealtimeUs, which);
8198             proto.end(sbToken);
8199         }
8200 
8201         // Signal scanning time (SIGNAL_SCANNING_TIME_DATA)
8202         dumpTimer(proto, SystemProto.SIGNAL_SCANNING, getPhoneSignalScanningTimer(), rawRealtimeUs,
8203                 which);
8204 
8205         // Phone signal strength (SIGNAL_STRENGTH_TIME_DATA and SIGNAL_STRENGTH_COUNT_DATA)
8206         for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); ++i) {
8207             final long pssToken = proto.start(SystemProto.PHONE_SIGNAL_STRENGTH);
8208             proto.write(SystemProto.PhoneSignalStrength.NAME, i);
8209             dumpTimer(proto, SystemProto.PhoneSignalStrength.TOTAL, getPhoneSignalStrengthTimer(i),
8210                     rawRealtimeUs, which);
8211             proto.end(pssToken);
8212         }
8213 
8214         // Wakeup reasons (WAKEUP_REASON_DATA)
8215         final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
8216         for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
8217             final long wrToken = proto.start(SystemProto.WAKEUP_REASON);
8218             proto.write(SystemProto.WakeupReason.NAME, ent.getKey());
8219             dumpTimer(proto, SystemProto.WakeupReason.TOTAL, ent.getValue(), rawRealtimeUs, which);
8220             proto.end(wrToken);
8221         }
8222 
8223         // Wifi signal strength (WIFI_SIGNAL_STRENGTH_TIME_DATA and WIFI_SIGNAL_STRENGTH_COUNT_DATA)
8224         for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; ++i) {
8225             final long wssToken = proto.start(SystemProto.WIFI_SIGNAL_STRENGTH);
8226             proto.write(SystemProto.WifiSignalStrength.NAME, i);
8227             dumpTimer(proto, SystemProto.WifiSignalStrength.TOTAL, getWifiSignalStrengthTimer(i),
8228                     rawRealtimeUs, which);
8229             proto.end(wssToken);
8230         }
8231 
8232         // Wifi state (WIFI_STATE_TIME_DATA and WIFI_STATE_COUNT_DATA)
8233         for (int i = 0; i < NUM_WIFI_STATES; ++i) {
8234             final long wsToken = proto.start(SystemProto.WIFI_STATE);
8235             proto.write(SystemProto.WifiState.NAME, i);
8236             dumpTimer(proto, SystemProto.WifiState.TOTAL, getWifiStateTimer(i),
8237                     rawRealtimeUs, which);
8238             proto.end(wsToken);
8239         }
8240 
8241         // Wifi supplicant state (WIFI_SUPPL_STATE_TIME_DATA and WIFI_SUPPL_STATE_COUNT_DATA)
8242         for (int i = 0; i < NUM_WIFI_SUPPL_STATES; ++i) {
8243             final long wssToken = proto.start(SystemProto.WIFI_SUPPLICANT_STATE);
8244             proto.write(SystemProto.WifiSupplicantState.NAME, i);
8245             dumpTimer(proto, SystemProto.WifiSupplicantState.TOTAL, getWifiSupplStateTimer(i),
8246                     rawRealtimeUs, which);
8247             proto.end(wssToken);
8248         }
8249 
8250         proto.end(sToken);
8251     }
8252 }
8253