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