BatteryStats.java revision 29cd7f19625a2a2a8528469e55f3aa495107b9e7
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.Printer;
33import android.util.SparseArray;
34import android.util.SparseIntArray;
35import android.util.TimeUtils;
36import android.view.Display;
37import com.android.internal.os.BatterySipper;
38import com.android.internal.os.BatteryStatsHelper;
39
40/**
41 * A class providing access to battery usage statistics, including information on
42 * wakelocks, processes, packages, and services.  All times are represented in microseconds
43 * except where indicated otherwise.
44 * @hide
45 */
46public abstract class BatteryStats implements Parcelable {
47
48    private static final boolean LOCAL_LOGV = false;
49
50    /** @hide */
51    public static final String SERVICE_NAME = "batterystats";
52
53    /**
54     * A constant indicating a partial wake lock timer.
55     */
56    public static final int WAKE_TYPE_PARTIAL = 0;
57
58    /**
59     * A constant indicating a full wake lock timer.
60     */
61    public static final int WAKE_TYPE_FULL = 1;
62
63    /**
64     * A constant indicating a window wake lock timer.
65     */
66    public static final int WAKE_TYPE_WINDOW = 2;
67
68    /**
69     * A constant indicating a sensor timer.
70     */
71    public static final int SENSOR = 3;
72
73    /**
74     * A constant indicating a a wifi running timer
75     */
76    public static final int WIFI_RUNNING = 4;
77
78    /**
79     * A constant indicating a full wifi lock timer
80     */
81    public static final int FULL_WIFI_LOCK = 5;
82
83    /**
84     * A constant indicating a wifi scan
85     */
86    public static final int WIFI_SCAN = 6;
87
88     /**
89      * A constant indicating a wifi multicast timer
90      */
91     public static final int WIFI_MULTICAST_ENABLED = 7;
92
93    /**
94     * A constant indicating a video turn on timer
95     */
96    public static final int VIDEO_TURNED_ON = 8;
97
98    /**
99     * A constant indicating a vibrator on timer
100     */
101    public static final int VIBRATOR_ON = 9;
102
103    /**
104     * A constant indicating a foreground activity timer
105     */
106    public static final int FOREGROUND_ACTIVITY = 10;
107
108    /**
109     * A constant indicating a wifi batched scan is active
110     */
111    public static final int WIFI_BATCHED_SCAN = 11;
112
113    /**
114     * A constant indicating a process state timer
115     */
116    public static final int PROCESS_STATE = 12;
117
118    /**
119     * A constant indicating a sync timer
120     */
121    public static final int SYNC = 13;
122
123    /**
124     * A constant indicating a job timer
125     */
126    public static final int JOB = 14;
127
128    /**
129     * A constant indicating an audio turn on timer
130     */
131    public static final int AUDIO_TURNED_ON = 15;
132
133    /**
134     * Include all of the data in the stats, including previously saved data.
135     */
136    public static final int STATS_SINCE_CHARGED = 0;
137
138    /**
139     * Include only the current run in the stats.
140     */
141    public static final int STATS_CURRENT = 1;
142
143    /**
144     * Include only the run since the last time the device was unplugged in the stats.
145     */
146    public static final int STATS_SINCE_UNPLUGGED = 2;
147
148    // NOTE: Update this list if you add/change any stats above.
149    // These characters are supposed to represent "total", "last", "current",
150    // and "unplugged". They were shortened for efficiency sake.
151    private static final String[] STAT_NAMES = { "l", "c", "u" };
152
153    /**
154     * Bump the version on this if the checkin format changes.
155     */
156    private static final int BATTERY_STATS_CHECKIN_VERSION = 9;
157
158    private static final long BYTES_PER_KB = 1024;
159    private static final long BYTES_PER_MB = 1048576; // 1024^2
160    private static final long BYTES_PER_GB = 1073741824; //1024^3
161
162    private static final String VERSION_DATA = "vers";
163    private static final String UID_DATA = "uid";
164    private static final String APK_DATA = "apk";
165    private static final String PROCESS_DATA = "pr";
166    private static final String SENSOR_DATA = "sr";
167    private static final String VIBRATOR_DATA = "vib";
168    private static final String FOREGROUND_DATA = "fg";
169    private static final String STATE_TIME_DATA = "st";
170    private static final String WAKELOCK_DATA = "wl";
171    private static final String SYNC_DATA = "sy";
172    private static final String JOB_DATA = "jb";
173    private static final String KERNEL_WAKELOCK_DATA = "kwl";
174    private static final String WAKEUP_REASON_DATA = "wr";
175    private static final String NETWORK_DATA = "nt";
176    private static final String USER_ACTIVITY_DATA = "ua";
177    private static final String BATTERY_DATA = "bt";
178    private static final String BATTERY_DISCHARGE_DATA = "dc";
179    private static final String BATTERY_LEVEL_DATA = "lv";
180    private static final String WIFI_DATA = "wfl";
181    private static final String MISC_DATA = "m";
182    private static final String GLOBAL_NETWORK_DATA = "gn";
183    private static final String HISTORY_STRING_POOL = "hsp";
184    private static final String HISTORY_DATA = "h";
185    private static final String SCREEN_BRIGHTNESS_DATA = "br";
186    private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
187    private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
188    private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
189    private static final String DATA_CONNECTION_TIME_DATA = "dct";
190    private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
191    private static final String WIFI_STATE_TIME_DATA = "wst";
192    private static final String WIFI_STATE_COUNT_DATA = "wsc";
193    private static final String WIFI_SUPPL_STATE_TIME_DATA = "wsst";
194    private static final String WIFI_SUPPL_STATE_COUNT_DATA = "wssc";
195    private static final String WIFI_SIGNAL_STRENGTH_TIME_DATA = "wsgt";
196    private static final String WIFI_SIGNAL_STRENGTH_COUNT_DATA = "wsgc";
197    private static final String BLUETOOTH_STATE_TIME_DATA = "bst";
198    private static final String BLUETOOTH_STATE_COUNT_DATA = "bsc";
199    private static final String POWER_USE_SUMMARY_DATA = "pws";
200    private static final String POWER_USE_ITEM_DATA = "pwi";
201    private static final String DISCHARGE_STEP_DATA = "dsd";
202    private static final String CHARGE_STEP_DATA = "csd";
203    private static final String DISCHARGE_TIME_REMAIN_DATA = "dtr";
204    private static final String CHARGE_TIME_REMAIN_DATA = "ctr";
205
206    private final StringBuilder mFormatBuilder = new StringBuilder(32);
207    private final Formatter mFormatter = new Formatter(mFormatBuilder);
208
209    /**
210     * State for keeping track of counting information.
211     */
212    public static abstract class Counter {
213
214        /**
215         * Returns the count associated with this Counter for the
216         * selected type of statistics.
217         *
218         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
219         */
220        public abstract int getCountLocked(int which);
221
222        /**
223         * Temporary for debugging.
224         */
225        public abstract void logState(Printer pw, String prefix);
226    }
227
228    /**
229     * State for keeping track of long counting information.
230     */
231    public static abstract class LongCounter {
232
233        /**
234         * Returns the count associated with this Counter for the
235         * selected type of statistics.
236         *
237         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
238         */
239        public abstract long getCountLocked(int which);
240
241        /**
242         * Temporary for debugging.
243         */
244        public abstract void logState(Printer pw, String prefix);
245    }
246
247    /**
248     * State for keeping track of timing information.
249     */
250    public static abstract class Timer {
251
252        /**
253         * Returns the count associated with this Timer for the
254         * selected type of statistics.
255         *
256         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
257         */
258        public abstract int getCountLocked(int which);
259
260        /**
261         * Returns the total time in microseconds associated with this Timer for the
262         * selected type of statistics.
263         *
264         * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
265         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
266         * @return a time in microseconds
267         */
268        public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which);
269
270        /**
271         * Temporary for debugging.
272         */
273        public abstract void logState(Printer pw, String prefix);
274    }
275
276    /**
277     * The statistics associated with a particular uid.
278     */
279    public static abstract class Uid {
280
281        /**
282         * Returns a mapping containing wakelock statistics.
283         *
284         * @return a Map from Strings to Uid.Wakelock objects.
285         */
286        public abstract Map<String, ? extends Wakelock> getWakelockStats();
287
288        /**
289         * Returns a mapping containing sync statistics.
290         *
291         * @return a Map from Strings to Timer objects.
292         */
293        public abstract Map<String, ? extends Timer> getSyncStats();
294
295        /**
296         * Returns a mapping containing scheduled job statistics.
297         *
298         * @return a Map from Strings to Timer objects.
299         */
300        public abstract Map<String, ? extends Timer> getJobStats();
301
302        /**
303         * The statistics associated with a particular wake lock.
304         */
305        public static abstract class Wakelock {
306            public abstract Timer getWakeTime(int type);
307        }
308
309        /**
310         * Returns a mapping containing sensor statistics.
311         *
312         * @return a Map from Integer sensor ids to Uid.Sensor objects.
313         */
314        public abstract SparseArray<? extends Sensor> getSensorStats();
315
316        /**
317         * Returns a mapping containing active process data.
318         */
319        public abstract SparseArray<? extends Pid> getPidStats();
320
321        /**
322         * Returns a mapping containing process statistics.
323         *
324         * @return a Map from Strings to Uid.Proc objects.
325         */
326        public abstract Map<String, ? extends Proc> getProcessStats();
327
328        /**
329         * Returns a mapping containing package statistics.
330         *
331         * @return a Map from Strings to Uid.Pkg objects.
332         */
333        public abstract Map<String, ? extends Pkg> getPackageStats();
334
335        /**
336         * {@hide}
337         */
338        public abstract int getUid();
339
340        public abstract void noteWifiRunningLocked(long elapsedRealtime);
341        public abstract void noteWifiStoppedLocked(long elapsedRealtime);
342        public abstract void noteFullWifiLockAcquiredLocked(long elapsedRealtime);
343        public abstract void noteFullWifiLockReleasedLocked(long elapsedRealtime);
344        public abstract void noteWifiScanStartedLocked(long elapsedRealtime);
345        public abstract void noteWifiScanStoppedLocked(long elapsedRealtime);
346        public abstract void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime);
347        public abstract void noteWifiBatchedScanStoppedLocked(long elapsedRealtime);
348        public abstract void noteWifiMulticastEnabledLocked(long elapsedRealtime);
349        public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime);
350        public abstract void noteActivityResumedLocked(long elapsedRealtime);
351        public abstract void noteActivityPausedLocked(long elapsedRealtime);
352        public abstract long getWifiRunningTime(long elapsedRealtimeUs, int which);
353        public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which);
354        public abstract long getWifiScanTime(long elapsedRealtimeUs, int which);
355        public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which);
356        public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which);
357        public abstract long getAudioTurnedOnTime(long elapsedRealtimeUs, int which);
358        public abstract long getVideoTurnedOnTime(long elapsedRealtimeUs, int which);
359        public abstract Timer getForegroundActivityTimer();
360
361        // Time this uid has any processes in foreground state.
362        public static final int PROCESS_STATE_FOREGROUND = 0;
363        // Time this uid has any process in active state (not cached).
364        public static final int PROCESS_STATE_ACTIVE = 1;
365        // Time this uid has any processes running at all.
366        public static final int PROCESS_STATE_RUNNING = 2;
367        // Total number of process states we track.
368        public static final int NUM_PROCESS_STATE = 3;
369
370        static final String[] PROCESS_STATE_NAMES = {
371            "Foreground", "Active", "Running"
372        };
373
374        public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which);
375
376        public abstract Timer getVibratorOnTimer();
377
378        public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5;
379
380        /**
381         * Note that these must match the constants in android.os.PowerManager.
382         * Also, if the user activity types change, the BatteryStatsImpl.VERSION must
383         * also be bumped.
384         */
385        static final String[] USER_ACTIVITY_TYPES = {
386            "other", "button", "touch"
387        };
388
389        public static final int NUM_USER_ACTIVITY_TYPES = 3;
390
391        public abstract void noteUserActivityLocked(int type);
392        public abstract boolean hasUserActivity();
393        public abstract int getUserActivityCount(int type, int which);
394
395        public abstract boolean hasNetworkActivity();
396        public abstract long getNetworkActivityBytes(int type, int which);
397        public abstract long getNetworkActivityPackets(int type, int which);
398        public abstract long getMobileRadioActiveTime(int which);
399        public abstract int getMobileRadioActiveCount(int which);
400
401        public static abstract class Sensor {
402            /*
403             * FIXME: it's not correct to use this magic value because it
404             * could clash with a sensor handle (which are defined by
405             * the sensor HAL, and therefore out of our control
406             */
407            // Magic sensor number for the GPS.
408            public static final int GPS = -10000;
409
410            public abstract int getHandle();
411
412            public abstract Timer getSensorTime();
413        }
414
415        public class Pid {
416            public int mWakeNesting;
417            public long mWakeSumMs;
418            public long mWakeStartMs;
419        }
420
421        /**
422         * The statistics associated with a particular process.
423         */
424        public static abstract class Proc {
425
426            public static class ExcessivePower {
427                public static final int TYPE_WAKE = 1;
428                public static final int TYPE_CPU = 2;
429
430                public int type;
431                public long overTime;
432                public long usedTime;
433            }
434
435            /**
436             * Returns true if this process is still active in the battery stats.
437             */
438            public abstract boolean isActive();
439
440            /**
441             * Returns the total time (in 1/100 sec) spent executing in user code.
442             *
443             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
444             */
445            public abstract long getUserTime(int which);
446
447            /**
448             * Returns the total time (in 1/100 sec) spent executing in system code.
449             *
450             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
451             */
452            public abstract long getSystemTime(int which);
453
454            /**
455             * Returns the number of times the process has been started.
456             *
457             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
458             */
459            public abstract int getStarts(int which);
460
461            /**
462             * Returns the number of times the process has crashed.
463             *
464             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
465             */
466            public abstract int getNumCrashes(int which);
467
468            /**
469             * Returns the number of times the process has ANRed.
470             *
471             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
472             */
473            public abstract int getNumAnrs(int which);
474
475            /**
476             * Returns the cpu time spent in microseconds while the process was in the foreground.
477             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
478             * @return foreground cpu time in microseconds
479             */
480            public abstract long getForegroundTime(int which);
481
482            /**
483             * Returns the approximate cpu time spent in microseconds, at a certain CPU speed.
484             * @param speedStep the index of the CPU speed. This is not the actual speed of the
485             * CPU.
486             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
487             * @see BatteryStats#getCpuSpeedSteps()
488             */
489            public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
490
491            public abstract int countExcessivePowers();
492
493            public abstract ExcessivePower getExcessivePower(int i);
494        }
495
496        /**
497         * The statistics associated with a particular package.
498         */
499        public static abstract class Pkg {
500
501            /**
502             * Returns the number of times this package has done something that could wake up the
503             * device from sleep.
504             *
505             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
506             */
507            public abstract int getWakeups(int which);
508
509            /**
510             * Returns a mapping containing service statistics.
511             */
512            public abstract Map<String, ? extends Serv> getServiceStats();
513
514            /**
515             * The statistics associated with a particular service.
516             */
517            public abstract class Serv {
518
519                /**
520                 * Returns the amount of time spent started.
521                 *
522                 * @param batteryUptime elapsed uptime on battery in microseconds.
523                 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
524                 * @return
525                 */
526                public abstract long getStartTime(long batteryUptime, int which);
527
528                /**
529                 * Returns the total number of times startService() has been called.
530                 *
531                 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
532                 */
533                public abstract int getStarts(int which);
534
535                /**
536                 * Returns the total number times the service has been launched.
537                 *
538                 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
539                 */
540                public abstract int getLaunches(int which);
541            }
542        }
543    }
544
545    public final static class HistoryTag {
546        public String string;
547        public int uid;
548
549        public int poolIdx;
550
551        public void setTo(HistoryTag o) {
552            string = o.string;
553            uid = o.uid;
554            poolIdx = o.poolIdx;
555        }
556
557        public void setTo(String _string, int _uid) {
558            string = _string;
559            uid = _uid;
560            poolIdx = -1;
561        }
562
563        public void writeToParcel(Parcel dest, int flags) {
564            dest.writeString(string);
565            dest.writeInt(uid);
566        }
567
568        public void readFromParcel(Parcel src) {
569            string = src.readString();
570            uid = src.readInt();
571            poolIdx = -1;
572        }
573
574        @Override
575        public boolean equals(Object o) {
576            if (this == o) return true;
577            if (o == null || getClass() != o.getClass()) return false;
578
579            HistoryTag that = (HistoryTag) o;
580
581            if (uid != that.uid) return false;
582            if (!string.equals(that.string)) return false;
583
584            return true;
585        }
586
587        @Override
588        public int hashCode() {
589            int result = string.hashCode();
590            result = 31 * result + uid;
591            return result;
592        }
593    }
594
595    public final static class HistoryItem implements Parcelable {
596        public HistoryItem next;
597
598        // The time of this event in milliseconds, as per SystemClock.elapsedRealtime().
599        public long time;
600
601        public static final byte CMD_UPDATE = 0;        // These can be written as deltas
602        public static final byte CMD_NULL = -1;
603        public static final byte CMD_START = 4;
604        public static final byte CMD_CURRENT_TIME = 5;
605        public static final byte CMD_OVERFLOW = 6;
606        public static final byte CMD_RESET = 7;
607        public static final byte CMD_SHUTDOWN = 8;
608
609        public byte cmd = CMD_NULL;
610
611        /**
612         * Return whether the command code is a delta data update.
613         */
614        public boolean isDeltaData() {
615            return cmd == CMD_UPDATE;
616        }
617
618        public byte batteryLevel;
619        public byte batteryStatus;
620        public byte batteryHealth;
621        public byte batteryPlugType;
622
623        public short batteryTemperature;
624        public char batteryVoltage;
625
626        // Constants from SCREEN_BRIGHTNESS_*
627        public static final int STATE_BRIGHTNESS_SHIFT = 0;
628        public static final int STATE_BRIGHTNESS_MASK = 0x7;
629        // Constants from SIGNAL_STRENGTH_*
630        public static final int STATE_PHONE_SIGNAL_STRENGTH_SHIFT = 3;
631        public static final int STATE_PHONE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_PHONE_SIGNAL_STRENGTH_SHIFT;
632        // Constants from ServiceState.STATE_*
633        public static final int STATE_PHONE_STATE_SHIFT = 6;
634        public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT;
635        // Constants from DATA_CONNECTION_*
636        public static final int STATE_DATA_CONNECTION_SHIFT = 9;
637        public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT;
638
639        // These states always appear directly in the first int token
640        // of a delta change; they should be ones that change relatively
641        // frequently.
642        public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
643        public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
644        public static final int STATE_GPS_ON_FLAG = 1<<29;
645        public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
646        public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
647        public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<26;
648        public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
649        // These are on the lower bits used for the command; if they change
650        // we need to write another int of data.
651        public static final int STATE_SENSOR_ON_FLAG = 1<<23;
652        public static final int STATE_AUDIO_ON_FLAG = 1<<22;
653        public static final int STATE_PHONE_SCANNING_FLAG = 1<<21;
654        public static final int STATE_SCREEN_ON_FLAG = 1<<20;
655        public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19;
656        public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18;
657        public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16;
658
659        public static final int MOST_INTERESTING_STATES =
660            STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG
661            | STATE_PHONE_IN_CALL_FLAG | STATE_BLUETOOTH_ON_FLAG;
662
663        public int states;
664
665        // Constants from WIFI_SUPPL_STATE_*
666        public static final int STATE2_WIFI_SUPPL_STATE_SHIFT = 0;
667        public static final int STATE2_WIFI_SUPPL_STATE_MASK = 0xf;
668        // Values for NUM_WIFI_SIGNAL_STRENGTH_BINS
669        public static final int STATE2_WIFI_SIGNAL_STRENGTH_SHIFT = 4;
670        public static final int STATE2_WIFI_SIGNAL_STRENGTH_MASK =
671                0x7 << STATE2_WIFI_SIGNAL_STRENGTH_SHIFT;
672
673        public static final int STATE2_LOW_POWER_FLAG = 1<<31;
674        public static final int STATE2_VIDEO_ON_FLAG = 1<<30;
675        public static final int STATE2_WIFI_RUNNING_FLAG = 1<<29;
676        public static final int STATE2_WIFI_ON_FLAG = 1<<28;
677        public static final int STATE2_FLASHLIGHT_FLAG = 1<<27;
678
679        public static final int MOST_INTERESTING_STATES2 =
680            STATE2_LOW_POWER_FLAG | STATE2_WIFI_ON_FLAG;
681
682        public int states2;
683
684        // The wake lock that was acquired at this point.
685        public HistoryTag wakelockTag;
686
687        // Kernel wakeup reason at this point.
688        public HistoryTag wakeReasonTag;
689
690        public static final int EVENT_FLAG_START = 0x8000;
691        public static final int EVENT_FLAG_FINISH = 0x4000;
692
693        // No event in this item.
694        public static final int EVENT_NONE = 0x0000;
695        // Event is about a process that is running.
696        public static final int EVENT_PROC = 0x0001;
697        // Event is about an application package that is in the foreground.
698        public static final int EVENT_FOREGROUND = 0x0002;
699        // Event is about an application package that is at the top of the screen.
700        public static final int EVENT_TOP = 0x0003;
701        // Event is about active sync operations.
702        public static final int EVENT_SYNC = 0x0004;
703        // Events for all additional wake locks aquired/release within a wake block.
704        // These are not generated by default.
705        public static final int EVENT_WAKE_LOCK = 0x0005;
706        // Event is about an application executing a scheduled job.
707        public static final int EVENT_JOB = 0x0006;
708        // Events for users running.
709        public static final int EVENT_USER_RUNNING = 0x0007;
710        // Events for foreground user.
711        public static final int EVENT_USER_FOREGROUND = 0x0008;
712        // Events for connectivity changed.
713        public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009;
714        // Number of event types.
715        public static final int EVENT_COUNT = 0x000a;
716        // Mask to extract out only the type part of the event.
717        public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
718
719        public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
720        public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
721        public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START;
722        public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
723        public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
724        public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
725        public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
726        public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
727        public static final int EVENT_WAKE_LOCK_START = EVENT_WAKE_LOCK | EVENT_FLAG_START;
728        public static final int EVENT_WAKE_LOCK_FINISH = EVENT_WAKE_LOCK | EVENT_FLAG_FINISH;
729        public static final int EVENT_JOB_START = EVENT_JOB | EVENT_FLAG_START;
730        public static final int EVENT_JOB_FINISH = EVENT_JOB | EVENT_FLAG_FINISH;
731        public static final int EVENT_USER_RUNNING_START = EVENT_USER_RUNNING | EVENT_FLAG_START;
732        public static final int EVENT_USER_RUNNING_FINISH = EVENT_USER_RUNNING | EVENT_FLAG_FINISH;
733        public static final int EVENT_USER_FOREGROUND_START =
734                EVENT_USER_FOREGROUND | EVENT_FLAG_START;
735        public static final int EVENT_USER_FOREGROUND_FINISH =
736                EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
737
738        // For CMD_EVENT.
739        public int eventCode;
740        public HistoryTag eventTag;
741
742        // Only set for CMD_CURRENT_TIME or CMD_RESET, as per System.currentTimeMillis().
743        public long currentTime;
744
745        // Meta-data when reading.
746        public int numReadInts;
747
748        // Pre-allocated objects.
749        public final HistoryTag localWakelockTag = new HistoryTag();
750        public final HistoryTag localWakeReasonTag = new HistoryTag();
751        public final HistoryTag localEventTag = new HistoryTag();
752
753        public HistoryItem() {
754        }
755
756        public HistoryItem(long time, Parcel src) {
757            this.time = time;
758            numReadInts = 2;
759            readFromParcel(src);
760        }
761
762        public int describeContents() {
763            return 0;
764        }
765
766        public void writeToParcel(Parcel dest, int flags) {
767            dest.writeLong(time);
768            int bat = (((int)cmd)&0xff)
769                    | ((((int)batteryLevel)<<8)&0xff00)
770                    | ((((int)batteryStatus)<<16)&0xf0000)
771                    | ((((int)batteryHealth)<<20)&0xf00000)
772                    | ((((int)batteryPlugType)<<24)&0xf000000)
773                    | (wakelockTag != null ? 0x10000000 : 0)
774                    | (wakeReasonTag != null ? 0x20000000 : 0)
775                    | (eventCode != EVENT_NONE ? 0x40000000 : 0);
776            dest.writeInt(bat);
777            bat = (((int)batteryTemperature)&0xffff)
778                    | ((((int)batteryVoltage)<<16)&0xffff0000);
779            dest.writeInt(bat);
780            dest.writeInt(states);
781            dest.writeInt(states2);
782            if (wakelockTag != null) {
783                wakelockTag.writeToParcel(dest, flags);
784            }
785            if (wakeReasonTag != null) {
786                wakeReasonTag.writeToParcel(dest, flags);
787            }
788            if (eventCode != EVENT_NONE) {
789                dest.writeInt(eventCode);
790                eventTag.writeToParcel(dest, flags);
791            }
792            if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
793                dest.writeLong(currentTime);
794            }
795        }
796
797        public void readFromParcel(Parcel src) {
798            int start = src.dataPosition();
799            int bat = src.readInt();
800            cmd = (byte)(bat&0xff);
801            batteryLevel = (byte)((bat>>8)&0xff);
802            batteryStatus = (byte)((bat>>16)&0xf);
803            batteryHealth = (byte)((bat>>20)&0xf);
804            batteryPlugType = (byte)((bat>>24)&0xf);
805            int bat2 = src.readInt();
806            batteryTemperature = (short)(bat2&0xffff);
807            batteryVoltage = (char)((bat2>>16)&0xffff);
808            states = src.readInt();
809            states2 = src.readInt();
810            if ((bat&0x10000000) != 0) {
811                wakelockTag = localWakelockTag;
812                wakelockTag.readFromParcel(src);
813            } else {
814                wakelockTag = null;
815            }
816            if ((bat&0x20000000) != 0) {
817                wakeReasonTag = localWakeReasonTag;
818                wakeReasonTag.readFromParcel(src);
819            } else {
820                wakeReasonTag = null;
821            }
822            if ((bat&0x40000000) != 0) {
823                eventCode = src.readInt();
824                eventTag = localEventTag;
825                eventTag.readFromParcel(src);
826            } else {
827                eventCode = EVENT_NONE;
828                eventTag = null;
829            }
830            if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
831                currentTime = src.readLong();
832            } else {
833                currentTime = 0;
834            }
835            numReadInts += (src.dataPosition()-start)/4;
836        }
837
838        public void clear() {
839            time = 0;
840            cmd = CMD_NULL;
841            batteryLevel = 0;
842            batteryStatus = 0;
843            batteryHealth = 0;
844            batteryPlugType = 0;
845            batteryTemperature = 0;
846            batteryVoltage = 0;
847            states = 0;
848            states2 = 0;
849            wakelockTag = null;
850            wakeReasonTag = null;
851            eventCode = EVENT_NONE;
852            eventTag = null;
853        }
854
855        public void setTo(HistoryItem o) {
856            time = o.time;
857            cmd = o.cmd;
858            setToCommon(o);
859        }
860
861        public void setTo(long time, byte cmd, HistoryItem o) {
862            this.time = time;
863            this.cmd = cmd;
864            setToCommon(o);
865        }
866
867        private void setToCommon(HistoryItem o) {
868            batteryLevel = o.batteryLevel;
869            batteryStatus = o.batteryStatus;
870            batteryHealth = o.batteryHealth;
871            batteryPlugType = o.batteryPlugType;
872            batteryTemperature = o.batteryTemperature;
873            batteryVoltage = o.batteryVoltage;
874            states = o.states;
875            states2 = o.states2;
876            if (o.wakelockTag != null) {
877                wakelockTag = localWakelockTag;
878                wakelockTag.setTo(o.wakelockTag);
879            } else {
880                wakelockTag = null;
881            }
882            if (o.wakeReasonTag != null) {
883                wakeReasonTag = localWakeReasonTag;
884                wakeReasonTag.setTo(o.wakeReasonTag);
885            } else {
886                wakeReasonTag = null;
887            }
888            eventCode = o.eventCode;
889            if (o.eventTag != null) {
890                eventTag = localEventTag;
891                eventTag.setTo(o.eventTag);
892            } else {
893                eventTag = null;
894            }
895            currentTime = o.currentTime;
896        }
897
898        public boolean sameNonEvent(HistoryItem o) {
899            return batteryLevel == o.batteryLevel
900                    && batteryStatus == o.batteryStatus
901                    && batteryHealth == o.batteryHealth
902                    && batteryPlugType == o.batteryPlugType
903                    && batteryTemperature == o.batteryTemperature
904                    && batteryVoltage == o.batteryVoltage
905                    && states == o.states
906                    && states2 == o.states2
907                    && currentTime == o.currentTime;
908        }
909
910        public boolean same(HistoryItem o) {
911            if (!sameNonEvent(o) || eventCode != o.eventCode) {
912                return false;
913            }
914            if (wakelockTag != o.wakelockTag) {
915                if (wakelockTag == null || o.wakelockTag == null) {
916                    return false;
917                }
918                if (!wakelockTag.equals(o.wakelockTag)) {
919                    return false;
920                }
921            }
922            if (wakeReasonTag != o.wakeReasonTag) {
923                if (wakeReasonTag == null || o.wakeReasonTag == null) {
924                    return false;
925                }
926                if (!wakeReasonTag.equals(o.wakeReasonTag)) {
927                    return false;
928                }
929            }
930            if (eventTag != o.eventTag) {
931                if (eventTag == null || o.eventTag == null) {
932                    return false;
933                }
934                if (!eventTag.equals(o.eventTag)) {
935                    return false;
936                }
937            }
938            return true;
939        }
940    }
941
942    public final static class HistoryEventTracker {
943        private final HashMap<String, SparseIntArray>[] mActiveEvents
944                = (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
945
946        public boolean updateState(int code, String name, int uid, int poolIdx) {
947            if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
948                int idx = code&HistoryItem.EVENT_TYPE_MASK;
949                HashMap<String, SparseIntArray> active = mActiveEvents[idx];
950                if (active == null) {
951                    active = new HashMap<String, SparseIntArray>();
952                    mActiveEvents[idx] = active;
953                }
954                SparseIntArray uids = active.get(name);
955                if (uids == null) {
956                    uids = new SparseIntArray();
957                    active.put(name, uids);
958                }
959                if (uids.indexOfKey(uid) >= 0) {
960                    // Already set, nothing to do!
961                    return false;
962                }
963                uids.put(uid, poolIdx);
964            } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
965                int idx = code&HistoryItem.EVENT_TYPE_MASK;
966                HashMap<String, SparseIntArray> active = mActiveEvents[idx];
967                if (active == null) {
968                    // not currently active, nothing to do.
969                    return false;
970                }
971                SparseIntArray uids = active.get(name);
972                if (uids == null) {
973                    // not currently active, nothing to do.
974                    return false;
975                }
976                idx = uids.indexOfKey(uid);
977                if (idx < 0) {
978                    // not currently active, nothing to do.
979                    return false;
980                }
981                uids.removeAt(idx);
982                if (uids.size() <= 0) {
983                    active.remove(name);
984                }
985            }
986            return true;
987        }
988
989        public void removeEvents(int code) {
990            int idx = code&HistoryItem.EVENT_TYPE_MASK;
991            mActiveEvents[idx] = null;
992        }
993
994        public HashMap<String, SparseIntArray> getStateForEvent(int code) {
995            return mActiveEvents[code];
996        }
997    }
998
999    public static final class BitDescription {
1000        public final int mask;
1001        public final int shift;
1002        public final String name;
1003        public final String shortName;
1004        public final String[] values;
1005        public final String[] shortValues;
1006
1007        public BitDescription(int mask, String name, String shortName) {
1008            this.mask = mask;
1009            this.shift = -1;
1010            this.name = name;
1011            this.shortName = shortName;
1012            this.values = null;
1013            this.shortValues = null;
1014        }
1015
1016        public BitDescription(int mask, int shift, String name, String shortName,
1017                String[] values, String[] shortValues) {
1018            this.mask = mask;
1019            this.shift = shift;
1020            this.name = name;
1021            this.shortName = shortName;
1022            this.values = values;
1023            this.shortValues = shortValues;
1024        }
1025    }
1026
1027    /**
1028     * Don't allow any more batching in to the current history event.  This
1029     * is called when printing partial histories, so to ensure that the next
1030     * history event will go in to a new batch after what was printed in the
1031     * last partial history.
1032     */
1033    public abstract void commitCurrentHistoryBatchLocked();
1034
1035    public abstract int getHistoryTotalSize();
1036
1037    public abstract int getHistoryUsedSize();
1038
1039    public abstract boolean startIteratingHistoryLocked();
1040
1041    public abstract int getHistoryStringPoolSize();
1042
1043    public abstract int getHistoryStringPoolBytes();
1044
1045    public abstract String getHistoryTagPoolString(int index);
1046
1047    public abstract int getHistoryTagPoolUid(int index);
1048
1049    public abstract boolean getNextHistoryLocked(HistoryItem out);
1050
1051    public abstract void finishIteratingHistoryLocked();
1052
1053    public abstract boolean startIteratingOldHistoryLocked();
1054
1055    public abstract boolean getNextOldHistoryLocked(HistoryItem out);
1056
1057    public abstract void finishIteratingOldHistoryLocked();
1058
1059    /**
1060     * Return the base time offset for the battery history.
1061     */
1062    public abstract long getHistoryBaseTime();
1063
1064    /**
1065     * Returns the number of times the device has been started.
1066     */
1067    public abstract int getStartCount();
1068
1069    /**
1070     * Returns the time in microseconds that the screen has been on while the device was
1071     * running on battery.
1072     *
1073     * {@hide}
1074     */
1075    public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
1076
1077    /**
1078     * Returns the number of times the screen was turned on.
1079     *
1080     * {@hide}
1081     */
1082    public abstract int getScreenOnCount(int which);
1083
1084    public abstract long getInteractiveTime(long elapsedRealtimeUs, int which);
1085
1086    public static final int SCREEN_BRIGHTNESS_DARK = 0;
1087    public static final int SCREEN_BRIGHTNESS_DIM = 1;
1088    public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
1089    public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
1090    public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
1091
1092    static final String[] SCREEN_BRIGHTNESS_NAMES = {
1093        "dark", "dim", "medium", "light", "bright"
1094    };
1095
1096    static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
1097        "0", "1", "2", "3", "4"
1098    };
1099
1100    public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
1101
1102    /**
1103     * Returns the time in microseconds that the screen has been on with
1104     * the given brightness
1105     *
1106     * {@hide}
1107     */
1108    public abstract long getScreenBrightnessTime(int brightnessBin,
1109            long elapsedRealtimeUs, int which);
1110
1111    /**
1112     * Returns the time in microseconds that low power mode has been enabled while the device was
1113     * running on battery.
1114     *
1115     * {@hide}
1116     */
1117    public abstract long getLowPowerModeEnabledTime(long elapsedRealtimeUs, int which);
1118
1119    /**
1120     * Returns the number of times that low power mode was enabled.
1121     *
1122     * {@hide}
1123     */
1124    public abstract int getLowPowerModeEnabledCount(int which);
1125
1126    /**
1127     * Returns the number of times that connectivity state changed.
1128     *
1129     * {@hide}
1130     */
1131    public abstract int getNumConnectivityChange(int which);
1132
1133    /**
1134     * Returns the time in microseconds that the phone has been on while the device was
1135     * running on battery.
1136     *
1137     * {@hide}
1138     */
1139    public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
1140
1141    /**
1142     * Returns the number of times a phone call was activated.
1143     *
1144     * {@hide}
1145     */
1146    public abstract int getPhoneOnCount(int which);
1147
1148    /**
1149     * Returns the time in microseconds that the phone has been running with
1150     * the given signal strength.
1151     *
1152     * {@hide}
1153     */
1154    public abstract long getPhoneSignalStrengthTime(int strengthBin,
1155            long elapsedRealtimeUs, int which);
1156
1157    /**
1158     * Returns the time in microseconds that the phone has been trying to
1159     * acquire a signal.
1160     *
1161     * {@hide}
1162     */
1163    public abstract long getPhoneSignalScanningTime(
1164            long elapsedRealtimeUs, int which);
1165
1166    /**
1167     * Returns the number of times the phone has entered the given signal strength.
1168     *
1169     * {@hide}
1170     */
1171    public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
1172
1173    /**
1174     * Returns the time in microseconds that the mobile network has been active
1175     * (in a high power state).
1176     *
1177     * {@hide}
1178     */
1179    public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which);
1180
1181    /**
1182     * Returns the number of times that the mobile network has transitioned to the
1183     * active state.
1184     *
1185     * {@hide}
1186     */
1187    public abstract int getMobileRadioActiveCount(int which);
1188
1189    /**
1190     * Returns the time in microseconds that is the difference between the mobile radio
1191     * time we saw based on the elapsed timestamp when going down vs. the given time stamp
1192     * from the radio.
1193     *
1194     * {@hide}
1195     */
1196    public abstract long getMobileRadioActiveAdjustedTime(int which);
1197
1198    /**
1199     * Returns the time in microseconds that the mobile network has been active
1200     * (in a high power state) but not being able to blame on an app.
1201     *
1202     * {@hide}
1203     */
1204    public abstract long getMobileRadioActiveUnknownTime(int which);
1205
1206    /**
1207     * Return count of number of times radio was up that could not be blamed on apps.
1208     *
1209     * {@hide}
1210     */
1211    public abstract int getMobileRadioActiveUnknownCount(int which);
1212
1213    public static final int DATA_CONNECTION_NONE = 0;
1214    public static final int DATA_CONNECTION_GPRS = 1;
1215    public static final int DATA_CONNECTION_EDGE = 2;
1216    public static final int DATA_CONNECTION_UMTS = 3;
1217    public static final int DATA_CONNECTION_CDMA = 4;
1218    public static final int DATA_CONNECTION_EVDO_0 = 5;
1219    public static final int DATA_CONNECTION_EVDO_A = 6;
1220    public static final int DATA_CONNECTION_1xRTT = 7;
1221    public static final int DATA_CONNECTION_HSDPA = 8;
1222    public static final int DATA_CONNECTION_HSUPA = 9;
1223    public static final int DATA_CONNECTION_HSPA = 10;
1224    public static final int DATA_CONNECTION_IDEN = 11;
1225    public static final int DATA_CONNECTION_EVDO_B = 12;
1226    public static final int DATA_CONNECTION_LTE = 13;
1227    public static final int DATA_CONNECTION_EHRPD = 14;
1228    public static final int DATA_CONNECTION_HSPAP = 15;
1229    public static final int DATA_CONNECTION_OTHER = 16;
1230
1231    static final String[] DATA_CONNECTION_NAMES = {
1232        "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
1233        "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
1234        "ehrpd", "hspap", "other"
1235    };
1236
1237    public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
1238
1239    /**
1240     * Returns the time in microseconds that the phone has been running with
1241     * the given data connection.
1242     *
1243     * {@hide}
1244     */
1245    public abstract long getPhoneDataConnectionTime(int dataType,
1246            long elapsedRealtimeUs, int which);
1247
1248    /**
1249     * Returns the number of times the phone has entered the given data
1250     * connection type.
1251     *
1252     * {@hide}
1253     */
1254    public abstract int getPhoneDataConnectionCount(int dataType, int which);
1255
1256    public static final int WIFI_SUPPL_STATE_INVALID = 0;
1257    public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1;
1258    public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2;
1259    public static final int WIFI_SUPPL_STATE_INACTIVE = 3;
1260    public static final int WIFI_SUPPL_STATE_SCANNING = 4;
1261    public static final int WIFI_SUPPL_STATE_AUTHENTICATING = 5;
1262    public static final int WIFI_SUPPL_STATE_ASSOCIATING = 6;
1263    public static final int WIFI_SUPPL_STATE_ASSOCIATED = 7;
1264    public static final int WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE = 8;
1265    public static final int WIFI_SUPPL_STATE_GROUP_HANDSHAKE = 9;
1266    public static final int WIFI_SUPPL_STATE_COMPLETED = 10;
1267    public static final int WIFI_SUPPL_STATE_DORMANT = 11;
1268    public static final int WIFI_SUPPL_STATE_UNINITIALIZED = 12;
1269
1270    public static final int NUM_WIFI_SUPPL_STATES = WIFI_SUPPL_STATE_UNINITIALIZED+1;
1271
1272    static final String[] WIFI_SUPPL_STATE_NAMES = {
1273        "invalid", "disconn", "disabled", "inactive", "scanning",
1274        "authenticating", "associating", "associated", "4-way-handshake",
1275        "group-handshake", "completed", "dormant", "uninit"
1276    };
1277
1278    static final String[] WIFI_SUPPL_STATE_SHORT_NAMES = {
1279        "inv", "dsc", "dis", "inact", "scan",
1280        "auth", "ascing", "asced", "4-way",
1281        "group", "compl", "dorm", "uninit"
1282    };
1283
1284    public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
1285            = new BitDescription[] {
1286        new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
1287        new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
1288        new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
1289        new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
1290        new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
1291        new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
1292        new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
1293        new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
1294        new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
1295        new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
1296        new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
1297        new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
1298        new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
1299        new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
1300        new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
1301                HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
1302                DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
1303        new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
1304                HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
1305                new String[] {"in", "out", "emergency", "off"},
1306                new String[] {"in", "out", "em", "off"}),
1307        new BitDescription(HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK,
1308                HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT, "phone_signal_strength", "Pss",
1309                SignalStrength.SIGNAL_STRENGTH_NAMES,
1310                new String[] { "0", "1", "2", "3", "4" }),
1311        new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
1312                HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
1313                SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
1314    };
1315
1316    public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
1317            = new BitDescription[] {
1318        new BitDescription(HistoryItem.STATE2_LOW_POWER_FLAG, "low_power", "lp"),
1319        new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
1320        new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Wr"),
1321        new BitDescription(HistoryItem.STATE2_WIFI_ON_FLAG, "wifi", "W"),
1322        new BitDescription(HistoryItem.STATE2_FLASHLIGHT_FLAG, "flashlight", "fl"),
1323        new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
1324                HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT, "wifi_signal_strength", "Wss",
1325                new String[] { "0", "1", "2", "3", "4" },
1326                new String[] { "0", "1", "2", "3", "4" }),
1327        new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK,
1328                HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp",
1329                WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES),
1330    };
1331
1332    public static final String[] HISTORY_EVENT_NAMES = new String[] {
1333            "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn"
1334    };
1335
1336    public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
1337            "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn"
1338    };
1339
1340    /**
1341     * Returns the time in microseconds that wifi has been on while the device was
1342     * running on battery.
1343     *
1344     * {@hide}
1345     */
1346    public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
1347
1348    /**
1349     * Returns the time in microseconds that wifi has been on and the driver has
1350     * been in the running state while the device was running on battery.
1351     *
1352     * {@hide}
1353     */
1354    public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
1355
1356    public static final int WIFI_STATE_OFF = 0;
1357    public static final int WIFI_STATE_OFF_SCANNING = 1;
1358    public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
1359    public static final int WIFI_STATE_ON_DISCONNECTED = 3;
1360    public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
1361    public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
1362    public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
1363    public static final int WIFI_STATE_SOFT_AP = 7;
1364
1365    static final String[] WIFI_STATE_NAMES = {
1366        "off", "scanning", "no_net", "disconn",
1367        "sta", "p2p", "sta_p2p", "soft_ap"
1368    };
1369
1370    public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1;
1371
1372    /**
1373     * Returns the time in microseconds that WiFi has been running in the given state.
1374     *
1375     * {@hide}
1376     */
1377    public abstract long getWifiStateTime(int wifiState,
1378            long elapsedRealtimeUs, int which);
1379
1380    /**
1381     * Returns the number of times that WiFi has entered the given state.
1382     *
1383     * {@hide}
1384     */
1385    public abstract int getWifiStateCount(int wifiState, int which);
1386
1387    /**
1388     * Returns the time in microseconds that the wifi supplicant has been
1389     * in a given state.
1390     *
1391     * {@hide}
1392     */
1393    public abstract long getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which);
1394
1395    /**
1396     * Returns the number of times that the wifi supplicant has transitioned
1397     * to a given state.
1398     *
1399     * {@hide}
1400     */
1401    public abstract int getWifiSupplStateCount(int state, int which);
1402
1403    public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5;
1404
1405    /**
1406     * Returns the time in microseconds that WIFI has been running with
1407     * the given signal strength.
1408     *
1409     * {@hide}
1410     */
1411    public abstract long getWifiSignalStrengthTime(int strengthBin,
1412            long elapsedRealtimeUs, int which);
1413
1414    /**
1415     * Returns the number of times WIFI has entered the given signal strength.
1416     *
1417     * {@hide}
1418     */
1419    public abstract int getWifiSignalStrengthCount(int strengthBin, int which);
1420
1421    /**
1422     * Returns the time in microseconds that bluetooth has been on while the device was
1423     * running on battery.
1424     *
1425     * {@hide}
1426     */
1427    public abstract long getBluetoothOnTime(long elapsedRealtimeUs, int which);
1428
1429    public abstract int getBluetoothPingCount();
1430
1431    public static final int BLUETOOTH_STATE_INACTIVE = 0;
1432    public static final int BLUETOOTH_STATE_LOW = 1;
1433    public static final int BLUETOOTH_STATE_MEDIUM = 2;
1434    public static final int BLUETOOTH_STATE_HIGH = 3;
1435
1436    static final String[] BLUETOOTH_STATE_NAMES = {
1437        "inactive", "low", "med", "high"
1438    };
1439
1440    public static final int NUM_BLUETOOTH_STATES = BLUETOOTH_STATE_HIGH +1;
1441
1442    /**
1443     * Returns the time in microseconds that Bluetooth has been running in the
1444     * given active state.
1445     *
1446     * {@hide}
1447     */
1448    public abstract long getBluetoothStateTime(int bluetoothState,
1449            long elapsedRealtimeUs, int which);
1450
1451    /**
1452     * Returns the number of times that Bluetooth has entered the given active state.
1453     *
1454     * {@hide}
1455     */
1456    public abstract int getBluetoothStateCount(int bluetoothState, int which);
1457
1458    /**
1459     * Returns the time in microseconds that the flashlight has been on while the device was
1460     * running on battery.
1461     *
1462     * {@hide}
1463     */
1464    public abstract long getFlashlightOnTime(long elapsedRealtimeUs, int which);
1465
1466    /**
1467     * Returns the number of times that the flashlight has been turned on while the device was
1468     * running on battery.
1469     *
1470     * {@hide}
1471     */
1472    public abstract long getFlashlightOnCount(int which);
1473
1474    public static final int NETWORK_MOBILE_RX_DATA = 0;
1475    public static final int NETWORK_MOBILE_TX_DATA = 1;
1476    public static final int NETWORK_WIFI_RX_DATA = 2;
1477    public static final int NETWORK_WIFI_TX_DATA = 3;
1478
1479    public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1;
1480
1481    public abstract long getNetworkActivityBytes(int type, int which);
1482    public abstract long getNetworkActivityPackets(int type, int which);
1483
1484    /**
1485     * Return the wall clock time when battery stats data collection started.
1486     */
1487    public abstract long getStartClockTime();
1488
1489    /**
1490     * Return platform version tag that we were running in when the battery stats started.
1491     */
1492    public abstract String getStartPlatformVersion();
1493
1494    /**
1495     * Return platform version tag that we were running in when the battery stats ended.
1496     */
1497    public abstract String getEndPlatformVersion();
1498
1499    /**
1500     * Return the internal version code of the parcelled format.
1501     */
1502    public abstract int getParcelVersion();
1503
1504    /**
1505     * Return whether we are currently running on battery.
1506     */
1507    public abstract boolean getIsOnBattery();
1508
1509    /**
1510     * Returns a SparseArray containing the statistics for each uid.
1511     */
1512    public abstract SparseArray<? extends Uid> getUidStats();
1513
1514    /**
1515     * Returns the current battery uptime in microseconds.
1516     *
1517     * @param curTime the amount of elapsed realtime in microseconds.
1518     */
1519    public abstract long getBatteryUptime(long curTime);
1520
1521    /**
1522     * Returns the current battery realtime in microseconds.
1523     *
1524     * @param curTime the amount of elapsed realtime in microseconds.
1525     */
1526    public abstract long getBatteryRealtime(long curTime);
1527
1528    /**
1529     * Returns the battery percentage level at the last time the device was unplugged from power, or
1530     * the last time it booted on battery power.
1531     */
1532    public abstract int getDischargeStartLevel();
1533
1534    /**
1535     * Returns the current battery percentage level if we are in a discharge cycle, otherwise
1536     * returns the level at the last plug event.
1537     */
1538    public abstract int getDischargeCurrentLevel();
1539
1540    /**
1541     * Get the amount the battery has discharged since the stats were
1542     * last reset after charging, as a lower-end approximation.
1543     */
1544    public abstract int getLowDischargeAmountSinceCharge();
1545
1546    /**
1547     * Get the amount the battery has discharged since the stats were
1548     * last reset after charging, as an upper-end approximation.
1549     */
1550    public abstract int getHighDischargeAmountSinceCharge();
1551
1552    /**
1553     * Retrieve the discharge amount over the selected discharge period <var>which</var>.
1554     */
1555    public abstract int getDischargeAmount(int which);
1556
1557    /**
1558     * Get the amount the battery has discharged while the screen was on,
1559     * since the last time power was unplugged.
1560     */
1561    public abstract int getDischargeAmountScreenOn();
1562
1563    /**
1564     * Get the amount the battery has discharged while the screen was on,
1565     * since the last time the device was charged.
1566     */
1567    public abstract int getDischargeAmountScreenOnSinceCharge();
1568
1569    /**
1570     * Get the amount the battery has discharged while the screen was off,
1571     * since the last time power was unplugged.
1572     */
1573    public abstract int getDischargeAmountScreenOff();
1574
1575    /**
1576     * Get the amount the battery has discharged while the screen was off,
1577     * since the last time the device was charged.
1578     */
1579    public abstract int getDischargeAmountScreenOffSinceCharge();
1580
1581    /**
1582     * Returns the total, last, or current battery uptime in microseconds.
1583     *
1584     * @param curTime the elapsed realtime in microseconds.
1585     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1586     */
1587    public abstract long computeBatteryUptime(long curTime, int which);
1588
1589    /**
1590     * Returns the total, last, or current battery realtime in microseconds.
1591     *
1592     * @param curTime the current elapsed realtime in microseconds.
1593     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1594     */
1595    public abstract long computeBatteryRealtime(long curTime, int which);
1596
1597    /**
1598     * Returns the total, last, or current battery screen off uptime in microseconds.
1599     *
1600     * @param curTime the elapsed realtime in microseconds.
1601     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1602     */
1603    public abstract long computeBatteryScreenOffUptime(long curTime, int which);
1604
1605    /**
1606     * Returns the total, last, or current battery screen off realtime in microseconds.
1607     *
1608     * @param curTime the current elapsed realtime in microseconds.
1609     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1610     */
1611    public abstract long computeBatteryScreenOffRealtime(long curTime, int which);
1612
1613    /**
1614     * Returns the total, last, or current uptime in microseconds.
1615     *
1616     * @param curTime the current elapsed realtime in microseconds.
1617     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1618     */
1619    public abstract long computeUptime(long curTime, int which);
1620
1621    /**
1622     * Returns the total, last, or current realtime in microseconds.
1623     *
1624     * @param curTime the current elapsed realtime in microseconds.
1625     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1626     */
1627    public abstract long computeRealtime(long curTime, int which);
1628
1629    /**
1630     * Compute an approximation for how much run time (in microseconds) is remaining on
1631     * the battery.  Returns -1 if no time can be computed: either there is not
1632     * enough current data to make a decision, or the battery is currently
1633     * charging.
1634     *
1635     * @param curTime The current elepsed realtime in microseconds.
1636     */
1637    public abstract long computeBatteryTimeRemaining(long curTime);
1638
1639    // The part of a step duration that is the actual time.
1640    public static final long STEP_LEVEL_TIME_MASK = 0x000000ffffffffffL;
1641
1642    // Bits in a step duration that are the new battery level we are at.
1643    public static final long STEP_LEVEL_LEVEL_MASK = 0x0000ff0000000000L;
1644    public static final long STEP_LEVEL_LEVEL_SHIFT = 40;
1645
1646    // Bits in a step duration that are the initial mode we were in at that step.
1647    public static final long STEP_LEVEL_INITIAL_MODE_MASK = 0x00ff000000000000L;
1648    public static final long STEP_LEVEL_INITIAL_MODE_SHIFT = 48;
1649
1650    // Bits in a step duration that indicate which modes changed during that step.
1651    public static final long STEP_LEVEL_MODIFIED_MODE_MASK = 0xff00000000000000L;
1652    public static final long STEP_LEVEL_MODIFIED_MODE_SHIFT = 56;
1653
1654    // Step duration mode: the screen is on, off, dozed, etc; value is Display.STATE_* - 1.
1655    public static final int STEP_LEVEL_MODE_SCREEN_STATE = 0x03;
1656
1657    // Step duration mode: power save is on.
1658    public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04;
1659
1660    /**
1661     * Return the historical number of discharge steps we currently have.
1662     */
1663    public abstract int getNumDischargeStepDurations();
1664
1665    /**
1666     * Return the array of discharge step durations; the number of valid
1667     * items in it is returned by {@link #getNumDischargeStepDurations()}.
1668     * These values are in milliseconds.
1669     */
1670    public abstract long[] getDischargeStepDurationsArray();
1671
1672    /**
1673     * Compute an approximation for how much time (in microseconds) remains until the battery
1674     * is fully charged.  Returns -1 if no time can be computed: either there is not
1675     * enough current data to make a decision, or the battery is currently
1676     * discharging.
1677     *
1678     * @param curTime The current elepsed realtime in microseconds.
1679     */
1680    public abstract long computeChargeTimeRemaining(long curTime);
1681
1682    /**
1683     * Return the historical number of charge steps we currently have.
1684     */
1685    public abstract int getNumChargeStepDurations();
1686
1687    /**
1688     * Return the array of charge step durations; the number of valid
1689     * items in it is returned by {@link #getNumChargeStepDurations()}.
1690     * These values are in milliseconds.
1691     */
1692    public abstract long[] getChargeStepDurationsArray();
1693
1694    public abstract Map<String, ? extends Timer> getWakeupReasonStats();
1695
1696    public abstract Map<String, ? extends Timer> getKernelWakelockStats();
1697
1698    /** Returns the number of different speeds that the CPU can run at */
1699    public abstract int getCpuSpeedSteps();
1700
1701    public abstract void writeToParcelWithoutUids(Parcel out, int flags);
1702
1703    private final static void formatTimeRaw(StringBuilder out, long seconds) {
1704        long days = seconds / (60 * 60 * 24);
1705        if (days != 0) {
1706            out.append(days);
1707            out.append("d ");
1708        }
1709        long used = days * 60 * 60 * 24;
1710
1711        long hours = (seconds - used) / (60 * 60);
1712        if (hours != 0 || used != 0) {
1713            out.append(hours);
1714            out.append("h ");
1715        }
1716        used += hours * 60 * 60;
1717
1718        long mins = (seconds-used) / 60;
1719        if (mins != 0 || used != 0) {
1720            out.append(mins);
1721            out.append("m ");
1722        }
1723        used += mins * 60;
1724
1725        if (seconds != 0 || used != 0) {
1726            out.append(seconds-used);
1727            out.append("s ");
1728        }
1729    }
1730
1731    public final static void formatTime(StringBuilder sb, long time) {
1732        long sec = time / 100;
1733        formatTimeRaw(sb, sec);
1734        sb.append((time - (sec * 100)) * 10);
1735        sb.append("ms ");
1736    }
1737
1738    public final static void formatTimeMs(StringBuilder sb, long time) {
1739        long sec = time / 1000;
1740        formatTimeRaw(sb, sec);
1741        sb.append(time - (sec * 1000));
1742        sb.append("ms ");
1743    }
1744
1745    public final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
1746        long sec = time / 1000;
1747        formatTimeRaw(sb, sec);
1748        sb.append(time - (sec * 1000));
1749        sb.append("ms");
1750    }
1751
1752    public final String formatRatioLocked(long num, long den) {
1753        if (den == 0L) {
1754            return "--%";
1755        }
1756        float perc = ((float)num) / ((float)den) * 100;
1757        mFormatBuilder.setLength(0);
1758        mFormatter.format("%.1f%%", perc);
1759        return mFormatBuilder.toString();
1760    }
1761
1762    final String formatBytesLocked(long bytes) {
1763        mFormatBuilder.setLength(0);
1764
1765        if (bytes < BYTES_PER_KB) {
1766            return bytes + "B";
1767        } else if (bytes < BYTES_PER_MB) {
1768            mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
1769            return mFormatBuilder.toString();
1770        } else if (bytes < BYTES_PER_GB){
1771            mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
1772            return mFormatBuilder.toString();
1773        } else {
1774            mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
1775            return mFormatBuilder.toString();
1776        }
1777    }
1778
1779    private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) {
1780        if (timer != null) {
1781            // Convert from microseconds to milliseconds with rounding
1782            long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
1783            long totalTimeMillis = (totalTimeMicros + 500) / 1000;
1784            return totalTimeMillis;
1785        }
1786        return 0;
1787    }
1788
1789    /**
1790     *
1791     * @param sb a StringBuilder object.
1792     * @param timer a Timer object contining the wakelock times.
1793     * @param elapsedRealtimeUs the current on-battery time in microseconds.
1794     * @param name the name of the wakelock.
1795     * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1796     * @param linePrefix a String to be prepended to each line of output.
1797     * @return the line prefix
1798     */
1799    private static final String printWakeLock(StringBuilder sb, Timer timer,
1800            long elapsedRealtimeUs, String name, int which, String linePrefix) {
1801
1802        if (timer != null) {
1803            long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which);
1804
1805            int count = timer.getCountLocked(which);
1806            if (totalTimeMillis != 0) {
1807                sb.append(linePrefix);
1808                formatTimeMs(sb, totalTimeMillis);
1809                if (name != null) {
1810                    sb.append(name);
1811                    sb.append(' ');
1812                }
1813                sb.append('(');
1814                sb.append(count);
1815                sb.append(" times)");
1816                return ", ";
1817            }
1818        }
1819        return linePrefix;
1820    }
1821
1822    /**
1823     * Checkin version of wakelock printer. Prints simple comma-separated list.
1824     *
1825     * @param sb a StringBuilder object.
1826     * @param timer a Timer object contining the wakelock times.
1827     * @param elapsedRealtimeUs the current time in microseconds.
1828     * @param name the name of the wakelock.
1829     * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1830     * @param linePrefix a String to be prepended to each line of output.
1831     * @return the line prefix
1832     */
1833    private static final String printWakeLockCheckin(StringBuilder sb, Timer timer,
1834            long elapsedRealtimeUs, String name, int which, String linePrefix) {
1835        long totalTimeMicros = 0;
1836        int count = 0;
1837        if (timer != null) {
1838            totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
1839            count = timer.getCountLocked(which);
1840        }
1841        sb.append(linePrefix);
1842        sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
1843        sb.append(',');
1844        sb.append(name != null ? name + "," : "");
1845        sb.append(count);
1846        return ",";
1847    }
1848
1849    /**
1850     * Dump a comma-separated line of values for terse checkin mode.
1851     *
1852     * @param pw the PageWriter to dump log to
1853     * @param category category of data (e.g. "total", "last", "unplugged", "current" )
1854     * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
1855     * @param args type-dependent data arguments
1856     */
1857    private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
1858           Object... args ) {
1859        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
1860        pw.print(uid); pw.print(',');
1861        pw.print(category); pw.print(',');
1862        pw.print(type);
1863
1864        for (Object arg : args) {
1865            pw.print(',');
1866            pw.print(arg);
1867        }
1868        pw.println();
1869    }
1870
1871    /**
1872     * Temporary for settings.
1873     */
1874    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
1875        dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
1876    }
1877
1878    /**
1879     * Checkin server version of dump to produce more compact, computer-readable log.
1880     *
1881     * NOTE: all times are expressed in 'ms'.
1882     */
1883    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
1884            boolean wifiOnly) {
1885        final long rawUptime = SystemClock.uptimeMillis() * 1000;
1886        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
1887        final long batteryUptime = getBatteryUptime(rawUptime);
1888        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
1889        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
1890        final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
1891        final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
1892                which);
1893        final long totalRealtime = computeRealtime(rawRealtime, which);
1894        final long totalUptime = computeUptime(rawUptime, which);
1895        final long screenOnTime = getScreenOnTime(rawRealtime, which);
1896        final long interactiveTime = getInteractiveTime(rawRealtime, which);
1897        final long lowPowerModeEnabledTime = getLowPowerModeEnabledTime(rawRealtime, which);
1898        final int connChanges = getNumConnectivityChange(which);
1899        final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
1900        final long wifiOnTime = getWifiOnTime(rawRealtime, which);
1901        final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
1902        final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which);
1903
1904        StringBuilder sb = new StringBuilder(128);
1905
1906        SparseArray<? extends Uid> uidStats = getUidStats();
1907        final int NU = uidStats.size();
1908
1909        String category = STAT_NAMES[which];
1910
1911        // Dump "battery" stat
1912        dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
1913                which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
1914                whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
1915                totalRealtime / 1000, totalUptime / 1000,
1916                getStartClockTime(),
1917                whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000);
1918
1919        // Calculate wakelock times across all uids.
1920        long fullWakeLockTimeTotal = 0;
1921        long partialWakeLockTimeTotal = 0;
1922
1923        for (int iu = 0; iu < NU; iu++) {
1924            Uid u = uidStats.valueAt(iu);
1925
1926            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1927            if (wakelocks.size() > 0) {
1928                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1929                        : wakelocks.entrySet()) {
1930                    Uid.Wakelock wl = ent.getValue();
1931
1932                    Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1933                    if (fullWakeTimer != null) {
1934                        fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
1935                                which);
1936                    }
1937
1938                    Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1939                    if (partialWakeTimer != null) {
1940                        partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
1941                            rawRealtime, which);
1942                    }
1943                }
1944            }
1945        }
1946
1947        long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
1948        long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
1949        long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
1950        long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
1951        long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
1952        long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
1953        long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
1954        long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
1955
1956        // Dump network stats
1957        dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
1958                mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
1959                mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets);
1960
1961        // Dump misc stats
1962        dumpLine(pw, 0 /* uid */, category, MISC_DATA,
1963                screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
1964                wifiRunningTime / 1000, bluetoothOnTime / 1000,
1965                mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
1966                fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000,
1967                0 /*legacy input event count*/, getMobileRadioActiveTime(rawRealtime, which) / 1000,
1968                getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000,
1969                lowPowerModeEnabledTime / 1000, connChanges);
1970
1971        // Dump screen brightness stats
1972        Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
1973        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1974            args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
1975        }
1976        dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
1977
1978        // Dump signal strength stats
1979        args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
1980        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
1981            args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
1982        }
1983        dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
1984        dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
1985                getPhoneSignalScanningTime(rawRealtime, which) / 1000);
1986        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
1987            args[i] = getPhoneSignalStrengthCount(i, which);
1988        }
1989        dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
1990
1991        // Dump network type stats
1992        args = new Object[NUM_DATA_CONNECTION_TYPES];
1993        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1994            args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
1995        }
1996        dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
1997        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1998            args[i] = getPhoneDataConnectionCount(i, which);
1999        }
2000        dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
2001
2002        // Dump wifi state stats
2003        args = new Object[NUM_WIFI_STATES];
2004        for (int i=0; i<NUM_WIFI_STATES; i++) {
2005            args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
2006        }
2007        dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args);
2008        for (int i=0; i<NUM_WIFI_STATES; i++) {
2009            args[i] = getWifiStateCount(i, which);
2010        }
2011        dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args);
2012
2013        // Dump wifi suppl state stats
2014        args = new Object[NUM_WIFI_SUPPL_STATES];
2015        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
2016            args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
2017        }
2018        dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_TIME_DATA, args);
2019        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
2020            args[i] = getWifiSupplStateCount(i, which);
2021        }
2022        dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_COUNT_DATA, args);
2023
2024        // Dump wifi signal strength stats
2025        args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
2026        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
2027            args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
2028        }
2029        dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
2030        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
2031            args[i] = getWifiSignalStrengthCount(i, which);
2032        }
2033        dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
2034
2035        // Dump bluetooth state stats
2036        args = new Object[NUM_BLUETOOTH_STATES];
2037        for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
2038            args[i] = getBluetoothStateTime(i, rawRealtime, which) / 1000;
2039        }
2040        dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_TIME_DATA, args);
2041        for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
2042            args[i] = getBluetoothStateCount(i, which);
2043        }
2044        dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_COUNT_DATA, args);
2045
2046        if (which == STATS_SINCE_UNPLUGGED) {
2047            dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
2048                    getDischargeCurrentLevel());
2049        }
2050
2051        if (which == STATS_SINCE_UNPLUGGED) {
2052            dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
2053                    getDischargeStartLevel()-getDischargeCurrentLevel(),
2054                    getDischargeStartLevel()-getDischargeCurrentLevel(),
2055                    getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
2056        } else {
2057            dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
2058                    getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
2059                    getDischargeAmountScreenOnSinceCharge(),
2060                    getDischargeAmountScreenOffSinceCharge());
2061        }
2062
2063        if (reqUid < 0) {
2064            Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
2065            if (kernelWakelocks.size() > 0) {
2066                for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
2067                    sb.setLength(0);
2068                    printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
2069                    dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
2070                            sb.toString());
2071                }
2072            }
2073            Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
2074            if (wakeupReasons.size() > 0) {
2075                for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
2076                    // Not doing the regular wake lock formatting to remain compatible
2077                    // with the old checkin format.
2078                    long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which);
2079                    int count = ent.getValue().getCountLocked(which);
2080                    dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA,
2081                            "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count);
2082                }
2083            }
2084        }
2085
2086        BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
2087        helper.create(this);
2088        helper.refreshStats(which, UserHandle.USER_ALL);
2089        List<BatterySipper> sippers = helper.getUsageList();
2090        if (sippers != null && sippers.size() > 0) {
2091            dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
2092                    BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
2093                    BatteryStatsHelper.makemAh(helper.getComputedPower()),
2094                    BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
2095                    BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
2096            for (int i=0; i<sippers.size(); i++) {
2097                BatterySipper bs = sippers.get(i);
2098                int uid = 0;
2099                String label;
2100                switch (bs.drainType) {
2101                    case IDLE:
2102                        label="idle";
2103                        break;
2104                    case CELL:
2105                        label="cell";
2106                        break;
2107                    case PHONE:
2108                        label="phone";
2109                        break;
2110                    case WIFI:
2111                        label="wifi";
2112                        break;
2113                    case BLUETOOTH:
2114                        label="blue";
2115                        break;
2116                    case SCREEN:
2117                        label="scrn";
2118                        break;
2119                    case FLASHLIGHT:
2120                        label="flashlight";
2121                        break;
2122                    case APP:
2123                        uid = bs.uidObj.getUid();
2124                        label = "uid";
2125                        break;
2126                    case USER:
2127                        uid = UserHandle.getUid(bs.userId, 0);
2128                        label = "user";
2129                        break;
2130                    case UNACCOUNTED:
2131                        label = "unacc";
2132                        break;
2133                    case OVERCOUNTED:
2134                        label = "over";
2135                        break;
2136                    default:
2137                        label = "???";
2138                }
2139                dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
2140                        BatteryStatsHelper.makemAh(bs.value));
2141            }
2142        }
2143
2144        for (int iu = 0; iu < NU; iu++) {
2145            final int uid = uidStats.keyAt(iu);
2146            if (reqUid >= 0 && uid != reqUid) {
2147                continue;
2148            }
2149            Uid u = uidStats.valueAt(iu);
2150            // Dump Network stats per uid, if any
2151            long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
2152            long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
2153            long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
2154            long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
2155            long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
2156            long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
2157            long mobileActiveTime = u.getMobileRadioActiveTime(which);
2158            int mobileActiveCount = u.getMobileRadioActiveCount(which);
2159            long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
2160            long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
2161            long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
2162            long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
2163            long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
2164
2165            if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
2166                    || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
2167                    || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0) {
2168                dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
2169                        wifiBytesRx, wifiBytesTx,
2170                        mobilePacketsRx, mobilePacketsTx,
2171                        wifiPacketsRx, wifiPacketsTx,
2172                        mobileActiveTime, mobileActiveCount);
2173            }
2174
2175            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
2176                    || uidWifiRunningTime != 0) {
2177                dumpLine(pw, uid, category, WIFI_DATA,
2178                        fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime);
2179            }
2180
2181            if (u.hasUserActivity()) {
2182                args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
2183                boolean hasData = false;
2184                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
2185                    int val = u.getUserActivityCount(i, which);
2186                    args[i] = val;
2187                    if (val != 0) hasData = true;
2188                }
2189                if (hasData) {
2190                    dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args);
2191                }
2192            }
2193
2194            Map<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
2195            if (wakelocks.size() > 0) {
2196                for (Map.Entry<String, ? extends Uid.Wakelock> ent : wakelocks.entrySet()) {
2197                    Uid.Wakelock wl = ent.getValue();
2198                    String linePrefix = "";
2199                    sb.setLength(0);
2200                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
2201                            rawRealtime, "f", which, linePrefix);
2202                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
2203                            rawRealtime, "p", which, linePrefix);
2204                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
2205                            rawRealtime, "w", which, linePrefix);
2206
2207                    // Only log if we had at lease one wakelock...
2208                    if (sb.length() > 0) {
2209                        String name = ent.getKey();
2210                        if (name.indexOf(',') >= 0) {
2211                            name = name.replace(',', '_');
2212                        }
2213                        dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
2214                    }
2215                }
2216            }
2217
2218            Map<String, ? extends Timer> syncs = u.getSyncStats();
2219            if (syncs.size() > 0) {
2220                for (Map.Entry<String, ? extends Timer> ent : syncs.entrySet()) {
2221                    Timer timer = ent.getValue();
2222                    // Convert from microseconds to milliseconds with rounding
2223                    long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2224                    int count = timer.getCountLocked(which);
2225                    if (totalTime != 0) {
2226                        dumpLine(pw, uid, category, SYNC_DATA, ent.getKey(), totalTime, count);
2227                    }
2228                }
2229            }
2230
2231            Map<String, ? extends Timer> jobs = u.getJobStats();
2232            if (jobs.size() > 0) {
2233                for (Map.Entry<String, ? extends Timer> ent : jobs.entrySet()) {
2234                    Timer timer = ent.getValue();
2235                    // Convert from microseconds to milliseconds with rounding
2236                    long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2237                    int count = timer.getCountLocked(which);
2238                    if (totalTime != 0) {
2239                        dumpLine(pw, uid, category, JOB_DATA, ent.getKey(), totalTime, count);
2240                    }
2241                }
2242            }
2243
2244            SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
2245            int NSE = sensors.size();
2246            for (int ise=0; ise<NSE; ise++) {
2247                Uid.Sensor se = sensors.valueAt(ise);
2248                int sensorNumber = sensors.keyAt(ise);
2249                Timer timer = se.getSensorTime();
2250                if (timer != null) {
2251                    // Convert from microseconds to milliseconds with rounding
2252                    long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2253                    int count = timer.getCountLocked(which);
2254                    if (totalTime != 0) {
2255                        dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
2256                    }
2257                }
2258            }
2259
2260            Timer vibTimer = u.getVibratorOnTimer();
2261            if (vibTimer != null) {
2262                // Convert from microseconds to milliseconds with rounding
2263                long totalTime = (vibTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2264                int count = vibTimer.getCountLocked(which);
2265                if (totalTime != 0) {
2266                    dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count);
2267                }
2268            }
2269
2270            Timer fgTimer = u.getForegroundActivityTimer();
2271            if (fgTimer != null) {
2272                // Convert from microseconds to milliseconds with rounding
2273                long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2274                int count = fgTimer.getCountLocked(which);
2275                if (totalTime != 0) {
2276                    dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count);
2277                }
2278            }
2279
2280            Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
2281            long totalStateTime = 0;
2282            for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
2283                totalStateTime += u.getProcessStateTime(ips, rawRealtime, which);
2284                stateTimes[ips] = (totalStateTime + 500) / 1000;
2285            }
2286            if (totalStateTime > 0) {
2287                dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
2288            }
2289
2290            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
2291            if (processStats.size() > 0) {
2292                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
2293                        : processStats.entrySet()) {
2294                    Uid.Proc ps = ent.getValue();
2295
2296                    final long userMillis = ps.getUserTime(which) * 10;
2297                    final long systemMillis = ps.getSystemTime(which) * 10;
2298                    final long foregroundMillis = ps.getForegroundTime(which) * 10;
2299                    final int starts = ps.getStarts(which);
2300                    final int numCrashes = ps.getNumCrashes(which);
2301                    final int numAnrs = ps.getNumAnrs(which);
2302
2303                    if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
2304                            || starts != 0 || numAnrs != 0 || numCrashes != 0) {
2305                        dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis,
2306                                systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
2307                    }
2308                }
2309            }
2310
2311            Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
2312            if (packageStats.size() > 0) {
2313                for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
2314                        : packageStats.entrySet()) {
2315
2316                    Uid.Pkg ps = ent.getValue();
2317                    int wakeups = ps.getWakeups(which);
2318                    Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
2319                    for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
2320                            : serviceStats.entrySet()) {
2321                        BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
2322                        long startTime = ss.getStartTime(batteryUptime, which);
2323                        int starts = ss.getStarts(which);
2324                        int launches = ss.getLaunches(which);
2325                        if (startTime != 0 || starts != 0 || launches != 0) {
2326                            dumpLine(pw, uid, category, APK_DATA,
2327                                    wakeups, // wakeup alarms
2328                                    ent.getKey(), // Apk
2329                                    sent.getKey(), // service
2330                                    startTime / 1000, // time spent started, in ms
2331                                    starts,
2332                                    launches);
2333                        }
2334                    }
2335                }
2336            }
2337        }
2338    }
2339
2340    static final class TimerEntry {
2341        final String mName;
2342        final int mId;
2343        final BatteryStats.Timer mTimer;
2344        final long mTime;
2345        TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
2346            mName = name;
2347            mId = id;
2348            mTimer = timer;
2349            mTime = time;
2350        }
2351    }
2352
2353    private void printmAh(PrintWriter printer, double power) {
2354        printer.print(BatteryStatsHelper.makemAh(power));
2355    }
2356
2357    /**
2358     * Temporary for settings.
2359     */
2360    public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which,
2361            int reqUid) {
2362        dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
2363    }
2364
2365    @SuppressWarnings("unused")
2366    public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
2367            int reqUid, boolean wifiOnly) {
2368        final long rawUptime = SystemClock.uptimeMillis() * 1000;
2369        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
2370        final long batteryUptime = getBatteryUptime(rawUptime);
2371
2372        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
2373        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
2374        final long totalRealtime = computeRealtime(rawRealtime, which);
2375        final long totalUptime = computeUptime(rawUptime, which);
2376        final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
2377        final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
2378                which);
2379        final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
2380        final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
2381
2382        StringBuilder sb = new StringBuilder(128);
2383
2384        SparseArray<? extends Uid> uidStats = getUidStats();
2385        final int NU = uidStats.size();
2386
2387        sb.setLength(0);
2388        sb.append(prefix);
2389                sb.append("  Time on battery: ");
2390                formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
2391                sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
2392                sb.append(") realtime, ");
2393                formatTimeMs(sb, whichBatteryUptime / 1000);
2394                sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
2395                sb.append(") uptime");
2396        pw.println(sb.toString());
2397        sb.setLength(0);
2398        sb.append(prefix);
2399                sb.append("  Time on battery screen off: ");
2400                formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("(");
2401                sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime));
2402                sb.append(") realtime, ");
2403                formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
2404                sb.append("(");
2405                sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime));
2406                sb.append(") uptime");
2407        pw.println(sb.toString());
2408        sb.setLength(0);
2409        sb.append(prefix);
2410                sb.append("  Total run time: ");
2411                formatTimeMs(sb, totalRealtime / 1000);
2412                sb.append("realtime, ");
2413                formatTimeMs(sb, totalUptime / 1000);
2414                sb.append("uptime");
2415        pw.println(sb.toString());
2416        if (batteryTimeRemaining >= 0) {
2417            sb.setLength(0);
2418            sb.append(prefix);
2419                    sb.append("  Battery time remaining: ");
2420                    formatTimeMs(sb, batteryTimeRemaining / 1000);
2421            pw.println(sb.toString());
2422        }
2423        if (chargeTimeRemaining >= 0) {
2424            sb.setLength(0);
2425            sb.append(prefix);
2426                    sb.append("  Charge time remaining: ");
2427                    formatTimeMs(sb, chargeTimeRemaining / 1000);
2428            pw.println(sb.toString());
2429        }
2430        pw.print("  Start clock time: ");
2431        pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
2432
2433        final long screenOnTime = getScreenOnTime(rawRealtime, which);
2434        final long interactiveTime = getInteractiveTime(rawRealtime, which);
2435        final long lowPowerModeEnabledTime = getLowPowerModeEnabledTime(rawRealtime, which);
2436        final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
2437        final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
2438        final long wifiOnTime = getWifiOnTime(rawRealtime, which);
2439        final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which);
2440        sb.setLength(0);
2441        sb.append(prefix);
2442                sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
2443                sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
2444                sb.append(") "); sb.append(getScreenOnCount(which));
2445                sb.append("x, Interactive: "); formatTimeMs(sb, interactiveTime / 1000);
2446                sb.append("("); sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime));
2447                sb.append(")");
2448        pw.println(sb.toString());
2449        sb.setLength(0);
2450        sb.append(prefix);
2451        sb.append("  Screen brightnesses:");
2452        boolean didOne = false;
2453        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
2454            final long time = getScreenBrightnessTime(i, rawRealtime, which);
2455            if (time == 0) {
2456                continue;
2457            }
2458            sb.append("\n    ");
2459            sb.append(prefix);
2460            didOne = true;
2461            sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
2462            sb.append(" ");
2463            formatTimeMs(sb, time/1000);
2464            sb.append("(");
2465            sb.append(formatRatioLocked(time, screenOnTime));
2466            sb.append(")");
2467        }
2468        if (!didOne) sb.append(" (no activity)");
2469        pw.println(sb.toString());
2470        if (lowPowerModeEnabledTime != 0) {
2471            sb.setLength(0);
2472            sb.append(prefix);
2473                    sb.append("  Low power mode enabled: ");
2474                    formatTimeMs(sb, lowPowerModeEnabledTime / 1000);
2475                    sb.append("(");
2476                    sb.append(formatRatioLocked(lowPowerModeEnabledTime, whichBatteryRealtime));
2477                    sb.append(")");
2478            pw.println(sb.toString());
2479        }
2480        if (phoneOnTime != 0) {
2481            sb.setLength(0);
2482            sb.append(prefix);
2483                    sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
2484                    sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
2485                    sb.append(") "); sb.append(getPhoneOnCount(which));
2486        }
2487        int connChanges = getNumConnectivityChange(which);
2488        if (connChanges != 0) {
2489            pw.print(prefix);
2490            pw.print("  Connectivity changes: "); pw.println(connChanges);
2491        }
2492
2493        // Calculate wakelock times across all uids.
2494        long fullWakeLockTimeTotalMicros = 0;
2495        long partialWakeLockTimeTotalMicros = 0;
2496
2497        final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
2498
2499        for (int iu = 0; iu < NU; iu++) {
2500            Uid u = uidStats.valueAt(iu);
2501
2502            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
2503            if (wakelocks.size() > 0) {
2504                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
2505                        : wakelocks.entrySet()) {
2506                    Uid.Wakelock wl = ent.getValue();
2507
2508                    Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
2509                    if (fullWakeTimer != null) {
2510                        fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
2511                                rawRealtime, which);
2512                    }
2513
2514                    Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
2515                    if (partialWakeTimer != null) {
2516                        long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
2517                                rawRealtime, which);
2518                        if (totalTimeMicros > 0) {
2519                            if (reqUid < 0) {
2520                                // Only show the ordered list of all wake
2521                                // locks if the caller is not asking for data
2522                                // about a specific uid.
2523                                timers.add(new TimerEntry(ent.getKey(), u.getUid(),
2524                                        partialWakeTimer, totalTimeMicros));
2525                            }
2526                            partialWakeLockTimeTotalMicros += totalTimeMicros;
2527                        }
2528                    }
2529                }
2530            }
2531        }
2532
2533        long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
2534        long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
2535        long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
2536        long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
2537        long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
2538        long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
2539        long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
2540        long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
2541
2542        if (fullWakeLockTimeTotalMicros != 0) {
2543            sb.setLength(0);
2544            sb.append(prefix);
2545                    sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
2546                            (fullWakeLockTimeTotalMicros + 500) / 1000);
2547            pw.println(sb.toString());
2548        }
2549
2550        if (partialWakeLockTimeTotalMicros != 0) {
2551            sb.setLength(0);
2552            sb.append(prefix);
2553                    sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
2554                            (partialWakeLockTimeTotalMicros + 500) / 1000);
2555            pw.println(sb.toString());
2556        }
2557
2558        pw.print(prefix);
2559                pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
2560                pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
2561                pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
2562                pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
2563        sb.setLength(0);
2564        sb.append(prefix);
2565        sb.append("  Phone signal levels:");
2566        didOne = false;
2567        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
2568            final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
2569            if (time == 0) {
2570                continue;
2571            }
2572            sb.append("\n    ");
2573            sb.append(prefix);
2574            didOne = true;
2575            sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
2576            sb.append(" ");
2577            formatTimeMs(sb, time/1000);
2578            sb.append("(");
2579            sb.append(formatRatioLocked(time, whichBatteryRealtime));
2580            sb.append(") ");
2581            sb.append(getPhoneSignalStrengthCount(i, which));
2582            sb.append("x");
2583        }
2584        if (!didOne) sb.append(" (no activity)");
2585        pw.println(sb.toString());
2586
2587        sb.setLength(0);
2588        sb.append(prefix);
2589        sb.append("  Signal scanning time: ");
2590        formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
2591        pw.println(sb.toString());
2592
2593        sb.setLength(0);
2594        sb.append(prefix);
2595        sb.append("  Radio types:");
2596        didOne = false;
2597        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
2598            final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
2599            if (time == 0) {
2600                continue;
2601            }
2602            sb.append("\n    ");
2603            sb.append(prefix);
2604            didOne = true;
2605            sb.append(DATA_CONNECTION_NAMES[i]);
2606            sb.append(" ");
2607            formatTimeMs(sb, time/1000);
2608            sb.append("(");
2609            sb.append(formatRatioLocked(time, whichBatteryRealtime));
2610            sb.append(") ");
2611            sb.append(getPhoneDataConnectionCount(i, which));
2612            sb.append("x");
2613        }
2614        if (!didOne) sb.append(" (no activity)");
2615        pw.println(sb.toString());
2616
2617        sb.setLength(0);
2618        sb.append(prefix);
2619        sb.append("  Mobile radio active time: ");
2620        final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
2621        formatTimeMs(sb, mobileActiveTime / 1000);
2622        sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
2623        sb.append(") "); sb.append(getMobileRadioActiveCount(which));
2624        sb.append("x");
2625        pw.println(sb.toString());
2626
2627        final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
2628        if (mobileActiveUnknownTime != 0) {
2629            sb.setLength(0);
2630            sb.append(prefix);
2631            sb.append("  Mobile radio active unknown time: ");
2632            formatTimeMs(sb, mobileActiveUnknownTime / 1000);
2633            sb.append("(");
2634            sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
2635            sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which));
2636            sb.append("x");
2637            pw.println(sb.toString());
2638        }
2639
2640        final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which);
2641        if (mobileActiveAdjustedTime != 0) {
2642            sb.setLength(0);
2643            sb.append(prefix);
2644            sb.append("  Mobile radio active adjusted time: ");
2645            formatTimeMs(sb, mobileActiveAdjustedTime / 1000);
2646            sb.append("(");
2647            sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime));
2648            sb.append(")");
2649            pw.println(sb.toString());
2650        }
2651
2652        pw.print(prefix);
2653                pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
2654                pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
2655                pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
2656                pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
2657        sb.setLength(0);
2658        sb.append(prefix);
2659                sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
2660                sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
2661                sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
2662                sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
2663                sb.append(")");
2664        pw.println(sb.toString());
2665
2666        sb.setLength(0);
2667        sb.append(prefix);
2668        sb.append("  Wifi states:");
2669        didOne = false;
2670        for (int i=0; i<NUM_WIFI_STATES; i++) {
2671            final long time = getWifiStateTime(i, rawRealtime, which);
2672            if (time == 0) {
2673                continue;
2674            }
2675            sb.append("\n    ");
2676            didOne = true;
2677            sb.append(WIFI_STATE_NAMES[i]);
2678            sb.append(" ");
2679            formatTimeMs(sb, time/1000);
2680            sb.append("(");
2681            sb.append(formatRatioLocked(time, whichBatteryRealtime));
2682            sb.append(") ");
2683            sb.append(getWifiStateCount(i, which));
2684            sb.append("x");
2685        }
2686        if (!didOne) sb.append(" (no activity)");
2687        pw.println(sb.toString());
2688
2689        sb.setLength(0);
2690        sb.append(prefix);
2691        sb.append("  Wifi supplicant states:");
2692        didOne = false;
2693        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
2694            final long time = getWifiSupplStateTime(i, rawRealtime, which);
2695            if (time == 0) {
2696                continue;
2697            }
2698            sb.append("\n    ");
2699            didOne = true;
2700            sb.append(WIFI_SUPPL_STATE_NAMES[i]);
2701            sb.append(" ");
2702            formatTimeMs(sb, time/1000);
2703            sb.append("(");
2704            sb.append(formatRatioLocked(time, whichBatteryRealtime));
2705            sb.append(") ");
2706            sb.append(getWifiSupplStateCount(i, which));
2707            sb.append("x");
2708        }
2709        if (!didOne) sb.append(" (no activity)");
2710        pw.println(sb.toString());
2711
2712        sb.setLength(0);
2713        sb.append(prefix);
2714        sb.append("  Wifi signal levels:");
2715        didOne = false;
2716        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
2717            final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
2718            if (time == 0) {
2719                continue;
2720            }
2721            sb.append("\n    ");
2722            sb.append(prefix);
2723            didOne = true;
2724            sb.append("level(");
2725            sb.append(i);
2726            sb.append(") ");
2727            formatTimeMs(sb, time/1000);
2728            sb.append("(");
2729            sb.append(formatRatioLocked(time, whichBatteryRealtime));
2730            sb.append(") ");
2731            sb.append(getWifiSignalStrengthCount(i, which));
2732            sb.append("x");
2733        }
2734        if (!didOne) sb.append(" (no activity)");
2735        pw.println(sb.toString());
2736
2737        sb.setLength(0);
2738        sb.append(prefix);
2739                sb.append("  Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
2740                sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
2741                sb.append(")");
2742        pw.println(sb.toString());
2743
2744        sb.setLength(0);
2745        sb.append(prefix);
2746        sb.append("  Bluetooth states:");
2747        didOne = false;
2748        for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
2749            final long time = getBluetoothStateTime(i, rawRealtime, which);
2750            if (time == 0) {
2751                continue;
2752            }
2753            sb.append("\n    ");
2754            didOne = true;
2755            sb.append(BLUETOOTH_STATE_NAMES[i]);
2756            sb.append(" ");
2757            formatTimeMs(sb, time/1000);
2758            sb.append("(");
2759            sb.append(formatRatioLocked(time, whichBatteryRealtime));
2760            sb.append(") ");
2761            sb.append(getPhoneDataConnectionCount(i, which));
2762            sb.append("x");
2763        }
2764        if (!didOne) sb.append(" (no activity)");
2765        pw.println(sb.toString());
2766
2767        pw.println();
2768
2769        if (which == STATS_SINCE_UNPLUGGED) {
2770            if (getIsOnBattery()) {
2771                pw.print(prefix); pw.println("  Device is currently unplugged");
2772                pw.print(prefix); pw.print("    Discharge cycle start level: ");
2773                        pw.println(getDischargeStartLevel());
2774                pw.print(prefix); pw.print("    Discharge cycle current level: ");
2775                        pw.println(getDischargeCurrentLevel());
2776            } else {
2777                pw.print(prefix); pw.println("  Device is currently plugged into power");
2778                pw.print(prefix); pw.print("    Last discharge cycle start level: ");
2779                        pw.println(getDischargeStartLevel());
2780                pw.print(prefix); pw.print("    Last discharge cycle end level: ");
2781                        pw.println(getDischargeCurrentLevel());
2782            }
2783            pw.print(prefix); pw.print("    Amount discharged while screen on: ");
2784                    pw.println(getDischargeAmountScreenOn());
2785            pw.print(prefix); pw.print("    Amount discharged while screen off: ");
2786                    pw.println(getDischargeAmountScreenOff());
2787            pw.println(" ");
2788        } else {
2789            pw.print(prefix); pw.println("  Device battery use since last full charge");
2790            pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
2791                    pw.println(getLowDischargeAmountSinceCharge());
2792            pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
2793                    pw.println(getHighDischargeAmountSinceCharge());
2794            pw.print(prefix); pw.print("    Amount discharged while screen on: ");
2795                    pw.println(getDischargeAmountScreenOnSinceCharge());
2796            pw.print(prefix); pw.print("    Amount discharged while screen off: ");
2797                    pw.println(getDischargeAmountScreenOffSinceCharge());
2798            pw.println();
2799        }
2800
2801        BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
2802        helper.create(this);
2803        helper.refreshStats(which, UserHandle.USER_ALL);
2804        List<BatterySipper> sippers = helper.getUsageList();
2805        if (sippers != null && sippers.size() > 0) {
2806            pw.print(prefix); pw.println("  Estimated power use (mAh):");
2807            pw.print(prefix); pw.print("    Capacity: ");
2808                    printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
2809                    pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
2810                    pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower());
2811                    if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
2812                        pw.print("-"); printmAh(pw, helper.getMaxDrainedPower());
2813                    }
2814                    pw.println();
2815            for (int i=0; i<sippers.size(); i++) {
2816                BatterySipper bs = sippers.get(i);
2817                switch (bs.drainType) {
2818                    case IDLE:
2819                        pw.print(prefix); pw.print("    Idle: "); printmAh(pw, bs.value);
2820                        pw.println();
2821                        break;
2822                    case CELL:
2823                        pw.print(prefix); pw.print("    Cell standby: "); printmAh(pw, bs.value);
2824                        pw.println();
2825                        break;
2826                    case PHONE:
2827                        pw.print(prefix); pw.print("    Phone calls: "); printmAh(pw, bs.value);
2828                        pw.println();
2829                        break;
2830                    case WIFI:
2831                        pw.print(prefix); pw.print("    Wifi: "); printmAh(pw, bs.value);
2832                        pw.println();
2833                        break;
2834                    case BLUETOOTH:
2835                        pw.print(prefix); pw.print("    Bluetooth: "); printmAh(pw, bs.value);
2836                        pw.println();
2837                        break;
2838                    case SCREEN:
2839                        pw.print(prefix); pw.print("    Screen: "); printmAh(pw, bs.value);
2840                        pw.println();
2841                        break;
2842                    case FLASHLIGHT:
2843                        pw.print(prefix); pw.print("    Flashlight: "); printmAh(pw, bs.value);
2844                        pw.println();
2845                        break;
2846                    case APP:
2847                        pw.print(prefix); pw.print("    Uid ");
2848                        UserHandle.formatUid(pw, bs.uidObj.getUid());
2849                        pw.print(": "); printmAh(pw, bs.value); pw.println();
2850                        break;
2851                    case USER:
2852                        pw.print(prefix); pw.print("    User "); pw.print(bs.userId);
2853                        pw.print(": "); printmAh(pw, bs.value); pw.println();
2854                        break;
2855                    case UNACCOUNTED:
2856                        pw.print(prefix); pw.print("    Unaccounted: "); printmAh(pw, bs.value);
2857                        pw.println();
2858                        break;
2859                    case OVERCOUNTED:
2860                        pw.print(prefix); pw.print("    Over-counted: "); printmAh(pw, bs.value);
2861                        pw.println();
2862                        break;
2863                }
2864            }
2865            pw.println();
2866        }
2867
2868        sippers = helper.getMobilemsppList();
2869        if (sippers != null && sippers.size() > 0) {
2870            pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
2871            long totalTime = 0;
2872            for (int i=0; i<sippers.size(); i++) {
2873                BatterySipper bs = sippers.get(i);
2874                sb.setLength(0);
2875                sb.append(prefix); sb.append("    Uid ");
2876                UserHandle.formatUid(sb, bs.uidObj.getUid());
2877                sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
2878                sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
2879                sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
2880                sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
2881                pw.println(sb.toString());
2882                totalTime += bs.mobileActive;
2883            }
2884            sb.setLength(0);
2885            sb.append(prefix);
2886            sb.append("    TOTAL TIME: ");
2887            formatTimeMs(sb, totalTime);
2888            sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
2889            sb.append(")");
2890            pw.println(sb.toString());
2891            pw.println();
2892        }
2893
2894        final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
2895            @Override
2896            public int compare(TimerEntry lhs, TimerEntry rhs) {
2897                long lhsTime = lhs.mTime;
2898                long rhsTime = rhs.mTime;
2899                if (lhsTime < rhsTime) {
2900                    return 1;
2901                }
2902                if (lhsTime > rhsTime) {
2903                    return -1;
2904                }
2905                return 0;
2906            }
2907        };
2908
2909        if (reqUid < 0) {
2910            Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
2911            if (kernelWakelocks.size() > 0) {
2912                final ArrayList<TimerEntry> ktimers = new ArrayList<TimerEntry>();
2913                for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
2914                    BatteryStats.Timer timer = ent.getValue();
2915                    long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
2916                    if (totalTimeMillis > 0) {
2917                        ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
2918                    }
2919                }
2920                if (ktimers.size() > 0) {
2921                    Collections.sort(ktimers, timerComparator);
2922                    pw.print(prefix); pw.println("  All kernel wake locks:");
2923                    for (int i=0; i<ktimers.size(); i++) {
2924                        TimerEntry timer = ktimers.get(i);
2925                        String linePrefix = ": ";
2926                        sb.setLength(0);
2927                        sb.append(prefix);
2928                        sb.append("  Kernel Wake lock ");
2929                        sb.append(timer.mName);
2930                        linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null,
2931                                which, linePrefix);
2932                        if (!linePrefix.equals(": ")) {
2933                            sb.append(" realtime");
2934                            // Only print out wake locks that were held
2935                            pw.println(sb.toString());
2936                        }
2937                    }
2938                    pw.println();
2939                }
2940            }
2941
2942            if (timers.size() > 0) {
2943                Collections.sort(timers, timerComparator);
2944                pw.print(prefix); pw.println("  All partial wake locks:");
2945                for (int i=0; i<timers.size(); i++) {
2946                    TimerEntry timer = timers.get(i);
2947                    sb.setLength(0);
2948                    sb.append("  Wake lock ");
2949                    UserHandle.formatUid(sb, timer.mId);
2950                    sb.append(" ");
2951                    sb.append(timer.mName);
2952                    printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
2953                    sb.append(" realtime");
2954                    pw.println(sb.toString());
2955                }
2956                timers.clear();
2957                pw.println();
2958            }
2959
2960            Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
2961            if (wakeupReasons.size() > 0) {
2962                pw.print(prefix); pw.println("  All wakeup reasons:");
2963                final ArrayList<TimerEntry> reasons = new ArrayList<TimerEntry>();
2964                for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
2965                    Timer timer = ent.getValue();
2966                    reasons.add(new TimerEntry(ent.getKey(), 0, timer,
2967                            timer.getCountLocked(which)));
2968                }
2969                Collections.sort(reasons, timerComparator);
2970                for (int i=0; i<reasons.size(); i++) {
2971                    TimerEntry timer = reasons.get(i);
2972                    String linePrefix = ": ";
2973                    sb.setLength(0);
2974                    sb.append(prefix);
2975                    sb.append("  Wakeup reason ");
2976                    sb.append(timer.mName);
2977                    printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
2978                    sb.append(" realtime");
2979                    pw.println(sb.toString());
2980                }
2981                pw.println();
2982            }
2983        }
2984
2985        for (int iu=0; iu<NU; iu++) {
2986            final int uid = uidStats.keyAt(iu);
2987            if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
2988                continue;
2989            }
2990
2991            Uid u = uidStats.valueAt(iu);
2992
2993            pw.print(prefix);
2994            pw.print("  ");
2995            UserHandle.formatUid(pw, uid);
2996            pw.println(":");
2997            boolean uidActivity = false;
2998
2999            long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
3000            long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
3001            long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
3002            long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
3003            long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
3004            long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
3005            long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
3006            int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
3007            long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
3008            long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
3009            long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
3010            long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
3011            long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
3012
3013            if (mobileRxBytes > 0 || mobileTxBytes > 0
3014                    || mobileRxPackets > 0 || mobileTxPackets > 0) {
3015                pw.print(prefix); pw.print("    Mobile network: ");
3016                        pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
3017                        pw.print(formatBytesLocked(mobileTxBytes));
3018                        pw.print(" sent (packets "); pw.print(mobileRxPackets);
3019                        pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
3020            }
3021            if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
3022                sb.setLength(0);
3023                sb.append(prefix); sb.append("    Mobile radio active: ");
3024                formatTimeMs(sb, uidMobileActiveTime / 1000);
3025                sb.append("(");
3026                sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
3027                sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
3028                long packets = mobileRxPackets + mobileTxPackets;
3029                if (packets == 0) {
3030                    packets = 1;
3031                }
3032                sb.append(" @ ");
3033                sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
3034                sb.append(" mspp");
3035                pw.println(sb.toString());
3036            }
3037
3038            if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
3039                pw.print(prefix); pw.print("    Wi-Fi network: ");
3040                        pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
3041                        pw.print(formatBytesLocked(wifiTxBytes));
3042                        pw.print(" sent (packets "); pw.print(wifiRxPackets);
3043                        pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
3044            }
3045
3046            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
3047                    || uidWifiRunningTime != 0) {
3048                sb.setLength(0);
3049                sb.append(prefix); sb.append("    Wifi Running: ");
3050                        formatTimeMs(sb, uidWifiRunningTime / 1000);
3051                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
3052                                whichBatteryRealtime)); sb.append(")\n");
3053                sb.append(prefix); sb.append("    Full Wifi Lock: ");
3054                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
3055                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
3056                                whichBatteryRealtime)); sb.append(")\n");
3057                sb.append(prefix); sb.append("    Wifi Scan: ");
3058                        formatTimeMs(sb, wifiScanTime / 1000);
3059                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
3060                                whichBatteryRealtime)); sb.append(")");
3061                pw.println(sb.toString());
3062            }
3063
3064            if (u.hasUserActivity()) {
3065                boolean hasData = false;
3066                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3067                    int val = u.getUserActivityCount(i, which);
3068                    if (val != 0) {
3069                        if (!hasData) {
3070                            sb.setLength(0);
3071                            sb.append("    User activity: ");
3072                            hasData = true;
3073                        } else {
3074                            sb.append(", ");
3075                        }
3076                        sb.append(val);
3077                        sb.append(" ");
3078                        sb.append(Uid.USER_ACTIVITY_TYPES[i]);
3079                    }
3080                }
3081                if (hasData) {
3082                    pw.println(sb.toString());
3083                }
3084            }
3085
3086            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
3087            if (wakelocks.size() > 0) {
3088                long totalFull = 0, totalPartial = 0, totalWindow = 0;
3089                int count = 0;
3090                for (Map.Entry<String, ? extends Uid.Wakelock> ent : wakelocks.entrySet()) {
3091                    Uid.Wakelock wl = ent.getValue();
3092                    String linePrefix = ": ";
3093                    sb.setLength(0);
3094                    sb.append(prefix);
3095                    sb.append("    Wake lock ");
3096                    sb.append(ent.getKey());
3097                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
3098                            "full", which, linePrefix);
3099                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
3100                            "partial", which, linePrefix);
3101                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
3102                            "window", which, linePrefix);
3103                    if (true || !linePrefix.equals(": ")) {
3104                        sb.append(" realtime");
3105                        // Only print out wake locks that were held
3106                        pw.println(sb.toString());
3107                        uidActivity = true;
3108                        count++;
3109                    }
3110                    totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
3111                            rawRealtime, which);
3112                    totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
3113                            rawRealtime, which);
3114                    totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
3115                            rawRealtime, which);
3116                }
3117                if (count > 1) {
3118                    if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) {
3119                        sb.setLength(0);
3120                        sb.append(prefix);
3121                        sb.append("    TOTAL wake: ");
3122                        boolean needComma = false;
3123                        if (totalFull != 0) {
3124                            needComma = true;
3125                            formatTimeMs(sb, totalFull);
3126                            sb.append("full");
3127                        }
3128                        if (totalPartial != 0) {
3129                            if (needComma) {
3130                                sb.append(", ");
3131                            }
3132                            needComma = true;
3133                            formatTimeMs(sb, totalPartial);
3134                            sb.append("partial");
3135                        }
3136                        if (totalWindow != 0) {
3137                            if (needComma) {
3138                                sb.append(", ");
3139                            }
3140                            needComma = true;
3141                            formatTimeMs(sb, totalWindow);
3142                            sb.append("window");
3143                        }
3144                        sb.append(" realtime");
3145                        pw.println(sb.toString());
3146                    }
3147                }
3148            }
3149
3150            Map<String, ? extends Timer> syncs = u.getSyncStats();
3151            if (syncs.size() > 0) {
3152                for (Map.Entry<String, ? extends Timer> ent : syncs.entrySet()) {
3153                    Timer timer = ent.getValue();
3154                    // Convert from microseconds to milliseconds with rounding
3155                    long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
3156                    int count = timer.getCountLocked(which);
3157                    sb.setLength(0);
3158                    sb.append(prefix);
3159                    sb.append("    Sync ");
3160                    sb.append(ent.getKey());
3161                    sb.append(": ");
3162                    if (totalTime != 0) {
3163                        formatTimeMs(sb, totalTime);
3164                        sb.append("realtime (");
3165                        sb.append(count);
3166                        sb.append(" times)");
3167                    } else {
3168                        sb.append("(not used)");
3169                    }
3170                    pw.println(sb.toString());
3171                    uidActivity = true;
3172                }
3173            }
3174
3175            Map<String, ? extends Timer> jobs = u.getJobStats();
3176            if (jobs.size() > 0) {
3177                for (Map.Entry<String, ? extends Timer> ent : jobs.entrySet()) {
3178                    Timer timer = ent.getValue();
3179                    // Convert from microseconds to milliseconds with rounding
3180                    long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
3181                    int count = timer.getCountLocked(which);
3182                    sb.setLength(0);
3183                    sb.append(prefix);
3184                    sb.append("    Job ");
3185                    sb.append(ent.getKey());
3186                    sb.append(": ");
3187                    if (totalTime != 0) {
3188                        formatTimeMs(sb, totalTime);
3189                        sb.append("realtime (");
3190                        sb.append(count);
3191                        sb.append(" times)");
3192                    } else {
3193                        sb.append("(not used)");
3194                    }
3195                    pw.println(sb.toString());
3196                    uidActivity = true;
3197                }
3198            }
3199
3200            SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
3201            int NSE = sensors.size();
3202            for (int ise=0; ise<NSE; ise++) {
3203                Uid.Sensor se = sensors.valueAt(ise);
3204                int sensorNumber = sensors.keyAt(ise);
3205                sb.setLength(0);
3206                sb.append(prefix);
3207                sb.append("    Sensor ");
3208                int handle = se.getHandle();
3209                if (handle == Uid.Sensor.GPS) {
3210                    sb.append("GPS");
3211                } else {
3212                    sb.append(handle);
3213                }
3214                sb.append(": ");
3215
3216                Timer timer = se.getSensorTime();
3217                if (timer != null) {
3218                    // Convert from microseconds to milliseconds with rounding
3219                    long totalTime = (timer.getTotalTimeLocked(
3220                            rawRealtime, which) + 500) / 1000;
3221                    int count = timer.getCountLocked(which);
3222                    //timer.logState();
3223                    if (totalTime != 0) {
3224                        formatTimeMs(sb, totalTime);
3225                        sb.append("realtime (");
3226                        sb.append(count);
3227                        sb.append(" times)");
3228                    } else {
3229                        sb.append("(not used)");
3230                    }
3231                } else {
3232                    sb.append("(not used)");
3233                }
3234
3235                pw.println(sb.toString());
3236                uidActivity = true;
3237            }
3238
3239            Timer vibTimer = u.getVibratorOnTimer();
3240            if (vibTimer != null) {
3241                // Convert from microseconds to milliseconds with rounding
3242                long totalTime = (vibTimer.getTotalTimeLocked(
3243                        rawRealtime, which) + 500) / 1000;
3244                int count = vibTimer.getCountLocked(which);
3245                //timer.logState();
3246                if (totalTime != 0) {
3247                    sb.setLength(0);
3248                    sb.append(prefix);
3249                    sb.append("    Vibrator: ");
3250                    formatTimeMs(sb, totalTime);
3251                    sb.append("realtime (");
3252                    sb.append(count);
3253                    sb.append(" times)");
3254                    pw.println(sb.toString());
3255                    uidActivity = true;
3256                }
3257            }
3258
3259            Timer fgTimer = u.getForegroundActivityTimer();
3260            if (fgTimer != null) {
3261                // Convert from microseconds to milliseconds with rounding
3262                long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
3263                int count = fgTimer.getCountLocked(which);
3264                if (totalTime != 0) {
3265                    sb.setLength(0);
3266                    sb.append(prefix);
3267                    sb.append("    Foreground activities: ");
3268                    formatTimeMs(sb, totalTime);
3269                    sb.append("realtime (");
3270                    sb.append(count);
3271                    sb.append(" times)");
3272                    pw.println(sb.toString());
3273                    uidActivity = true;
3274                }
3275            }
3276
3277            long totalStateTime = 0;
3278            for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
3279                long time = u.getProcessStateTime(ips, rawRealtime, which);
3280                if (time > 0) {
3281                    totalStateTime += time;
3282                    sb.setLength(0);
3283                    sb.append(prefix);
3284                    sb.append("    ");
3285                    sb.append(Uid.PROCESS_STATE_NAMES[ips]);
3286                    sb.append(" for: ");
3287                    formatTimeMs(sb, (totalStateTime + 500) / 1000);
3288                    pw.println(sb.toString());
3289                    uidActivity = true;
3290                }
3291            }
3292
3293            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
3294            if (processStats.size() > 0) {
3295                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
3296                    : processStats.entrySet()) {
3297                    Uid.Proc ps = ent.getValue();
3298                    long userTime;
3299                    long systemTime;
3300                    long foregroundTime;
3301                    int starts;
3302                    int numExcessive;
3303
3304                    userTime = ps.getUserTime(which);
3305                    systemTime = ps.getSystemTime(which);
3306                    foregroundTime = ps.getForegroundTime(which);
3307                    starts = ps.getStarts(which);
3308                    final int numCrashes = ps.getNumCrashes(which);
3309                    final int numAnrs = ps.getNumAnrs(which);
3310                    numExcessive = which == STATS_SINCE_CHARGED
3311                            ? ps.countExcessivePowers() : 0;
3312
3313                    if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
3314                            || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
3315                        sb.setLength(0);
3316                        sb.append(prefix); sb.append("    Proc ");
3317                                sb.append(ent.getKey()); sb.append(":\n");
3318                        sb.append(prefix); sb.append("      CPU: ");
3319                                formatTime(sb, userTime); sb.append("usr + ");
3320                                formatTime(sb, systemTime); sb.append("krn ; ");
3321                                formatTime(sb, foregroundTime); sb.append("fg");
3322                        if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
3323                            sb.append("\n"); sb.append(prefix); sb.append("      ");
3324                            boolean hasOne = false;
3325                            if (starts != 0) {
3326                                hasOne = true;
3327                                sb.append(starts); sb.append(" starts");
3328                            }
3329                            if (numCrashes != 0) {
3330                                if (hasOne) {
3331                                    sb.append(", ");
3332                                }
3333                                hasOne = true;
3334                                sb.append(numCrashes); sb.append(" crashes");
3335                            }
3336                            if (numAnrs != 0) {
3337                                if (hasOne) {
3338                                    sb.append(", ");
3339                                }
3340                                sb.append(numAnrs); sb.append(" anrs");
3341                            }
3342                        }
3343                        pw.println(sb.toString());
3344                        for (int e=0; e<numExcessive; e++) {
3345                            Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
3346                            if (ew != null) {
3347                                pw.print(prefix); pw.print("      * Killed for ");
3348                                        if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
3349                                            pw.print("wake lock");
3350                                        } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
3351                                            pw.print("cpu");
3352                                        } else {
3353                                            pw.print("unknown");
3354                                        }
3355                                        pw.print(" use: ");
3356                                        TimeUtils.formatDuration(ew.usedTime, pw);
3357                                        pw.print(" over ");
3358                                        TimeUtils.formatDuration(ew.overTime, pw);
3359                                        if (ew.overTime != 0) {
3360                                            pw.print(" (");
3361                                            pw.print((ew.usedTime*100)/ew.overTime);
3362                                            pw.println("%)");
3363                                        }
3364                            }
3365                        }
3366                        uidActivity = true;
3367                    }
3368                }
3369            }
3370
3371            Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
3372            if (packageStats.size() > 0) {
3373                for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
3374                    : packageStats.entrySet()) {
3375                    pw.print(prefix); pw.print("    Apk "); pw.print(ent.getKey()); pw.println(":");
3376                    boolean apkActivity = false;
3377                    Uid.Pkg ps = ent.getValue();
3378                    int wakeups = ps.getWakeups(which);
3379                    if (wakeups != 0) {
3380                        pw.print(prefix); pw.print("      ");
3381                                pw.print(wakeups); pw.println(" wakeup alarms");
3382                        apkActivity = true;
3383                    }
3384                    Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
3385                    if (serviceStats.size() > 0) {
3386                        for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
3387                                : serviceStats.entrySet()) {
3388                            BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
3389                            long startTime = ss.getStartTime(batteryUptime, which);
3390                            int starts = ss.getStarts(which);
3391                            int launches = ss.getLaunches(which);
3392                            if (startTime != 0 || starts != 0 || launches != 0) {
3393                                sb.setLength(0);
3394                                sb.append(prefix); sb.append("      Service ");
3395                                        sb.append(sent.getKey()); sb.append(":\n");
3396                                sb.append(prefix); sb.append("        Created for: ");
3397                                        formatTimeMs(sb, startTime / 1000);
3398                                        sb.append("uptime\n");
3399                                sb.append(prefix); sb.append("        Starts: ");
3400                                        sb.append(starts);
3401                                        sb.append(", launches: "); sb.append(launches);
3402                                pw.println(sb.toString());
3403                                apkActivity = true;
3404                            }
3405                        }
3406                    }
3407                    if (!apkActivity) {
3408                        pw.print(prefix); pw.println("      (nothing executed)");
3409                    }
3410                    uidActivity = true;
3411                }
3412            }
3413            if (!uidActivity) {
3414                pw.print(prefix); pw.println("    (nothing executed)");
3415            }
3416        }
3417    }
3418
3419    static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag,
3420            BitDescription[] descriptions, boolean longNames) {
3421        int diff = oldval ^ newval;
3422        if (diff == 0) return;
3423        boolean didWake = false;
3424        for (int i=0; i<descriptions.length; i++) {
3425            BitDescription bd = descriptions[i];
3426            if ((diff&bd.mask) != 0) {
3427                pw.print(longNames ? " " : ",");
3428                if (bd.shift < 0) {
3429                    pw.print((newval&bd.mask) != 0 ? "+" : "-");
3430                    pw.print(longNames ? bd.name : bd.shortName);
3431                    if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
3432                        didWake = true;
3433                        pw.print("=");
3434                        if (longNames) {
3435                            UserHandle.formatUid(pw, wakelockTag.uid);
3436                            pw.print(":\"");
3437                            pw.print(wakelockTag.string);
3438                            pw.print("\"");
3439                        } else {
3440                            pw.print(wakelockTag.poolIdx);
3441                        }
3442                    }
3443                } else {
3444                    pw.print(longNames ? bd.name : bd.shortName);
3445                    pw.print("=");
3446                    int val = (newval&bd.mask)>>bd.shift;
3447                    if (bd.values != null && val >= 0 && val < bd.values.length) {
3448                        pw.print(longNames? bd.values[val] : bd.shortValues[val]);
3449                    } else {
3450                        pw.print(val);
3451                    }
3452                }
3453            }
3454        }
3455        if (!didWake && wakelockTag != null) {
3456            pw.print(longNames ? " wake_lock=" : ",w=");
3457            if (longNames) {
3458                UserHandle.formatUid(pw, wakelockTag.uid);
3459                pw.print(":\"");
3460                pw.print(wakelockTag.string);
3461                pw.print("\"");
3462            } else {
3463                pw.print(wakelockTag.poolIdx);
3464            }
3465        }
3466    }
3467
3468    public void prepareForDumpLocked() {
3469    }
3470
3471    public static class HistoryPrinter {
3472        int oldState = 0;
3473        int oldState2 = 0;
3474        int oldLevel = -1;
3475        int oldStatus = -1;
3476        int oldHealth = -1;
3477        int oldPlug = -1;
3478        int oldTemp = -1;
3479        int oldVolt = -1;
3480        long lastTime = -1;
3481
3482        void reset() {
3483            oldState = oldState2 = 0;
3484            oldLevel = -1;
3485            oldStatus = -1;
3486            oldHealth = -1;
3487            oldPlug = -1;
3488            oldTemp = -1;
3489            oldVolt = -1;
3490        }
3491
3492        public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
3493                boolean verbose) {
3494            if (!checkin) {
3495                pw.print("  ");
3496                TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
3497                pw.print(" (");
3498                pw.print(rec.numReadInts);
3499                pw.print(") ");
3500            } else {
3501                pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
3502                pw.print(HISTORY_DATA); pw.print(',');
3503                if (lastTime < 0) {
3504                    pw.print(rec.time - baseTime);
3505                } else {
3506                    pw.print(rec.time - lastTime);
3507                }
3508                lastTime = rec.time;
3509            }
3510            if (rec.cmd == HistoryItem.CMD_START) {
3511                if (checkin) {
3512                    pw.print(":");
3513                }
3514                pw.println("START");
3515                reset();
3516            } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
3517                    || rec.cmd == HistoryItem.CMD_RESET) {
3518                if (checkin) {
3519                    pw.print(":");
3520                }
3521                if (rec.cmd == HistoryItem.CMD_RESET) {
3522                    pw.print("RESET:");
3523                    reset();
3524                }
3525                pw.print("TIME:");
3526                if (checkin) {
3527                    pw.println(rec.currentTime);
3528                } else {
3529                    pw.print(" ");
3530                    pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
3531                            rec.currentTime).toString());
3532                }
3533            } else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) {
3534                if (checkin) {
3535                    pw.print(":");
3536                }
3537                pw.println("SHUTDOWN");
3538            } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
3539                if (checkin) {
3540                    pw.print(":");
3541                }
3542                pw.println("*OVERFLOW*");
3543            } else {
3544                if (!checkin) {
3545                    if (rec.batteryLevel < 10) pw.print("00");
3546                    else if (rec.batteryLevel < 100) pw.print("0");
3547                    pw.print(rec.batteryLevel);
3548                    if (verbose) {
3549                        pw.print(" ");
3550                        if (rec.states < 0) ;
3551                        else if (rec.states < 0x10) pw.print("0000000");
3552                        else if (rec.states < 0x100) pw.print("000000");
3553                        else if (rec.states < 0x1000) pw.print("00000");
3554                        else if (rec.states < 0x10000) pw.print("0000");
3555                        else if (rec.states < 0x100000) pw.print("000");
3556                        else if (rec.states < 0x1000000) pw.print("00");
3557                        else if (rec.states < 0x10000000) pw.print("0");
3558                        pw.print(Integer.toHexString(rec.states));
3559                    }
3560                } else {
3561                    if (oldLevel != rec.batteryLevel) {
3562                        oldLevel = rec.batteryLevel;
3563                        pw.print(",Bl="); pw.print(rec.batteryLevel);
3564                    }
3565                }
3566                if (oldStatus != rec.batteryStatus) {
3567                    oldStatus = rec.batteryStatus;
3568                    pw.print(checkin ? ",Bs=" : " status=");
3569                    switch (oldStatus) {
3570                        case BatteryManager.BATTERY_STATUS_UNKNOWN:
3571                            pw.print(checkin ? "?" : "unknown");
3572                            break;
3573                        case BatteryManager.BATTERY_STATUS_CHARGING:
3574                            pw.print(checkin ? "c" : "charging");
3575                            break;
3576                        case BatteryManager.BATTERY_STATUS_DISCHARGING:
3577                            pw.print(checkin ? "d" : "discharging");
3578                            break;
3579                        case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
3580                            pw.print(checkin ? "n" : "not-charging");
3581                            break;
3582                        case BatteryManager.BATTERY_STATUS_FULL:
3583                            pw.print(checkin ? "f" : "full");
3584                            break;
3585                        default:
3586                            pw.print(oldStatus);
3587                            break;
3588                    }
3589                }
3590                if (oldHealth != rec.batteryHealth) {
3591                    oldHealth = rec.batteryHealth;
3592                    pw.print(checkin ? ",Bh=" : " health=");
3593                    switch (oldHealth) {
3594                        case BatteryManager.BATTERY_HEALTH_UNKNOWN:
3595                            pw.print(checkin ? "?" : "unknown");
3596                            break;
3597                        case BatteryManager.BATTERY_HEALTH_GOOD:
3598                            pw.print(checkin ? "g" : "good");
3599                            break;
3600                        case BatteryManager.BATTERY_HEALTH_OVERHEAT:
3601                            pw.print(checkin ? "h" : "overheat");
3602                            break;
3603                        case BatteryManager.BATTERY_HEALTH_DEAD:
3604                            pw.print(checkin ? "d" : "dead");
3605                            break;
3606                        case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
3607                            pw.print(checkin ? "v" : "over-voltage");
3608                            break;
3609                        case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
3610                            pw.print(checkin ? "f" : "failure");
3611                            break;
3612                        case BatteryManager.BATTERY_HEALTH_COLD:
3613                            pw.print(checkin ? "c" : "cold");
3614                            break;
3615                        default:
3616                            pw.print(oldHealth);
3617                            break;
3618                    }
3619                }
3620                if (oldPlug != rec.batteryPlugType) {
3621                    oldPlug = rec.batteryPlugType;
3622                    pw.print(checkin ? ",Bp=" : " plug=");
3623                    switch (oldPlug) {
3624                        case 0:
3625                            pw.print(checkin ? "n" : "none");
3626                            break;
3627                        case BatteryManager.BATTERY_PLUGGED_AC:
3628                            pw.print(checkin ? "a" : "ac");
3629                            break;
3630                        case BatteryManager.BATTERY_PLUGGED_USB:
3631                            pw.print(checkin ? "u" : "usb");
3632                            break;
3633                        case BatteryManager.BATTERY_PLUGGED_WIRELESS:
3634                            pw.print(checkin ? "w" : "wireless");
3635                            break;
3636                        default:
3637                            pw.print(oldPlug);
3638                            break;
3639                    }
3640                }
3641                if (oldTemp != rec.batteryTemperature) {
3642                    oldTemp = rec.batteryTemperature;
3643                    pw.print(checkin ? ",Bt=" : " temp=");
3644                    pw.print(oldTemp);
3645                }
3646                if (oldVolt != rec.batteryVoltage) {
3647                    oldVolt = rec.batteryVoltage;
3648                    pw.print(checkin ? ",Bv=" : " volt=");
3649                    pw.print(oldVolt);
3650                }
3651                printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
3652                        HISTORY_STATE_DESCRIPTIONS, !checkin);
3653                printBitDescriptions(pw, oldState2, rec.states2, null,
3654                        HISTORY_STATE2_DESCRIPTIONS, !checkin);
3655                if (rec.wakeReasonTag != null) {
3656                    if (checkin) {
3657                        pw.print(",wr=");
3658                        pw.print(rec.wakeReasonTag.poolIdx);
3659                    } else {
3660                        pw.print(" wake_reason=");
3661                        pw.print(rec.wakeReasonTag.uid);
3662                        pw.print(":\"");
3663                        pw.print(rec.wakeReasonTag.string);
3664                        pw.print("\"");
3665                    }
3666                }
3667                if (rec.eventCode != HistoryItem.EVENT_NONE) {
3668                    pw.print(checkin ? "," : " ");
3669                    if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
3670                        pw.print("+");
3671                    } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
3672                        pw.print("-");
3673                    }
3674                    String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
3675                            : HISTORY_EVENT_NAMES;
3676                    int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
3677                            | HistoryItem.EVENT_FLAG_FINISH);
3678                    if (idx >= 0 && idx < eventNames.length) {
3679                        pw.print(eventNames[idx]);
3680                    } else {
3681                        pw.print(checkin ? "Ev" : "event");
3682                        pw.print(idx);
3683                    }
3684                    pw.print("=");
3685                    if (checkin) {
3686                        pw.print(rec.eventTag.poolIdx);
3687                    } else {
3688                        UserHandle.formatUid(pw, rec.eventTag.uid);
3689                        pw.print(":\"");
3690                        pw.print(rec.eventTag.string);
3691                        pw.print("\"");
3692                    }
3693                }
3694                pw.println();
3695                oldState = rec.states;
3696                oldState2 = rec.states2;
3697            }
3698        }
3699    }
3700
3701    private void printSizeValue(PrintWriter pw, long size) {
3702        float result = size;
3703        String suffix = "";
3704        if (result >= 10*1024) {
3705            suffix = "KB";
3706            result = result / 1024;
3707        }
3708        if (result >= 10*1024) {
3709            suffix = "MB";
3710            result = result / 1024;
3711        }
3712        if (result >= 10*1024) {
3713            suffix = "GB";
3714            result = result / 1024;
3715        }
3716        if (result >= 10*1024) {
3717            suffix = "TB";
3718            result = result / 1024;
3719        }
3720        if (result >= 10*1024) {
3721            suffix = "PB";
3722            result = result / 1024;
3723        }
3724        pw.print((int)result);
3725        pw.print(suffix);
3726    }
3727
3728    private static boolean dumpTimeEstimate(PrintWriter pw, String label, long[] steps,
3729            int count, long modesOfInterest, long modeValues) {
3730        if (count <= 0) {
3731            return false;
3732        }
3733        long total = 0;
3734        int numOfInterest = 0;
3735        for (int i=0; i<count; i++) {
3736            long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK)
3737                    >> STEP_LEVEL_INITIAL_MODE_SHIFT;
3738            long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK)
3739                    >> STEP_LEVEL_MODIFIED_MODE_SHIFT;
3740            // If the modes of interest didn't change during this step period...
3741            if ((modMode&modesOfInterest) == 0) {
3742                // And the mode values during this period match those we are measuring...
3743                if ((initMode&modesOfInterest) == modeValues) {
3744                    // Then this can be used to estimate the total time!
3745                    numOfInterest++;
3746                    total += steps[i] & STEP_LEVEL_TIME_MASK;
3747                }
3748            }
3749        }
3750        if (numOfInterest <= 0) {
3751            return false;
3752        }
3753
3754        // The estimated time is the average time we spend in each level, multipled
3755        // by 100 -- the total number of battery levels
3756        long estimatedTime = (total / numOfInterest) * 100;
3757
3758        pw.print(label);
3759        StringBuilder sb = new StringBuilder(64);
3760        formatTimeMs(sb, estimatedTime);
3761        pw.print(sb);
3762        pw.println();
3763
3764        return true;
3765    }
3766
3767    private static boolean dumpDurationSteps(PrintWriter pw, String header, long[] steps,
3768            int count, boolean checkin) {
3769        if (count <= 0) {
3770            return false;
3771        }
3772        if (!checkin) {
3773            pw.println(header);
3774        }
3775        String[] lineArgs = new String[4];
3776        for (int i=0; i<count; i++) {
3777            long duration = steps[i] & STEP_LEVEL_TIME_MASK;
3778            int level = (int)((steps[i] & STEP_LEVEL_LEVEL_MASK)
3779                    >> STEP_LEVEL_LEVEL_SHIFT);
3780            long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK)
3781                    >> STEP_LEVEL_INITIAL_MODE_SHIFT;
3782            long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK)
3783                    >> STEP_LEVEL_MODIFIED_MODE_SHIFT;
3784            if (checkin) {
3785                lineArgs[0] = Long.toString(duration);
3786                lineArgs[1] = Integer.toString(level);
3787                if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
3788                    switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
3789                        case Display.STATE_OFF: lineArgs[2] = "s-"; break;
3790                        case Display.STATE_ON: lineArgs[2] = "s+"; break;
3791                        case Display.STATE_DOZE: lineArgs[2] = "sd"; break;
3792                        case Display.STATE_DOZE_SUSPEND: lineArgs[2] = "sds"; break;
3793                        default: lineArgs[1] = "?"; break;
3794                    }
3795                } else {
3796                    lineArgs[2] = "";
3797                }
3798                if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
3799                    lineArgs[3] = (initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 ? "p+" : "p-";
3800                } else {
3801                    lineArgs[3] = "";
3802                }
3803                dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs);
3804            } else {
3805                pw.print("  #"); pw.print(i); pw.print(": ");
3806                TimeUtils.formatDuration(duration, pw);
3807                pw.print(" to "); pw.print(level);
3808                boolean haveModes = false;
3809                if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
3810                    pw.print(" (");
3811                    switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
3812                        case Display.STATE_OFF: pw.print("screen-off"); break;
3813                        case Display.STATE_ON: pw.print("screen-on"); break;
3814                        case Display.STATE_DOZE: pw.print("screen-doze"); break;
3815                        case Display.STATE_DOZE_SUSPEND: pw.print("screen-doze-suspend"); break;
3816                        default: lineArgs[1] = "screen-?"; break;
3817                    }
3818                    haveModes = true;
3819                }
3820                if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
3821                    pw.print(haveModes ? ", " : " (");
3822                    pw.print((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0
3823                            ? "power-save-on" : "power-save-off");
3824                    haveModes = true;
3825                }
3826                if (haveModes) {
3827                    pw.print(")");
3828                }
3829                pw.println();
3830            }
3831        }
3832        return true;
3833    }
3834
3835    public static final int DUMP_UNPLUGGED_ONLY = 1<<0;
3836    public static final int DUMP_CHARGED_ONLY = 1<<1;
3837    public static final int DUMP_HISTORY_ONLY = 1<<2;
3838    public static final int DUMP_INCLUDE_HISTORY = 1<<3;
3839    public static final int DUMP_VERBOSE = 1<<4;
3840    public static final int DUMP_DEVICE_WIFI_ONLY = 1<<5;
3841
3842    private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
3843        final HistoryPrinter hprinter = new HistoryPrinter();
3844        final HistoryItem rec = new HistoryItem();
3845        long lastTime = -1;
3846        long baseTime = -1;
3847        boolean printed = false;
3848        HistoryEventTracker tracker = null;
3849        while (getNextHistoryLocked(rec)) {
3850            lastTime = rec.time;
3851            if (baseTime < 0) {
3852                baseTime = lastTime;
3853            }
3854            if (rec.time >= histStart) {
3855                if (histStart >= 0 && !printed) {
3856                    if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
3857                            || rec.cmd == HistoryItem.CMD_RESET
3858                            || rec.cmd == HistoryItem.CMD_START
3859                            || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
3860                        printed = true;
3861                        hprinter.printNextItem(pw, rec, baseTime, checkin,
3862                                (flags&DUMP_VERBOSE) != 0);
3863                        rec.cmd = HistoryItem.CMD_UPDATE;
3864                    } else if (rec.currentTime != 0) {
3865                        printed = true;
3866                        byte cmd = rec.cmd;
3867                        rec.cmd = HistoryItem.CMD_CURRENT_TIME;
3868                        hprinter.printNextItem(pw, rec, baseTime, checkin,
3869                                (flags&DUMP_VERBOSE) != 0);
3870                        rec.cmd = cmd;
3871                    }
3872                    if (tracker != null) {
3873                        if (rec.cmd != HistoryItem.CMD_UPDATE) {
3874                            hprinter.printNextItem(pw, rec, baseTime, checkin,
3875                                    (flags&DUMP_VERBOSE) != 0);
3876                            rec.cmd = HistoryItem.CMD_UPDATE;
3877                        }
3878                        int oldEventCode = rec.eventCode;
3879                        HistoryTag oldEventTag = rec.eventTag;
3880                        rec.eventTag = new HistoryTag();
3881                        for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
3882                            HashMap<String, SparseIntArray> active
3883                                    = tracker.getStateForEvent(i);
3884                            if (active == null) {
3885                                continue;
3886                            }
3887                            for (HashMap.Entry<String, SparseIntArray> ent
3888                                    : active.entrySet()) {
3889                                SparseIntArray uids = ent.getValue();
3890                                for (int j=0; j<uids.size(); j++) {
3891                                    rec.eventCode = i;
3892                                    rec.eventTag.string = ent.getKey();
3893                                    rec.eventTag.uid = uids.keyAt(j);
3894                                    rec.eventTag.poolIdx = uids.valueAt(j);
3895                                    hprinter.printNextItem(pw, rec, baseTime, checkin,
3896                                            (flags&DUMP_VERBOSE) != 0);
3897                                    rec.wakeReasonTag = null;
3898                                    rec.wakelockTag = null;
3899                                }
3900                            }
3901                        }
3902                        rec.eventCode = oldEventCode;
3903                        rec.eventTag = oldEventTag;
3904                        tracker = null;
3905                    }
3906                }
3907                hprinter.printNextItem(pw, rec, baseTime, checkin,
3908                        (flags&DUMP_VERBOSE) != 0);
3909            } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) {
3910                // This is an attempt to aggregate the previous state and generate
3911                // fake events to reflect that state at the point where we start
3912                // printing real events.  It doesn't really work right, so is turned off.
3913                if (tracker == null) {
3914                    tracker = new HistoryEventTracker();
3915                }
3916                tracker.updateState(rec.eventCode, rec.eventTag.string,
3917                        rec.eventTag.uid, rec.eventTag.poolIdx);
3918            }
3919        }
3920        if (histStart >= 0) {
3921            commitCurrentHistoryBatchLocked();
3922            pw.print(checkin ? "NEXT: " : "  NEXT: "); pw.println(lastTime+1);
3923        }
3924    }
3925
3926    /**
3927     * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
3928     *
3929     * @param pw a Printer to receive the dump output.
3930     */
3931    @SuppressWarnings("unused")
3932    public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
3933        prepareForDumpLocked();
3934
3935        final boolean filtering =
3936                (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;
3937
3938        if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
3939            final long historyTotalSize = getHistoryTotalSize();
3940            final long historyUsedSize = getHistoryUsedSize();
3941            if (startIteratingHistoryLocked()) {
3942                try {
3943                    pw.print("Battery History (");
3944                    pw.print((100*historyUsedSize)/historyTotalSize);
3945                    pw.print("% used, ");
3946                    printSizeValue(pw, historyUsedSize);
3947                    pw.print(" used of ");
3948                    printSizeValue(pw, historyTotalSize);
3949                    pw.print(", ");
3950                    pw.print(getHistoryStringPoolSize());
3951                    pw.print(" strings using ");
3952                    printSizeValue(pw, getHistoryStringPoolBytes());
3953                    pw.println("):");
3954                    dumpHistoryLocked(pw, flags, histStart, false);
3955                    pw.println();
3956                } finally {
3957                    finishIteratingHistoryLocked();
3958                }
3959            }
3960
3961            if (startIteratingOldHistoryLocked()) {
3962                try {
3963                    final HistoryItem rec = new HistoryItem();
3964                    pw.println("Old battery History:");
3965                    HistoryPrinter hprinter = new HistoryPrinter();
3966                    long baseTime = -1;
3967                    while (getNextOldHistoryLocked(rec)) {
3968                        if (baseTime < 0) {
3969                            baseTime = rec.time;
3970                        }
3971                        hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0);
3972                    }
3973                    pw.println();
3974                } finally {
3975                    finishIteratingOldHistoryLocked();
3976                }
3977            }
3978        }
3979
3980        if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) {
3981            return;
3982        }
3983
3984        if (!filtering) {
3985            SparseArray<? extends Uid> uidStats = getUidStats();
3986            final int NU = uidStats.size();
3987            boolean didPid = false;
3988            long nowRealtime = SystemClock.elapsedRealtime();
3989            for (int i=0; i<NU; i++) {
3990                Uid uid = uidStats.valueAt(i);
3991                SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
3992                if (pids != null) {
3993                    for (int j=0; j<pids.size(); j++) {
3994                        Uid.Pid pid = pids.valueAt(j);
3995                        if (!didPid) {
3996                            pw.println("Per-PID Stats:");
3997                            didPid = true;
3998                        }
3999                        long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
4000                                ? (nowRealtime - pid.mWakeStartMs) : 0);
4001                        pw.print("  PID "); pw.print(pids.keyAt(j));
4002                                pw.print(" wake time: ");
4003                                TimeUtils.formatDuration(time, pw);
4004                                pw.println("");
4005                    }
4006                }
4007            }
4008            if (didPid) {
4009                pw.println();
4010            }
4011        }
4012
4013        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
4014            if (dumpDurationSteps(pw, "Discharge step durations:", getDischargeStepDurationsArray(),
4015                    getNumDischargeStepDurations(), false)) {
4016                long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
4017                if (timeRemaining >= 0) {
4018                    pw.print("  Estimated discharge time remaining: ");
4019                    TimeUtils.formatDuration(timeRemaining / 1000, pw);
4020                    pw.println();
4021                }
4022                dumpTimeEstimate(pw, "  Estimated screen off time: ",
4023                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
4024                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
4025                        (Display.STATE_OFF-1));
4026                dumpTimeEstimate(pw, "  Estimated screen off power save time: ",
4027                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
4028                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
4029                        (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE);
4030                dumpTimeEstimate(pw, "  Estimated screen on time: ",
4031                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
4032                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
4033                        (Display.STATE_ON-1));
4034                dumpTimeEstimate(pw, "  Estimated screen on power save time: ",
4035                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
4036                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
4037                        (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE);
4038                dumpTimeEstimate(pw, "  Estimated screen doze time: ",
4039                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
4040                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
4041                        (Display.STATE_DOZE-1));
4042                dumpTimeEstimate(pw, "  Estimated screen doze power save time: ",
4043                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
4044                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
4045                        (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE);
4046                dumpTimeEstimate(pw, "  Estimated screen doze suspend time: ",
4047                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
4048                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
4049                        (Display.STATE_DOZE_SUSPEND-1));
4050                dumpTimeEstimate(pw, "  Estimated screen doze suspend power save time: ",
4051                        getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
4052                        STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
4053                        (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE);
4054                pw.println();
4055            }
4056            if (dumpDurationSteps(pw, "Charge step durations:", getChargeStepDurationsArray(),
4057                    getNumChargeStepDurations(), false)) {
4058                long timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
4059                if (timeRemaining >= 0) {
4060                    pw.print("  Estimated charge time remaining: ");
4061                    TimeUtils.formatDuration(timeRemaining / 1000, pw);
4062                    pw.println();
4063                }
4064                pw.println();
4065            }
4066            pw.println("Statistics since last charge:");
4067            pw.println("  System starts: " + getStartCount()
4068                    + ", currently on battery: " + getIsOnBattery());
4069            dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
4070                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
4071            pw.println();
4072        }
4073        if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
4074            pw.println("Statistics since last unplugged:");
4075            dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid,
4076                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
4077        }
4078    }
4079
4080    @SuppressWarnings("unused")
4081    public void dumpCheckinLocked(Context context, PrintWriter pw,
4082            List<ApplicationInfo> apps, int flags, long histStart) {
4083        prepareForDumpLocked();
4084
4085        dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
4086                "11", getParcelVersion(), getStartPlatformVersion(), getEndPlatformVersion());
4087
4088        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
4089
4090        final boolean filtering =
4091                (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;
4092
4093        if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) {
4094            if (startIteratingHistoryLocked()) {
4095                try {
4096                    for (int i=0; i<getHistoryStringPoolSize(); i++) {
4097                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
4098                        pw.print(HISTORY_STRING_POOL); pw.print(',');
4099                        pw.print(i);
4100                        pw.print(",");
4101                        pw.print(getHistoryTagPoolUid(i));
4102                        pw.print(",\"");
4103                        String str = getHistoryTagPoolString(i);
4104                        str = str.replace("\\", "\\\\");
4105                        str = str.replace("\"", "\\\"");
4106                        pw.print(str);
4107                        pw.print("\"");
4108                        pw.println();
4109                    }
4110                    dumpHistoryLocked(pw, flags, histStart, true);
4111                } finally {
4112                    finishIteratingHistoryLocked();
4113                }
4114            }
4115        }
4116
4117        if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) {
4118            return;
4119        }
4120
4121        if (apps != null) {
4122            SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
4123            for (int i=0; i<apps.size(); i++) {
4124                ApplicationInfo ai = apps.get(i);
4125                ArrayList<String> pkgs = uids.get(ai.uid);
4126                if (pkgs == null) {
4127                    pkgs = new ArrayList<String>();
4128                    uids.put(ai.uid, pkgs);
4129                }
4130                pkgs.add(ai.packageName);
4131            }
4132            SparseArray<? extends Uid> uidStats = getUidStats();
4133            final int NU = uidStats.size();
4134            String[] lineArgs = new String[2];
4135            for (int i=0; i<NU; i++) {
4136                int uid = uidStats.keyAt(i);
4137                ArrayList<String> pkgs = uids.get(uid);
4138                if (pkgs != null) {
4139                    for (int j=0; j<pkgs.size(); j++) {
4140                        lineArgs[0] = Integer.toString(uid);
4141                        lineArgs[1] = pkgs.get(j);
4142                        dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
4143                                (Object[])lineArgs);
4144                    }
4145                }
4146            }
4147        }
4148        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
4149            dumpDurationSteps(pw, DISCHARGE_STEP_DATA, getDischargeStepDurationsArray(),
4150                    getNumDischargeStepDurations(), true);
4151            String[] lineArgs = new String[1];
4152            long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
4153            if (timeRemaining >= 0) {
4154                lineArgs[0] = Long.toString(timeRemaining);
4155                dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA,
4156                        (Object[])lineArgs);
4157            }
4158            dumpDurationSteps(pw, CHARGE_STEP_DATA, getChargeStepDurationsArray(),
4159                    getNumChargeStepDurations(), true);
4160            timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
4161            if (timeRemaining >= 0) {
4162                lineArgs[0] = Long.toString(timeRemaining);
4163                dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA,
4164                        (Object[])lineArgs);
4165            }
4166            dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
4167                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
4168        }
4169        if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
4170            dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1,
4171                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
4172        }
4173    }
4174}
4175