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