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