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