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