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