BatteryStats.java revision 099bc627c463d9941e23e480f25a78a154429c55
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.List;
25import java.util.Map;
26
27import android.content.Context;
28import android.content.pm.ApplicationInfo;
29import android.telephony.SignalStrength;
30import android.util.Printer;
31import android.util.SparseArray;
32import android.util.TimeUtils;
33import com.android.internal.os.BatterySipper;
34import com.android.internal.os.BatteryStatsHelper;
35
36/**
37 * A class providing access to battery usage statistics, including information on
38 * wakelocks, processes, packages, and services.  All times are represented in microseconds
39 * except where indicated otherwise.
40 * @hide
41 */
42public abstract class BatteryStats implements Parcelable {
43
44    private static final boolean LOCAL_LOGV = false;
45
46    /** @hide */
47    public static final String SERVICE_NAME = "batterystats";
48
49    /**
50     * A constant indicating a partial wake lock timer.
51     */
52    public static final int WAKE_TYPE_PARTIAL = 0;
53
54    /**
55     * A constant indicating a full wake lock timer.
56     */
57    public static final int WAKE_TYPE_FULL = 1;
58
59    /**
60     * A constant indicating a window wake lock timer.
61     */
62    public static final int WAKE_TYPE_WINDOW = 2;
63
64    /**
65     * A constant indicating a sensor timer.
66     */
67    public static final int SENSOR = 3;
68
69    /**
70     * A constant indicating a a wifi running timer
71     */
72    public static final int WIFI_RUNNING = 4;
73
74    /**
75     * A constant indicating a full wifi lock timer
76     */
77    public static final int FULL_WIFI_LOCK = 5;
78
79    /**
80     * A constant indicating a wifi scan
81     */
82    public static final int WIFI_SCAN = 6;
83
84     /**
85      * A constant indicating a wifi multicast timer
86      */
87     public static final int WIFI_MULTICAST_ENABLED = 7;
88
89    /**
90     * A constant indicating an audio turn on timer
91     */
92    public static final int AUDIO_TURNED_ON = 7;
93
94    /**
95     * A constant indicating a video turn on timer
96     */
97    public static final int VIDEO_TURNED_ON = 8;
98
99    /**
100     * A constant indicating a vibrator on timer
101     */
102    public static final int VIBRATOR_ON = 9;
103
104    /**
105     * A constant indicating a foreground activity timer
106     */
107    public static final int FOREGROUND_ACTIVITY = 10;
108
109    /**
110     * A constant indicating a wifi batched scan is active
111     */
112    public static final int WIFI_BATCHED_SCAN = 11;
113
114    /**
115     * Include all of the data in the stats, including previously saved data.
116     */
117    public static final int STATS_SINCE_CHARGED = 0;
118
119    /**
120     * Include only the last run in the stats.
121     */
122    public static final int STATS_LAST = 1;
123
124    /**
125     * Include only the current run in the stats.
126     */
127    public static final int STATS_CURRENT = 2;
128
129    /**
130     * Include only the run since the last time the device was unplugged in the stats.
131     */
132    public static final int STATS_SINCE_UNPLUGGED = 3;
133
134    // NOTE: Update this list if you add/change any stats above.
135    // These characters are supposed to represent "total", "last", "current",
136    // and "unplugged". They were shortened for efficiency sake.
137    private static final String[] STAT_NAMES = { "t", "l", "c", "u" };
138
139    /**
140     * Bump the version on this if the checkin format changes.
141     */
142    private static final int BATTERY_STATS_CHECKIN_VERSION = 7;
143
144    private static final long BYTES_PER_KB = 1024;
145    private static final long BYTES_PER_MB = 1048576; // 1024^2
146    private static final long BYTES_PER_GB = 1073741824; //1024^3
147
148
149    private static final String UID_DATA = "uid";
150    private static final String APK_DATA = "apk";
151    private static final String PROCESS_DATA = "pr";
152    private static final String SENSOR_DATA = "sr";
153    private static final String VIBRATOR_DATA = "vib";
154    private static final String FOREGROUND_DATA = "fg";
155    private static final String WAKELOCK_DATA = "wl";
156    private static final String KERNEL_WAKELOCK_DATA = "kwl";
157    private static final String NETWORK_DATA = "nt";
158    private static final String USER_ACTIVITY_DATA = "ua";
159    private static final String BATTERY_DATA = "bt";
160    private static final String BATTERY_DISCHARGE_DATA = "dc";
161    private static final String BATTERY_LEVEL_DATA = "lv";
162    private static final String WIFI_DATA = "wfl";
163    private static final String MISC_DATA = "m";
164    private static final String GLOBAL_NETWORK_DATA = "gn";
165    private static final String HISTORY_STRING_POOL = "hsp";
166    private static final String HISTORY_DATA = "h";
167    private static final String SCREEN_BRIGHTNESS_DATA = "br";
168    private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
169    private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
170    private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
171    private static final String DATA_CONNECTION_TIME_DATA = "dct";
172    private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
173    private static final String POWER_USE_SUMMARY_DATA = "pws";
174    private static final String POWER_USE_ITEM_DATA = "pwi";
175
176    private final StringBuilder mFormatBuilder = new StringBuilder(32);
177    private final Formatter mFormatter = new Formatter(mFormatBuilder);
178
179    /**
180     * State for keeping track of counting information.
181     */
182    public static abstract class Counter {
183
184        /**
185         * Returns the count associated with this Counter for the
186         * selected type of statistics.
187         *
188         * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
189         */
190        public abstract int getCountLocked(int which);
191
192        /**
193         * Temporary for debugging.
194         */
195        public abstract void logState(Printer pw, String prefix);
196    }
197
198    /**
199     * State for keeping track of timing information.
200     */
201    public static abstract class Timer {
202
203        /**
204         * Returns the count associated with this Timer for the
205         * selected type of statistics.
206         *
207         * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
208         */
209        public abstract int getCountLocked(int which);
210
211        /**
212         * Returns the total time in microseconds associated with this Timer for the
213         * selected type of statistics.
214         *
215         * @param batteryRealtime system realtime on  battery in microseconds
216         * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
217         * @return a time in microseconds
218         */
219        public abstract long getTotalTimeLocked(long batteryRealtime, int which);
220
221        /**
222         * Temporary for debugging.
223         */
224        public abstract void logState(Printer pw, String prefix);
225    }
226
227    /**
228     * The statistics associated with a particular uid.
229     */
230    public static abstract class Uid {
231
232        /**
233         * Returns a mapping containing wakelock statistics.
234         *
235         * @return a Map from Strings to Uid.Wakelock objects.
236         */
237        public abstract Map<String, ? extends Wakelock> getWakelockStats();
238
239        /**
240         * The statistics associated with a particular wake lock.
241         */
242        public static abstract class Wakelock {
243            public abstract Timer getWakeTime(int type);
244        }
245
246        /**
247         * Returns a mapping containing sensor statistics.
248         *
249         * @return a Map from Integer sensor ids to Uid.Sensor objects.
250         */
251        public abstract Map<Integer, ? extends Sensor> getSensorStats();
252
253        /**
254         * Returns a mapping containing active process data.
255         */
256        public abstract SparseArray<? extends Pid> getPidStats();
257
258        /**
259         * Returns a mapping containing process statistics.
260         *
261         * @return a Map from Strings to Uid.Proc objects.
262         */
263        public abstract Map<String, ? extends Proc> getProcessStats();
264
265        /**
266         * Returns a mapping containing package statistics.
267         *
268         * @return a Map from Strings to Uid.Pkg objects.
269         */
270        public abstract Map<String, ? extends Pkg> getPackageStats();
271
272        /**
273         * {@hide}
274         */
275        public abstract int getUid();
276
277        public abstract void noteWifiRunningLocked();
278        public abstract void noteWifiStoppedLocked();
279        public abstract void noteFullWifiLockAcquiredLocked();
280        public abstract void noteFullWifiLockReleasedLocked();
281        public abstract void noteWifiScanStartedLocked();
282        public abstract void noteWifiScanStoppedLocked();
283        public abstract void noteWifiBatchedScanStartedLocked(int csph);
284        public abstract void noteWifiBatchedScanStoppedLocked();
285        public abstract void noteWifiMulticastEnabledLocked();
286        public abstract void noteWifiMulticastDisabledLocked();
287        public abstract void noteAudioTurnedOnLocked();
288        public abstract void noteAudioTurnedOffLocked();
289        public abstract void noteVideoTurnedOnLocked();
290        public abstract void noteVideoTurnedOffLocked();
291        public abstract void noteActivityResumedLocked();
292        public abstract void noteActivityPausedLocked();
293        public abstract long getWifiRunningTime(long batteryRealtime, int which);
294        public abstract long getFullWifiLockTime(long batteryRealtime, int which);
295        public abstract long getWifiScanTime(long batteryRealtime, int which);
296        public abstract long getWifiBatchedScanTime(int csphBin, long batteryRealtime, int which);
297        public abstract long getWifiMulticastTime(long batteryRealtime,
298                                                  int which);
299        public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
300        public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
301        public abstract Timer getForegroundActivityTimer();
302        public abstract Timer getVibratorOnTimer();
303
304        public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5;
305
306        /**
307         * Note that these must match the constants in android.os.PowerManager.
308         * Also, if the user activity types change, the BatteryStatsImpl.VERSION must
309         * also be bumped.
310         */
311        static final String[] USER_ACTIVITY_TYPES = {
312            "other", "button", "touch"
313        };
314
315        public static final int NUM_USER_ACTIVITY_TYPES = 3;
316
317        public abstract void noteUserActivityLocked(int type);
318        public abstract boolean hasUserActivity();
319        public abstract int getUserActivityCount(int type, int which);
320
321        public abstract boolean hasNetworkActivity();
322        public abstract long getNetworkActivityBytes(int type, int which);
323        public abstract long getNetworkActivityPackets(int type, int which);
324
325        public static abstract class Sensor {
326            /*
327             * FIXME: it's not correct to use this magic value because it
328             * could clash with a sensor handle (which are defined by
329             * the sensor HAL, and therefore out of our control
330             */
331            // Magic sensor number for the GPS.
332            public static final int GPS = -10000;
333
334            public abstract int getHandle();
335
336            public abstract Timer getSensorTime();
337        }
338
339        public class Pid {
340            public long mWakeSum;
341            public long mWakeStart;
342        }
343
344        /**
345         * The statistics associated with a particular process.
346         */
347        public static abstract class Proc {
348
349            public static class ExcessivePower {
350                public static final int TYPE_WAKE = 1;
351                public static final int TYPE_CPU = 2;
352
353                public int type;
354                public long overTime;
355                public long usedTime;
356            }
357
358            /**
359             * Returns true if this process is still active in the battery stats.
360             */
361            public abstract boolean isActive();
362
363            /**
364             * Returns the total time (in 1/100 sec) spent executing in user code.
365             *
366             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
367             */
368            public abstract long getUserTime(int which);
369
370            /**
371             * Returns the total time (in 1/100 sec) spent executing in system code.
372             *
373             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
374             */
375            public abstract long getSystemTime(int which);
376
377            /**
378             * Returns the number of times the process has been started.
379             *
380             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
381             */
382            public abstract int getStarts(int which);
383
384            /**
385             * Returns the cpu time spent in microseconds while the process was in the foreground.
386             * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
387             * @return foreground cpu time in microseconds
388             */
389            public abstract long getForegroundTime(int which);
390
391            /**
392             * Returns the approximate cpu time spent in microseconds, at a certain CPU speed.
393             * @param speedStep the index of the CPU speed. This is not the actual speed of the
394             * CPU.
395             * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
396             * @see BatteryStats#getCpuSpeedSteps()
397             */
398            public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
399
400            public abstract int countExcessivePowers();
401
402            public abstract ExcessivePower getExcessivePower(int i);
403        }
404
405        /**
406         * The statistics associated with a particular package.
407         */
408        public static abstract class Pkg {
409
410            /**
411             * Returns the number of times this package has done something that could wake up the
412             * device from sleep.
413             *
414             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
415             */
416            public abstract int getWakeups(int which);
417
418            /**
419             * Returns a mapping containing service statistics.
420             */
421            public abstract Map<String, ? extends Serv> getServiceStats();
422
423            /**
424             * The statistics associated with a particular service.
425             */
426            public abstract class Serv {
427
428                /**
429                 * Returns the amount of time spent started.
430                 *
431                 * @param batteryUptime elapsed uptime on battery in microseconds.
432                 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
433                 * @return
434                 */
435                public abstract long getStartTime(long batteryUptime, int which);
436
437                /**
438                 * Returns the total number of times startService() has been called.
439                 *
440                 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
441                 */
442                public abstract int getStarts(int which);
443
444                /**
445                 * Returns the total number times the service has been launched.
446                 *
447                 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
448                 */
449                public abstract int getLaunches(int which);
450            }
451        }
452    }
453
454    public final static class HistoryItem implements Parcelable {
455        public HistoryItem next;
456
457        public long time;
458
459        // The command codes 0-3 can be written with delta updates; all others require
460        // that a full entry be written.
461        public static final byte CMD_UPDATE = 0;
462        public static final byte CMD_EVENT = 1;
463        public static final byte CMD_NULL = -1;
464        public static final byte CMD_START = 4;
465        public static final byte CMD_OVERFLOW = 5;
466
467        public byte cmd = CMD_NULL;
468
469        /**
470         * Return whether the command code is a delta data update.
471         */
472        public static boolean isDeltaData(byte cmd) {
473            return cmd >= 0 && cmd <= 3;
474        }
475
476        /**
477         * Return whether the command code is a delta data update.
478         */
479        public boolean isDeltaData() {
480            return cmd >= 0 && cmd <= 3;
481        }
482
483        public byte batteryLevel;
484        public byte batteryStatus;
485        public byte batteryHealth;
486        public byte batteryPlugType;
487
488        public short batteryTemperature;
489        public char batteryVoltage;
490
491        // Constants from SCREEN_BRIGHTNESS_*
492        public static final int STATE_BRIGHTNESS_SHIFT = 0;
493        public static final int STATE_BRIGHTNESS_MASK = 0x7;
494        // Constants from SIGNAL_STRENGTH_*
495        public static final int STATE_SIGNAL_STRENGTH_SHIFT = 3;
496        public static final int STATE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_SIGNAL_STRENGTH_SHIFT;
497        // Constants from ServiceState.STATE_*
498        public static final int STATE_PHONE_STATE_SHIFT = 6;
499        public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT;
500        // Constants from DATA_CONNECTION_*
501        public static final int STATE_DATA_CONNECTION_SHIFT = 9;
502        public static final int STATE_DATA_CONNECTION_MASK = 0x1f;
503
504        // These states always appear directly in the first int token
505        // of a delta change; they should be ones that change relatively
506        // frequently.
507        public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
508        public static final int STATE_SENSOR_ON_FLAG = 1<<29;
509        public static final int STATE_GPS_ON_FLAG = 1<<28;
510        public static final int STATE_PHONE_SCANNING_FLAG = 1<<27;
511        public static final int STATE_WIFI_RUNNING_FLAG = 1<<26;
512        public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<25;
513        public static final int STATE_WIFI_SCAN_FLAG = 1<<24;
514        public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<23;
515        // These are on the lower bits used for the command; if they change
516        // we need to write another int of data.
517        public static final int STATE_AUDIO_ON_FLAG = 1<<22;
518        public static final int STATE_VIDEO_ON_FLAG = 1<<21;
519        public static final int STATE_SCREEN_ON_FLAG = 1<<20;
520        public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19;
521        public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18;
522        public static final int STATE_WIFI_ON_FLAG = 1<<17;
523        public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16;
524
525        public static final int MOST_INTERESTING_STATES =
526            STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG
527            | STATE_GPS_ON_FLAG | STATE_PHONE_IN_CALL_FLAG;
528
529        public int states;
530
531        public static final int EVENT_NONE = 0;
532        public static final int EVENT_PROC_STARTED = 1;
533        public static final int EVENT_PROC_FINISHED = 2;
534
535        // For CMD_EVENT.
536        public int eventCode;
537        public String eventName;
538        public int eventNameIdx;    // only filled in when iterating.
539        public int eventUid;
540
541        public HistoryItem() {
542        }
543
544        public HistoryItem(long time, Parcel src) {
545            this.time = time;
546            readFromParcel(src);
547        }
548
549        public int describeContents() {
550            return 0;
551        }
552
553        public void writeToParcel(Parcel dest, int flags) {
554            dest.writeLong(time);
555            int bat = (((int)cmd)&0xff)
556                    | ((((int)batteryLevel)<<8)&0xff00)
557                    | ((((int)batteryStatus)<<16)&0xf0000)
558                    | ((((int)batteryHealth)<<20)&0xf00000)
559                    | ((((int)batteryPlugType)<<24)&0xf000000);
560            dest.writeInt(bat);
561            bat = (((int)batteryTemperature)&0xffff)
562                    | ((((int)batteryVoltage)<<16)&0xffff0000);
563            dest.writeInt(bat);
564            dest.writeInt(states);
565            if (cmd == CMD_EVENT) {
566                dest.writeInt(eventCode);
567                dest.writeInt(eventUid);
568                dest.writeString(eventName);
569            }
570        }
571
572        public void readFromParcel(Parcel src) {
573            int bat = src.readInt();
574            cmd = (byte)(bat&0xff);
575            batteryLevel = (byte)((bat>>8)&0xff);
576            batteryStatus = (byte)((bat>>16)&0xf);
577            batteryHealth = (byte)((bat>>20)&0xf);
578            batteryPlugType = (byte)((bat>>24)&0xf);
579            bat = src.readInt();
580            batteryTemperature = (short)(bat&0xffff);
581            batteryVoltage = (char)((bat>>16)&0xffff);
582            states = src.readInt();
583            if (cmd == CMD_EVENT) {
584                eventCode = src.readInt();
585                eventUid = src.readInt();
586                eventName = src.readString();
587                eventNameIdx = 0;
588            } else {
589                eventCode = EVENT_NONE;
590            }
591        }
592
593        public void clear() {
594            time = 0;
595            cmd = CMD_NULL;
596            batteryLevel = 0;
597            batteryStatus = 0;
598            batteryHealth = 0;
599            batteryPlugType = 0;
600            batteryTemperature = 0;
601            batteryVoltage = 0;
602            states = 0;
603            eventCode = EVENT_NONE;
604            eventUid = 0;
605            eventName = null;
606        }
607
608        public void setTo(HistoryItem o) {
609            time = o.time;
610            cmd = o.cmd;
611            batteryLevel = o.batteryLevel;
612            batteryStatus = o.batteryStatus;
613            batteryHealth = o.batteryHealth;
614            batteryPlugType = o.batteryPlugType;
615            batteryTemperature = o.batteryTemperature;
616            batteryVoltage = o.batteryVoltage;
617            states = o.states;
618            eventCode = o.eventCode;
619            eventUid = o.eventUid;
620            eventName = o.eventName;
621            eventNameIdx = o.eventNameIdx;
622        }
623
624        public void setTo(long time, byte cmd, int eventCode, int eventUid, String eventName,
625                HistoryItem o) {
626            this.time = time;
627            this.cmd = cmd;
628            this.eventCode = eventCode;
629            this.eventUid = eventUid;
630            this.eventName = eventName;
631            this.eventNameIdx = 0;
632            batteryLevel = o.batteryLevel;
633            batteryStatus = o.batteryStatus;
634            batteryHealth = o.batteryHealth;
635            batteryPlugType = o.batteryPlugType;
636            batteryTemperature = o.batteryTemperature;
637            batteryVoltage = o.batteryVoltage;
638            states = o.states;
639        }
640
641        public boolean sameNonEvent(HistoryItem o) {
642            return batteryLevel == o.batteryLevel
643                    && batteryStatus == o.batteryStatus
644                    && batteryHealth == o.batteryHealth
645                    && batteryPlugType == o.batteryPlugType
646                    && batteryTemperature == o.batteryTemperature
647                    && batteryVoltage == o.batteryVoltage
648                    && states == o.states;
649        }
650
651        public boolean same(HistoryItem o) {
652            if (!sameNonEvent(o) || eventCode != o.eventCode || eventUid != o.eventUid) {
653                return false;
654            }
655            if (eventName == o.eventName) {
656                return true;
657            }
658            return eventName != null && o.eventName != null && eventName.equals(o.eventName);
659        }
660    }
661
662    public static final class BitDescription {
663        public final int mask;
664        public final int shift;
665        public final String name;
666        public final String shortName;
667        public final String[] values;
668        public final String[] shortValues;
669
670        public BitDescription(int mask, String name, String shortName) {
671            this.mask = mask;
672            this.shift = -1;
673            this.name = name;
674            this.shortName = shortName;
675            this.values = null;
676            this.shortValues = null;
677        }
678
679        public BitDescription(int mask, int shift, String name, String shortName,
680                String[] values, String[] shortValues) {
681            this.mask = mask;
682            this.shift = shift;
683            this.name = name;
684            this.shortName = shortName;
685            this.values = values;
686            this.shortValues = shortValues;
687        }
688    }
689
690    public abstract boolean startIteratingHistoryLocked();
691
692    public abstract int getHistoryStringPoolSize();
693
694    public abstract String getHistoryStringPoolItem(int index);
695
696    public abstract boolean getNextHistoryLocked(HistoryItem out);
697
698    public abstract void finishIteratingHistoryLocked();
699
700    public abstract boolean startIteratingOldHistoryLocked();
701
702    public abstract boolean getNextOldHistoryLocked(HistoryItem out);
703
704    public abstract void finishIteratingOldHistoryLocked();
705
706    /**
707     * Return the base time offset for the battery history.
708     */
709    public abstract long getHistoryBaseTime();
710
711    /**
712     * Returns the number of times the device has been started.
713     */
714    public abstract int getStartCount();
715
716    /**
717     * Returns the time in microseconds that the screen has been on while the device was
718     * running on battery.
719     *
720     * {@hide}
721     */
722    public abstract long getScreenOnTime(long batteryRealtime, int which);
723
724    public static final int SCREEN_BRIGHTNESS_DARK = 0;
725    public static final int SCREEN_BRIGHTNESS_DIM = 1;
726    public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
727    public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
728    public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
729
730    static final String[] SCREEN_BRIGHTNESS_NAMES = {
731        "dark", "dim", "medium", "light", "bright"
732    };
733
734    static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
735        "0", "1", "2", "3", "4"
736    };
737
738    public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
739
740    /**
741     * Returns the time in microseconds that the screen has been on with
742     * the given brightness
743     *
744     * {@hide}
745     */
746    public abstract long getScreenBrightnessTime(int brightnessBin,
747            long batteryRealtime, int which);
748
749    public abstract int getInputEventCount(int which);
750
751    /**
752     * Returns the time in microseconds that the phone has been on while the device was
753     * running on battery.
754     *
755     * {@hide}
756     */
757    public abstract long getPhoneOnTime(long batteryRealtime, int which);
758
759    /**
760     * Returns the time in microseconds that the phone has been running with
761     * the given signal strength.
762     *
763     * {@hide}
764     */
765    public abstract long getPhoneSignalStrengthTime(int strengthBin,
766            long batteryRealtime, int which);
767
768    /**
769     * Returns the time in microseconds that the phone has been trying to
770     * acquire a signal.
771     *
772     * {@hide}
773     */
774    public abstract long getPhoneSignalScanningTime(
775            long batteryRealtime, int which);
776
777    /**
778     * Returns the number of times the phone has entered the given signal strength.
779     *
780     * {@hide}
781     */
782    public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
783
784    public static final int DATA_CONNECTION_NONE = 0;
785    public static final int DATA_CONNECTION_GPRS = 1;
786    public static final int DATA_CONNECTION_EDGE = 2;
787    public static final int DATA_CONNECTION_UMTS = 3;
788    public static final int DATA_CONNECTION_CDMA = 4;
789    public static final int DATA_CONNECTION_EVDO_0 = 5;
790    public static final int DATA_CONNECTION_EVDO_A = 6;
791    public static final int DATA_CONNECTION_1xRTT = 7;
792    public static final int DATA_CONNECTION_HSDPA = 8;
793    public static final int DATA_CONNECTION_HSUPA = 9;
794    public static final int DATA_CONNECTION_HSPA = 10;
795    public static final int DATA_CONNECTION_IDEN = 11;
796    public static final int DATA_CONNECTION_EVDO_B = 12;
797    public static final int DATA_CONNECTION_LTE = 13;
798    public static final int DATA_CONNECTION_EHRPD = 14;
799    public static final int DATA_CONNECTION_HSPAP = 15;
800    public static final int DATA_CONNECTION_OTHER = 16;
801
802    static final String[] DATA_CONNECTION_NAMES = {
803        "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
804        "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
805        "ehrpd", "hspap", "other"
806    };
807
808    public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
809
810    /**
811     * Returns the time in microseconds that the phone has been running with
812     * the given data connection.
813     *
814     * {@hide}
815     */
816    public abstract long getPhoneDataConnectionTime(int dataType,
817            long batteryRealtime, int which);
818
819    /**
820     * Returns the number of times the phone has entered the given data
821     * connection type.
822     *
823     * {@hide}
824     */
825    public abstract int getPhoneDataConnectionCount(int dataType, int which);
826
827    public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
828            = new BitDescription[] {
829        new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
830        new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
831        new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
832        new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
833        new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
834        new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi", "W"),
835        new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running", "Wr"),
836        new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
837        new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
838        new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
839        new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
840        new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
841        new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video", "v"),
842        new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
843        new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
844        new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
845                HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
846                SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
847        new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK,
848                HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength", "Pss",
849                SignalStrength.SIGNAL_STRENGTH_NAMES, new String[] {
850                    "0", "1", "2", "3", "4"
851        }),
852        new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
853                HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
854                new String[] {"in", "out", "emergency", "off"},
855                new String[] {"in", "out", "em", "off"}),
856        new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
857                HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
858                DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
859    };
860
861    /**
862     * Returns the time in microseconds that wifi has been on while the device was
863     * running on battery.
864     *
865     * {@hide}
866     */
867    public abstract long getWifiOnTime(long batteryRealtime, int which);
868
869    /**
870     * Returns the time in microseconds that wifi has been on and the driver has
871     * been in the running state while the device was running on battery.
872     *
873     * {@hide}
874     */
875    public abstract long getGlobalWifiRunningTime(long batteryRealtime, int which);
876
877    /**
878     * Returns the time in microseconds that bluetooth has been on while the device was
879     * running on battery.
880     *
881     * {@hide}
882     */
883    public abstract long getBluetoothOnTime(long batteryRealtime, int which);
884
885    public abstract int getBluetoothPingCount();
886
887    public static final int NETWORK_MOBILE_RX_DATA = 0;
888    public static final int NETWORK_MOBILE_TX_DATA = 1;
889    public static final int NETWORK_WIFI_RX_DATA = 2;
890    public static final int NETWORK_WIFI_TX_DATA = 3;
891
892    public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1;
893
894    public abstract long getNetworkActivityBytes(int type, int which);
895    public abstract long getNetworkActivityPackets(int type, int which);
896
897    /**
898     * Return whether we are currently running on battery.
899     */
900    public abstract boolean getIsOnBattery();
901
902    /**
903     * Returns a SparseArray containing the statistics for each uid.
904     */
905    public abstract SparseArray<? extends Uid> getUidStats();
906
907    /**
908     * Returns the current battery uptime in microseconds.
909     *
910     * @param curTime the amount of elapsed realtime in microseconds.
911     */
912    public abstract long getBatteryUptime(long curTime);
913
914    /**
915     * @deprecated use getRadioDataUptime
916     */
917    public long getRadioDataUptimeMs() {
918        return getRadioDataUptime() / 1000;
919    }
920
921    /**
922     * Returns the time that the radio was on for data transfers.
923     * @return the uptime in microseconds while unplugged
924     */
925    public abstract long getRadioDataUptime();
926
927    /**
928     * Returns the current battery realtime in microseconds.
929     *
930     * @param curTime the amount of elapsed realtime in microseconds.
931     */
932    public abstract long getBatteryRealtime(long curTime);
933
934    /**
935     * Returns the battery percentage level at the last time the device was unplugged from power, or
936     * the last time it booted on battery power.
937     */
938    public abstract int getDischargeStartLevel();
939
940    /**
941     * Returns the current battery percentage level if we are in a discharge cycle, otherwise
942     * returns the level at the last plug event.
943     */
944    public abstract int getDischargeCurrentLevel();
945
946    /**
947     * Get the amount the battery has discharged since the stats were
948     * last reset after charging, as a lower-end approximation.
949     */
950    public abstract int getLowDischargeAmountSinceCharge();
951
952    /**
953     * Get the amount the battery has discharged since the stats were
954     * last reset after charging, as an upper-end approximation.
955     */
956    public abstract int getHighDischargeAmountSinceCharge();
957
958    /**
959     * Get the amount the battery has discharged while the screen was on,
960     * since the last time power was unplugged.
961     */
962    public abstract int getDischargeAmountScreenOn();
963
964    /**
965     * Get the amount the battery has discharged while the screen was on,
966     * since the last time the device was charged.
967     */
968    public abstract int getDischargeAmountScreenOnSinceCharge();
969
970    /**
971     * Get the amount the battery has discharged while the screen was off,
972     * since the last time power was unplugged.
973     */
974    public abstract int getDischargeAmountScreenOff();
975
976    /**
977     * Get the amount the battery has discharged while the screen was off,
978     * since the last time the device was charged.
979     */
980    public abstract int getDischargeAmountScreenOffSinceCharge();
981
982    /**
983     * Returns the total, last, or current battery uptime in microseconds.
984     *
985     * @param curTime the elapsed realtime in microseconds.
986     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
987     */
988    public abstract long computeBatteryUptime(long curTime, int which);
989
990    /**
991     * Returns the total, last, or current battery realtime in microseconds.
992     *
993     * @param curTime the current elapsed realtime in microseconds.
994     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
995     */
996    public abstract long computeBatteryRealtime(long curTime, int which);
997
998    /**
999     * Returns the total, last, or current uptime in microseconds.
1000     *
1001     * @param curTime the current elapsed realtime in microseconds.
1002     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1003     */
1004    public abstract long computeUptime(long curTime, int which);
1005
1006    /**
1007     * Returns the total, last, or current realtime in microseconds.
1008     * *
1009     * @param curTime the current elapsed realtime in microseconds.
1010     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1011     */
1012    public abstract long computeRealtime(long curTime, int which);
1013
1014    public abstract Map<String, ? extends Timer> getKernelWakelockStats();
1015
1016    /** Returns the number of different speeds that the CPU can run at */
1017    public abstract int getCpuSpeedSteps();
1018
1019    public abstract void writeToParcelWithoutUids(Parcel out, int flags);
1020
1021    private final static void formatTimeRaw(StringBuilder out, long seconds) {
1022        long days = seconds / (60 * 60 * 24);
1023        if (days != 0) {
1024            out.append(days);
1025            out.append("d ");
1026        }
1027        long used = days * 60 * 60 * 24;
1028
1029        long hours = (seconds - used) / (60 * 60);
1030        if (hours != 0 || used != 0) {
1031            out.append(hours);
1032            out.append("h ");
1033        }
1034        used += hours * 60 * 60;
1035
1036        long mins = (seconds-used) / 60;
1037        if (mins != 0 || used != 0) {
1038            out.append(mins);
1039            out.append("m ");
1040        }
1041        used += mins * 60;
1042
1043        if (seconds != 0 || used != 0) {
1044            out.append(seconds-used);
1045            out.append("s ");
1046        }
1047    }
1048
1049    private final static void formatTime(StringBuilder sb, long time) {
1050        long sec = time / 100;
1051        formatTimeRaw(sb, sec);
1052        sb.append((time - (sec * 100)) * 10);
1053        sb.append("ms ");
1054    }
1055
1056    private final static void formatTimeMs(StringBuilder sb, long time) {
1057        long sec = time / 1000;
1058        formatTimeRaw(sb, sec);
1059        sb.append(time - (sec * 1000));
1060        sb.append("ms ");
1061    }
1062
1063    private final String formatRatioLocked(long num, long den) {
1064        if (den == 0L) {
1065            return "--%";
1066        }
1067        float perc = ((float)num) / ((float)den) * 100;
1068        mFormatBuilder.setLength(0);
1069        mFormatter.format("%.1f%%", perc);
1070        return mFormatBuilder.toString();
1071    }
1072
1073    private final String formatBytesLocked(long bytes) {
1074        mFormatBuilder.setLength(0);
1075
1076        if (bytes < BYTES_PER_KB) {
1077            return bytes + "B";
1078        } else if (bytes < BYTES_PER_MB) {
1079            mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
1080            return mFormatBuilder.toString();
1081        } else if (bytes < BYTES_PER_GB){
1082            mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
1083            return mFormatBuilder.toString();
1084        } else {
1085            mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
1086            return mFormatBuilder.toString();
1087        }
1088    }
1089
1090    private static long computeWakeLock(Timer timer, long batteryRealtime, int which) {
1091        if (timer != null) {
1092            // Convert from microseconds to milliseconds with rounding
1093            long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
1094            long totalTimeMillis = (totalTimeMicros + 500) / 1000;
1095            return totalTimeMillis;
1096        }
1097        return 0;
1098    }
1099
1100    /**
1101     *
1102     * @param sb a StringBuilder object.
1103     * @param timer a Timer object contining the wakelock times.
1104     * @param batteryRealtime the current on-battery time in microseconds.
1105     * @param name the name of the wakelock.
1106     * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1107     * @param linePrefix a String to be prepended to each line of output.
1108     * @return the line prefix
1109     */
1110    private static final String printWakeLock(StringBuilder sb, Timer timer,
1111            long batteryRealtime, String name, int which, String linePrefix) {
1112
1113        if (timer != null) {
1114            long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which);
1115
1116            int count = timer.getCountLocked(which);
1117            if (totalTimeMillis != 0) {
1118                sb.append(linePrefix);
1119                formatTimeMs(sb, totalTimeMillis);
1120                if (name != null) {
1121                    sb.append(name);
1122                    sb.append(' ');
1123                }
1124                sb.append('(');
1125                sb.append(count);
1126                sb.append(" times)");
1127                return ", ";
1128            }
1129        }
1130        return linePrefix;
1131    }
1132
1133    /**
1134     * Checkin version of wakelock printer. Prints simple comma-separated list.
1135     *
1136     * @param sb a StringBuilder object.
1137     * @param timer a Timer object contining the wakelock times.
1138     * @param now the current time in microseconds.
1139     * @param name the name of the wakelock.
1140     * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1141     * @param linePrefix a String to be prepended to each line of output.
1142     * @return the line prefix
1143     */
1144    private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
1145            String name, int which, String linePrefix) {
1146        long totalTimeMicros = 0;
1147        int count = 0;
1148        if (timer != null) {
1149            totalTimeMicros = timer.getTotalTimeLocked(now, which);
1150            count = timer.getCountLocked(which);
1151        }
1152        sb.append(linePrefix);
1153        sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
1154        sb.append(',');
1155        sb.append(name != null ? name + "," : "");
1156        sb.append(count);
1157        return ",";
1158    }
1159
1160    /**
1161     * Dump a comma-separated line of values for terse checkin mode.
1162     *
1163     * @param pw the PageWriter to dump log to
1164     * @param category category of data (e.g. "total", "last", "unplugged", "current" )
1165     * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
1166     * @param args type-dependent data arguments
1167     */
1168    private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
1169           Object... args ) {
1170        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
1171        pw.print(uid); pw.print(',');
1172        pw.print(category); pw.print(',');
1173        pw.print(type);
1174
1175        for (Object arg : args) {
1176            pw.print(',');
1177            pw.print(arg);
1178        }
1179        pw.println();
1180    }
1181
1182    /**
1183     * Checkin server version of dump to produce more compact, computer-readable log.
1184     *
1185     * NOTE: all times are expressed in 'ms'.
1186     */
1187    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
1188        final long rawUptime = SystemClock.uptimeMillis() * 1000;
1189        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
1190        final long batteryUptime = getBatteryUptime(rawUptime);
1191        final long batteryRealtime = getBatteryRealtime(rawRealtime);
1192        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
1193        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
1194        final long totalRealtime = computeRealtime(rawRealtime, which);
1195        final long totalUptime = computeUptime(rawUptime, which);
1196        final long screenOnTime = getScreenOnTime(batteryRealtime, which);
1197        final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
1198        final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
1199        final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
1200        final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
1201
1202        StringBuilder sb = new StringBuilder(128);
1203
1204        SparseArray<? extends Uid> uidStats = getUidStats();
1205        final int NU = uidStats.size();
1206
1207        String category = STAT_NAMES[which];
1208
1209        // Dump "battery" stat
1210        dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
1211                which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
1212                whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
1213                totalRealtime / 1000, totalUptime / 1000);
1214
1215        // Calculate wakelock times across all uids.
1216        long fullWakeLockTimeTotal = 0;
1217        long partialWakeLockTimeTotal = 0;
1218
1219        for (int iu = 0; iu < NU; iu++) {
1220            Uid u = uidStats.valueAt(iu);
1221
1222            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1223            if (wakelocks.size() > 0) {
1224                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1225                        : wakelocks.entrySet()) {
1226                    Uid.Wakelock wl = ent.getValue();
1227
1228                    Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1229                    if (fullWakeTimer != null) {
1230                        fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
1231                    }
1232
1233                    Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1234                    if (partialWakeTimer != null) {
1235                        partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
1236                            batteryRealtime, which);
1237                    }
1238                }
1239            }
1240        }
1241
1242        long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
1243        long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
1244        long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
1245        long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
1246        long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
1247        long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
1248        long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
1249        long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
1250
1251        // Dump network stats
1252        dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
1253                mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
1254                mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets);
1255
1256        // Dump misc stats
1257        dumpLine(pw, 0 /* uid */, category, MISC_DATA,
1258                screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
1259                wifiRunningTime / 1000, bluetoothOnTime / 1000,
1260                mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
1261                fullWakeLockTimeTotal, partialWakeLockTimeTotal,
1262                getInputEventCount(which));
1263
1264        // Dump screen brightness stats
1265        Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
1266        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1267            args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
1268        }
1269        dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
1270
1271        // Dump signal strength stats
1272        args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
1273        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
1274            args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
1275        }
1276        dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
1277        dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
1278                getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
1279        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
1280            args[i] = getPhoneSignalStrengthCount(i, which);
1281        }
1282        dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
1283
1284        // Dump network type stats
1285        args = new Object[NUM_DATA_CONNECTION_TYPES];
1286        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1287            args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
1288        }
1289        dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
1290        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1291            args[i] = getPhoneDataConnectionCount(i, which);
1292        }
1293        dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
1294
1295        if (which == STATS_SINCE_UNPLUGGED) {
1296            dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
1297                    getDischargeCurrentLevel());
1298        }
1299
1300        if (which == STATS_SINCE_UNPLUGGED) {
1301            dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
1302                    getDischargeStartLevel()-getDischargeCurrentLevel(),
1303                    getDischargeStartLevel()-getDischargeCurrentLevel(),
1304                    getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
1305        } else {
1306            dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
1307                    getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
1308                    getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
1309        }
1310
1311        if (reqUid < 0) {
1312            Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1313            if (kernelWakelocks.size() > 0) {
1314                for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1315                    sb.setLength(0);
1316                    printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
1317
1318                    dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
1319                            sb.toString());
1320                }
1321            }
1322        }
1323
1324        BatteryStatsHelper helper = new BatteryStatsHelper(context);
1325        helper.create(this);
1326        helper.refreshStats(which, UserHandle.USER_ALL);
1327        List<BatterySipper> sippers = helper.getUsageList();
1328        if (sippers != null && sippers.size() > 0) {
1329            dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
1330                    BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
1331                    BatteryStatsHelper.makemAh(helper.getComputedPower()),
1332                    BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
1333                    BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
1334            for (int i=0; i<sippers.size(); i++) {
1335                BatterySipper bs = sippers.get(i);
1336                int uid = 0;
1337                String label;
1338                switch (bs.drainType) {
1339                    case IDLE:
1340                        label="idle";
1341                        break;
1342                    case CELL:
1343                        label="cell";
1344                        break;
1345                    case PHONE:
1346                        label="phone";
1347                        break;
1348                    case WIFI:
1349                        label="wifi";
1350                        break;
1351                    case BLUETOOTH:
1352                        label="blue";
1353                        break;
1354                    case SCREEN:
1355                        label="scrn";
1356                        break;
1357                    case APP:
1358                        uid = bs.uidObj.getUid();
1359                        label = "uid";
1360                        break;
1361                    case USER:
1362                        uid = UserHandle.getUid(bs.userId, 0);
1363                        label = "user";
1364                        break;
1365                    case UNACCOUNTED:
1366                        label = "unacc";
1367                        break;
1368                    case OVERCOUNTED:
1369                        label = "over";
1370                        break;
1371                    default:
1372                        label = "???";
1373                }
1374                dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
1375                        BatteryStatsHelper.makemAh(bs.value));
1376            }
1377        }
1378
1379        for (int iu = 0; iu < NU; iu++) {
1380            final int uid = uidStats.keyAt(iu);
1381            if (reqUid >= 0 && uid != reqUid) {
1382                continue;
1383            }
1384            Uid u = uidStats.valueAt(iu);
1385            // Dump Network stats per uid, if any
1386            long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
1387            long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
1388            long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
1389            long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
1390            long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
1391            long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
1392            long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
1393            long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
1394            long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1395            long wifiScanTime = u.getWifiScanTime(batteryRealtime, which);
1396            long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
1397
1398            if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
1399                    || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
1400                    || wifiPacketsTx > 0) {
1401                dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
1402                        wifiBytesRx, wifiBytesTx,
1403                        mobilePacketsRx, mobilePacketsTx,
1404                        wifiPacketsRx, wifiPacketsTx);
1405            }
1406
1407            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
1408                    || uidWifiRunningTime != 0) {
1409                dumpLine(pw, uid, category, WIFI_DATA,
1410                        fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime);
1411            }
1412
1413            if (u.hasUserActivity()) {
1414                args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
1415                boolean hasData = false;
1416                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
1417                    int val = u.getUserActivityCount(i, which);
1418                    args[i] = val;
1419                    if (val != 0) hasData = true;
1420                }
1421                if (hasData) {
1422                    dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args);
1423                }
1424            }
1425
1426            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1427            if (wakelocks.size() > 0) {
1428                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1429                        : wakelocks.entrySet()) {
1430                    Uid.Wakelock wl = ent.getValue();
1431                    String linePrefix = "";
1432                    sb.setLength(0);
1433                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
1434                            batteryRealtime, "f", which, linePrefix);
1435                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
1436                            batteryRealtime, "p", which, linePrefix);
1437                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
1438                            batteryRealtime, "w", which, linePrefix);
1439
1440                    // Only log if we had at lease one wakelock...
1441                    if (sb.length() > 0) {
1442                        String name = ent.getKey();
1443                        if (name.indexOf(',') >= 0) {
1444                            name = name.replace(',', '_');
1445                        }
1446                        dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
1447                    }
1448                }
1449            }
1450
1451            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1452            if (sensors.size() > 0)  {
1453                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1454                        : sensors.entrySet()) {
1455                    Uid.Sensor se = ent.getValue();
1456                    int sensorNumber = ent.getKey();
1457                    Timer timer = se.getSensorTime();
1458                    if (timer != null) {
1459                        // Convert from microseconds to milliseconds with rounding
1460                        long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
1461                        int count = timer.getCountLocked(which);
1462                        if (totalTime != 0) {
1463                            dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
1464                        }
1465                    }
1466                }
1467            }
1468
1469            Timer vibTimer = u.getVibratorOnTimer();
1470            if (vibTimer != null) {
1471                // Convert from microseconds to milliseconds with rounding
1472                long totalTime = (vibTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
1473                int count = vibTimer.getCountLocked(which);
1474                if (totalTime != 0) {
1475                    dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count);
1476                }
1477            }
1478
1479            Timer fgTimer = u.getForegroundActivityTimer();
1480            if (fgTimer != null) {
1481                // Convert from microseconds to milliseconds with rounding
1482                long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
1483                int count = fgTimer.getCountLocked(which);
1484                if (totalTime != 0) {
1485                    dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count);
1486                }
1487            }
1488
1489            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1490            if (processStats.size() > 0) {
1491                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1492                        : processStats.entrySet()) {
1493                    Uid.Proc ps = ent.getValue();
1494
1495                    final long userMillis = ps.getUserTime(which) * 10;
1496                    final long systemMillis = ps.getSystemTime(which) * 10;
1497                    final long foregroundMillis = ps.getForegroundTime(which) * 10;
1498                    final long starts = ps.getStarts(which);
1499
1500                    if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
1501                            || starts != 0) {
1502                        dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis,
1503                                systemMillis, foregroundMillis, starts);
1504                    }
1505                }
1506            }
1507
1508            Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1509            if (packageStats.size() > 0) {
1510                for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1511                        : packageStats.entrySet()) {
1512
1513                    Uid.Pkg ps = ent.getValue();
1514                    int wakeups = ps.getWakeups(which);
1515                    Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1516                    for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1517                            : serviceStats.entrySet()) {
1518                        BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1519                        long startTime = ss.getStartTime(batteryUptime, which);
1520                        int starts = ss.getStarts(which);
1521                        int launches = ss.getLaunches(which);
1522                        if (startTime != 0 || starts != 0 || launches != 0) {
1523                            dumpLine(pw, uid, category, APK_DATA,
1524                                    wakeups, // wakeup alarms
1525                                    ent.getKey(), // Apk
1526                                    sent.getKey(), // service
1527                                    startTime / 1000, // time spent started, in ms
1528                                    starts,
1529                                    launches);
1530                        }
1531                    }
1532                }
1533            }
1534        }
1535    }
1536
1537    static final class TimerEntry {
1538        final String mName;
1539        final int mId;
1540        final BatteryStats.Timer mTimer;
1541        final long mTime;
1542        TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
1543            mName = name;
1544            mId = id;
1545            mTimer = timer;
1546            mTime = time;
1547        }
1548    }
1549
1550    private void printmAh(PrintWriter printer, double power) {
1551        printer.print(BatteryStatsHelper.makemAh(power));
1552    }
1553
1554    @SuppressWarnings("unused")
1555    public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
1556            int reqUid) {
1557        final long rawUptime = SystemClock.uptimeMillis() * 1000;
1558        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
1559        final long batteryUptime = getBatteryUptime(rawUptime);
1560        final long batteryRealtime = getBatteryRealtime(rawRealtime);
1561
1562        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
1563        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
1564        final long totalRealtime = computeRealtime(rawRealtime, which);
1565        final long totalUptime = computeUptime(rawUptime, which);
1566
1567        StringBuilder sb = new StringBuilder(128);
1568
1569        SparseArray<? extends Uid> uidStats = getUidStats();
1570        final int NU = uidStats.size();
1571
1572        sb.setLength(0);
1573        sb.append(prefix);
1574                sb.append("  Time on battery: ");
1575                formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
1576                sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
1577                sb.append(") realtime, ");
1578                formatTimeMs(sb, whichBatteryUptime / 1000);
1579                sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
1580                sb.append(") uptime");
1581        pw.println(sb.toString());
1582        sb.setLength(0);
1583        sb.append(prefix);
1584                sb.append("  Total run time: ");
1585                formatTimeMs(sb, totalRealtime / 1000);
1586                sb.append("realtime, ");
1587                formatTimeMs(sb, totalUptime / 1000);
1588                sb.append("uptime, ");
1589        pw.println(sb.toString());
1590
1591        final long screenOnTime = getScreenOnTime(batteryRealtime, which);
1592        final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
1593        final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
1594        final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
1595        final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
1596        sb.setLength(0);
1597        sb.append(prefix);
1598                sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
1599                sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
1600                sb.append("), Input events: "); sb.append(getInputEventCount(which));
1601                sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
1602                sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
1603                sb.append(")");
1604        pw.println(sb.toString());
1605        sb.setLength(0);
1606        sb.append(prefix);
1607        sb.append("  Screen brightnesses: ");
1608        boolean didOne = false;
1609        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1610            final long time = getScreenBrightnessTime(i, batteryRealtime, which);
1611            if (time == 0) {
1612                continue;
1613            }
1614            if (didOne) sb.append(", ");
1615            didOne = true;
1616            sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
1617            sb.append(" ");
1618            formatTimeMs(sb, time/1000);
1619            sb.append("(");
1620            sb.append(formatRatioLocked(time, screenOnTime));
1621            sb.append(")");
1622        }
1623        if (!didOne) sb.append("No activity");
1624        pw.println(sb.toString());
1625
1626        // Calculate wakelock times across all uids.
1627        long fullWakeLockTimeTotalMicros = 0;
1628        long partialWakeLockTimeTotalMicros = 0;
1629
1630        final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
1631            @Override
1632            public int compare(TimerEntry lhs, TimerEntry rhs) {
1633                long lhsTime = lhs.mTime;
1634                long rhsTime = rhs.mTime;
1635                if (lhsTime < rhsTime) {
1636                    return 1;
1637                }
1638                if (lhsTime > rhsTime) {
1639                    return -1;
1640                }
1641                return 0;
1642            }
1643        };
1644
1645        if (reqUid < 0) {
1646            Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1647            if (kernelWakelocks.size() > 0) {
1648                final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
1649                for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1650                    BatteryStats.Timer timer = ent.getValue();
1651                    long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which);
1652                    if (totalTimeMillis > 0) {
1653                        timers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
1654                    }
1655                }
1656                Collections.sort(timers, timerComparator);
1657                for (int i=0; i<timers.size(); i++) {
1658                    TimerEntry timer = timers.get(i);
1659                    String linePrefix = ": ";
1660                    sb.setLength(0);
1661                    sb.append(prefix);
1662                    sb.append("  Kernel Wake lock ");
1663                    sb.append(timer.mName);
1664                    linePrefix = printWakeLock(sb, timer.mTimer, batteryRealtime, null,
1665                            which, linePrefix);
1666                    if (!linePrefix.equals(": ")) {
1667                        sb.append(" realtime");
1668                        // Only print out wake locks that were held
1669                        pw.println(sb.toString());
1670                    }
1671                }
1672            }
1673        }
1674
1675        final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
1676
1677        for (int iu = 0; iu < NU; iu++) {
1678            Uid u = uidStats.valueAt(iu);
1679
1680            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1681            if (wakelocks.size() > 0) {
1682                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1683                        : wakelocks.entrySet()) {
1684                    Uid.Wakelock wl = ent.getValue();
1685
1686                    Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1687                    if (fullWakeTimer != null) {
1688                        fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
1689                                batteryRealtime, which);
1690                    }
1691
1692                    Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1693                    if (partialWakeTimer != null) {
1694                        long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
1695                                batteryRealtime, which);
1696                        if (totalTimeMicros > 0) {
1697                            if (reqUid < 0) {
1698                                // Only show the ordered list of all wake
1699                                // locks if the caller is not asking for data
1700                                // about a specific uid.
1701                                timers.add(new TimerEntry(ent.getKey(), u.getUid(),
1702                                        partialWakeTimer, totalTimeMicros));
1703                            }
1704                            partialWakeLockTimeTotalMicros += totalTimeMicros;
1705                        }
1706                    }
1707                }
1708            }
1709        }
1710
1711        long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
1712        long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
1713        long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
1714        long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
1715        long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
1716        long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
1717        long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
1718        long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
1719
1720        pw.print(prefix);
1721                pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
1722                pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
1723                pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
1724                pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
1725        pw.print(prefix);
1726                pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
1727                pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
1728                pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
1729                pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
1730        sb.setLength(0);
1731        sb.append(prefix);
1732                sb.append("  Total full wakelock time: "); formatTimeMs(sb,
1733                        (fullWakeLockTimeTotalMicros + 500) / 1000);
1734                sb.append(", Total partial wakelock time: "); formatTimeMs(sb,
1735                        (partialWakeLockTimeTotalMicros + 500) / 1000);
1736        pw.println(sb.toString());
1737
1738        sb.setLength(0);
1739        sb.append(prefix);
1740        sb.append("  Signal levels: ");
1741        didOne = false;
1742        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
1743            final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
1744            if (time == 0) {
1745                continue;
1746            }
1747            if (didOne) sb.append(", ");
1748            didOne = true;
1749            sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
1750            sb.append(" ");
1751            formatTimeMs(sb, time/1000);
1752            sb.append("(");
1753            sb.append(formatRatioLocked(time, whichBatteryRealtime));
1754            sb.append(") ");
1755            sb.append(getPhoneSignalStrengthCount(i, which));
1756            sb.append("x");
1757        }
1758        if (!didOne) sb.append("No activity");
1759        pw.println(sb.toString());
1760
1761        sb.setLength(0);
1762        sb.append(prefix);
1763        sb.append("  Signal scanning time: ");
1764        formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
1765        pw.println(sb.toString());
1766
1767        sb.setLength(0);
1768        sb.append(prefix);
1769        sb.append("  Radio types: ");
1770        didOne = false;
1771        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1772            final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
1773            if (time == 0) {
1774                continue;
1775            }
1776            if (didOne) sb.append(", ");
1777            didOne = true;
1778            sb.append(DATA_CONNECTION_NAMES[i]);
1779            sb.append(" ");
1780            formatTimeMs(sb, time/1000);
1781            sb.append("(");
1782            sb.append(formatRatioLocked(time, whichBatteryRealtime));
1783            sb.append(") ");
1784            sb.append(getPhoneDataConnectionCount(i, which));
1785            sb.append("x");
1786        }
1787        if (!didOne) sb.append("No activity");
1788        pw.println(sb.toString());
1789
1790        sb.setLength(0);
1791        sb.append(prefix);
1792        sb.append("  Radio data uptime when unplugged: ");
1793        sb.append(getRadioDataUptime() / 1000);
1794        sb.append(" ms");
1795        pw.println(sb.toString());
1796
1797        sb.setLength(0);
1798        sb.append(prefix);
1799                sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
1800                sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
1801                sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
1802                sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
1803                sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
1804                sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
1805                sb.append(")");
1806        pw.println(sb.toString());
1807
1808        pw.println(" ");
1809
1810        if (which == STATS_SINCE_UNPLUGGED) {
1811            if (getIsOnBattery()) {
1812                pw.print(prefix); pw.println("  Device is currently unplugged");
1813                pw.print(prefix); pw.print("    Discharge cycle start level: ");
1814                        pw.println(getDischargeStartLevel());
1815                pw.print(prefix); pw.print("    Discharge cycle current level: ");
1816                        pw.println(getDischargeCurrentLevel());
1817            } else {
1818                pw.print(prefix); pw.println("  Device is currently plugged into power");
1819                pw.print(prefix); pw.print("    Last discharge cycle start level: ");
1820                        pw.println(getDischargeStartLevel());
1821                pw.print(prefix); pw.print("    Last discharge cycle end level: ");
1822                        pw.println(getDischargeCurrentLevel());
1823            }
1824            pw.print(prefix); pw.print("    Amount discharged while screen on: ");
1825                    pw.println(getDischargeAmountScreenOn());
1826            pw.print(prefix); pw.print("    Amount discharged while screen off: ");
1827                    pw.println(getDischargeAmountScreenOff());
1828            pw.println(" ");
1829        } else {
1830            pw.print(prefix); pw.println("  Device battery use since last full charge");
1831            pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
1832                    pw.println(getLowDischargeAmountSinceCharge());
1833            pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
1834                    pw.println(getHighDischargeAmountSinceCharge());
1835            pw.print(prefix); pw.print("    Amount discharged while screen on: ");
1836                    pw.println(getDischargeAmountScreenOnSinceCharge());
1837            pw.print(prefix); pw.print("    Amount discharged while screen off: ");
1838                    pw.println(getDischargeAmountScreenOffSinceCharge());
1839            pw.println();
1840        }
1841
1842        BatteryStatsHelper helper = new BatteryStatsHelper(context);
1843        helper.create(this);
1844        helper.refreshStats(which, UserHandle.USER_ALL);
1845        List<BatterySipper> sippers = helper.getUsageList();
1846        if (sippers != null && sippers.size() > 0) {
1847            pw.print(prefix); pw.println("  Estimated power use (mAh):");
1848            pw.print(prefix); pw.print("    Capacity: ");
1849                    printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
1850                    pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
1851                    pw.print(", Min drain: "); printmAh(pw, helper.getMinDrainedPower());
1852                    pw.print(", Max drain: "); printmAh(pw, helper.getMaxDrainedPower());
1853                    pw.println();
1854            for (int i=0; i<sippers.size(); i++) {
1855                BatterySipper bs = sippers.get(i);
1856                switch (bs.drainType) {
1857                    case IDLE:
1858                        pw.print(prefix); pw.print("    Idle: "); printmAh(pw, bs.value);
1859                        pw.println();
1860                        break;
1861                    case CELL:
1862                        pw.print(prefix); pw.print("    Cell standby: "); printmAh(pw, bs.value);
1863                        pw.println();
1864                        break;
1865                    case PHONE:
1866                        pw.print(prefix); pw.print("    Phone calls: "); printmAh(pw, bs.value);
1867                        pw.println();
1868                        break;
1869                    case WIFI:
1870                        pw.print(prefix); pw.print("    Wifi: "); printmAh(pw, bs.value);
1871                        pw.println();
1872                        break;
1873                    case BLUETOOTH:
1874                        pw.print(prefix); pw.print("    Bluetooth: "); printmAh(pw, bs.value);
1875                        pw.println();
1876                        break;
1877                    case SCREEN:
1878                        pw.print(prefix); pw.print("    Screen: "); printmAh(pw, bs.value);
1879                        pw.println();
1880                        break;
1881                    case APP:
1882                        pw.print(prefix); pw.print("    Uid "); pw.print(bs.uidObj.getUid());
1883                        pw.print(": "); printmAh(pw, bs.value); pw.println();
1884                        break;
1885                    case USER:
1886                        pw.print(prefix); pw.print("    User "); pw.print(bs.userId);
1887                        pw.print(": "); printmAh(pw, bs.value); pw.println();
1888                        break;
1889                    case UNACCOUNTED:
1890                        pw.print(prefix); pw.print("    Unaccounted: "); printmAh(pw, bs.value);
1891                        pw.println();
1892                        break;
1893                    case OVERCOUNTED:
1894                        pw.print(prefix); pw.print("    Over-counted: "); printmAh(pw, bs.value);
1895                        pw.println();
1896                        break;
1897                }
1898            }
1899            pw.println();
1900        }
1901
1902        if (timers.size() > 0) {
1903            Collections.sort(timers, timerComparator);
1904            pw.print(prefix); pw.println("  All partial wake locks:");
1905            for (int i=0; i<timers.size(); i++) {
1906                TimerEntry timer = timers.get(i);
1907                sb.setLength(0);
1908                sb.append("  Wake lock ");
1909                UserHandle.formatUid(sb, timer.mId);
1910                sb.append(" ");
1911                sb.append(timer.mName);
1912                printWakeLock(sb, timer.mTimer, batteryRealtime, null, which, ": ");
1913                sb.append(" realtime");
1914                pw.println(sb.toString());
1915            }
1916            timers.clear();
1917            pw.println();
1918        }
1919
1920        for (int iu=0; iu<NU; iu++) {
1921            final int uid = uidStats.keyAt(iu);
1922            if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
1923                continue;
1924            }
1925
1926            Uid u = uidStats.valueAt(iu);
1927
1928            pw.print(prefix);
1929            pw.print("  ");
1930            UserHandle.formatUid(pw, uid);
1931            pw.println(":");
1932            boolean uidActivity = false;
1933
1934            long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
1935            long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
1936            long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
1937            long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
1938            long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
1939            long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
1940            long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
1941            long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
1942            long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1943            long wifiScanTime = u.getWifiScanTime(batteryRealtime, which);
1944            long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
1945
1946            if (mobileRxBytes > 0 || mobileTxBytes > 0
1947                    || mobileRxPackets > 0 || mobileTxPackets > 0) {
1948                pw.print(prefix); pw.print("    Mobile network: ");
1949                        pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
1950                        pw.print(formatBytesLocked(mobileTxBytes));
1951                        pw.print(" sent (packets "); pw.print(mobileRxPackets);
1952                        pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
1953            }
1954            if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
1955                pw.print(prefix); pw.print("    Wi-Fi network: ");
1956                        pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
1957                        pw.print(formatBytesLocked(wifiTxBytes));
1958                        pw.print(" sent (packets "); pw.print(wifiRxPackets);
1959                        pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
1960            }
1961
1962            if (u.hasUserActivity()) {
1963                boolean hasData = false;
1964                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
1965                    int val = u.getUserActivityCount(i, which);
1966                    if (val != 0) {
1967                        if (!hasData) {
1968                            sb.setLength(0);
1969                            sb.append("    User activity: ");
1970                            hasData = true;
1971                        } else {
1972                            sb.append(", ");
1973                        }
1974                        sb.append(val);
1975                        sb.append(" ");
1976                        sb.append(Uid.USER_ACTIVITY_TYPES[i]);
1977                    }
1978                }
1979                if (hasData) {
1980                    pw.println(sb.toString());
1981                }
1982            }
1983
1984            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
1985                    || uidWifiRunningTime != 0) {
1986                sb.setLength(0);
1987                sb.append(prefix); sb.append("    Wifi Running: ");
1988                        formatTimeMs(sb, uidWifiRunningTime / 1000);
1989                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
1990                                whichBatteryRealtime)); sb.append(")\n");
1991                sb.append(prefix); sb.append("    Full Wifi Lock: ");
1992                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
1993                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
1994                                whichBatteryRealtime)); sb.append(")\n");
1995                sb.append(prefix); sb.append("    Wifi Scan: ");
1996                        formatTimeMs(sb, wifiScanTime / 1000);
1997                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
1998                                whichBatteryRealtime)); sb.append(")");
1999                pw.println(sb.toString());
2000            }
2001
2002            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
2003            if (wakelocks.size() > 0) {
2004                long totalFull = 0, totalPartial = 0, totalWindow = 0;
2005                int count = 0;
2006                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
2007                    : wakelocks.entrySet()) {
2008                    Uid.Wakelock wl = ent.getValue();
2009                    String linePrefix = ": ";
2010                    sb.setLength(0);
2011                    sb.append(prefix);
2012                    sb.append("    Wake lock ");
2013                    sb.append(ent.getKey());
2014                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
2015                            "full", which, linePrefix);
2016                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
2017                            "partial", which, linePrefix);
2018                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
2019                            "window", which, linePrefix);
2020                    if (!linePrefix.equals(": ")) {
2021                        sb.append(" realtime");
2022                        // Only print out wake locks that were held
2023                        pw.println(sb.toString());
2024                        uidActivity = true;
2025                        count++;
2026                    }
2027                    totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
2028                            batteryRealtime, which);
2029                    totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
2030                            batteryRealtime, which);
2031                    totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
2032                            batteryRealtime, which);
2033                }
2034                if (count > 1) {
2035                    if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) {
2036                        sb.setLength(0);
2037                        sb.append(prefix);
2038                        sb.append("    TOTAL wake: ");
2039                        boolean needComma = false;
2040                        if (totalFull != 0) {
2041                            needComma = true;
2042                            formatTimeMs(sb, totalFull);
2043                            sb.append("full");
2044                        }
2045                        if (totalPartial != 0) {
2046                            if (needComma) {
2047                                sb.append(", ");
2048                            }
2049                            needComma = true;
2050                            formatTimeMs(sb, totalPartial);
2051                            sb.append("partial");
2052                        }
2053                        if (totalWindow != 0) {
2054                            if (needComma) {
2055                                sb.append(", ");
2056                            }
2057                            needComma = true;
2058                            formatTimeMs(sb, totalWindow);
2059                            sb.append("window");
2060                        }
2061                        sb.append(" realtime");
2062                        pw.println(sb.toString());
2063                    }
2064                }
2065            }
2066
2067            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
2068            if (sensors.size() > 0) {
2069                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
2070                    : sensors.entrySet()) {
2071                    Uid.Sensor se = ent.getValue();
2072                    int sensorNumber = ent.getKey();
2073                    sb.setLength(0);
2074                    sb.append(prefix);
2075                    sb.append("    Sensor ");
2076                    int handle = se.getHandle();
2077                    if (handle == Uid.Sensor.GPS) {
2078                        sb.append("GPS");
2079                    } else {
2080                        sb.append(handle);
2081                    }
2082                    sb.append(": ");
2083
2084                    Timer timer = se.getSensorTime();
2085                    if (timer != null) {
2086                        // Convert from microseconds to milliseconds with rounding
2087                        long totalTime = (timer.getTotalTimeLocked(
2088                                batteryRealtime, which) + 500) / 1000;
2089                        int count = timer.getCountLocked(which);
2090                        //timer.logState();
2091                        if (totalTime != 0) {
2092                            formatTimeMs(sb, totalTime);
2093                            sb.append("realtime (");
2094                            sb.append(count);
2095                            sb.append(" times)");
2096                        } else {
2097                            sb.append("(not used)");
2098                        }
2099                    } else {
2100                        sb.append("(not used)");
2101                    }
2102
2103                    pw.println(sb.toString());
2104                    uidActivity = true;
2105                }
2106            }
2107
2108            Timer vibTimer = u.getVibratorOnTimer();
2109            if (vibTimer != null) {
2110                // Convert from microseconds to milliseconds with rounding
2111                long totalTime = (vibTimer.getTotalTimeLocked(
2112                        batteryRealtime, which) + 500) / 1000;
2113                int count = vibTimer.getCountLocked(which);
2114                //timer.logState();
2115                if (totalTime != 0) {
2116                    sb.setLength(0);
2117                    sb.append(prefix);
2118                    sb.append("    Vibrator: ");
2119                    formatTimeMs(sb, totalTime);
2120                    sb.append("realtime (");
2121                    sb.append(count);
2122                    sb.append(" times)");
2123                    pw.println(sb.toString());
2124                    uidActivity = true;
2125                }
2126            }
2127
2128            Timer fgTimer = u.getForegroundActivityTimer();
2129            if (fgTimer != null) {
2130                // Convert from microseconds to milliseconds with rounding
2131                long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
2132                int count = fgTimer.getCountLocked(which);
2133                if (totalTime != 0) {
2134                    sb.setLength(0);
2135                    sb.append(prefix);
2136                    sb.append("    Foreground activities: ");
2137                    formatTimeMs(sb, totalTime);
2138                    sb.append("realtime (");
2139                    sb.append(count);
2140                    sb.append(" times)");
2141                    pw.println(sb.toString());
2142                    uidActivity = true;
2143                }
2144            }
2145
2146            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
2147            if (processStats.size() > 0) {
2148                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
2149                    : processStats.entrySet()) {
2150                    Uid.Proc ps = ent.getValue();
2151                    long userTime;
2152                    long systemTime;
2153                    long foregroundTime;
2154                    int starts;
2155                    int numExcessive;
2156
2157                    userTime = ps.getUserTime(which);
2158                    systemTime = ps.getSystemTime(which);
2159                    foregroundTime = ps.getForegroundTime(which);
2160                    starts = ps.getStarts(which);
2161                    numExcessive = which == STATS_SINCE_CHARGED
2162                            ? ps.countExcessivePowers() : 0;
2163
2164                    if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
2165                            || numExcessive != 0) {
2166                        sb.setLength(0);
2167                        sb.append(prefix); sb.append("    Proc ");
2168                                sb.append(ent.getKey()); sb.append(":\n");
2169                        sb.append(prefix); sb.append("      CPU: ");
2170                                formatTime(sb, userTime); sb.append("usr + ");
2171                                formatTime(sb, systemTime); sb.append("krn ; ");
2172                                formatTime(sb, foregroundTime); sb.append("fg");
2173                        if (starts != 0) {
2174                            sb.append("\n"); sb.append(prefix); sb.append("      ");
2175                                    sb.append(starts); sb.append(" proc starts");
2176                        }
2177                        pw.println(sb.toString());
2178                        for (int e=0; e<numExcessive; e++) {
2179                            Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
2180                            if (ew != null) {
2181                                pw.print(prefix); pw.print("      * Killed for ");
2182                                        if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
2183                                            pw.print("wake lock");
2184                                        } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
2185                                            pw.print("cpu");
2186                                        } else {
2187                                            pw.print("unknown");
2188                                        }
2189                                        pw.print(" use: ");
2190                                        TimeUtils.formatDuration(ew.usedTime, pw);
2191                                        pw.print(" over ");
2192                                        TimeUtils.formatDuration(ew.overTime, pw);
2193                                        if (ew.overTime != 0) {
2194                                            pw.print(" (");
2195                                            pw.print((ew.usedTime*100)/ew.overTime);
2196                                            pw.println("%)");
2197                                        }
2198                            }
2199                        }
2200                        uidActivity = true;
2201                    }
2202                }
2203            }
2204
2205            Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
2206            if (packageStats.size() > 0) {
2207                for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
2208                    : packageStats.entrySet()) {
2209                    pw.print(prefix); pw.print("    Apk "); pw.print(ent.getKey()); pw.println(":");
2210                    boolean apkActivity = false;
2211                    Uid.Pkg ps = ent.getValue();
2212                    int wakeups = ps.getWakeups(which);
2213                    if (wakeups != 0) {
2214                        pw.print(prefix); pw.print("      ");
2215                                pw.print(wakeups); pw.println(" wakeup alarms");
2216                        apkActivity = true;
2217                    }
2218                    Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
2219                    if (serviceStats.size() > 0) {
2220                        for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
2221                                : serviceStats.entrySet()) {
2222                            BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
2223                            long startTime = ss.getStartTime(batteryUptime, which);
2224                            int starts = ss.getStarts(which);
2225                            int launches = ss.getLaunches(which);
2226                            if (startTime != 0 || starts != 0 || launches != 0) {
2227                                sb.setLength(0);
2228                                sb.append(prefix); sb.append("      Service ");
2229                                        sb.append(sent.getKey()); sb.append(":\n");
2230                                sb.append(prefix); sb.append("        Created for: ");
2231                                        formatTimeMs(sb, startTime / 1000);
2232                                        sb.append("uptime\n");
2233                                sb.append(prefix); sb.append("        Starts: ");
2234                                        sb.append(starts);
2235                                        sb.append(", launches: "); sb.append(launches);
2236                                pw.println(sb.toString());
2237                                apkActivity = true;
2238                            }
2239                        }
2240                    }
2241                    if (!apkActivity) {
2242                        pw.print(prefix); pw.println("      (nothing executed)");
2243                    }
2244                    uidActivity = true;
2245                }
2246            }
2247            if (!uidActivity) {
2248                pw.print(prefix); pw.println("    (nothing executed)");
2249            }
2250        }
2251    }
2252
2253    static void printBitDescriptions(PrintWriter pw, int oldval, int newval,
2254            BitDescription[] descriptions, boolean longNames) {
2255        int diff = oldval ^ newval;
2256        if (diff == 0) return;
2257        for (int i=0; i<descriptions.length; i++) {
2258            BitDescription bd = descriptions[i];
2259            int mask = bd.mask;
2260            if (bd.shift > 0) {
2261                mask <<= bd.shift;
2262            }
2263            if ((diff&mask) != 0) {
2264                pw.print(longNames ? " " : ",");
2265                if (bd.shift < 0) {
2266                    pw.print((newval&mask) != 0 ? "+" : "-");
2267                    pw.print(longNames ? bd.name : bd.shortName);
2268                } else {
2269                    pw.print(longNames ? bd.name : bd.shortName);
2270                    pw.print("=");
2271                    int val = (newval&bd.mask)>>bd.shift;
2272                    if (bd.values != null && val >= 0 && val < bd.values.length) {
2273                        pw.print(longNames? bd.values[val] : bd.shortValues[val]);
2274                    } else {
2275                        pw.print(val);
2276                    }
2277                }
2278            }
2279        }
2280    }
2281
2282    public void prepareForDumpLocked() {
2283    }
2284
2285    public static class HistoryPrinter {
2286        int oldState = 0;
2287        int oldLevel = -1;
2288        int oldStatus = -1;
2289        int oldHealth = -1;
2290        int oldPlug = -1;
2291        int oldTemp = -1;
2292        int oldVolt = -1;
2293        long lastTime = -1;
2294
2295        public void printNextItem(PrintWriter pw, HistoryItem rec, long now, boolean checkin) {
2296            if (!checkin) {
2297                pw.print("  ");
2298                TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
2299                pw.print(" ");
2300            } else {
2301                if (lastTime < 0) {
2302                    pw.print("@");
2303                    pw.print(rec.time-now);
2304                } else {
2305                    pw.print(rec.time-lastTime);
2306                }
2307                lastTime = rec.time;
2308            }
2309            if (rec.cmd == HistoryItem.CMD_START) {
2310                if (checkin) {
2311                    pw.print(":");
2312                }
2313                pw.println("START");
2314            } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
2315                if (checkin) {
2316                    pw.print(":");
2317                }
2318                pw.println("*OVERFLOW*");
2319            } else {
2320                if (!checkin) {
2321                    if (rec.batteryLevel < 10) pw.print("00");
2322                    else if (rec.batteryLevel < 100) pw.print("0");
2323                    pw.print(rec.batteryLevel);
2324                    pw.print(" ");
2325                    if (rec.states < 0x10) pw.print("0000000");
2326                    else if (rec.states < 0x100) pw.print("000000");
2327                    else if (rec.states < 0x1000) pw.print("00000");
2328                    else if (rec.states < 0x10000) pw.print("0000");
2329                    else if (rec.states < 0x100000) pw.print("000");
2330                    else if (rec.states < 0x1000000) pw.print("00");
2331                    else if (rec.states < 0x10000000) pw.print("0");
2332                    pw.print(Integer.toHexString(rec.states));
2333                } else {
2334                    if (oldLevel != rec.batteryLevel) {
2335                        oldLevel = rec.batteryLevel;
2336                        pw.print(",Bl="); pw.print(rec.batteryLevel);
2337                    }
2338                }
2339                if (oldStatus != rec.batteryStatus) {
2340                    oldStatus = rec.batteryStatus;
2341                    pw.print(checkin ? ",Bs=" : " status=");
2342                    switch (oldStatus) {
2343                        case BatteryManager.BATTERY_STATUS_UNKNOWN:
2344                            pw.print(checkin ? "?" : "unknown");
2345                            break;
2346                        case BatteryManager.BATTERY_STATUS_CHARGING:
2347                            pw.print(checkin ? "c" : "charging");
2348                            break;
2349                        case BatteryManager.BATTERY_STATUS_DISCHARGING:
2350                            pw.print(checkin ? "d" : "discharging");
2351                            break;
2352                        case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
2353                            pw.print(checkin ? "n" : "not-charging");
2354                            break;
2355                        case BatteryManager.BATTERY_STATUS_FULL:
2356                            pw.print(checkin ? "f" : "full");
2357                            break;
2358                        default:
2359                            pw.print(oldStatus);
2360                            break;
2361                    }
2362                }
2363                if (oldHealth != rec.batteryHealth) {
2364                    oldHealth = rec.batteryHealth;
2365                    pw.print(checkin ? ",Bh=" : " health=");
2366                    switch (oldHealth) {
2367                        case BatteryManager.BATTERY_HEALTH_UNKNOWN:
2368                            pw.print(checkin ? "?" : "unknown");
2369                            break;
2370                        case BatteryManager.BATTERY_HEALTH_GOOD:
2371                            pw.print(checkin ? "g" : "good");
2372                            break;
2373                        case BatteryManager.BATTERY_HEALTH_OVERHEAT:
2374                            pw.print(checkin ? "h" : "overheat");
2375                            break;
2376                        case BatteryManager.BATTERY_HEALTH_DEAD:
2377                            pw.print(checkin ? "d" : "dead");
2378                            break;
2379                        case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
2380                            pw.print(checkin ? "v" : "over-voltage");
2381                            break;
2382                        case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
2383                            pw.print(checkin ? "f" : "failure");
2384                            break;
2385                        default:
2386                            pw.print(oldHealth);
2387                            break;
2388                    }
2389                }
2390                if (oldPlug != rec.batteryPlugType) {
2391                    oldPlug = rec.batteryPlugType;
2392                    pw.print(checkin ? ",Bp=" : " plug=");
2393                    switch (oldPlug) {
2394                        case 0:
2395                            pw.print(checkin ? "n" : "none");
2396                            break;
2397                        case BatteryManager.BATTERY_PLUGGED_AC:
2398                            pw.print(checkin ? "a" : "ac");
2399                            break;
2400                        case BatteryManager.BATTERY_PLUGGED_USB:
2401                            pw.print(checkin ? "u" : "usb");
2402                            break;
2403                        case BatteryManager.BATTERY_PLUGGED_WIRELESS:
2404                            pw.print(checkin ? "w" : "wireless");
2405                            break;
2406                        default:
2407                            pw.print(oldPlug);
2408                            break;
2409                    }
2410                }
2411                if (oldTemp != rec.batteryTemperature) {
2412                    oldTemp = rec.batteryTemperature;
2413                    pw.print(checkin ? ",Bt=" : " temp=");
2414                    pw.print(oldTemp);
2415                }
2416                if (oldVolt != rec.batteryVoltage) {
2417                    oldVolt = rec.batteryVoltage;
2418                    pw.print(checkin ? ",Bv=" : " volt=");
2419                    pw.print(oldVolt);
2420                }
2421                printBitDescriptions(pw, oldState, rec.states,
2422                        HISTORY_STATE_DESCRIPTIONS, !checkin);
2423                if (rec.eventCode != HistoryItem.EVENT_NONE) {
2424                    switch (rec.eventCode) {
2425                        case HistoryItem.EVENT_PROC_STARTED:
2426                            pw.print(checkin ? ",PrSt=" : " procstart=");
2427                            break;
2428                        case HistoryItem.EVENT_PROC_FINISHED:
2429                            pw.print(checkin ? ",PrFn=" : " procfin=");
2430                            break;
2431                        default:
2432                            if (checkin) {
2433                                pw.print(",?cmd_");
2434                                pw.print(rec.eventCode);
2435                                pw.print("=");
2436                            } else {
2437                                pw.print(" cmd_");
2438                                pw.print(rec.eventCode);
2439                                pw.print("=");
2440                            }
2441                            break;
2442                    }
2443                    if (checkin) {
2444                        pw.print(rec.eventUid);
2445                    } else {
2446                        UserHandle.formatUid(pw, rec.eventUid);
2447                    }
2448                    pw.print(":");
2449                    if (checkin) {
2450                        pw.print(rec.eventNameIdx);
2451                    } else {
2452                        pw.print(rec.eventName);
2453                    }
2454                }
2455                pw.println();
2456            }
2457            oldState = rec.states;
2458        }
2459    }
2460
2461    /**
2462     * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
2463     *
2464     * @param pw a Printer to receive the dump output.
2465     */
2466    @SuppressWarnings("unused")
2467    public void dumpLocked(Context context, PrintWriter pw, boolean isUnpluggedOnly, int reqUid,
2468            boolean historyOnly) {
2469        prepareForDumpLocked();
2470
2471        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
2472
2473        final HistoryItem rec = new HistoryItem();
2474        if (startIteratingHistoryLocked()) {
2475            pw.println("Battery History:");
2476            HistoryPrinter hprinter = new HistoryPrinter();
2477            while (getNextHistoryLocked(rec)) {
2478                hprinter.printNextItem(pw, rec, now, false);
2479            }
2480            finishIteratingHistoryLocked();
2481            pw.println("");
2482        }
2483
2484        if (startIteratingOldHistoryLocked()) {
2485            pw.println("Old battery History:");
2486            HistoryPrinter hprinter = new HistoryPrinter();
2487            while (getNextOldHistoryLocked(rec)) {
2488                hprinter.printNextItem(pw, rec, now, false);
2489            }
2490            finishIteratingOldHistoryLocked();
2491            pw.println("");
2492        }
2493
2494        if (historyOnly) {
2495            return;
2496        }
2497
2498        SparseArray<? extends Uid> uidStats = getUidStats();
2499        final int NU = uidStats.size();
2500        boolean didPid = false;
2501        long nowRealtime = SystemClock.elapsedRealtime();
2502        for (int i=0; i<NU; i++) {
2503            Uid uid = uidStats.valueAt(i);
2504            SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
2505            if (pids != null) {
2506                for (int j=0; j<pids.size(); j++) {
2507                    Uid.Pid pid = pids.valueAt(j);
2508                    if (!didPid) {
2509                        pw.println("Per-PID Stats:");
2510                        didPid = true;
2511                    }
2512                    long time = pid.mWakeSum + (pid.mWakeStart != 0
2513                            ? (nowRealtime - pid.mWakeStart) : 0);
2514                    pw.print("  PID "); pw.print(pids.keyAt(j));
2515                            pw.print(" wake time: ");
2516                            TimeUtils.formatDuration(time, pw);
2517                            pw.println("");
2518                }
2519            }
2520        }
2521        if (didPid) {
2522            pw.println("");
2523        }
2524
2525        if (!isUnpluggedOnly) {
2526            pw.println("Statistics since last charge:");
2527            pw.println("  System starts: " + getStartCount()
2528                    + ", currently on battery: " + getIsOnBattery());
2529            dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid);
2530            pw.println("");
2531        }
2532        pw.println("Statistics since last unplugged:");
2533        dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid);
2534    }
2535
2536    @SuppressWarnings("unused")
2537    public void dumpCheckinLocked(Context context,
2538            PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly,
2539            boolean includeHistory, boolean historyOnly) {
2540        prepareForDumpLocked();
2541
2542        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
2543
2544        if (includeHistory || historyOnly) {
2545            final HistoryItem rec = new HistoryItem();
2546            if (startIteratingHistoryLocked()) {
2547                for (int i=0; i<getHistoryStringPoolSize(); i++) {
2548                    pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
2549                    pw.print(HISTORY_STRING_POOL); pw.print(',');
2550                    pw.print(i);
2551                    pw.print(',');
2552                    pw.print(getHistoryStringPoolItem(i));
2553                    pw.println();
2554                }
2555                HistoryPrinter hprinter = new HistoryPrinter();
2556                while (getNextHistoryLocked(rec)) {
2557                    pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
2558                    pw.print(HISTORY_DATA); pw.print(',');
2559                    hprinter.printNextItem(pw, rec, now, true);
2560                }
2561                finishIteratingHistoryLocked();
2562            }
2563        }
2564
2565        if (historyOnly) {
2566            return;
2567        }
2568
2569        if (apps != null) {
2570            SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
2571            for (int i=0; i<apps.size(); i++) {
2572                ApplicationInfo ai = apps.get(i);
2573                ArrayList<String> pkgs = uids.get(ai.uid);
2574                if (pkgs == null) {
2575                    pkgs = new ArrayList<String>();
2576                    uids.put(ai.uid, pkgs);
2577                }
2578                pkgs.add(ai.packageName);
2579            }
2580            SparseArray<? extends Uid> uidStats = getUidStats();
2581            final int NU = uidStats.size();
2582            String[] lineArgs = new String[2];
2583            for (int i=0; i<NU; i++) {
2584                int uid = uidStats.keyAt(i);
2585                ArrayList<String> pkgs = uids.get(uid);
2586                if (pkgs != null) {
2587                    for (int j=0; j<pkgs.size(); j++) {
2588                        lineArgs[0] = Integer.toString(uid);
2589                        lineArgs[1] = pkgs.get(j);
2590                        dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
2591                                (Object[])lineArgs);
2592                    }
2593                }
2594            }
2595        }
2596        if (isUnpluggedOnly) {
2597            dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1);
2598        }
2599        else {
2600            dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1);
2601            dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1);
2602        }
2603    }
2604}
2605