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