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