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