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