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