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