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