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