BatteryStats.java revision 17d7d9dcdf581ccbee46c65ab036b529011720cb
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
1223        public HistoryStepDetails() {
1224            clear();
1225        }
1226
1227        public void clear() {
1228            userTime = systemTime = 0;
1229            appCpuUid1 = appCpuUid2 = appCpuUid3 = -1;
1230            appCpuUTime1 = appCpuSTime1 = appCpuUTime2 = appCpuSTime2
1231                    = appCpuUTime3 = appCpuSTime3 = 0;
1232        }
1233
1234        public void writeToParcel(Parcel out) {
1235            out.writeInt(userTime);
1236            out.writeInt(systemTime);
1237            out.writeInt(appCpuUid1);
1238            out.writeInt(appCpuUTime1);
1239            out.writeInt(appCpuSTime1);
1240            out.writeInt(appCpuUid2);
1241            out.writeInt(appCpuUTime2);
1242            out.writeInt(appCpuSTime2);
1243            out.writeInt(appCpuUid3);
1244            out.writeInt(appCpuUTime3);
1245            out.writeInt(appCpuSTime3);
1246            out.writeInt(statUserTime);
1247            out.writeInt(statSystemTime);
1248            out.writeInt(statIOWaitTime);
1249            out.writeInt(statIrqTime);
1250            out.writeInt(statSoftIrqTime);
1251            out.writeInt(statIdlTime);
1252            out.writeString(statPlatformIdleState);
1253        }
1254
1255        public void readFromParcel(Parcel in) {
1256            userTime = in.readInt();
1257            systemTime = in.readInt();
1258            appCpuUid1 = in.readInt();
1259            appCpuUTime1 = in.readInt();
1260            appCpuSTime1 = in.readInt();
1261            appCpuUid2 = in.readInt();
1262            appCpuUTime2 = in.readInt();
1263            appCpuSTime2 = in.readInt();
1264            appCpuUid3 = in.readInt();
1265            appCpuUTime3 = in.readInt();
1266            appCpuSTime3 = in.readInt();
1267            statUserTime = in.readInt();
1268            statSystemTime = in.readInt();
1269            statIOWaitTime = in.readInt();
1270            statIrqTime = in.readInt();
1271            statSoftIrqTime = in.readInt();
1272            statIdlTime = in.readInt();
1273            statPlatformIdleState = in.readString();
1274        }
1275    }
1276
1277    public final static class HistoryItem implements Parcelable {
1278        public HistoryItem next;
1279
1280        // The time of this event in milliseconds, as per SystemClock.elapsedRealtime().
1281        public long time;
1282
1283        public static final byte CMD_UPDATE = 0;        // These can be written as deltas
1284        public static final byte CMD_NULL = -1;
1285        public static final byte CMD_START = 4;
1286        public static final byte CMD_CURRENT_TIME = 5;
1287        public static final byte CMD_OVERFLOW = 6;
1288        public static final byte CMD_RESET = 7;
1289        public static final byte CMD_SHUTDOWN = 8;
1290
1291        public byte cmd = CMD_NULL;
1292
1293        /**
1294         * Return whether the command code is a delta data update.
1295         */
1296        public boolean isDeltaData() {
1297            return cmd == CMD_UPDATE;
1298        }
1299
1300        public byte batteryLevel;
1301        public byte batteryStatus;
1302        public byte batteryHealth;
1303        public byte batteryPlugType;
1304
1305        public short batteryTemperature;
1306        public char batteryVoltage;
1307
1308        // The charge of the battery in micro-Ampere-hours.
1309        public int batteryChargeUAh;
1310
1311        // Constants from SCREEN_BRIGHTNESS_*
1312        public static final int STATE_BRIGHTNESS_SHIFT = 0;
1313        public static final int STATE_BRIGHTNESS_MASK = 0x7;
1314        // Constants from SIGNAL_STRENGTH_*
1315        public static final int STATE_PHONE_SIGNAL_STRENGTH_SHIFT = 3;
1316        public static final int STATE_PHONE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_PHONE_SIGNAL_STRENGTH_SHIFT;
1317        // Constants from ServiceState.STATE_*
1318        public static final int STATE_PHONE_STATE_SHIFT = 6;
1319        public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT;
1320        // Constants from DATA_CONNECTION_*
1321        public static final int STATE_DATA_CONNECTION_SHIFT = 9;
1322        public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT;
1323
1324        // These states always appear directly in the first int token
1325        // of a delta change; they should be ones that change relatively
1326        // frequently.
1327        public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
1328        public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
1329        public static final int STATE_GPS_ON_FLAG = 1<<29;
1330        public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
1331        public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
1332        public static final int STATE_WIFI_RADIO_ACTIVE_FLAG = 1<<26;
1333        public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
1334        // Do not use, this is used for coulomb delta count.
1335        private static final int STATE_RESERVED_0 = 1<<24;
1336        // These are on the lower bits used for the command; if they change
1337        // we need to write another int of data.
1338        public static final int STATE_SENSOR_ON_FLAG = 1<<23;
1339        public static final int STATE_AUDIO_ON_FLAG = 1<<22;
1340        public static final int STATE_PHONE_SCANNING_FLAG = 1<<21;
1341        public static final int STATE_SCREEN_ON_FLAG = 1<<20;       // consider moving to states2
1342        public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; // consider moving to states2
1343        // empty slot
1344        // empty slot
1345        public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<16;
1346
1347        public static final int MOST_INTERESTING_STATES =
1348            STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG;
1349
1350        public static final int SETTLE_TO_ZERO_STATES = 0xffff0000 & ~MOST_INTERESTING_STATES;
1351
1352        public int states;
1353
1354        // Constants from WIFI_SUPPL_STATE_*
1355        public static final int STATE2_WIFI_SUPPL_STATE_SHIFT = 0;
1356        public static final int STATE2_WIFI_SUPPL_STATE_MASK = 0xf;
1357        // Values for NUM_WIFI_SIGNAL_STRENGTH_BINS
1358        public static final int STATE2_WIFI_SIGNAL_STRENGTH_SHIFT = 4;
1359        public static final int STATE2_WIFI_SIGNAL_STRENGTH_MASK =
1360                0x7 << STATE2_WIFI_SIGNAL_STRENGTH_SHIFT;
1361
1362        public static final int STATE2_POWER_SAVE_FLAG = 1<<31;
1363        public static final int STATE2_VIDEO_ON_FLAG = 1<<30;
1364        public static final int STATE2_WIFI_RUNNING_FLAG = 1<<29;
1365        public static final int STATE2_WIFI_ON_FLAG = 1<<28;
1366        public static final int STATE2_FLASHLIGHT_FLAG = 1<<27;
1367        public static final int STATE2_DEVICE_IDLE_SHIFT = 25;
1368        public static final int STATE2_DEVICE_IDLE_MASK = 0x3 << STATE2_DEVICE_IDLE_SHIFT;
1369        public static final int STATE2_CHARGING_FLAG = 1<<24;
1370        public static final int STATE2_PHONE_IN_CALL_FLAG = 1<<23;
1371        public static final int STATE2_BLUETOOTH_ON_FLAG = 1<<22;
1372        public static final int STATE2_CAMERA_FLAG = 1<<21;
1373        public static final int STATE2_BLUETOOTH_SCAN_FLAG = 1 << 20;
1374
1375        public static final int MOST_INTERESTING_STATES2 =
1376            STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_MASK
1377            | STATE2_CHARGING_FLAG | STATE2_PHONE_IN_CALL_FLAG | STATE2_BLUETOOTH_ON_FLAG;
1378
1379        public static final int SETTLE_TO_ZERO_STATES2 = 0xffff0000 & ~MOST_INTERESTING_STATES2;
1380
1381        public int states2;
1382
1383        // The wake lock that was acquired at this point.
1384        public HistoryTag wakelockTag;
1385
1386        // Kernel wakeup reason at this point.
1387        public HistoryTag wakeReasonTag;
1388
1389        // Non-null when there is more detailed information at this step.
1390        public HistoryStepDetails stepDetails;
1391
1392        public static final int EVENT_FLAG_START = 0x8000;
1393        public static final int EVENT_FLAG_FINISH = 0x4000;
1394
1395        // No event in this item.
1396        public static final int EVENT_NONE = 0x0000;
1397        // Event is about a process that is running.
1398        public static final int EVENT_PROC = 0x0001;
1399        // Event is about an application package that is in the foreground.
1400        public static final int EVENT_FOREGROUND = 0x0002;
1401        // Event is about an application package that is at the top of the screen.
1402        public static final int EVENT_TOP = 0x0003;
1403        // Event is about active sync operations.
1404        public static final int EVENT_SYNC = 0x0004;
1405        // Events for all additional wake locks aquired/release within a wake block.
1406        // These are not generated by default.
1407        public static final int EVENT_WAKE_LOCK = 0x0005;
1408        // Event is about an application executing a scheduled job.
1409        public static final int EVENT_JOB = 0x0006;
1410        // Events for users running.
1411        public static final int EVENT_USER_RUNNING = 0x0007;
1412        // Events for foreground user.
1413        public static final int EVENT_USER_FOREGROUND = 0x0008;
1414        // Event for connectivity changed.
1415        public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009;
1416        // Event for becoming active taking us out of idle mode.
1417        public static final int EVENT_ACTIVE = 0x000a;
1418        // Event for a package being installed.
1419        public static final int EVENT_PACKAGE_INSTALLED = 0x000b;
1420        // Event for a package being uninstalled.
1421        public static final int EVENT_PACKAGE_UNINSTALLED = 0x000c;
1422        // Event for a package being uninstalled.
1423        public static final int EVENT_ALARM = 0x000d;
1424        // Record that we have decided we need to collect new stats data.
1425        public static final int EVENT_COLLECT_EXTERNAL_STATS = 0x000e;
1426        // Event for a package becoming inactive due to being unused for a period of time.
1427        public static final int EVENT_PACKAGE_INACTIVE = 0x000f;
1428        // Event for a package becoming active due to an interaction.
1429        public static final int EVENT_PACKAGE_ACTIVE = 0x0010;
1430        // Event for a package being on the temporary whitelist.
1431        public static final int EVENT_TEMP_WHITELIST = 0x0011;
1432        // Event for the screen waking up.
1433        public static final int EVENT_SCREEN_WAKE_UP = 0x0012;
1434        // Event for the UID that woke up the application processor.
1435        // Used for wakeups coming from WiFi, modem, etc.
1436        public static final int EVENT_WAKEUP_AP = 0x0013;
1437        // Event for reporting that a specific partial wake lock has been held for a long duration.
1438        public static final int EVENT_LONG_WAKE_LOCK = 0x0014;
1439
1440        // Number of event types.
1441        public static final int EVENT_COUNT = 0x0016;
1442        // Mask to extract out only the type part of the event.
1443        public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
1444
1445        public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
1446        public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
1447        public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START;
1448        public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
1449        public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
1450        public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
1451        public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
1452        public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
1453        public static final int EVENT_WAKE_LOCK_START = EVENT_WAKE_LOCK | EVENT_FLAG_START;
1454        public static final int EVENT_WAKE_LOCK_FINISH = EVENT_WAKE_LOCK | EVENT_FLAG_FINISH;
1455        public static final int EVENT_JOB_START = EVENT_JOB | EVENT_FLAG_START;
1456        public static final int EVENT_JOB_FINISH = EVENT_JOB | EVENT_FLAG_FINISH;
1457        public static final int EVENT_USER_RUNNING_START = EVENT_USER_RUNNING | EVENT_FLAG_START;
1458        public static final int EVENT_USER_RUNNING_FINISH = EVENT_USER_RUNNING | EVENT_FLAG_FINISH;
1459        public static final int EVENT_USER_FOREGROUND_START =
1460                EVENT_USER_FOREGROUND | EVENT_FLAG_START;
1461        public static final int EVENT_USER_FOREGROUND_FINISH =
1462                EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
1463        public static final int EVENT_ALARM_START = EVENT_ALARM | EVENT_FLAG_START;
1464        public static final int EVENT_ALARM_FINISH = EVENT_ALARM | EVENT_FLAG_FINISH;
1465        public static final int EVENT_TEMP_WHITELIST_START =
1466                EVENT_TEMP_WHITELIST | EVENT_FLAG_START;
1467        public static final int EVENT_TEMP_WHITELIST_FINISH =
1468                EVENT_TEMP_WHITELIST | EVENT_FLAG_FINISH;
1469        public static final int EVENT_LONG_WAKE_LOCK_START =
1470                EVENT_LONG_WAKE_LOCK | EVENT_FLAG_START;
1471        public static final int EVENT_LONG_WAKE_LOCK_FINISH =
1472                EVENT_LONG_WAKE_LOCK | EVENT_FLAG_FINISH;
1473
1474        // For CMD_EVENT.
1475        public int eventCode;
1476        public HistoryTag eventTag;
1477
1478        // Only set for CMD_CURRENT_TIME or CMD_RESET, as per System.currentTimeMillis().
1479        public long currentTime;
1480
1481        // Meta-data when reading.
1482        public int numReadInts;
1483
1484        // Pre-allocated objects.
1485        public final HistoryTag localWakelockTag = new HistoryTag();
1486        public final HistoryTag localWakeReasonTag = new HistoryTag();
1487        public final HistoryTag localEventTag = new HistoryTag();
1488
1489        public HistoryItem() {
1490        }
1491
1492        public HistoryItem(long time, Parcel src) {
1493            this.time = time;
1494            numReadInts = 2;
1495            readFromParcel(src);
1496        }
1497
1498        public int describeContents() {
1499            return 0;
1500        }
1501
1502        public void writeToParcel(Parcel dest, int flags) {
1503            dest.writeLong(time);
1504            int bat = (((int)cmd)&0xff)
1505                    | ((((int)batteryLevel)<<8)&0xff00)
1506                    | ((((int)batteryStatus)<<16)&0xf0000)
1507                    | ((((int)batteryHealth)<<20)&0xf00000)
1508                    | ((((int)batteryPlugType)<<24)&0xf000000)
1509                    | (wakelockTag != null ? 0x10000000 : 0)
1510                    | (wakeReasonTag != null ? 0x20000000 : 0)
1511                    | (eventCode != EVENT_NONE ? 0x40000000 : 0);
1512            dest.writeInt(bat);
1513            bat = (((int)batteryTemperature)&0xffff)
1514                    | ((((int)batteryVoltage)<<16)&0xffff0000);
1515            dest.writeInt(bat);
1516            dest.writeInt(batteryChargeUAh);
1517            dest.writeInt(states);
1518            dest.writeInt(states2);
1519            if (wakelockTag != null) {
1520                wakelockTag.writeToParcel(dest, flags);
1521            }
1522            if (wakeReasonTag != null) {
1523                wakeReasonTag.writeToParcel(dest, flags);
1524            }
1525            if (eventCode != EVENT_NONE) {
1526                dest.writeInt(eventCode);
1527                eventTag.writeToParcel(dest, flags);
1528            }
1529            if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
1530                dest.writeLong(currentTime);
1531            }
1532        }
1533
1534        public void readFromParcel(Parcel src) {
1535            int start = src.dataPosition();
1536            int bat = src.readInt();
1537            cmd = (byte)(bat&0xff);
1538            batteryLevel = (byte)((bat>>8)&0xff);
1539            batteryStatus = (byte)((bat>>16)&0xf);
1540            batteryHealth = (byte)((bat>>20)&0xf);
1541            batteryPlugType = (byte)((bat>>24)&0xf);
1542            int bat2 = src.readInt();
1543            batteryTemperature = (short)(bat2&0xffff);
1544            batteryVoltage = (char)((bat2>>16)&0xffff);
1545            batteryChargeUAh = src.readInt();
1546            states = src.readInt();
1547            states2 = src.readInt();
1548            if ((bat&0x10000000) != 0) {
1549                wakelockTag = localWakelockTag;
1550                wakelockTag.readFromParcel(src);
1551            } else {
1552                wakelockTag = null;
1553            }
1554            if ((bat&0x20000000) != 0) {
1555                wakeReasonTag = localWakeReasonTag;
1556                wakeReasonTag.readFromParcel(src);
1557            } else {
1558                wakeReasonTag = null;
1559            }
1560            if ((bat&0x40000000) != 0) {
1561                eventCode = src.readInt();
1562                eventTag = localEventTag;
1563                eventTag.readFromParcel(src);
1564            } else {
1565                eventCode = EVENT_NONE;
1566                eventTag = null;
1567            }
1568            if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
1569                currentTime = src.readLong();
1570            } else {
1571                currentTime = 0;
1572            }
1573            numReadInts += (src.dataPosition()-start)/4;
1574        }
1575
1576        public void clear() {
1577            time = 0;
1578            cmd = CMD_NULL;
1579            batteryLevel = 0;
1580            batteryStatus = 0;
1581            batteryHealth = 0;
1582            batteryPlugType = 0;
1583            batteryTemperature = 0;
1584            batteryVoltage = 0;
1585            batteryChargeUAh = 0;
1586            states = 0;
1587            states2 = 0;
1588            wakelockTag = null;
1589            wakeReasonTag = null;
1590            eventCode = EVENT_NONE;
1591            eventTag = null;
1592        }
1593
1594        public void setTo(HistoryItem o) {
1595            time = o.time;
1596            cmd = o.cmd;
1597            setToCommon(o);
1598        }
1599
1600        public void setTo(long time, byte cmd, HistoryItem o) {
1601            this.time = time;
1602            this.cmd = cmd;
1603            setToCommon(o);
1604        }
1605
1606        private void setToCommon(HistoryItem o) {
1607            batteryLevel = o.batteryLevel;
1608            batteryStatus = o.batteryStatus;
1609            batteryHealth = o.batteryHealth;
1610            batteryPlugType = o.batteryPlugType;
1611            batteryTemperature = o.batteryTemperature;
1612            batteryVoltage = o.batteryVoltage;
1613            batteryChargeUAh = o.batteryChargeUAh;
1614            states = o.states;
1615            states2 = o.states2;
1616            if (o.wakelockTag != null) {
1617                wakelockTag = localWakelockTag;
1618                wakelockTag.setTo(o.wakelockTag);
1619            } else {
1620                wakelockTag = null;
1621            }
1622            if (o.wakeReasonTag != null) {
1623                wakeReasonTag = localWakeReasonTag;
1624                wakeReasonTag.setTo(o.wakeReasonTag);
1625            } else {
1626                wakeReasonTag = null;
1627            }
1628            eventCode = o.eventCode;
1629            if (o.eventTag != null) {
1630                eventTag = localEventTag;
1631                eventTag.setTo(o.eventTag);
1632            } else {
1633                eventTag = null;
1634            }
1635            currentTime = o.currentTime;
1636        }
1637
1638        public boolean sameNonEvent(HistoryItem o) {
1639            return batteryLevel == o.batteryLevel
1640                    && batteryStatus == o.batteryStatus
1641                    && batteryHealth == o.batteryHealth
1642                    && batteryPlugType == o.batteryPlugType
1643                    && batteryTemperature == o.batteryTemperature
1644                    && batteryVoltage == o.batteryVoltage
1645                    && batteryChargeUAh == o.batteryChargeUAh
1646                    && states == o.states
1647                    && states2 == o.states2
1648                    && currentTime == o.currentTime;
1649        }
1650
1651        public boolean same(HistoryItem o) {
1652            if (!sameNonEvent(o) || eventCode != o.eventCode) {
1653                return false;
1654            }
1655            if (wakelockTag != o.wakelockTag) {
1656                if (wakelockTag == null || o.wakelockTag == null) {
1657                    return false;
1658                }
1659                if (!wakelockTag.equals(o.wakelockTag)) {
1660                    return false;
1661                }
1662            }
1663            if (wakeReasonTag != o.wakeReasonTag) {
1664                if (wakeReasonTag == null || o.wakeReasonTag == null) {
1665                    return false;
1666                }
1667                if (!wakeReasonTag.equals(o.wakeReasonTag)) {
1668                    return false;
1669                }
1670            }
1671            if (eventTag != o.eventTag) {
1672                if (eventTag == null || o.eventTag == null) {
1673                    return false;
1674                }
1675                if (!eventTag.equals(o.eventTag)) {
1676                    return false;
1677                }
1678            }
1679            return true;
1680        }
1681    }
1682
1683    public final static class HistoryEventTracker {
1684        private final HashMap<String, SparseIntArray>[] mActiveEvents
1685                = (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
1686
1687        public boolean updateState(int code, String name, int uid, int poolIdx) {
1688            if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
1689                int idx = code&HistoryItem.EVENT_TYPE_MASK;
1690                HashMap<String, SparseIntArray> active = mActiveEvents[idx];
1691                if (active == null) {
1692                    active = new HashMap<>();
1693                    mActiveEvents[idx] = active;
1694                }
1695                SparseIntArray uids = active.get(name);
1696                if (uids == null) {
1697                    uids = new SparseIntArray();
1698                    active.put(name, uids);
1699                }
1700                if (uids.indexOfKey(uid) >= 0) {
1701                    // Already set, nothing to do!
1702                    return false;
1703                }
1704                uids.put(uid, poolIdx);
1705            } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
1706                int idx = code&HistoryItem.EVENT_TYPE_MASK;
1707                HashMap<String, SparseIntArray> active = mActiveEvents[idx];
1708                if (active == null) {
1709                    // not currently active, nothing to do.
1710                    return false;
1711                }
1712                SparseIntArray uids = active.get(name);
1713                if (uids == null) {
1714                    // not currently active, nothing to do.
1715                    return false;
1716                }
1717                idx = uids.indexOfKey(uid);
1718                if (idx < 0) {
1719                    // not currently active, nothing to do.
1720                    return false;
1721                }
1722                uids.removeAt(idx);
1723                if (uids.size() <= 0) {
1724                    active.remove(name);
1725                }
1726            }
1727            return true;
1728        }
1729
1730        public void removeEvents(int code) {
1731            int idx = code&HistoryItem.EVENT_TYPE_MASK;
1732            mActiveEvents[idx] = null;
1733        }
1734
1735        public HashMap<String, SparseIntArray> getStateForEvent(int code) {
1736            return mActiveEvents[code];
1737        }
1738    }
1739
1740    public static final class BitDescription {
1741        public final int mask;
1742        public final int shift;
1743        public final String name;
1744        public final String shortName;
1745        public final String[] values;
1746        public final String[] shortValues;
1747
1748        public BitDescription(int mask, String name, String shortName) {
1749            this.mask = mask;
1750            this.shift = -1;
1751            this.name = name;
1752            this.shortName = shortName;
1753            this.values = null;
1754            this.shortValues = null;
1755        }
1756
1757        public BitDescription(int mask, int shift, String name, String shortName,
1758                String[] values, String[] shortValues) {
1759            this.mask = mask;
1760            this.shift = shift;
1761            this.name = name;
1762            this.shortName = shortName;
1763            this.values = values;
1764            this.shortValues = shortValues;
1765        }
1766    }
1767
1768    /**
1769     * Don't allow any more batching in to the current history event.  This
1770     * is called when printing partial histories, so to ensure that the next
1771     * history event will go in to a new batch after what was printed in the
1772     * last partial history.
1773     */
1774    public abstract void commitCurrentHistoryBatchLocked();
1775
1776    public abstract int getHistoryTotalSize();
1777
1778    public abstract int getHistoryUsedSize();
1779
1780    public abstract boolean startIteratingHistoryLocked();
1781
1782    public abstract int getHistoryStringPoolSize();
1783
1784    public abstract int getHistoryStringPoolBytes();
1785
1786    public abstract String getHistoryTagPoolString(int index);
1787
1788    public abstract int getHistoryTagPoolUid(int index);
1789
1790    public abstract boolean getNextHistoryLocked(HistoryItem out);
1791
1792    public abstract void finishIteratingHistoryLocked();
1793
1794    public abstract boolean startIteratingOldHistoryLocked();
1795
1796    public abstract boolean getNextOldHistoryLocked(HistoryItem out);
1797
1798    public abstract void finishIteratingOldHistoryLocked();
1799
1800    /**
1801     * Return the base time offset for the battery history.
1802     */
1803    public abstract long getHistoryBaseTime();
1804
1805    /**
1806     * Returns the number of times the device has been started.
1807     */
1808    public abstract int getStartCount();
1809
1810    /**
1811     * Returns the time in microseconds that the screen has been on while the device was
1812     * running on battery.
1813     *
1814     * {@hide}
1815     */
1816    public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
1817
1818    /**
1819     * Returns the number of times the screen was turned on.
1820     *
1821     * {@hide}
1822     */
1823    public abstract int getScreenOnCount(int which);
1824
1825    public abstract long getInteractiveTime(long elapsedRealtimeUs, int which);
1826
1827    public static final int SCREEN_BRIGHTNESS_DARK = 0;
1828    public static final int SCREEN_BRIGHTNESS_DIM = 1;
1829    public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
1830    public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
1831    public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
1832
1833    static final String[] SCREEN_BRIGHTNESS_NAMES = {
1834        "dark", "dim", "medium", "light", "bright"
1835    };
1836
1837    static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
1838        "0", "1", "2", "3", "4"
1839    };
1840
1841    public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
1842
1843    /**
1844     * Returns the time in microseconds that the screen has been on with
1845     * the given brightness
1846     *
1847     * {@hide}
1848     */
1849    public abstract long getScreenBrightnessTime(int brightnessBin,
1850            long elapsedRealtimeUs, int which);
1851
1852    /**
1853     * Returns the time in microseconds that power save mode has been enabled while the device was
1854     * running on battery.
1855     *
1856     * {@hide}
1857     */
1858    public abstract long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which);
1859
1860    /**
1861     * Returns the number of times that power save mode was enabled.
1862     *
1863     * {@hide}
1864     */
1865    public abstract int getPowerSaveModeEnabledCount(int which);
1866
1867    /**
1868     * Constant for device idle mode: not active.
1869     */
1870    public static final int DEVICE_IDLE_MODE_OFF = 0;
1871
1872    /**
1873     * Constant for device idle mode: active in lightweight mode.
1874     */
1875    public static final int DEVICE_IDLE_MODE_LIGHT = 1;
1876
1877    /**
1878     * Constant for device idle mode: active in full mode.
1879     */
1880    public static final int DEVICE_IDLE_MODE_DEEP = 2;
1881
1882    /**
1883     * Returns the time in microseconds that device has been in idle mode while
1884     * running on battery.
1885     *
1886     * {@hide}
1887     */
1888    public abstract long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which);
1889
1890    /**
1891     * Returns the number of times that the devie has gone in to idle mode.
1892     *
1893     * {@hide}
1894     */
1895    public abstract int getDeviceIdleModeCount(int mode, int which);
1896
1897    /**
1898     * Return the longest duration we spent in a particular device idle mode (fully in the
1899     * mode, not in idle maintenance etc).
1900     */
1901    public abstract long getLongestDeviceIdleModeTime(int mode);
1902
1903    /**
1904     * Returns the time in microseconds that device has been in idling while on
1905     * battery.  This is broader than {@link #getDeviceIdleModeTime} -- it
1906     * counts all of the time that we consider the device to be idle, whether or not
1907     * it is currently in the actual device idle mode.
1908     *
1909     * {@hide}
1910     */
1911    public abstract long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which);
1912
1913    /**
1914     * Returns the number of times that the devie has started idling.
1915     *
1916     * {@hide}
1917     */
1918    public abstract int getDeviceIdlingCount(int mode, int which);
1919
1920    /**
1921     * Returns the number of times that connectivity state changed.
1922     *
1923     * {@hide}
1924     */
1925    public abstract int getNumConnectivityChange(int which);
1926
1927    /**
1928     * Returns the time in microseconds that the phone has been on while the device was
1929     * running on battery.
1930     *
1931     * {@hide}
1932     */
1933    public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
1934
1935    /**
1936     * Returns the number of times a phone call was activated.
1937     *
1938     * {@hide}
1939     */
1940    public abstract int getPhoneOnCount(int which);
1941
1942    /**
1943     * Returns the time in microseconds that the phone has been running with
1944     * the given signal strength.
1945     *
1946     * {@hide}
1947     */
1948    public abstract long getPhoneSignalStrengthTime(int strengthBin,
1949            long elapsedRealtimeUs, int which);
1950
1951    /**
1952     * Returns the time in microseconds that the phone has been trying to
1953     * acquire a signal.
1954     *
1955     * {@hide}
1956     */
1957    public abstract long getPhoneSignalScanningTime(
1958            long elapsedRealtimeUs, int which);
1959
1960    /**
1961     * Returns the number of times the phone has entered the given signal strength.
1962     *
1963     * {@hide}
1964     */
1965    public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
1966
1967    /**
1968     * Returns the time in microseconds that the mobile network has been active
1969     * (in a high power state).
1970     *
1971     * {@hide}
1972     */
1973    public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which);
1974
1975    /**
1976     * Returns the number of times that the mobile network has transitioned to the
1977     * active state.
1978     *
1979     * {@hide}
1980     */
1981    public abstract int getMobileRadioActiveCount(int which);
1982
1983    /**
1984     * Returns the time in microseconds that is the difference between the mobile radio
1985     * time we saw based on the elapsed timestamp when going down vs. the given time stamp
1986     * from the radio.
1987     *
1988     * {@hide}
1989     */
1990    public abstract long getMobileRadioActiveAdjustedTime(int which);
1991
1992    /**
1993     * Returns the time in microseconds that the mobile network has been active
1994     * (in a high power state) but not being able to blame on an app.
1995     *
1996     * {@hide}
1997     */
1998    public abstract long getMobileRadioActiveUnknownTime(int which);
1999
2000    /**
2001     * Return count of number of times radio was up that could not be blamed on apps.
2002     *
2003     * {@hide}
2004     */
2005    public abstract int getMobileRadioActiveUnknownCount(int which);
2006
2007    public static final int DATA_CONNECTION_NONE = 0;
2008    public static final int DATA_CONNECTION_GPRS = 1;
2009    public static final int DATA_CONNECTION_EDGE = 2;
2010    public static final int DATA_CONNECTION_UMTS = 3;
2011    public static final int DATA_CONNECTION_CDMA = 4;
2012    public static final int DATA_CONNECTION_EVDO_0 = 5;
2013    public static final int DATA_CONNECTION_EVDO_A = 6;
2014    public static final int DATA_CONNECTION_1xRTT = 7;
2015    public static final int DATA_CONNECTION_HSDPA = 8;
2016    public static final int DATA_CONNECTION_HSUPA = 9;
2017    public static final int DATA_CONNECTION_HSPA = 10;
2018    public static final int DATA_CONNECTION_IDEN = 11;
2019    public static final int DATA_CONNECTION_EVDO_B = 12;
2020    public static final int DATA_CONNECTION_LTE = 13;
2021    public static final int DATA_CONNECTION_EHRPD = 14;
2022    public static final int DATA_CONNECTION_HSPAP = 15;
2023    public static final int DATA_CONNECTION_OTHER = 16;
2024
2025    static final String[] DATA_CONNECTION_NAMES = {
2026        "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
2027        "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
2028        "ehrpd", "hspap", "other"
2029    };
2030
2031    public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
2032
2033    /**
2034     * Returns the time in microseconds that the phone has been running with
2035     * the given data connection.
2036     *
2037     * {@hide}
2038     */
2039    public abstract long getPhoneDataConnectionTime(int dataType,
2040            long elapsedRealtimeUs, int which);
2041
2042    /**
2043     * Returns the number of times the phone has entered the given data
2044     * connection type.
2045     *
2046     * {@hide}
2047     */
2048    public abstract int getPhoneDataConnectionCount(int dataType, int which);
2049
2050    public static final int WIFI_SUPPL_STATE_INVALID = 0;
2051    public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1;
2052    public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2;
2053    public static final int WIFI_SUPPL_STATE_INACTIVE = 3;
2054    public static final int WIFI_SUPPL_STATE_SCANNING = 4;
2055    public static final int WIFI_SUPPL_STATE_AUTHENTICATING = 5;
2056    public static final int WIFI_SUPPL_STATE_ASSOCIATING = 6;
2057    public static final int WIFI_SUPPL_STATE_ASSOCIATED = 7;
2058    public static final int WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE = 8;
2059    public static final int WIFI_SUPPL_STATE_GROUP_HANDSHAKE = 9;
2060    public static final int WIFI_SUPPL_STATE_COMPLETED = 10;
2061    public static final int WIFI_SUPPL_STATE_DORMANT = 11;
2062    public static final int WIFI_SUPPL_STATE_UNINITIALIZED = 12;
2063
2064    public static final int NUM_WIFI_SUPPL_STATES = WIFI_SUPPL_STATE_UNINITIALIZED+1;
2065
2066    static final String[] WIFI_SUPPL_STATE_NAMES = {
2067        "invalid", "disconn", "disabled", "inactive", "scanning",
2068        "authenticating", "associating", "associated", "4-way-handshake",
2069        "group-handshake", "completed", "dormant", "uninit"
2070    };
2071
2072    static final String[] WIFI_SUPPL_STATE_SHORT_NAMES = {
2073        "inv", "dsc", "dis", "inact", "scan",
2074        "auth", "ascing", "asced", "4-way",
2075        "group", "compl", "dorm", "uninit"
2076    };
2077
2078    public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
2079            = new BitDescription[] {
2080        new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
2081        new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
2082        new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
2083        new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
2084        new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
2085        new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
2086        new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
2087        new BitDescription(HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG, "wifi_radio", "Wr"),
2088        new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
2089        new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
2090        new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
2091        new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
2092        new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
2093        new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
2094                HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
2095                DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
2096        new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
2097                HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
2098                new String[] {"in", "out", "emergency", "off"},
2099                new String[] {"in", "out", "em", "off"}),
2100        new BitDescription(HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK,
2101                HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT, "phone_signal_strength", "Pss",
2102                SignalStrength.SIGNAL_STRENGTH_NAMES,
2103                new String[] { "0", "1", "2", "3", "4" }),
2104        new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
2105                HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
2106                SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
2107    };
2108
2109    public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
2110            = new BitDescription[] {
2111        new BitDescription(HistoryItem.STATE2_POWER_SAVE_FLAG, "power_save", "ps"),
2112        new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
2113        new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Ww"),
2114        new BitDescription(HistoryItem.STATE2_WIFI_ON_FLAG, "wifi", "W"),
2115        new BitDescription(HistoryItem.STATE2_FLASHLIGHT_FLAG, "flashlight", "fl"),
2116        new BitDescription(HistoryItem.STATE2_DEVICE_IDLE_MASK,
2117                HistoryItem.STATE2_DEVICE_IDLE_SHIFT, "device_idle", "di",
2118                new String[] { "off", "light", "full", "???" },
2119                new String[] { "off", "light", "full", "???" }),
2120        new BitDescription(HistoryItem.STATE2_CHARGING_FLAG, "charging", "ch"),
2121        new BitDescription(HistoryItem.STATE2_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
2122        new BitDescription(HistoryItem.STATE2_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
2123        new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
2124                HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT, "wifi_signal_strength", "Wss",
2125                new String[] { "0", "1", "2", "3", "4" },
2126                new String[] { "0", "1", "2", "3", "4" }),
2127        new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK,
2128                HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp",
2129                WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES),
2130        new BitDescription(HistoryItem.STATE2_CAMERA_FLAG, "camera", "ca"),
2131        new BitDescription(HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG, "ble_scan", "bles"),
2132    };
2133
2134    public static final String[] HISTORY_EVENT_NAMES = new String[] {
2135            "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
2136            "active", "pkginst", "pkgunin", "alarm", "stats", "pkginactive", "pkgactive",
2137            "tmpwhitelist", "screenwake", "wakeupap", "longwake", "est_capacity"
2138    };
2139
2140    public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
2141            "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
2142            "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa", "Etw",
2143            "Esw", "Ewa", "Elw", "Eec"
2144    };
2145
2146    @FunctionalInterface
2147    public interface IntToString {
2148        String applyAsString(int val);
2149    }
2150
2151    private static final IntToString sUidToString = UserHandle::formatUid;
2152    private static final IntToString sIntToString = Integer::toString;
2153
2154    public static final IntToString[] HISTORY_EVENT_INT_FORMATTERS = new IntToString[] {
2155            sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sUidToString,
2156            sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sUidToString,
2157            sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sUidToString,
2158            sUidToString, sUidToString, sUidToString, sIntToString
2159    };
2160
2161    /**
2162     * Returns the time in microseconds that wifi has been on while the device was
2163     * running on battery.
2164     *
2165     * {@hide}
2166     */
2167    public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
2168
2169    /**
2170     * Returns the time in microseconds that wifi has been on and the driver has
2171     * been in the running state while the device was running on battery.
2172     *
2173     * {@hide}
2174     */
2175    public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
2176
2177    public static final int WIFI_STATE_OFF = 0;
2178    public static final int WIFI_STATE_OFF_SCANNING = 1;
2179    public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
2180    public static final int WIFI_STATE_ON_DISCONNECTED = 3;
2181    public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
2182    public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
2183    public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
2184    public static final int WIFI_STATE_SOFT_AP = 7;
2185
2186    static final String[] WIFI_STATE_NAMES = {
2187        "off", "scanning", "no_net", "disconn",
2188        "sta", "p2p", "sta_p2p", "soft_ap"
2189    };
2190
2191    public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1;
2192
2193    /**
2194     * Returns the time in microseconds that WiFi has been running in the given state.
2195     *
2196     * {@hide}
2197     */
2198    public abstract long getWifiStateTime(int wifiState,
2199            long elapsedRealtimeUs, int which);
2200
2201    /**
2202     * Returns the number of times that WiFi has entered the given state.
2203     *
2204     * {@hide}
2205     */
2206    public abstract int getWifiStateCount(int wifiState, int which);
2207
2208    /**
2209     * Returns the time in microseconds that the wifi supplicant has been
2210     * in a given state.
2211     *
2212     * {@hide}
2213     */
2214    public abstract long getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which);
2215
2216    /**
2217     * Returns the number of times that the wifi supplicant has transitioned
2218     * to a given state.
2219     *
2220     * {@hide}
2221     */
2222    public abstract int getWifiSupplStateCount(int state, int which);
2223
2224    public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5;
2225
2226    /**
2227     * Returns the time in microseconds that WIFI has been running with
2228     * the given signal strength.
2229     *
2230     * {@hide}
2231     */
2232    public abstract long getWifiSignalStrengthTime(int strengthBin,
2233            long elapsedRealtimeUs, int which);
2234
2235    /**
2236     * Returns the number of times WIFI has entered the given signal strength.
2237     *
2238     * {@hide}
2239     */
2240    public abstract int getWifiSignalStrengthCount(int strengthBin, int which);
2241
2242    /**
2243     * Returns the time in microseconds that the flashlight has been on while the device was
2244     * running on battery.
2245     *
2246     * {@hide}
2247     */
2248    public abstract long getFlashlightOnTime(long elapsedRealtimeUs, int which);
2249
2250    /**
2251     * Returns the number of times that the flashlight has been turned on while the device was
2252     * running on battery.
2253     *
2254     * {@hide}
2255     */
2256    public abstract long getFlashlightOnCount(int which);
2257
2258    /**
2259     * Returns the time in microseconds that the camera has been on while the device was
2260     * running on battery.
2261     *
2262     * {@hide}
2263     */
2264    public abstract long getCameraOnTime(long elapsedRealtimeUs, int which);
2265
2266    /**
2267     * Returns the time in microseconds that bluetooth scans were running while the device was
2268     * on battery.
2269     *
2270     * {@hide}
2271     */
2272    public abstract long getBluetoothScanTime(long elapsedRealtimeUs, int which);
2273
2274    public static final int NETWORK_MOBILE_RX_DATA = 0;
2275    public static final int NETWORK_MOBILE_TX_DATA = 1;
2276    public static final int NETWORK_WIFI_RX_DATA = 2;
2277    public static final int NETWORK_WIFI_TX_DATA = 3;
2278    public static final int NETWORK_BT_RX_DATA = 4;
2279    public static final int NETWORK_BT_TX_DATA = 5;
2280    public static final int NETWORK_MOBILE_BG_RX_DATA = 6;
2281    public static final int NETWORK_MOBILE_BG_TX_DATA = 7;
2282    public static final int NETWORK_WIFI_BG_RX_DATA = 8;
2283    public static final int NETWORK_WIFI_BG_TX_DATA = 9;
2284    public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_BG_TX_DATA + 1;
2285
2286    public abstract long getNetworkActivityBytes(int type, int which);
2287    public abstract long getNetworkActivityPackets(int type, int which);
2288
2289    /**
2290     * Returns true if the BatteryStats object has detailed WiFi power reports.
2291     * When true, calling {@link #getWifiControllerActivity()} will yield the
2292     * actual power data.
2293     */
2294    public abstract boolean hasWifiActivityReporting();
2295
2296    /**
2297     * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
2298     * in various radio controller states, such as transmit, receive, and idle.
2299     * @return non-null {@link ControllerActivityCounter}
2300     */
2301    public abstract ControllerActivityCounter getWifiControllerActivity();
2302
2303    /**
2304     * Returns true if the BatteryStats object has detailed bluetooth power reports.
2305     * When true, calling {@link #getBluetoothControllerActivity()} will yield the
2306     * actual power data.
2307     */
2308    public abstract boolean hasBluetoothActivityReporting();
2309
2310    /**
2311     * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
2312     * in various radio controller states, such as transmit, receive, and idle.
2313     * @return non-null {@link ControllerActivityCounter}
2314     */
2315    public abstract ControllerActivityCounter getBluetoothControllerActivity();
2316
2317    /**
2318     * Returns true if the BatteryStats object has detailed modem power reports.
2319     * When true, calling {@link #getModemControllerActivity()} will yield the
2320     * actual power data.
2321     */
2322    public abstract boolean hasModemActivityReporting();
2323
2324    /**
2325     * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
2326     * in various radio controller states, such as transmit, receive, and idle.
2327     * @return non-null {@link ControllerActivityCounter}
2328     */
2329    public abstract ControllerActivityCounter getModemControllerActivity();
2330
2331    /**
2332     * Return the wall clock time when battery stats data collection started.
2333     */
2334    public abstract long getStartClockTime();
2335
2336    /**
2337     * Return platform version tag that we were running in when the battery stats started.
2338     */
2339    public abstract String getStartPlatformVersion();
2340
2341    /**
2342     * Return platform version tag that we were running in when the battery stats ended.
2343     */
2344    public abstract String getEndPlatformVersion();
2345
2346    /**
2347     * Return the internal version code of the parcelled format.
2348     */
2349    public abstract int getParcelVersion();
2350
2351    /**
2352     * Return whether we are currently running on battery.
2353     */
2354    public abstract boolean getIsOnBattery();
2355
2356    /**
2357     * Returns a SparseArray containing the statistics for each uid.
2358     */
2359    public abstract SparseArray<? extends Uid> getUidStats();
2360
2361    /**
2362     * Returns the current battery uptime in microseconds.
2363     *
2364     * @param curTime the amount of elapsed realtime in microseconds.
2365     */
2366    public abstract long getBatteryUptime(long curTime);
2367
2368    /**
2369     * Returns the current battery realtime in microseconds.
2370     *
2371     * @param curTime the amount of elapsed realtime in microseconds.
2372     */
2373    public abstract long getBatteryRealtime(long curTime);
2374
2375    /**
2376     * Returns the battery percentage level at the last time the device was unplugged from power, or
2377     * the last time it booted on battery power.
2378     */
2379    public abstract int getDischargeStartLevel();
2380
2381    /**
2382     * Returns the current battery percentage level if we are in a discharge cycle, otherwise
2383     * returns the level at the last plug event.
2384     */
2385    public abstract int getDischargeCurrentLevel();
2386
2387    /**
2388     * Get the amount the battery has discharged since the stats were
2389     * last reset after charging, as a lower-end approximation.
2390     */
2391    public abstract int getLowDischargeAmountSinceCharge();
2392
2393    /**
2394     * Get the amount the battery has discharged since the stats were
2395     * last reset after charging, as an upper-end approximation.
2396     */
2397    public abstract int getHighDischargeAmountSinceCharge();
2398
2399    /**
2400     * Retrieve the discharge amount over the selected discharge period <var>which</var>.
2401     */
2402    public abstract int getDischargeAmount(int which);
2403
2404    /**
2405     * Get the amount the battery has discharged while the screen was on,
2406     * since the last time power was unplugged.
2407     */
2408    public abstract int getDischargeAmountScreenOn();
2409
2410    /**
2411     * Get the amount the battery has discharged while the screen was on,
2412     * since the last time the device was charged.
2413     */
2414    public abstract int getDischargeAmountScreenOnSinceCharge();
2415
2416    /**
2417     * Get the amount the battery has discharged while the screen was off,
2418     * since the last time power was unplugged.
2419     */
2420    public abstract int getDischargeAmountScreenOff();
2421
2422    /**
2423     * Get the amount the battery has discharged while the screen was off,
2424     * since the last time the device was charged.
2425     */
2426    public abstract int getDischargeAmountScreenOffSinceCharge();
2427
2428    /**
2429     * Returns the total, last, or current battery uptime in microseconds.
2430     *
2431     * @param curTime the elapsed realtime in microseconds.
2432     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2433     */
2434    public abstract long computeBatteryUptime(long curTime, int which);
2435
2436    /**
2437     * Returns the total, last, or current battery realtime in microseconds.
2438     *
2439     * @param curTime the current elapsed realtime in microseconds.
2440     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2441     */
2442    public abstract long computeBatteryRealtime(long curTime, int which);
2443
2444    /**
2445     * Returns the total, last, or current battery screen off uptime in microseconds.
2446     *
2447     * @param curTime the elapsed realtime in microseconds.
2448     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2449     */
2450    public abstract long computeBatteryScreenOffUptime(long curTime, int which);
2451
2452    /**
2453     * Returns the total, last, or current battery screen off realtime in microseconds.
2454     *
2455     * @param curTime the current elapsed realtime in microseconds.
2456     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2457     */
2458    public abstract long computeBatteryScreenOffRealtime(long curTime, int which);
2459
2460    /**
2461     * Returns the total, last, or current uptime in microseconds.
2462     *
2463     * @param curTime the current elapsed realtime in microseconds.
2464     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2465     */
2466    public abstract long computeUptime(long curTime, int which);
2467
2468    /**
2469     * Returns the total, last, or current realtime in microseconds.
2470     *
2471     * @param curTime the current elapsed realtime in microseconds.
2472     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2473     */
2474    public abstract long computeRealtime(long curTime, int which);
2475
2476    /**
2477     * Compute an approximation for how much run time (in microseconds) is remaining on
2478     * the battery.  Returns -1 if no time can be computed: either there is not
2479     * enough current data to make a decision, or the battery is currently
2480     * charging.
2481     *
2482     * @param curTime The current elepsed realtime in microseconds.
2483     */
2484    public abstract long computeBatteryTimeRemaining(long curTime);
2485
2486    // The part of a step duration that is the actual time.
2487    public static final long STEP_LEVEL_TIME_MASK = 0x000000ffffffffffL;
2488
2489    // Bits in a step duration that are the new battery level we are at.
2490    public static final long STEP_LEVEL_LEVEL_MASK = 0x0000ff0000000000L;
2491    public static final int STEP_LEVEL_LEVEL_SHIFT = 40;
2492
2493    // Bits in a step duration that are the initial mode we were in at that step.
2494    public static final long STEP_LEVEL_INITIAL_MODE_MASK = 0x00ff000000000000L;
2495    public static final int STEP_LEVEL_INITIAL_MODE_SHIFT = 48;
2496
2497    // Bits in a step duration that indicate which modes changed during that step.
2498    public static final long STEP_LEVEL_MODIFIED_MODE_MASK = 0xff00000000000000L;
2499    public static final int STEP_LEVEL_MODIFIED_MODE_SHIFT = 56;
2500
2501    // Step duration mode: the screen is on, off, dozed, etc; value is Display.STATE_* - 1.
2502    public static final int STEP_LEVEL_MODE_SCREEN_STATE = 0x03;
2503
2504    // The largest value for screen state that is tracked in battery states. Any values above
2505    // this should be mapped back to one of the tracked values before being tracked here.
2506    public static final int MAX_TRACKED_SCREEN_STATE = Display.STATE_DOZE_SUSPEND;
2507
2508    // Step duration mode: power save is on.
2509    public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04;
2510
2511    // Step duration mode: device is currently in idle mode.
2512    public static final int STEP_LEVEL_MODE_DEVICE_IDLE = 0x08;
2513
2514    public static final int[] STEP_LEVEL_MODES_OF_INTEREST = new int[] {
2515            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2516            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE,
2517            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
2518            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2519            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2520            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
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|STEP_LEVEL_MODE_DEVICE_IDLE,
2524            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
2525    };
2526    public static final int[] STEP_LEVEL_MODE_VALUES = new int[] {
2527            (Display.STATE_OFF-1),
2528            (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE,
2529            (Display.STATE_OFF-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
2530            (Display.STATE_ON-1),
2531            (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE,
2532            (Display.STATE_DOZE-1),
2533            (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE,
2534            (Display.STATE_DOZE_SUSPEND-1),
2535            (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE,
2536            (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
2537    };
2538    public static final String[] STEP_LEVEL_MODE_LABELS = new String[] {
2539            "screen off",
2540            "screen off power save",
2541            "screen off device idle",
2542            "screen on",
2543            "screen on power save",
2544            "screen doze",
2545            "screen doze power save",
2546            "screen doze-suspend",
2547            "screen doze-suspend power save",
2548            "screen doze-suspend device idle",
2549    };
2550
2551    /**
2552     * Return the counter keeping track of the amount of battery discharge while the screen was off,
2553     * measured in micro-Ampere-hours. This will be non-zero only if the device's battery has
2554     * a coulomb counter.
2555     */
2556    public abstract LongCounter getDischargeScreenOffCoulombCounter();
2557
2558    /**
2559     * Return the counter keeping track of the amount of battery discharge measured in
2560     * micro-Ampere-hours. This will be non-zero only if the device's battery has
2561     * a coulomb counter.
2562     */
2563    public abstract LongCounter getDischargeCoulombCounter();
2564
2565    /**
2566     * Returns the estimated real battery capacity, which may be less than the capacity
2567     * declared by the PowerProfile.
2568     * @return The estimated battery capacity in mAh.
2569     */
2570    public abstract int getEstimatedBatteryCapacity();
2571
2572    /**
2573     * @return The minimum learned battery capacity in uAh.
2574     */
2575    public abstract int getMinLearnedBatteryCapacity();
2576
2577    /**
2578     * @return The maximum learned battery capacity in uAh.
2579     */
2580    public abstract int getMaxLearnedBatteryCapacity() ;
2581
2582    /**
2583     * Return the array of discharge step durations.
2584     */
2585    public abstract LevelStepTracker getDischargeLevelStepTracker();
2586
2587    /**
2588     * Return the array of daily discharge step durations.
2589     */
2590    public abstract LevelStepTracker getDailyDischargeLevelStepTracker();
2591
2592    /**
2593     * Compute an approximation for how much time (in microseconds) remains until the battery
2594     * is fully charged.  Returns -1 if no time can be computed: either there is not
2595     * enough current data to make a decision, or the battery is currently
2596     * discharging.
2597     *
2598     * @param curTime The current elepsed realtime in microseconds.
2599     */
2600    public abstract long computeChargeTimeRemaining(long curTime);
2601
2602    /**
2603     * Return the array of charge step durations.
2604     */
2605    public abstract LevelStepTracker getChargeLevelStepTracker();
2606
2607    /**
2608     * Return the array of daily charge step durations.
2609     */
2610    public abstract LevelStepTracker getDailyChargeLevelStepTracker();
2611
2612    public abstract ArrayList<PackageChange> getDailyPackageChanges();
2613
2614    public abstract Map<String, ? extends Timer> getWakeupReasonStats();
2615
2616    public abstract Map<String, ? extends Timer> getKernelWakelockStats();
2617
2618    public abstract LongSparseArray<? extends Timer> getKernelMemoryStats();
2619
2620    public abstract void writeToParcelWithoutUids(Parcel out, int flags);
2621
2622    private final static void formatTimeRaw(StringBuilder out, long seconds) {
2623        long days = seconds / (60 * 60 * 24);
2624        if (days != 0) {
2625            out.append(days);
2626            out.append("d ");
2627        }
2628        long used = days * 60 * 60 * 24;
2629
2630        long hours = (seconds - used) / (60 * 60);
2631        if (hours != 0 || used != 0) {
2632            out.append(hours);
2633            out.append("h ");
2634        }
2635        used += hours * 60 * 60;
2636
2637        long mins = (seconds-used) / 60;
2638        if (mins != 0 || used != 0) {
2639            out.append(mins);
2640            out.append("m ");
2641        }
2642        used += mins * 60;
2643
2644        if (seconds != 0 || used != 0) {
2645            out.append(seconds-used);
2646            out.append("s ");
2647        }
2648    }
2649
2650    public final static void formatTimeMs(StringBuilder sb, long time) {
2651        long sec = time / 1000;
2652        formatTimeRaw(sb, sec);
2653        sb.append(time - (sec * 1000));
2654        sb.append("ms ");
2655    }
2656
2657    public final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
2658        long sec = time / 1000;
2659        formatTimeRaw(sb, sec);
2660        sb.append(time - (sec * 1000));
2661        sb.append("ms");
2662    }
2663
2664    public final String formatRatioLocked(long num, long den) {
2665        if (den == 0L) {
2666            return "--%";
2667        }
2668        float perc = ((float)num) / ((float)den) * 100;
2669        mFormatBuilder.setLength(0);
2670        mFormatter.format("%.1f%%", perc);
2671        return mFormatBuilder.toString();
2672    }
2673
2674    final String formatBytesLocked(long bytes) {
2675        mFormatBuilder.setLength(0);
2676
2677        if (bytes < BYTES_PER_KB) {
2678            return bytes + "B";
2679        } else if (bytes < BYTES_PER_MB) {
2680            mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
2681            return mFormatBuilder.toString();
2682        } else if (bytes < BYTES_PER_GB){
2683            mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
2684            return mFormatBuilder.toString();
2685        } else {
2686            mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
2687            return mFormatBuilder.toString();
2688        }
2689    }
2690
2691    private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) {
2692        if (timer != null) {
2693            // Convert from microseconds to milliseconds with rounding
2694            long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
2695            long totalTimeMillis = (totalTimeMicros + 500) / 1000;
2696            return totalTimeMillis;
2697        }
2698        return 0;
2699    }
2700
2701    /**
2702     *
2703     * @param sb a StringBuilder object.
2704     * @param timer a Timer object contining the wakelock times.
2705     * @param elapsedRealtimeUs the current on-battery time in microseconds.
2706     * @param name the name of the wakelock.
2707     * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2708     * @param linePrefix a String to be prepended to each line of output.
2709     * @return the line prefix
2710     */
2711    private static final String printWakeLock(StringBuilder sb, Timer timer,
2712            long elapsedRealtimeUs, String name, int which, String linePrefix) {
2713
2714        if (timer != null) {
2715            long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which);
2716
2717            int count = timer.getCountLocked(which);
2718            if (totalTimeMillis != 0) {
2719                sb.append(linePrefix);
2720                formatTimeMs(sb, totalTimeMillis);
2721                if (name != null) {
2722                    sb.append(name);
2723                    sb.append(' ');
2724                }
2725                sb.append('(');
2726                sb.append(count);
2727                sb.append(" times)");
2728                final long maxDurationMs = timer.getMaxDurationMsLocked(elapsedRealtimeUs/1000);
2729                if (maxDurationMs >= 0) {
2730                    sb.append(" max=");
2731                    sb.append(maxDurationMs);
2732                }
2733                // Put actual time if it is available and different from totalTimeMillis.
2734                final long totalDurMs = timer.getTotalDurationMsLocked(elapsedRealtimeUs/1000);
2735                if (totalDurMs > totalTimeMillis) {
2736                    sb.append(" actual=");
2737                    sb.append(totalDurMs);
2738                }
2739                if (timer.isRunningLocked()) {
2740                    final long currentMs = timer.getCurrentDurationMsLocked(elapsedRealtimeUs/1000);
2741                    if (currentMs >= 0) {
2742                        sb.append(" (running for ");
2743                        sb.append(currentMs);
2744                        sb.append("ms)");
2745                    } else {
2746                        sb.append(" (running)");
2747                    }
2748                }
2749
2750                return ", ";
2751            }
2752        }
2753        return linePrefix;
2754    }
2755
2756    /**
2757     * Prints details about a timer, if its total time was greater than 0.
2758     *
2759     * @param pw a PrintWriter object to print to.
2760     * @param sb a StringBuilder object.
2761     * @param timer a Timer object contining the wakelock times.
2762     * @param rawRealtimeUs the current on-battery time in microseconds.
2763     * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2764     * @param prefix a String to be prepended to each line of output.
2765     * @param type the name of the timer.
2766     * @return true if anything was printed.
2767     */
2768    private static final boolean printTimer(PrintWriter pw, StringBuilder sb, Timer timer,
2769            long rawRealtimeUs, int which, String prefix, String type) {
2770        if (timer != null) {
2771            // Convert from microseconds to milliseconds with rounding
2772            final long totalTimeMs = (timer.getTotalTimeLocked(
2773                    rawRealtimeUs, which) + 500) / 1000;
2774            final int count = timer.getCountLocked(which);
2775            if (totalTimeMs != 0) {
2776                sb.setLength(0);
2777                sb.append(prefix);
2778                sb.append("    ");
2779                sb.append(type);
2780                sb.append(": ");
2781                formatTimeMs(sb, totalTimeMs);
2782                sb.append("realtime (");
2783                sb.append(count);
2784                sb.append(" times)");
2785                final long maxDurationMs = timer.getMaxDurationMsLocked(rawRealtimeUs/1000);
2786                if (maxDurationMs >= 0) {
2787                    sb.append(" max=");
2788                    sb.append(maxDurationMs);
2789                }
2790                if (timer.isRunningLocked()) {
2791                    final long currentMs = timer.getCurrentDurationMsLocked(rawRealtimeUs/1000);
2792                    if (currentMs >= 0) {
2793                        sb.append(" (running for ");
2794                        sb.append(currentMs);
2795                        sb.append("ms)");
2796                    } else {
2797                        sb.append(" (running)");
2798                    }
2799                }
2800                pw.println(sb.toString());
2801                return true;
2802            }
2803        }
2804        return false;
2805    }
2806
2807    /**
2808     * Checkin version of wakelock printer. Prints simple comma-separated list.
2809     *
2810     * @param sb a StringBuilder object.
2811     * @param timer a Timer object contining the wakelock times.
2812     * @param elapsedRealtimeUs the current time in microseconds.
2813     * @param name the name of the wakelock.
2814     * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2815     * @param linePrefix a String to be prepended to each line of output.
2816     * @return the line prefix
2817     */
2818    private static final String printWakeLockCheckin(StringBuilder sb, Timer timer,
2819            long elapsedRealtimeUs, String name, int which, String linePrefix) {
2820        long totalTimeMicros = 0;
2821        int count = 0;
2822        long max = 0;
2823        long current = 0;
2824        long totalDuration = 0;
2825        if (timer != null) {
2826            totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
2827            count = timer.getCountLocked(which);
2828            current = timer.getCurrentDurationMsLocked(elapsedRealtimeUs/1000);
2829            max = timer.getMaxDurationMsLocked(elapsedRealtimeUs/1000);
2830            totalDuration = timer.getTotalDurationMsLocked(elapsedRealtimeUs/1000);
2831        }
2832        sb.append(linePrefix);
2833        sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
2834        sb.append(',');
2835        sb.append(name != null ? name + "," : "");
2836        sb.append(count);
2837        sb.append(',');
2838        sb.append(current);
2839        sb.append(',');
2840        sb.append(max);
2841        // Partial, full, and window wakelocks are pooled, so totalDuration is meaningful (albeit
2842        // not always tracked). Kernel wakelocks (which have name == null) have no notion of
2843        // totalDuration independent of totalTimeMicros (since they are not pooled).
2844        if (name != null) {
2845            sb.append(',');
2846            sb.append(totalDuration);
2847        }
2848        return ",";
2849    }
2850
2851    private static final void dumpLineHeader(PrintWriter pw, int uid, String category,
2852                                             String type) {
2853        pw.print(BATTERY_STATS_CHECKIN_VERSION);
2854        pw.print(',');
2855        pw.print(uid);
2856        pw.print(',');
2857        pw.print(category);
2858        pw.print(',');
2859        pw.print(type);
2860    }
2861
2862    /**
2863     * Dump a comma-separated line of values for terse checkin mode.
2864     *
2865     * @param pw the PageWriter to dump log to
2866     * @param category category of data (e.g. "total", "last", "unplugged", "current" )
2867     * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
2868     * @param args type-dependent data arguments
2869     */
2870    private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
2871           Object... args ) {
2872        dumpLineHeader(pw, uid, category, type);
2873        for (Object arg : args) {
2874            pw.print(',');
2875            pw.print(arg);
2876        }
2877        pw.println();
2878    }
2879
2880    /**
2881     * Dump a given timer stat for terse checkin mode.
2882     *
2883     * @param pw the PageWriter to dump log to
2884     * @param uid the UID to log
2885     * @param category category of data (e.g. "total", "last", "unplugged", "current" )
2886     * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
2887     * @param timer a {@link Timer} to dump stats for
2888     * @param rawRealtime the current elapsed realtime of the system in microseconds
2889     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
2890     */
2891    private static final void dumpTimer(PrintWriter pw, int uid, String category, String type,
2892                                        Timer timer, long rawRealtime, int which) {
2893        if (timer != null) {
2894            // Convert from microseconds to milliseconds with rounding
2895            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
2896                    / 1000;
2897            final int count = timer.getCountLocked(which);
2898            if (totalTime != 0) {
2899                dumpLine(pw, uid, category, type, totalTime, count);
2900            }
2901        }
2902    }
2903
2904    /**
2905     * Checks if the ControllerActivityCounter has any data worth dumping.
2906     */
2907    private static boolean controllerActivityHasData(ControllerActivityCounter counter, int which) {
2908        if (counter == null) {
2909            return false;
2910        }
2911
2912        if (counter.getIdleTimeCounter().getCountLocked(which) != 0
2913                || counter.getRxTimeCounter().getCountLocked(which) != 0
2914                || counter.getPowerCounter().getCountLocked(which) != 0) {
2915            return true;
2916        }
2917
2918        for (LongCounter c : counter.getTxTimeCounters()) {
2919            if (c.getCountLocked(which) != 0) {
2920                return true;
2921            }
2922        }
2923        return false;
2924    }
2925
2926    /**
2927     * Dumps the ControllerActivityCounter if it has any data worth dumping.
2928     * The order of the arguments in the final check in line is:
2929     *
2930     * idle, rx, power, tx...
2931     *
2932     * where tx... is one or more transmit level times.
2933     */
2934    private static final void dumpControllerActivityLine(PrintWriter pw, int uid, String category,
2935                                                         String type,
2936                                                         ControllerActivityCounter counter,
2937                                                         int which) {
2938        if (!controllerActivityHasData(counter, which)) {
2939            return;
2940        }
2941
2942        dumpLineHeader(pw, uid, category, type);
2943        pw.print(",");
2944        pw.print(counter.getIdleTimeCounter().getCountLocked(which));
2945        pw.print(",");
2946        pw.print(counter.getRxTimeCounter().getCountLocked(which));
2947        pw.print(",");
2948        pw.print(counter.getPowerCounter().getCountLocked(which) / (1000 * 60 * 60));
2949        for (LongCounter c : counter.getTxTimeCounters()) {
2950            pw.print(",");
2951            pw.print(c.getCountLocked(which));
2952        }
2953        pw.println();
2954    }
2955
2956    private final void printControllerActivityIfInteresting(PrintWriter pw, StringBuilder sb,
2957                                                            String prefix, String controllerName,
2958                                                            ControllerActivityCounter counter,
2959                                                            int which) {
2960        if (controllerActivityHasData(counter, which)) {
2961            printControllerActivity(pw, sb, prefix, controllerName, counter, which);
2962        }
2963    }
2964
2965    private final void printControllerActivity(PrintWriter pw, StringBuilder sb, String prefix,
2966                                               String controllerName,
2967                                               ControllerActivityCounter counter, int which) {
2968        final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
2969        final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
2970        final long powerDrainMaMs = counter.getPowerCounter().getCountLocked(which);
2971        long totalTxTimeMs = 0;
2972        for (LongCounter txState : counter.getTxTimeCounters()) {
2973            totalTxTimeMs += txState.getCountLocked(which);
2974        }
2975
2976        final long totalTimeMs = idleTimeMs + rxTimeMs + totalTxTimeMs;
2977
2978        sb.setLength(0);
2979        sb.append(prefix);
2980        sb.append("  ");
2981        sb.append(controllerName);
2982        sb.append(" Idle time:   ");
2983        formatTimeMs(sb, idleTimeMs);
2984        sb.append("(");
2985        sb.append(formatRatioLocked(idleTimeMs, totalTimeMs));
2986        sb.append(")");
2987        pw.println(sb.toString());
2988
2989        sb.setLength(0);
2990        sb.append(prefix);
2991        sb.append("  ");
2992        sb.append(controllerName);
2993        sb.append(" Rx time:     ");
2994        formatTimeMs(sb, rxTimeMs);
2995        sb.append("(");
2996        sb.append(formatRatioLocked(rxTimeMs, totalTimeMs));
2997        sb.append(")");
2998        pw.println(sb.toString());
2999
3000        sb.setLength(0);
3001        sb.append(prefix);
3002        sb.append("  ");
3003        sb.append(controllerName);
3004        sb.append(" Tx time:     ");
3005        formatTimeMs(sb, totalTxTimeMs);
3006        sb.append("(");
3007        sb.append(formatRatioLocked(totalTxTimeMs, totalTimeMs));
3008        sb.append(")");
3009        pw.println(sb.toString());
3010
3011        final int numTxLvls = counter.getTxTimeCounters().length;
3012        if (numTxLvls > 1) {
3013            for (int lvl = 0; lvl < numTxLvls; lvl++) {
3014                final long txLvlTimeMs = counter.getTxTimeCounters()[lvl].getCountLocked(which);
3015                sb.setLength(0);
3016                sb.append(prefix);
3017                sb.append("    [");
3018                sb.append(lvl);
3019                sb.append("] ");
3020                formatTimeMs(sb, txLvlTimeMs);
3021                sb.append("(");
3022                sb.append(formatRatioLocked(txLvlTimeMs, totalTxTimeMs));
3023                sb.append(")");
3024                pw.println(sb.toString());
3025            }
3026        }
3027
3028        sb.setLength(0);
3029        sb.append(prefix);
3030        sb.append("  ");
3031        sb.append(controllerName);
3032        sb.append(" Power drain: ").append(
3033                BatteryStatsHelper.makemAh(powerDrainMaMs / (double) (1000*60*60)));
3034        sb.append("mAh");
3035        pw.println(sb.toString());
3036    }
3037
3038    /**
3039     * Temporary for settings.
3040     */
3041    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
3042        dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
3043    }
3044
3045    /**
3046     * Checkin server version of dump to produce more compact, computer-readable log.
3047     *
3048     * NOTE: all times are expressed in 'ms'.
3049     */
3050    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
3051            boolean wifiOnly) {
3052        final long rawUptime = SystemClock.uptimeMillis() * 1000;
3053        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
3054        final long batteryUptime = getBatteryUptime(rawUptime);
3055        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
3056        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
3057        final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
3058        final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
3059                which);
3060        final long totalRealtime = computeRealtime(rawRealtime, which);
3061        final long totalUptime = computeUptime(rawUptime, which);
3062        final long screenOnTime = getScreenOnTime(rawRealtime, which);
3063        final long interactiveTime = getInteractiveTime(rawRealtime, which);
3064        final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
3065        final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT,
3066                rawRealtime, which);
3067        final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP,
3068                rawRealtime, which);
3069        final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT,
3070                rawRealtime, which);
3071        final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP,
3072                rawRealtime, which);
3073        final int connChanges = getNumConnectivityChange(which);
3074        final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
3075        final long dischargeCount = getDischargeCoulombCounter().getCountLocked(which);
3076        final long dischargeScreenOffCount = getDischargeScreenOffCoulombCounter()
3077                .getCountLocked(which);
3078
3079        final StringBuilder sb = new StringBuilder(128);
3080
3081        final SparseArray<? extends Uid> uidStats = getUidStats();
3082        final int NU = uidStats.size();
3083
3084        final String category = STAT_NAMES[which];
3085
3086        // Dump "battery" stat
3087        dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
3088                which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
3089                whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
3090                totalRealtime / 1000, totalUptime / 1000,
3091                getStartClockTime(),
3092                whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000,
3093                getEstimatedBatteryCapacity(),
3094                getMinLearnedBatteryCapacity(), getMaxLearnedBatteryCapacity());
3095
3096
3097        // Calculate wakelock times across all uids.
3098        long fullWakeLockTimeTotal = 0;
3099        long partialWakeLockTimeTotal = 0;
3100
3101        for (int iu = 0; iu < NU; iu++) {
3102            final Uid u = uidStats.valueAt(iu);
3103
3104            final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
3105                    = u.getWakelockStats();
3106            for (int iw=wakelocks.size()-1; iw>=0; iw--) {
3107                final Uid.Wakelock wl = wakelocks.valueAt(iw);
3108
3109                final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
3110                if (fullWakeTimer != null) {
3111                    fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
3112                            which);
3113                }
3114
3115                final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
3116                if (partialWakeTimer != null) {
3117                    partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
3118                        rawRealtime, which);
3119                }
3120            }
3121        }
3122
3123        // Dump network stats
3124        final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
3125        final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
3126        final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
3127        final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
3128        final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
3129        final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
3130        final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
3131        final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
3132        final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
3133        final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
3134        dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
3135                mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
3136                mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets,
3137                btRxTotalBytes, btTxTotalBytes);
3138
3139        // Dump Modem controller stats
3140        dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_MODEM_CONTROLLER_DATA,
3141                getModemControllerActivity(), which);
3142
3143        // Dump Wifi controller stats
3144        final long wifiOnTime = getWifiOnTime(rawRealtime, which);
3145        final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
3146        dumpLine(pw, 0 /* uid */, category, GLOBAL_WIFI_DATA, wifiOnTime / 1000,
3147                wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */ 0, 0, 0);
3148
3149        dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_WIFI_CONTROLLER_DATA,
3150                getWifiControllerActivity(), which);
3151
3152        // Dump Bluetooth controller stats
3153        dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_BLUETOOTH_CONTROLLER_DATA,
3154                getBluetoothControllerActivity(), which);
3155
3156        // Dump misc stats
3157        dumpLine(pw, 0 /* uid */, category, MISC_DATA,
3158                screenOnTime / 1000, phoneOnTime / 1000,
3159                fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000,
3160                getMobileRadioActiveTime(rawRealtime, which) / 1000,
3161                getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000,
3162                powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeFullTime / 1000,
3163                getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which), deviceIdlingTime / 1000,
3164                getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which),
3165                getMobileRadioActiveCount(which),
3166                getMobileRadioActiveUnknownTime(which) / 1000, deviceIdleModeLightTime / 1000,
3167                getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which), deviceLightIdlingTime / 1000,
3168                getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which),
3169                getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT),
3170                getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
3171
3172        // Dump screen brightness stats
3173        Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
3174        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3175            args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
3176        }
3177        dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
3178
3179        // Dump signal strength stats
3180        args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
3181        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
3182            args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
3183        }
3184        dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
3185        dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
3186                getPhoneSignalScanningTime(rawRealtime, which) / 1000);
3187        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
3188            args[i] = getPhoneSignalStrengthCount(i, which);
3189        }
3190        dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
3191
3192        // Dump network type stats
3193        args = new Object[NUM_DATA_CONNECTION_TYPES];
3194        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3195            args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
3196        }
3197        dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
3198        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3199            args[i] = getPhoneDataConnectionCount(i, which);
3200        }
3201        dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
3202
3203        // Dump wifi state stats
3204        args = new Object[NUM_WIFI_STATES];
3205        for (int i=0; i<NUM_WIFI_STATES; i++) {
3206            args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
3207        }
3208        dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args);
3209        for (int i=0; i<NUM_WIFI_STATES; i++) {
3210            args[i] = getWifiStateCount(i, which);
3211        }
3212        dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args);
3213
3214        // Dump wifi suppl state stats
3215        args = new Object[NUM_WIFI_SUPPL_STATES];
3216        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
3217            args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
3218        }
3219        dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_TIME_DATA, args);
3220        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
3221            args[i] = getWifiSupplStateCount(i, which);
3222        }
3223        dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_COUNT_DATA, args);
3224
3225        // Dump wifi signal strength stats
3226        args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
3227        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
3228            args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
3229        }
3230        dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
3231        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
3232            args[i] = getWifiSignalStrengthCount(i, which);
3233        }
3234        dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
3235
3236        if (which == STATS_SINCE_UNPLUGGED) {
3237            dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
3238                    getDischargeCurrentLevel());
3239        }
3240
3241        if (which == STATS_SINCE_UNPLUGGED) {
3242            dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
3243                    getDischargeStartLevel()-getDischargeCurrentLevel(),
3244                    getDischargeStartLevel()-getDischargeCurrentLevel(),
3245                    getDischargeAmountScreenOn(), getDischargeAmountScreenOff(),
3246                    dischargeCount / 1000, dischargeScreenOffCount / 1000);
3247        } else {
3248            dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
3249                    getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
3250                    getDischargeAmountScreenOnSinceCharge(),
3251                    getDischargeAmountScreenOffSinceCharge(),
3252                    dischargeCount / 1000, dischargeScreenOffCount / 1000);
3253        }
3254
3255        if (reqUid < 0) {
3256            final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
3257            if (kernelWakelocks.size() > 0) {
3258                for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
3259                    sb.setLength(0);
3260                    printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
3261                    dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA,
3262                            "\"" + ent.getKey() + "\"", sb.toString());
3263                }
3264            }
3265            final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
3266            if (wakeupReasons.size() > 0) {
3267                for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
3268                    // Not doing the regular wake lock formatting to remain compatible
3269                    // with the old checkin format.
3270                    long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which);
3271                    int count = ent.getValue().getCountLocked(which);
3272                    dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA,
3273                            "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count);
3274                }
3275            }
3276        }
3277
3278        final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
3279        helper.create(this);
3280        helper.refreshStats(which, UserHandle.USER_ALL);
3281        final List<BatterySipper> sippers = helper.getUsageList();
3282        if (sippers != null && sippers.size() > 0) {
3283            dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
3284                    BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
3285                    BatteryStatsHelper.makemAh(helper.getComputedPower()),
3286                    BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
3287                    BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
3288            for (int i=0; i<sippers.size(); i++) {
3289                final BatterySipper bs = sippers.get(i);
3290                int uid = 0;
3291                String label;
3292                switch (bs.drainType) {
3293                    case IDLE:
3294                        label="idle";
3295                        break;
3296                    case CELL:
3297                        label="cell";
3298                        break;
3299                    case PHONE:
3300                        label="phone";
3301                        break;
3302                    case WIFI:
3303                        label="wifi";
3304                        break;
3305                    case BLUETOOTH:
3306                        label="blue";
3307                        break;
3308                    case SCREEN:
3309                        label="scrn";
3310                        break;
3311                    case FLASHLIGHT:
3312                        label="flashlight";
3313                        break;
3314                    case APP:
3315                        uid = bs.uidObj.getUid();
3316                        label = "uid";
3317                        break;
3318                    case USER:
3319                        uid = UserHandle.getUid(bs.userId, 0);
3320                        label = "user";
3321                        break;
3322                    case UNACCOUNTED:
3323                        label = "unacc";
3324                        break;
3325                    case OVERCOUNTED:
3326                        label = "over";
3327                        break;
3328                    case CAMERA:
3329                        label = "camera";
3330                        break;
3331                    default:
3332                        label = "???";
3333                }
3334                dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
3335                        BatteryStatsHelper.makemAh(bs.totalPowerMah),
3336                        bs.shouldHide ? 1 : 0,
3337                        BatteryStatsHelper.makemAh(bs.screenPowerMah),
3338                        BatteryStatsHelper.makemAh(bs.proportionalSmearMah));
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
4369                // If there is additional smearing information, include it.
4370                if (bs.totalSmearedPowerMah != bs.totalPowerMah) {
4371                    pw.print(" Including smearing: ");
4372                    printmAh(pw, bs.totalSmearedPowerMah);
4373                    pw.print(" (");
4374                    if (bs.screenPowerMah != 0) {
4375                        pw.print(" screen=");
4376                        printmAh(pw, bs.screenPowerMah);
4377                    }
4378                    if (bs.proportionalSmearMah != 0) {
4379                        pw.print(" proportional=");
4380                        printmAh(pw, bs.proportionalSmearMah);
4381                    }
4382                    pw.print(" )");
4383                }
4384                if (bs.shouldHide) {
4385                    pw.print(" Excluded from smearing");
4386                }
4387
4388                pw.println();
4389            }
4390            pw.println();
4391        }
4392
4393        sippers = helper.getMobilemsppList();
4394        if (sippers != null && sippers.size() > 0) {
4395            pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
4396            long totalTime = 0;
4397            for (int i=0; i<sippers.size(); i++) {
4398                final BatterySipper bs = sippers.get(i);
4399                sb.setLength(0);
4400                sb.append(prefix); sb.append("    Uid ");
4401                UserHandle.formatUid(sb, bs.uidObj.getUid());
4402                sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
4403                sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
4404                sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
4405                sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
4406                pw.println(sb.toString());
4407                totalTime += bs.mobileActive;
4408            }
4409            sb.setLength(0);
4410            sb.append(prefix);
4411            sb.append("    TOTAL TIME: ");
4412            formatTimeMs(sb, totalTime);
4413            sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
4414            sb.append(")");
4415            pw.println(sb.toString());
4416            pw.println();
4417        }
4418
4419        final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
4420            @Override
4421            public int compare(TimerEntry lhs, TimerEntry rhs) {
4422                long lhsTime = lhs.mTime;
4423                long rhsTime = rhs.mTime;
4424                if (lhsTime < rhsTime) {
4425                    return 1;
4426                }
4427                if (lhsTime > rhsTime) {
4428                    return -1;
4429                }
4430                return 0;
4431            }
4432        };
4433
4434        if (reqUid < 0) {
4435            final Map<String, ? extends BatteryStats.Timer> kernelWakelocks
4436                    = getKernelWakelockStats();
4437            if (kernelWakelocks.size() > 0) {
4438                final ArrayList<TimerEntry> ktimers = new ArrayList<>();
4439                for (Map.Entry<String, ? extends BatteryStats.Timer> ent
4440                        : kernelWakelocks.entrySet()) {
4441                    final BatteryStats.Timer timer = ent.getValue();
4442                    final long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
4443                    if (totalTimeMillis > 0) {
4444                        ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
4445                    }
4446                }
4447                if (ktimers.size() > 0) {
4448                    Collections.sort(ktimers, timerComparator);
4449                    pw.print(prefix); pw.println("  All kernel wake locks:");
4450                    for (int i=0; i<ktimers.size(); i++) {
4451                        final TimerEntry timer = ktimers.get(i);
4452                        String linePrefix = ": ";
4453                        sb.setLength(0);
4454                        sb.append(prefix);
4455                        sb.append("  Kernel Wake lock ");
4456                        sb.append(timer.mName);
4457                        linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null,
4458                                which, linePrefix);
4459                        if (!linePrefix.equals(": ")) {
4460                            sb.append(" realtime");
4461                            // Only print out wake locks that were held
4462                            pw.println(sb.toString());
4463                        }
4464                    }
4465                    pw.println();
4466                }
4467            }
4468
4469            if (timers.size() > 0) {
4470                Collections.sort(timers, timerComparator);
4471                pw.print(prefix); pw.println("  All partial wake locks:");
4472                for (int i=0; i<timers.size(); i++) {
4473                    TimerEntry timer = timers.get(i);
4474                    sb.setLength(0);
4475                    sb.append("  Wake lock ");
4476                    UserHandle.formatUid(sb, timer.mId);
4477                    sb.append(" ");
4478                    sb.append(timer.mName);
4479                    printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
4480                    sb.append(" realtime");
4481                    pw.println(sb.toString());
4482                }
4483                timers.clear();
4484                pw.println();
4485            }
4486
4487            final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
4488            if (wakeupReasons.size() > 0) {
4489                pw.print(prefix); pw.println("  All wakeup reasons:");
4490                final ArrayList<TimerEntry> reasons = new ArrayList<>();
4491                for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
4492                    final Timer timer = ent.getValue();
4493                    reasons.add(new TimerEntry(ent.getKey(), 0, timer,
4494                            timer.getCountLocked(which)));
4495                }
4496                Collections.sort(reasons, timerComparator);
4497                for (int i=0; i<reasons.size(); i++) {
4498                    TimerEntry timer = reasons.get(i);
4499                    String linePrefix = ": ";
4500                    sb.setLength(0);
4501                    sb.append(prefix);
4502                    sb.append("  Wakeup reason ");
4503                    sb.append(timer.mName);
4504                    printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
4505                    sb.append(" realtime");
4506                    pw.println(sb.toString());
4507                }
4508                pw.println();
4509            }
4510        }
4511
4512        final LongSparseArray<? extends Timer> mMemoryStats = getKernelMemoryStats();
4513        pw.println("Memory Stats");
4514        for (int i = 0; i < mMemoryStats.size(); i++) {
4515            sb.setLength(0);
4516            sb.append("Bandwidth ");
4517            sb.append(mMemoryStats.keyAt(i));
4518            sb.append(" Time ");
4519            sb.append(mMemoryStats.valueAt(i).getTotalTimeLocked(rawRealtime, which));
4520            pw.println(sb.toString());
4521        }
4522
4523        final long[] cpuFreqs = getCpuFreqs();
4524        if (cpuFreqs != null) {
4525            sb.setLength(0);
4526            sb.append("CPU freqs:");
4527            for (int i = 0; i < cpuFreqs.length; ++i) {
4528                sb.append(" " + cpuFreqs[i]);
4529            }
4530            pw.println(sb.toString());
4531        }
4532
4533        for (int iu=0; iu<NU; iu++) {
4534            final int uid = uidStats.keyAt(iu);
4535            if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
4536                continue;
4537            }
4538
4539            final Uid u = uidStats.valueAt(iu);
4540
4541            pw.print(prefix);
4542            pw.print("  ");
4543            UserHandle.formatUid(pw, uid);
4544            pw.println(":");
4545            boolean uidActivity = false;
4546
4547            final long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
4548            final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
4549            final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
4550            final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
4551            final long btRxBytes = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
4552            final long btTxBytes = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
4553
4554            final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
4555            final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
4556            final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
4557            final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
4558
4559            final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
4560            final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
4561
4562            final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
4563            final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
4564            final int wifiScanCount = u.getWifiScanCount(which);
4565            final int wifiScanCountBg = u.getWifiScanBackgroundCount(which);
4566            // 'actualTime' are unpooled and always since reset (regardless of 'which')
4567            final long wifiScanActualTime = u.getWifiScanActualTime(rawRealtime);
4568            final long wifiScanActualTimeBg = u.getWifiScanBackgroundTime(rawRealtime);
4569            final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
4570
4571            final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
4572            final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
4573
4574            if (mobileRxBytes > 0 || mobileTxBytes > 0
4575                    || mobileRxPackets > 0 || mobileTxPackets > 0) {
4576                pw.print(prefix); pw.print("    Mobile network: ");
4577                        pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
4578                        pw.print(formatBytesLocked(mobileTxBytes));
4579                        pw.print(" sent (packets "); pw.print(mobileRxPackets);
4580                        pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
4581            }
4582            if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
4583                sb.setLength(0);
4584                sb.append(prefix); sb.append("    Mobile radio active: ");
4585                formatTimeMs(sb, uidMobileActiveTime / 1000);
4586                sb.append("(");
4587                sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
4588                sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
4589                long packets = mobileRxPackets + mobileTxPackets;
4590                if (packets == 0) {
4591                    packets = 1;
4592                }
4593                sb.append(" @ ");
4594                sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
4595                sb.append(" mspp");
4596                pw.println(sb.toString());
4597            }
4598
4599            if (mobileWakeup > 0) {
4600                sb.setLength(0);
4601                sb.append(prefix);
4602                sb.append("    Mobile radio AP wakeups: ");
4603                sb.append(mobileWakeup);
4604                pw.println(sb.toString());
4605            }
4606
4607            printControllerActivityIfInteresting(pw, sb, prefix + "  ", "Modem",
4608                    u.getModemControllerActivity(), which);
4609
4610            if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
4611                pw.print(prefix); pw.print("    Wi-Fi network: ");
4612                        pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
4613                        pw.print(formatBytesLocked(wifiTxBytes));
4614                        pw.print(" sent (packets "); pw.print(wifiRxPackets);
4615                        pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
4616            }
4617
4618            if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
4619                    || wifiScanCountBg != 0 || wifiScanActualTime != 0 || wifiScanActualTimeBg != 0
4620                    || uidWifiRunningTime != 0) {
4621                sb.setLength(0);
4622                sb.append(prefix); sb.append("    Wifi Running: ");
4623                        formatTimeMs(sb, uidWifiRunningTime / 1000);
4624                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
4625                                whichBatteryRealtime)); sb.append(")\n");
4626                sb.append(prefix); sb.append("    Full Wifi Lock: ");
4627                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
4628                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
4629                                whichBatteryRealtime)); sb.append(")\n");
4630                sb.append(prefix); sb.append("    Wifi Scan (blamed): ");
4631                        formatTimeMs(sb, wifiScanTime / 1000);
4632                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
4633                                whichBatteryRealtime)); sb.append(") ");
4634                                sb.append(wifiScanCount);
4635                                sb.append("x\n");
4636                // actual and background times are unpooled and since reset (regardless of 'which')
4637                sb.append(prefix); sb.append("    Wifi Scan (actual): ");
4638                        formatTimeMs(sb, wifiScanActualTime / 1000);
4639                        sb.append("("); sb.append(formatRatioLocked(wifiScanActualTime,
4640                                computeBatteryRealtime(rawRealtime, STATS_SINCE_CHARGED)));
4641                                sb.append(") ");
4642                                sb.append(wifiScanCount);
4643                                sb.append("x\n");
4644                sb.append(prefix); sb.append("    Background Wifi Scan: ");
4645                        formatTimeMs(sb, wifiScanActualTimeBg / 1000);
4646                        sb.append("("); sb.append(formatRatioLocked(wifiScanActualTimeBg,
4647                                computeBatteryRealtime(rawRealtime, STATS_SINCE_CHARGED)));
4648                                sb.append(") ");
4649                                sb.append(wifiScanCountBg);
4650                                sb.append("x");
4651                pw.println(sb.toString());
4652            }
4653
4654            if (wifiWakeup > 0) {
4655                sb.setLength(0);
4656                sb.append(prefix);
4657                sb.append("    WiFi AP wakeups: ");
4658                sb.append(wifiWakeup);
4659                pw.println(sb.toString());
4660            }
4661
4662            printControllerActivityIfInteresting(pw, sb, prefix + "  ", "WiFi",
4663                    u.getWifiControllerActivity(), which);
4664
4665            if (btRxBytes > 0 || btTxBytes > 0) {
4666                pw.print(prefix); pw.print("    Bluetooth network: ");
4667                pw.print(formatBytesLocked(btRxBytes)); pw.print(" received, ");
4668                pw.print(formatBytesLocked(btTxBytes));
4669                pw.println(" sent");
4670            }
4671
4672            final Timer bleTimer = u.getBluetoothScanTimer();
4673            if (bleTimer != null) {
4674                // Convert from microseconds to milliseconds with rounding
4675                final long totalTimeMs = (bleTimer.getTotalTimeLocked(rawRealtime, which) + 500)
4676                        / 1000;
4677                if (totalTimeMs != 0) {
4678                    final int count = bleTimer.getCountLocked(which);
4679                    final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
4680                    final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
4681                    final long rawRealtimeMs = (rawRealtime + 500) / 1000;
4682                    // 'actualTime' are unpooled and always since reset (regardless of 'which')
4683                    final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
4684                    final long actualTimeMsBg = bleTimerBg != null ?
4685                            bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4686                    // Result counters
4687                    final int resultCount = u.getBluetoothScanResultCounter() != null ?
4688                            u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
4689                    final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
4690                            u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
4691                    // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
4692                    final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
4693                    final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
4694                            unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4695                    final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
4696                            unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
4697                    // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
4698                    final Timer unoptimizedScanTimerBg =
4699                            u.getBluetoothUnoptimizedScanBackgroundTimer();
4700                    final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
4701                            unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4702                    final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
4703                            unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
4704
4705                    sb.setLength(0);
4706                    if (actualTimeMs != totalTimeMs) {
4707                        sb.append(prefix);
4708                        sb.append("    Bluetooth Scan (total blamed realtime): ");
4709                        formatTimeMs(sb, totalTimeMs);
4710                        sb.append(" (");
4711                        sb.append(count);
4712                        sb.append(" times)");
4713                        if (bleTimer.isRunningLocked()) {
4714                            sb.append(" (currently running)");
4715                        }
4716                        sb.append("\n");
4717                    }
4718
4719                    sb.append(prefix);
4720                    sb.append("    Bluetooth Scan (total actual realtime): ");
4721                    formatTimeMs(sb, actualTimeMs); // since reset, ignores 'which'
4722                    sb.append(" (");
4723                    sb.append(count);
4724                    sb.append(" times)");
4725                    if (bleTimer.isRunningLocked()) {
4726                            sb.append(" (currently running)");
4727                    }
4728                    sb.append("\n");
4729                    if (actualTimeMsBg > 0 || countBg > 0) {
4730                        sb.append(prefix);
4731                        sb.append("    Bluetooth Scan (background realtime): ");
4732                        formatTimeMs(sb, actualTimeMsBg); // since reset, ignores 'which'
4733                        sb.append(" (");
4734                        sb.append(countBg);
4735                        sb.append(" times)");
4736                        if (bleTimerBg != null && bleTimerBg.isRunningLocked()) {
4737                            sb.append(" (currently running in background)");
4738                        }
4739                        sb.append("\n");
4740                    }
4741
4742                    sb.append(prefix);
4743                    sb.append("    Bluetooth Scan Results: ");
4744                    sb.append(resultCount);
4745                    sb.append(" (");
4746                    sb.append(resultCountBg);
4747                    sb.append(" in background)");
4748
4749                    if (unoptimizedScanTotalTime > 0 || unoptimizedScanTotalTimeBg > 0) {
4750                        sb.append("\n");
4751                        sb.append(prefix);
4752                        sb.append("    Unoptimized Bluetooth Scan (realtime): ");
4753                        formatTimeMs(sb, unoptimizedScanTotalTime); // since reset, ignores 'which'
4754                        sb.append(" (max ");
4755                        formatTimeMs(sb, unoptimizedScanMaxTime); // since reset, ignores 'which'
4756                        sb.append(")");
4757                        if (unoptimizedScanTimer != null
4758                                && unoptimizedScanTimer.isRunningLocked()) {
4759                            sb.append(" (currently running unoptimized)");
4760                        }
4761                        if (unoptimizedScanTimerBg != null && unoptimizedScanTotalTimeBg > 0) {
4762                            sb.append("\n");
4763                            sb.append(prefix);
4764                            sb.append("    Unoptimized Bluetooth Scan (background realtime): ");
4765                            formatTimeMs(sb, unoptimizedScanTotalTimeBg); // since reset
4766                            sb.append(" (max ");
4767                            formatTimeMs(sb, unoptimizedScanMaxTimeBg); // since reset
4768                            sb.append(")");
4769                            if (unoptimizedScanTimerBg.isRunningLocked()) {
4770                                sb.append(" (currently running unoptimized in background)");
4771                            }
4772                        }
4773                    }
4774                    pw.println(sb.toString());
4775                    uidActivity = true;
4776                }
4777            }
4778
4779
4780
4781            if (u.hasUserActivity()) {
4782                boolean hasData = false;
4783                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
4784                    final int val = u.getUserActivityCount(i, which);
4785                    if (val != 0) {
4786                        if (!hasData) {
4787                            sb.setLength(0);
4788                            sb.append("    User activity: ");
4789                            hasData = true;
4790                        } else {
4791                            sb.append(", ");
4792                        }
4793                        sb.append(val);
4794                        sb.append(" ");
4795                        sb.append(Uid.USER_ACTIVITY_TYPES[i]);
4796                    }
4797                }
4798                if (hasData) {
4799                    pw.println(sb.toString());
4800                }
4801            }
4802
4803            final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
4804                    = u.getWakelockStats();
4805            long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
4806            long totalDrawWakelock = 0;
4807            int countWakelock = 0;
4808            for (int iw=wakelocks.size()-1; iw>=0; iw--) {
4809                final Uid.Wakelock wl = wakelocks.valueAt(iw);
4810                String linePrefix = ": ";
4811                sb.setLength(0);
4812                sb.append(prefix);
4813                sb.append("    Wake lock ");
4814                sb.append(wakelocks.keyAt(iw));
4815                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
4816                        "full", which, linePrefix);
4817                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
4818                linePrefix = printWakeLock(sb, pTimer, rawRealtime,
4819                        "partial", which, linePrefix);
4820                linePrefix = printWakeLock(sb, pTimer != null ? pTimer.getSubTimer() : null,
4821                        rawRealtime, "background partial", which, linePrefix);
4822                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
4823                        "window", which, linePrefix);
4824                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
4825                        "draw", which, linePrefix);
4826                sb.append(" realtime");
4827                pw.println(sb.toString());
4828                uidActivity = true;
4829                countWakelock++;
4830
4831                totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
4832                        rawRealtime, which);
4833                totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
4834                        rawRealtime, which);
4835                totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
4836                        rawRealtime, which);
4837                totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW),
4838                        rawRealtime, which);
4839            }
4840            if (countWakelock > 1) {
4841                // get unpooled partial wakelock quantities (unlike totalPartialWakelock, which is
4842                // pooled and therefore just a lower bound)
4843                long actualTotalPartialWakelock = 0;
4844                long actualBgPartialWakelock = 0;
4845                if (u.getAggregatedPartialWakelockTimer() != null) {
4846                    final Timer aggTimer = u.getAggregatedPartialWakelockTimer();
4847                    // Convert from microseconds to milliseconds with rounding
4848                    actualTotalPartialWakelock =
4849                            (aggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
4850                    final Timer bgAggTimer = aggTimer.getSubTimer();
4851                    actualBgPartialWakelock = bgAggTimer != null ?
4852                            (bgAggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
4853                }
4854
4855                if (actualTotalPartialWakelock != 0 || actualBgPartialWakelock != 0 ||
4856                        totalFullWakelock != 0 || totalPartialWakelock != 0 ||
4857                        totalWindowWakelock != 0) {
4858                    sb.setLength(0);
4859                    sb.append(prefix);
4860                    sb.append("    TOTAL wake: ");
4861                    boolean needComma = false;
4862                    if (totalFullWakelock != 0) {
4863                        needComma = true;
4864                        formatTimeMs(sb, totalFullWakelock);
4865                        sb.append("full");
4866                    }
4867                    if (totalPartialWakelock != 0) {
4868                        if (needComma) {
4869                            sb.append(", ");
4870                        }
4871                        needComma = true;
4872                        formatTimeMs(sb, totalPartialWakelock);
4873                        sb.append("blamed partial");
4874                    }
4875                    if (actualTotalPartialWakelock != 0) {
4876                        if (needComma) {
4877                            sb.append(", ");
4878                        }
4879                        needComma = true;
4880                        formatTimeMs(sb, actualTotalPartialWakelock);
4881                        sb.append("actual partial");
4882                    }
4883                    if (actualBgPartialWakelock != 0) {
4884                        if (needComma) {
4885                            sb.append(", ");
4886                        }
4887                        needComma = true;
4888                        formatTimeMs(sb, actualBgPartialWakelock);
4889                        sb.append("actual background partial");
4890                    }
4891                    if (totalWindowWakelock != 0) {
4892                        if (needComma) {
4893                            sb.append(", ");
4894                        }
4895                        needComma = true;
4896                        formatTimeMs(sb, totalWindowWakelock);
4897                        sb.append("window");
4898                    }
4899                    if (totalDrawWakelock != 0) {
4900                        if (needComma) {
4901                            sb.append(",");
4902                        }
4903                        needComma = true;
4904                        formatTimeMs(sb, totalDrawWakelock);
4905                        sb.append("draw");
4906                    }
4907                    sb.append(" realtime");
4908                    pw.println(sb.toString());
4909                }
4910            }
4911
4912            final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
4913            for (int isy=syncs.size()-1; isy>=0; isy--) {
4914                final Timer timer = syncs.valueAt(isy);
4915                // Convert from microseconds to milliseconds with rounding
4916                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
4917                final int count = timer.getCountLocked(which);
4918                final Timer bgTimer = timer.getSubTimer();
4919                final long bgTime = bgTimer != null ?
4920                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
4921                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
4922                sb.setLength(0);
4923                sb.append(prefix);
4924                sb.append("    Sync ");
4925                sb.append(syncs.keyAt(isy));
4926                sb.append(": ");
4927                if (totalTime != 0) {
4928                    formatTimeMs(sb, totalTime);
4929                    sb.append("realtime (");
4930                    sb.append(count);
4931                    sb.append(" times)");
4932                    if (bgTime > 0) {
4933                        sb.append(", ");
4934                        formatTimeMs(sb, bgTime);
4935                        sb.append("background (");
4936                        sb.append(bgCount);
4937                        sb.append(" times)");
4938                    }
4939                } else {
4940                    sb.append("(not used)");
4941                }
4942                pw.println(sb.toString());
4943                uidActivity = true;
4944            }
4945
4946            final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
4947            for (int ij=jobs.size()-1; ij>=0; ij--) {
4948                final Timer timer = jobs.valueAt(ij);
4949                // Convert from microseconds to milliseconds with rounding
4950                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
4951                final int count = timer.getCountLocked(which);
4952                final Timer bgTimer = timer.getSubTimer();
4953                final long bgTime = bgTimer != null ?
4954                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
4955                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
4956                sb.setLength(0);
4957                sb.append(prefix);
4958                sb.append("    Job ");
4959                sb.append(jobs.keyAt(ij));
4960                sb.append(": ");
4961                if (totalTime != 0) {
4962                    formatTimeMs(sb, totalTime);
4963                    sb.append("realtime (");
4964                    sb.append(count);
4965                    sb.append(" times)");
4966                    if (bgTime > 0) {
4967                        sb.append(", ");
4968                        formatTimeMs(sb, bgTime);
4969                        sb.append("background (");
4970                        sb.append(bgCount);
4971                        sb.append(" times)");
4972                    }
4973                } else {
4974                    sb.append("(not used)");
4975                }
4976                pw.println(sb.toString());
4977                uidActivity = true;
4978            }
4979
4980            uidActivity |= printTimer(pw, sb, u.getFlashlightTurnedOnTimer(), rawRealtime, which,
4981                    prefix, "Flashlight");
4982            uidActivity |= printTimer(pw, sb, u.getCameraTurnedOnTimer(), rawRealtime, which,
4983                    prefix, "Camera");
4984            uidActivity |= printTimer(pw, sb, u.getVideoTurnedOnTimer(), rawRealtime, which,
4985                    prefix, "Video");
4986            uidActivity |= printTimer(pw, sb, u.getAudioTurnedOnTimer(), rawRealtime, which,
4987                    prefix, "Audio");
4988
4989            final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
4990            final int NSE = sensors.size();
4991            for (int ise=0; ise<NSE; ise++) {
4992                final Uid.Sensor se = sensors.valueAt(ise);
4993                final int sensorNumber = sensors.keyAt(ise);
4994                sb.setLength(0);
4995                sb.append(prefix);
4996                sb.append("    Sensor ");
4997                int handle = se.getHandle();
4998                if (handle == Uid.Sensor.GPS) {
4999                    sb.append("GPS");
5000                } else {
5001                    sb.append(handle);
5002                }
5003                sb.append(": ");
5004
5005                final Timer timer = se.getSensorTime();
5006                if (timer != null) {
5007                    // Convert from microseconds to milliseconds with rounding
5008                    final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
5009                            / 1000;
5010                    final int count = timer.getCountLocked(which);
5011                    final Timer bgTimer = se.getSensorBackgroundTime();
5012                    final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
5013                    final long rawRealtimeMs = (rawRealtime + 500) / 1000;
5014                    // 'actualTime' are unpooled and always since reset (regardless of 'which')
5015                    final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
5016                    final long bgActualTime = bgTimer != null ?
5017                            bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5018
5019                    //timer.logState();
5020                    if (totalTime != 0) {
5021                        if (actualTime != totalTime) {
5022                            formatTimeMs(sb, totalTime);
5023                            sb.append("blamed realtime, ");
5024                        }
5025
5026                        formatTimeMs(sb, actualTime); // since reset, regardless of 'which'
5027                        sb.append("realtime (");
5028                        sb.append(count);
5029                        sb.append(" times)");
5030
5031                        if (bgActualTime != 0 || bgCount > 0) {
5032                            sb.append(", ");
5033                            formatTimeMs(sb, bgActualTime); // since reset, regardless of 'which'
5034                            sb.append("background (");
5035                            sb.append(bgCount);
5036                            sb.append(" times)");
5037                        }
5038                    } else {
5039                        sb.append("(not used)");
5040                    }
5041                } else {
5042                    sb.append("(not used)");
5043                }
5044
5045                pw.println(sb.toString());
5046                uidActivity = true;
5047            }
5048
5049            uidActivity |= printTimer(pw, sb, u.getVibratorOnTimer(), rawRealtime, which, prefix,
5050                    "Vibrator");
5051            uidActivity |= printTimer(pw, sb, u.getForegroundActivityTimer(), rawRealtime, which,
5052                    prefix, "Foreground activities");
5053
5054            long totalStateTime = 0;
5055            for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
5056                long time = u.getProcessStateTime(ips, rawRealtime, which);
5057                if (time > 0) {
5058                    totalStateTime += time;
5059                    sb.setLength(0);
5060                    sb.append(prefix);
5061                    sb.append("    ");
5062                    sb.append(Uid.PROCESS_STATE_NAMES[ips]);
5063                    sb.append(" for: ");
5064                    formatTimeMs(sb, (time + 500) / 1000);
5065                    pw.println(sb.toString());
5066                    uidActivity = true;
5067                }
5068            }
5069            if (totalStateTime > 0) {
5070                sb.setLength(0);
5071                sb.append(prefix);
5072                sb.append("    Total running: ");
5073                formatTimeMs(sb, (totalStateTime + 500) / 1000);
5074                pw.println(sb.toString());
5075            }
5076
5077            final long userCpuTimeUs = u.getUserCpuTimeUs(which);
5078            final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
5079            if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
5080                sb.setLength(0);
5081                sb.append(prefix);
5082                sb.append("    Total cpu time: u=");
5083                formatTimeMs(sb, userCpuTimeUs / 1000);
5084                sb.append("s=");
5085                formatTimeMs(sb, systemCpuTimeUs / 1000);
5086                pw.println(sb.toString());
5087            }
5088
5089            final long[] cpuFreqTimes = u.getCpuFreqTimes(which);
5090            if (cpuFreqTimes != null) {
5091                sb.setLength(0);
5092                sb.append("    Total cpu time per freq:");
5093                for (int i = 0; i < cpuFreqTimes.length; ++i) {
5094                    sb.append(" " + cpuFreqTimes[i]);
5095                }
5096                pw.println(sb.toString());
5097            }
5098            final long[] screenOffCpuFreqTimes = u.getScreenOffCpuFreqTimes(which);
5099            if (screenOffCpuFreqTimes != null) {
5100                sb.setLength(0);
5101                sb.append("    Total screen-off cpu time per freq:");
5102                for (int i = 0; i < screenOffCpuFreqTimes.length; ++i) {
5103                    sb.append(" " + screenOffCpuFreqTimes[i]);
5104                }
5105                pw.println(sb.toString());
5106            }
5107
5108            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
5109                    = u.getProcessStats();
5110            for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
5111                final Uid.Proc ps = processStats.valueAt(ipr);
5112                long userTime;
5113                long systemTime;
5114                long foregroundTime;
5115                int starts;
5116                int numExcessive;
5117
5118                userTime = ps.getUserTime(which);
5119                systemTime = ps.getSystemTime(which);
5120                foregroundTime = ps.getForegroundTime(which);
5121                starts = ps.getStarts(which);
5122                final int numCrashes = ps.getNumCrashes(which);
5123                final int numAnrs = ps.getNumAnrs(which);
5124                numExcessive = which == STATS_SINCE_CHARGED
5125                        ? ps.countExcessivePowers() : 0;
5126
5127                if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
5128                        || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
5129                    sb.setLength(0);
5130                    sb.append(prefix); sb.append("    Proc ");
5131                            sb.append(processStats.keyAt(ipr)); sb.append(":\n");
5132                    sb.append(prefix); sb.append("      CPU: ");
5133                            formatTimeMs(sb, userTime); sb.append("usr + ");
5134                            formatTimeMs(sb, systemTime); sb.append("krn ; ");
5135                            formatTimeMs(sb, foregroundTime); sb.append("fg");
5136                    if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
5137                        sb.append("\n"); sb.append(prefix); sb.append("      ");
5138                        boolean hasOne = false;
5139                        if (starts != 0) {
5140                            hasOne = true;
5141                            sb.append(starts); sb.append(" starts");
5142                        }
5143                        if (numCrashes != 0) {
5144                            if (hasOne) {
5145                                sb.append(", ");
5146                            }
5147                            hasOne = true;
5148                            sb.append(numCrashes); sb.append(" crashes");
5149                        }
5150                        if (numAnrs != 0) {
5151                            if (hasOne) {
5152                                sb.append(", ");
5153                            }
5154                            sb.append(numAnrs); sb.append(" anrs");
5155                        }
5156                    }
5157                    pw.println(sb.toString());
5158                    for (int e=0; e<numExcessive; e++) {
5159                        Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
5160                        if (ew != null) {
5161                            pw.print(prefix); pw.print("      * Killed for ");
5162                                    if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
5163                                        pw.print("wake lock");
5164                                    } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
5165                                        pw.print("cpu");
5166                                    } else {
5167                                        pw.print("unknown");
5168                                    }
5169                                    pw.print(" use: ");
5170                                    TimeUtils.formatDuration(ew.usedTime, pw);
5171                                    pw.print(" over ");
5172                                    TimeUtils.formatDuration(ew.overTime, pw);
5173                                    if (ew.overTime != 0) {
5174                                        pw.print(" (");
5175                                        pw.print((ew.usedTime*100)/ew.overTime);
5176                                        pw.println("%)");
5177                                    }
5178                        }
5179                    }
5180                    uidActivity = true;
5181                }
5182            }
5183
5184            final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
5185                    = u.getPackageStats();
5186            for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
5187                pw.print(prefix); pw.print("    Apk "); pw.print(packageStats.keyAt(ipkg));
5188                pw.println(":");
5189                boolean apkActivity = false;
5190                final Uid.Pkg ps = packageStats.valueAt(ipkg);
5191                final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
5192                for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
5193                    pw.print(prefix); pw.print("      Wakeup alarm ");
5194                            pw.print(alarms.keyAt(iwa)); pw.print(": ");
5195                            pw.print(alarms.valueAt(iwa).getCountLocked(which));
5196                            pw.println(" times");
5197                    apkActivity = true;
5198                }
5199                final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
5200                for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
5201                    final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
5202                    final long startTime = ss.getStartTime(batteryUptime, which);
5203                    final int starts = ss.getStarts(which);
5204                    final int launches = ss.getLaunches(which);
5205                    if (startTime != 0 || starts != 0 || launches != 0) {
5206                        sb.setLength(0);
5207                        sb.append(prefix); sb.append("      Service ");
5208                                sb.append(serviceStats.keyAt(isvc)); sb.append(":\n");
5209                        sb.append(prefix); sb.append("        Created for: ");
5210                                formatTimeMs(sb, startTime / 1000);
5211                                sb.append("uptime\n");
5212                        sb.append(prefix); sb.append("        Starts: ");
5213                                sb.append(starts);
5214                                sb.append(", launches: "); sb.append(launches);
5215                        pw.println(sb.toString());
5216                        apkActivity = true;
5217                    }
5218                }
5219                if (!apkActivity) {
5220                    pw.print(prefix); pw.println("      (nothing executed)");
5221                }
5222                uidActivity = true;
5223            }
5224            if (!uidActivity) {
5225                pw.print(prefix); pw.println("    (nothing executed)");
5226            }
5227        }
5228    }
5229
5230    static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag,
5231            BitDescription[] descriptions, boolean longNames) {
5232        int diff = oldval ^ newval;
5233        if (diff == 0) return;
5234        boolean didWake = false;
5235        for (int i=0; i<descriptions.length; i++) {
5236            BitDescription bd = descriptions[i];
5237            if ((diff&bd.mask) != 0) {
5238                pw.print(longNames ? " " : ",");
5239                if (bd.shift < 0) {
5240                    pw.print((newval&bd.mask) != 0 ? "+" : "-");
5241                    pw.print(longNames ? bd.name : bd.shortName);
5242                    if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
5243                        didWake = true;
5244                        pw.print("=");
5245                        if (longNames) {
5246                            UserHandle.formatUid(pw, wakelockTag.uid);
5247                            pw.print(":\"");
5248                            pw.print(wakelockTag.string);
5249                            pw.print("\"");
5250                        } else {
5251                            pw.print(wakelockTag.poolIdx);
5252                        }
5253                    }
5254                } else {
5255                    pw.print(longNames ? bd.name : bd.shortName);
5256                    pw.print("=");
5257                    int val = (newval&bd.mask)>>bd.shift;
5258                    if (bd.values != null && val >= 0 && val < bd.values.length) {
5259                        pw.print(longNames? bd.values[val] : bd.shortValues[val]);
5260                    } else {
5261                        pw.print(val);
5262                    }
5263                }
5264            }
5265        }
5266        if (!didWake && wakelockTag != null) {
5267            pw.print(longNames ? " wake_lock=" : ",w=");
5268            if (longNames) {
5269                UserHandle.formatUid(pw, wakelockTag.uid);
5270                pw.print(":\"");
5271                pw.print(wakelockTag.string);
5272                pw.print("\"");
5273            } else {
5274                pw.print(wakelockTag.poolIdx);
5275            }
5276        }
5277    }
5278
5279    public void prepareForDumpLocked() {
5280    }
5281
5282    public static class HistoryPrinter {
5283        int oldState = 0;
5284        int oldState2 = 0;
5285        int oldLevel = -1;
5286        int oldStatus = -1;
5287        int oldHealth = -1;
5288        int oldPlug = -1;
5289        int oldTemp = -1;
5290        int oldVolt = -1;
5291        int oldChargeMAh = -1;
5292        long lastTime = -1;
5293
5294        void reset() {
5295            oldState = oldState2 = 0;
5296            oldLevel = -1;
5297            oldStatus = -1;
5298            oldHealth = -1;
5299            oldPlug = -1;
5300            oldTemp = -1;
5301            oldVolt = -1;
5302            oldChargeMAh = -1;
5303        }
5304
5305        public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
5306                boolean verbose) {
5307            if (!checkin) {
5308                pw.print("  ");
5309                TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
5310                pw.print(" (");
5311                pw.print(rec.numReadInts);
5312                pw.print(") ");
5313            } else {
5314                pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
5315                pw.print(HISTORY_DATA); pw.print(',');
5316                if (lastTime < 0) {
5317                    pw.print(rec.time - baseTime);
5318                } else {
5319                    pw.print(rec.time - lastTime);
5320                }
5321                lastTime = rec.time;
5322            }
5323            if (rec.cmd == HistoryItem.CMD_START) {
5324                if (checkin) {
5325                    pw.print(":");
5326                }
5327                pw.println("START");
5328                reset();
5329            } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
5330                    || rec.cmd == HistoryItem.CMD_RESET) {
5331                if (checkin) {
5332                    pw.print(":");
5333                }
5334                if (rec.cmd == HistoryItem.CMD_RESET) {
5335                    pw.print("RESET:");
5336                    reset();
5337                }
5338                pw.print("TIME:");
5339                if (checkin) {
5340                    pw.println(rec.currentTime);
5341                } else {
5342                    pw.print(" ");
5343                    pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
5344                            rec.currentTime).toString());
5345                }
5346            } else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) {
5347                if (checkin) {
5348                    pw.print(":");
5349                }
5350                pw.println("SHUTDOWN");
5351            } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
5352                if (checkin) {
5353                    pw.print(":");
5354                }
5355                pw.println("*OVERFLOW*");
5356            } else {
5357                if (!checkin) {
5358                    if (rec.batteryLevel < 10) pw.print("00");
5359                    else if (rec.batteryLevel < 100) pw.print("0");
5360                    pw.print(rec.batteryLevel);
5361                    if (verbose) {
5362                        pw.print(" ");
5363                        if (rec.states < 0) ;
5364                        else if (rec.states < 0x10) pw.print("0000000");
5365                        else if (rec.states < 0x100) pw.print("000000");
5366                        else if (rec.states < 0x1000) pw.print("00000");
5367                        else if (rec.states < 0x10000) pw.print("0000");
5368                        else if (rec.states < 0x100000) pw.print("000");
5369                        else if (rec.states < 0x1000000) pw.print("00");
5370                        else if (rec.states < 0x10000000) pw.print("0");
5371                        pw.print(Integer.toHexString(rec.states));
5372                    }
5373                } else {
5374                    if (oldLevel != rec.batteryLevel) {
5375                        oldLevel = rec.batteryLevel;
5376                        pw.print(",Bl="); pw.print(rec.batteryLevel);
5377                    }
5378                }
5379                if (oldStatus != rec.batteryStatus) {
5380                    oldStatus = rec.batteryStatus;
5381                    pw.print(checkin ? ",Bs=" : " status=");
5382                    switch (oldStatus) {
5383                        case BatteryManager.BATTERY_STATUS_UNKNOWN:
5384                            pw.print(checkin ? "?" : "unknown");
5385                            break;
5386                        case BatteryManager.BATTERY_STATUS_CHARGING:
5387                            pw.print(checkin ? "c" : "charging");
5388                            break;
5389                        case BatteryManager.BATTERY_STATUS_DISCHARGING:
5390                            pw.print(checkin ? "d" : "discharging");
5391                            break;
5392                        case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
5393                            pw.print(checkin ? "n" : "not-charging");
5394                            break;
5395                        case BatteryManager.BATTERY_STATUS_FULL:
5396                            pw.print(checkin ? "f" : "full");
5397                            break;
5398                        default:
5399                            pw.print(oldStatus);
5400                            break;
5401                    }
5402                }
5403                if (oldHealth != rec.batteryHealth) {
5404                    oldHealth = rec.batteryHealth;
5405                    pw.print(checkin ? ",Bh=" : " health=");
5406                    switch (oldHealth) {
5407                        case BatteryManager.BATTERY_HEALTH_UNKNOWN:
5408                            pw.print(checkin ? "?" : "unknown");
5409                            break;
5410                        case BatteryManager.BATTERY_HEALTH_GOOD:
5411                            pw.print(checkin ? "g" : "good");
5412                            break;
5413                        case BatteryManager.BATTERY_HEALTH_OVERHEAT:
5414                            pw.print(checkin ? "h" : "overheat");
5415                            break;
5416                        case BatteryManager.BATTERY_HEALTH_DEAD:
5417                            pw.print(checkin ? "d" : "dead");
5418                            break;
5419                        case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
5420                            pw.print(checkin ? "v" : "over-voltage");
5421                            break;
5422                        case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
5423                            pw.print(checkin ? "f" : "failure");
5424                            break;
5425                        case BatteryManager.BATTERY_HEALTH_COLD:
5426                            pw.print(checkin ? "c" : "cold");
5427                            break;
5428                        default:
5429                            pw.print(oldHealth);
5430                            break;
5431                    }
5432                }
5433                if (oldPlug != rec.batteryPlugType) {
5434                    oldPlug = rec.batteryPlugType;
5435                    pw.print(checkin ? ",Bp=" : " plug=");
5436                    switch (oldPlug) {
5437                        case 0:
5438                            pw.print(checkin ? "n" : "none");
5439                            break;
5440                        case BatteryManager.BATTERY_PLUGGED_AC:
5441                            pw.print(checkin ? "a" : "ac");
5442                            break;
5443                        case BatteryManager.BATTERY_PLUGGED_USB:
5444                            pw.print(checkin ? "u" : "usb");
5445                            break;
5446                        case BatteryManager.BATTERY_PLUGGED_WIRELESS:
5447                            pw.print(checkin ? "w" : "wireless");
5448                            break;
5449                        default:
5450                            pw.print(oldPlug);
5451                            break;
5452                    }
5453                }
5454                if (oldTemp != rec.batteryTemperature) {
5455                    oldTemp = rec.batteryTemperature;
5456                    pw.print(checkin ? ",Bt=" : " temp=");
5457                    pw.print(oldTemp);
5458                }
5459                if (oldVolt != rec.batteryVoltage) {
5460                    oldVolt = rec.batteryVoltage;
5461                    pw.print(checkin ? ",Bv=" : " volt=");
5462                    pw.print(oldVolt);
5463                }
5464                final int chargeMAh = rec.batteryChargeUAh / 1000;
5465                if (oldChargeMAh != chargeMAh) {
5466                    oldChargeMAh = chargeMAh;
5467                    pw.print(checkin ? ",Bcc=" : " charge=");
5468                    pw.print(oldChargeMAh);
5469                }
5470                printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
5471                        HISTORY_STATE_DESCRIPTIONS, !checkin);
5472                printBitDescriptions(pw, oldState2, rec.states2, null,
5473                        HISTORY_STATE2_DESCRIPTIONS, !checkin);
5474                if (rec.wakeReasonTag != null) {
5475                    if (checkin) {
5476                        pw.print(",wr=");
5477                        pw.print(rec.wakeReasonTag.poolIdx);
5478                    } else {
5479                        pw.print(" wake_reason=");
5480                        pw.print(rec.wakeReasonTag.uid);
5481                        pw.print(":\"");
5482                        pw.print(rec.wakeReasonTag.string);
5483                        pw.print("\"");
5484                    }
5485                }
5486                if (rec.eventCode != HistoryItem.EVENT_NONE) {
5487                    pw.print(checkin ? "," : " ");
5488                    if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
5489                        pw.print("+");
5490                    } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
5491                        pw.print("-");
5492                    }
5493                    String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
5494                            : HISTORY_EVENT_NAMES;
5495                    int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
5496                            | HistoryItem.EVENT_FLAG_FINISH);
5497                    if (idx >= 0 && idx < eventNames.length) {
5498                        pw.print(eventNames[idx]);
5499                    } else {
5500                        pw.print(checkin ? "Ev" : "event");
5501                        pw.print(idx);
5502                    }
5503                    pw.print("=");
5504                    if (checkin) {
5505                        pw.print(rec.eventTag.poolIdx);
5506                    } else {
5507                        pw.append(HISTORY_EVENT_INT_FORMATTERS[idx]
5508                                .applyAsString(rec.eventTag.uid));
5509                        pw.print(":\"");
5510                        pw.print(rec.eventTag.string);
5511                        pw.print("\"");
5512                    }
5513                }
5514                pw.println();
5515                if (rec.stepDetails != null) {
5516                    if (!checkin) {
5517                        pw.print("                 Details: cpu=");
5518                        pw.print(rec.stepDetails.userTime);
5519                        pw.print("u+");
5520                        pw.print(rec.stepDetails.systemTime);
5521                        pw.print("s");
5522                        if (rec.stepDetails.appCpuUid1 >= 0) {
5523                            pw.print(" (");
5524                            printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid1,
5525                                    rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
5526                            if (rec.stepDetails.appCpuUid2 >= 0) {
5527                                pw.print(", ");
5528                                printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid2,
5529                                        rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
5530                            }
5531                            if (rec.stepDetails.appCpuUid3 >= 0) {
5532                                pw.print(", ");
5533                                printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid3,
5534                                        rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
5535                            }
5536                            pw.print(')');
5537                        }
5538                        pw.println();
5539                        pw.print("                          /proc/stat=");
5540                        pw.print(rec.stepDetails.statUserTime);
5541                        pw.print(" usr, ");
5542                        pw.print(rec.stepDetails.statSystemTime);
5543                        pw.print(" sys, ");
5544                        pw.print(rec.stepDetails.statIOWaitTime);
5545                        pw.print(" io, ");
5546                        pw.print(rec.stepDetails.statIrqTime);
5547                        pw.print(" irq, ");
5548                        pw.print(rec.stepDetails.statSoftIrqTime);
5549                        pw.print(" sirq, ");
5550                        pw.print(rec.stepDetails.statIdlTime);
5551                        pw.print(" idle");
5552                        int totalRun = rec.stepDetails.statUserTime + rec.stepDetails.statSystemTime
5553                                + rec.stepDetails.statIOWaitTime + rec.stepDetails.statIrqTime
5554                                + rec.stepDetails.statSoftIrqTime;
5555                        int total = totalRun + rec.stepDetails.statIdlTime;
5556                        if (total > 0) {
5557                            pw.print(" (");
5558                            float perc = ((float)totalRun) / ((float)total) * 100;
5559                            pw.print(String.format("%.1f%%", perc));
5560                            pw.print(" of ");
5561                            StringBuilder sb = new StringBuilder(64);
5562                            formatTimeMsNoSpace(sb, total*10);
5563                            pw.print(sb);
5564                            pw.print(")");
5565                        }
5566                        pw.print(", PlatformIdleStat ");
5567                        pw.print(rec.stepDetails.statPlatformIdleState);
5568                        pw.println();
5569                    } else {
5570                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
5571                        pw.print(HISTORY_DATA); pw.print(",0,Dcpu=");
5572                        pw.print(rec.stepDetails.userTime);
5573                        pw.print(":");
5574                        pw.print(rec.stepDetails.systemTime);
5575                        if (rec.stepDetails.appCpuUid1 >= 0) {
5576                            printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid1,
5577                                    rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
5578                            if (rec.stepDetails.appCpuUid2 >= 0) {
5579                                printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid2,
5580                                        rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
5581                            }
5582                            if (rec.stepDetails.appCpuUid3 >= 0) {
5583                                printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid3,
5584                                        rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
5585                            }
5586                        }
5587                        pw.println();
5588                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
5589                        pw.print(HISTORY_DATA); pw.print(",0,Dpst=");
5590                        pw.print(rec.stepDetails.statUserTime);
5591                        pw.print(',');
5592                        pw.print(rec.stepDetails.statSystemTime);
5593                        pw.print(',');
5594                        pw.print(rec.stepDetails.statIOWaitTime);
5595                        pw.print(',');
5596                        pw.print(rec.stepDetails.statIrqTime);
5597                        pw.print(',');
5598                        pw.print(rec.stepDetails.statSoftIrqTime);
5599                        pw.print(',');
5600                        pw.print(rec.stepDetails.statIdlTime);
5601                        pw.print(',');
5602                        if (rec.stepDetails.statPlatformIdleState != null) {
5603                            pw.print(rec.stepDetails.statPlatformIdleState);
5604                        }
5605                        pw.println();
5606                    }
5607                }
5608                oldState = rec.states;
5609                oldState2 = rec.states2;
5610            }
5611        }
5612
5613        private void printStepCpuUidDetails(PrintWriter pw, int uid, int utime, int stime) {
5614            UserHandle.formatUid(pw, uid);
5615            pw.print("=");
5616            pw.print(utime);
5617            pw.print("u+");
5618            pw.print(stime);
5619            pw.print("s");
5620        }
5621
5622        private void printStepCpuUidCheckinDetails(PrintWriter pw, int uid, int utime, int stime) {
5623            pw.print('/');
5624            pw.print(uid);
5625            pw.print(":");
5626            pw.print(utime);
5627            pw.print(":");
5628            pw.print(stime);
5629        }
5630    }
5631
5632    private void printSizeValue(PrintWriter pw, long size) {
5633        float result = size;
5634        String suffix = "";
5635        if (result >= 10*1024) {
5636            suffix = "KB";
5637            result = result / 1024;
5638        }
5639        if (result >= 10*1024) {
5640            suffix = "MB";
5641            result = result / 1024;
5642        }
5643        if (result >= 10*1024) {
5644            suffix = "GB";
5645            result = result / 1024;
5646        }
5647        if (result >= 10*1024) {
5648            suffix = "TB";
5649            result = result / 1024;
5650        }
5651        if (result >= 10*1024) {
5652            suffix = "PB";
5653            result = result / 1024;
5654        }
5655        pw.print((int)result);
5656        pw.print(suffix);
5657    }
5658
5659    private static boolean dumpTimeEstimate(PrintWriter pw, String label1, String label2,
5660            String label3, long estimatedTime) {
5661        if (estimatedTime < 0) {
5662            return false;
5663        }
5664        pw.print(label1);
5665        pw.print(label2);
5666        pw.print(label3);
5667        StringBuilder sb = new StringBuilder(64);
5668        formatTimeMs(sb, estimatedTime);
5669        pw.print(sb);
5670        pw.println();
5671        return true;
5672    }
5673
5674    private static boolean dumpDurationSteps(PrintWriter pw, String prefix, String header,
5675            LevelStepTracker steps, boolean checkin) {
5676        if (steps == null) {
5677            return false;
5678        }
5679        int count = steps.mNumStepDurations;
5680        if (count <= 0) {
5681            return false;
5682        }
5683        if (!checkin) {
5684            pw.println(header);
5685        }
5686        String[] lineArgs = new String[5];
5687        for (int i=0; i<count; i++) {
5688            long duration = steps.getDurationAt(i);
5689            int level = steps.getLevelAt(i);
5690            long initMode = steps.getInitModeAt(i);
5691            long modMode = steps.getModModeAt(i);
5692            if (checkin) {
5693                lineArgs[0] = Long.toString(duration);
5694                lineArgs[1] = Integer.toString(level);
5695                if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
5696                    switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
5697                        case Display.STATE_OFF: lineArgs[2] = "s-"; break;
5698                        case Display.STATE_ON: lineArgs[2] = "s+"; break;
5699                        case Display.STATE_DOZE: lineArgs[2] = "sd"; break;
5700                        case Display.STATE_DOZE_SUSPEND: lineArgs[2] = "sds"; break;
5701                        default: lineArgs[2] = "?"; break;
5702                    }
5703                } else {
5704                    lineArgs[2] = "";
5705                }
5706                if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
5707                    lineArgs[3] = (initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 ? "p+" : "p-";
5708                } else {
5709                    lineArgs[3] = "";
5710                }
5711                if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
5712                    lineArgs[4] = (initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0 ? "i+" : "i-";
5713                } else {
5714                    lineArgs[4] = "";
5715                }
5716                dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs);
5717            } else {
5718                pw.print(prefix);
5719                pw.print("#"); pw.print(i); pw.print(": ");
5720                TimeUtils.formatDuration(duration, pw);
5721                pw.print(" to "); pw.print(level);
5722                boolean haveModes = false;
5723                if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
5724                    pw.print(" (");
5725                    switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
5726                        case Display.STATE_OFF: pw.print("screen-off"); break;
5727                        case Display.STATE_ON: pw.print("screen-on"); break;
5728                        case Display.STATE_DOZE: pw.print("screen-doze"); break;
5729                        case Display.STATE_DOZE_SUSPEND: pw.print("screen-doze-suspend"); break;
5730                        default: pw.print("screen-?"); break;
5731                    }
5732                    haveModes = true;
5733                }
5734                if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
5735                    pw.print(haveModes ? ", " : " (");
5736                    pw.print((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0
5737                            ? "power-save-on" : "power-save-off");
5738                    haveModes = true;
5739                }
5740                if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
5741                    pw.print(haveModes ? ", " : " (");
5742                    pw.print((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0
5743                            ? "device-idle-on" : "device-idle-off");
5744                    haveModes = true;
5745                }
5746                if (haveModes) {
5747                    pw.print(")");
5748                }
5749                pw.println();
5750            }
5751        }
5752        return true;
5753    }
5754
5755    public static final int DUMP_CHARGED_ONLY = 1<<1;
5756    public static final int DUMP_DAILY_ONLY = 1<<2;
5757    public static final int DUMP_HISTORY_ONLY = 1<<3;
5758    public static final int DUMP_INCLUDE_HISTORY = 1<<4;
5759    public static final int DUMP_VERBOSE = 1<<5;
5760    public static final int DUMP_DEVICE_WIFI_ONLY = 1<<6;
5761
5762    private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
5763        final HistoryPrinter hprinter = new HistoryPrinter();
5764        final HistoryItem rec = new HistoryItem();
5765        long lastTime = -1;
5766        long baseTime = -1;
5767        boolean printed = false;
5768        HistoryEventTracker tracker = null;
5769        while (getNextHistoryLocked(rec)) {
5770            lastTime = rec.time;
5771            if (baseTime < 0) {
5772                baseTime = lastTime;
5773            }
5774            if (rec.time >= histStart) {
5775                if (histStart >= 0 && !printed) {
5776                    if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
5777                            || rec.cmd == HistoryItem.CMD_RESET
5778                            || rec.cmd == HistoryItem.CMD_START
5779                            || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
5780                        printed = true;
5781                        hprinter.printNextItem(pw, rec, baseTime, checkin,
5782                                (flags&DUMP_VERBOSE) != 0);
5783                        rec.cmd = HistoryItem.CMD_UPDATE;
5784                    } else if (rec.currentTime != 0) {
5785                        printed = true;
5786                        byte cmd = rec.cmd;
5787                        rec.cmd = HistoryItem.CMD_CURRENT_TIME;
5788                        hprinter.printNextItem(pw, rec, baseTime, checkin,
5789                                (flags&DUMP_VERBOSE) != 0);
5790                        rec.cmd = cmd;
5791                    }
5792                    if (tracker != null) {
5793                        if (rec.cmd != HistoryItem.CMD_UPDATE) {
5794                            hprinter.printNextItem(pw, rec, baseTime, checkin,
5795                                    (flags&DUMP_VERBOSE) != 0);
5796                            rec.cmd = HistoryItem.CMD_UPDATE;
5797                        }
5798                        int oldEventCode = rec.eventCode;
5799                        HistoryTag oldEventTag = rec.eventTag;
5800                        rec.eventTag = new HistoryTag();
5801                        for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
5802                            HashMap<String, SparseIntArray> active
5803                                    = tracker.getStateForEvent(i);
5804                            if (active == null) {
5805                                continue;
5806                            }
5807                            for (HashMap.Entry<String, SparseIntArray> ent
5808                                    : active.entrySet()) {
5809                                SparseIntArray uids = ent.getValue();
5810                                for (int j=0; j<uids.size(); j++) {
5811                                    rec.eventCode = i;
5812                                    rec.eventTag.string = ent.getKey();
5813                                    rec.eventTag.uid = uids.keyAt(j);
5814                                    rec.eventTag.poolIdx = uids.valueAt(j);
5815                                    hprinter.printNextItem(pw, rec, baseTime, checkin,
5816                                            (flags&DUMP_VERBOSE) != 0);
5817                                    rec.wakeReasonTag = null;
5818                                    rec.wakelockTag = null;
5819                                }
5820                            }
5821                        }
5822                        rec.eventCode = oldEventCode;
5823                        rec.eventTag = oldEventTag;
5824                        tracker = null;
5825                    }
5826                }
5827                hprinter.printNextItem(pw, rec, baseTime, checkin,
5828                        (flags&DUMP_VERBOSE) != 0);
5829            } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) {
5830                // This is an attempt to aggregate the previous state and generate
5831                // fake events to reflect that state at the point where we start
5832                // printing real events.  It doesn't really work right, so is turned off.
5833                if (tracker == null) {
5834                    tracker = new HistoryEventTracker();
5835                }
5836                tracker.updateState(rec.eventCode, rec.eventTag.string,
5837                        rec.eventTag.uid, rec.eventTag.poolIdx);
5838            }
5839        }
5840        if (histStart >= 0) {
5841            commitCurrentHistoryBatchLocked();
5842            pw.print(checkin ? "NEXT: " : "  NEXT: "); pw.println(lastTime+1);
5843        }
5844    }
5845
5846    private void dumpDailyLevelStepSummary(PrintWriter pw, String prefix, String label,
5847            LevelStepTracker steps, StringBuilder tmpSb, int[] tmpOutInt) {
5848        if (steps == null) {
5849            return;
5850        }
5851        long timeRemaining = steps.computeTimeEstimate(0, 0, tmpOutInt);
5852        if (timeRemaining >= 0) {
5853            pw.print(prefix); pw.print(label); pw.print(" total time: ");
5854            tmpSb.setLength(0);
5855            formatTimeMs(tmpSb, timeRemaining);
5856            pw.print(tmpSb);
5857            pw.print(" (from "); pw.print(tmpOutInt[0]);
5858            pw.println(" steps)");
5859        }
5860        for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
5861            long estimatedTime = steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
5862                    STEP_LEVEL_MODE_VALUES[i], tmpOutInt);
5863            if (estimatedTime > 0) {
5864                pw.print(prefix); pw.print(label); pw.print(" ");
5865                pw.print(STEP_LEVEL_MODE_LABELS[i]);
5866                pw.print(" time: ");
5867                tmpSb.setLength(0);
5868                formatTimeMs(tmpSb, estimatedTime);
5869                pw.print(tmpSb);
5870                pw.print(" (from "); pw.print(tmpOutInt[0]);
5871                pw.println(" steps)");
5872            }
5873        }
5874    }
5875
5876    private void dumpDailyPackageChanges(PrintWriter pw, String prefix,
5877            ArrayList<PackageChange> changes) {
5878        if (changes == null) {
5879            return;
5880        }
5881        pw.print(prefix); pw.println("Package changes:");
5882        for (int i=0; i<changes.size(); i++) {
5883            PackageChange pc = changes.get(i);
5884            if (pc.mUpdate) {
5885                pw.print(prefix); pw.print("  Update "); pw.print(pc.mPackageName);
5886                pw.print(" vers="); pw.println(pc.mVersionCode);
5887            } else {
5888                pw.print(prefix); pw.print("  Uninstall "); pw.println(pc.mPackageName);
5889            }
5890        }
5891    }
5892
5893    /**
5894     * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
5895     *
5896     * @param pw a Printer to receive the dump output.
5897     */
5898    @SuppressWarnings("unused")
5899    public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
5900        prepareForDumpLocked();
5901
5902        final boolean filtering = (flags
5903                & (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
5904
5905        if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
5906            final long historyTotalSize = getHistoryTotalSize();
5907            final long historyUsedSize = getHistoryUsedSize();
5908            if (startIteratingHistoryLocked()) {
5909                try {
5910                    pw.print("Battery History (");
5911                    pw.print((100*historyUsedSize)/historyTotalSize);
5912                    pw.print("% used, ");
5913                    printSizeValue(pw, historyUsedSize);
5914                    pw.print(" used of ");
5915                    printSizeValue(pw, historyTotalSize);
5916                    pw.print(", ");
5917                    pw.print(getHistoryStringPoolSize());
5918                    pw.print(" strings using ");
5919                    printSizeValue(pw, getHistoryStringPoolBytes());
5920                    pw.println("):");
5921                    dumpHistoryLocked(pw, flags, histStart, false);
5922                    pw.println();
5923                } finally {
5924                    finishIteratingHistoryLocked();
5925                }
5926            }
5927
5928            if (startIteratingOldHistoryLocked()) {
5929                try {
5930                    final HistoryItem rec = new HistoryItem();
5931                    pw.println("Old battery History:");
5932                    HistoryPrinter hprinter = new HistoryPrinter();
5933                    long baseTime = -1;
5934                    while (getNextOldHistoryLocked(rec)) {
5935                        if (baseTime < 0) {
5936                            baseTime = rec.time;
5937                        }
5938                        hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0);
5939                    }
5940                    pw.println();
5941                } finally {
5942                    finishIteratingOldHistoryLocked();
5943                }
5944            }
5945        }
5946
5947        if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
5948            return;
5949        }
5950
5951        if (!filtering) {
5952            SparseArray<? extends Uid> uidStats = getUidStats();
5953            final int NU = uidStats.size();
5954            boolean didPid = false;
5955            long nowRealtime = SystemClock.elapsedRealtime();
5956            for (int i=0; i<NU; i++) {
5957                Uid uid = uidStats.valueAt(i);
5958                SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
5959                if (pids != null) {
5960                    for (int j=0; j<pids.size(); j++) {
5961                        Uid.Pid pid = pids.valueAt(j);
5962                        if (!didPid) {
5963                            pw.println("Per-PID Stats:");
5964                            didPid = true;
5965                        }
5966                        long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
5967                                ? (nowRealtime - pid.mWakeStartMs) : 0);
5968                        pw.print("  PID "); pw.print(pids.keyAt(j));
5969                                pw.print(" wake time: ");
5970                                TimeUtils.formatDuration(time, pw);
5971                                pw.println("");
5972                    }
5973                }
5974            }
5975            if (didPid) {
5976                pw.println();
5977            }
5978        }
5979
5980        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
5981            if (dumpDurationSteps(pw, "  ", "Discharge step durations:",
5982                    getDischargeLevelStepTracker(), false)) {
5983                long timeRemaining = computeBatteryTimeRemaining(
5984                    SystemClock.elapsedRealtime() * 1000);
5985                if (timeRemaining >= 0) {
5986                    pw.print("  Estimated discharge time remaining: ");
5987                    TimeUtils.formatDuration(timeRemaining / 1000, pw);
5988                    pw.println();
5989                }
5990                final LevelStepTracker steps = getDischargeLevelStepTracker();
5991                for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
5992                    dumpTimeEstimate(pw, "  Estimated ", STEP_LEVEL_MODE_LABELS[i], " time: ",
5993                            steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
5994                                    STEP_LEVEL_MODE_VALUES[i], null));
5995                }
5996                pw.println();
5997            }
5998            if (dumpDurationSteps(pw, "  ", "Charge step durations:",
5999                    getChargeLevelStepTracker(), false)) {
6000                long timeRemaining = computeChargeTimeRemaining(
6001                    SystemClock.elapsedRealtime() * 1000);
6002                if (timeRemaining >= 0) {
6003                    pw.print("  Estimated charge time remaining: ");
6004                    TimeUtils.formatDuration(timeRemaining / 1000, pw);
6005                    pw.println();
6006                }
6007                pw.println();
6008            }
6009        }
6010        if (!filtering || (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0) {
6011            pw.println("Daily stats:");
6012            pw.print("  Current start time: ");
6013            pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6014                    getCurrentDailyStartTime()).toString());
6015            pw.print("  Next min deadline: ");
6016            pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6017                    getNextMinDailyDeadline()).toString());
6018            pw.print("  Next max deadline: ");
6019            pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6020                    getNextMaxDailyDeadline()).toString());
6021            StringBuilder sb = new StringBuilder(64);
6022            int[] outInt = new int[1];
6023            LevelStepTracker dsteps = getDailyDischargeLevelStepTracker();
6024            LevelStepTracker csteps = getDailyChargeLevelStepTracker();
6025            ArrayList<PackageChange> pkgc = getDailyPackageChanges();
6026            if (dsteps.mNumStepDurations > 0 || csteps.mNumStepDurations > 0 || pkgc != null) {
6027                if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
6028                    if (dumpDurationSteps(pw, "    ", "  Current daily discharge step durations:",
6029                            dsteps, false)) {
6030                        dumpDailyLevelStepSummary(pw, "      ", "Discharge", dsteps,
6031                                sb, outInt);
6032                    }
6033                    if (dumpDurationSteps(pw, "    ", "  Current daily charge step durations:",
6034                            csteps, false)) {
6035                        dumpDailyLevelStepSummary(pw, "      ", "Charge", csteps,
6036                                sb, outInt);
6037                    }
6038                    dumpDailyPackageChanges(pw, "    ", pkgc);
6039                } else {
6040                    pw.println("  Current daily steps:");
6041                    dumpDailyLevelStepSummary(pw, "    ", "Discharge", dsteps,
6042                            sb, outInt);
6043                    dumpDailyLevelStepSummary(pw, "    ", "Charge", csteps,
6044                            sb, outInt);
6045                }
6046            }
6047            DailyItem dit;
6048            int curIndex = 0;
6049            while ((dit=getDailyItemLocked(curIndex)) != null) {
6050                curIndex++;
6051                if ((flags&DUMP_DAILY_ONLY) != 0) {
6052                    pw.println();
6053                }
6054                pw.print("  Daily from ");
6055                pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mStartTime).toString());
6056                pw.print(" to ");
6057                pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mEndTime).toString());
6058                pw.println(":");
6059                if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
6060                    if (dumpDurationSteps(pw, "      ",
6061                            "    Discharge step durations:", dit.mDischargeSteps, false)) {
6062                        dumpDailyLevelStepSummary(pw, "        ", "Discharge", dit.mDischargeSteps,
6063                                sb, outInt);
6064                    }
6065                    if (dumpDurationSteps(pw, "      ",
6066                            "    Charge step durations:", dit.mChargeSteps, false)) {
6067                        dumpDailyLevelStepSummary(pw, "        ", "Charge", dit.mChargeSteps,
6068                                sb, outInt);
6069                    }
6070                    dumpDailyPackageChanges(pw, "    ", dit.mPackageChanges);
6071                } else {
6072                    dumpDailyLevelStepSummary(pw, "    ", "Discharge", dit.mDischargeSteps,
6073                            sb, outInt);
6074                    dumpDailyLevelStepSummary(pw, "    ", "Charge", dit.mChargeSteps,
6075                            sb, outInt);
6076                }
6077            }
6078            pw.println();
6079        }
6080        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
6081            pw.println("Statistics since last charge:");
6082            pw.println("  System starts: " + getStartCount()
6083                    + ", currently on battery: " + getIsOnBattery());
6084            dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
6085                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
6086            pw.println();
6087        }
6088    }
6089
6090    @SuppressWarnings("unused")
6091    public void dumpCheckinLocked(Context context, PrintWriter pw,
6092            List<ApplicationInfo> apps, int flags, long histStart) {
6093        prepareForDumpLocked();
6094
6095        dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
6096                CHECKIN_VERSION, getParcelVersion(), getStartPlatformVersion(),
6097                getEndPlatformVersion());
6098
6099        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
6100
6101        final boolean filtering = (flags &
6102                (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
6103
6104        if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) {
6105            if (startIteratingHistoryLocked()) {
6106                try {
6107                    for (int i=0; i<getHistoryStringPoolSize(); i++) {
6108                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
6109                        pw.print(HISTORY_STRING_POOL); pw.print(',');
6110                        pw.print(i);
6111                        pw.print(",");
6112                        pw.print(getHistoryTagPoolUid(i));
6113                        pw.print(",\"");
6114                        String str = getHistoryTagPoolString(i);
6115                        str = str.replace("\\", "\\\\");
6116                        str = str.replace("\"", "\\\"");
6117                        pw.print(str);
6118                        pw.print("\"");
6119                        pw.println();
6120                    }
6121                    dumpHistoryLocked(pw, flags, histStart, true);
6122                } finally {
6123                    finishIteratingHistoryLocked();
6124                }
6125            }
6126        }
6127
6128        if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
6129            return;
6130        }
6131
6132        if (apps != null) {
6133            SparseArray<Pair<ArrayList<String>, MutableBoolean>> uids = new SparseArray<>();
6134            for (int i=0; i<apps.size(); i++) {
6135                ApplicationInfo ai = apps.get(i);
6136                Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(
6137                        UserHandle.getAppId(ai.uid));
6138                if (pkgs == null) {
6139                    pkgs = new Pair<>(new ArrayList<String>(), new MutableBoolean(false));
6140                    uids.put(UserHandle.getAppId(ai.uid), pkgs);
6141                }
6142                pkgs.first.add(ai.packageName);
6143            }
6144            SparseArray<? extends Uid> uidStats = getUidStats();
6145            final int NU = uidStats.size();
6146            String[] lineArgs = new String[2];
6147            for (int i=0; i<NU; i++) {
6148                int uid = UserHandle.getAppId(uidStats.keyAt(i));
6149                Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(uid);
6150                if (pkgs != null && !pkgs.second.value) {
6151                    pkgs.second.value = true;
6152                    for (int j=0; j<pkgs.first.size(); j++) {
6153                        lineArgs[0] = Integer.toString(uid);
6154                        lineArgs[1] = pkgs.first.get(j);
6155                        dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
6156                                (Object[])lineArgs);
6157                    }
6158                }
6159            }
6160        }
6161        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
6162            dumpDurationSteps(pw, "", DISCHARGE_STEP_DATA, getDischargeLevelStepTracker(), true);
6163            String[] lineArgs = new String[1];
6164            long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime() * 1000);
6165            if (timeRemaining >= 0) {
6166                lineArgs[0] = Long.toString(timeRemaining);
6167                dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA,
6168                        (Object[])lineArgs);
6169            }
6170            dumpDurationSteps(pw, "", CHARGE_STEP_DATA, getChargeLevelStepTracker(), true);
6171            timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime() * 1000);
6172            if (timeRemaining >= 0) {
6173                lineArgs[0] = Long.toString(timeRemaining);
6174                dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA,
6175                        (Object[])lineArgs);
6176            }
6177            dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
6178                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
6179        }
6180    }
6181}
6182