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