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