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