BatteryStats.java revision b50a684ba8310a7d9b9738f9304b029268dedd64
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 android.app.ActivityManager;
20import android.app.job.JobParameters;
21import android.content.Context;
22import android.content.pm.ApplicationInfo;
23import android.service.batterystats.BatteryStatsServiceDumpProto;
24import android.telephony.SignalStrength;
25import android.text.format.DateFormat;
26import android.util.ArrayMap;
27import android.util.LongSparseArray;
28import android.util.MutableBoolean;
29import android.util.Pair;
30import android.util.Printer;
31import android.util.SparseArray;
32import android.util.SparseIntArray;
33import android.util.TimeUtils;
34import android.util.proto.ProtoOutputStream;
35import android.view.Display;
36
37import com.android.internal.annotations.VisibleForTesting;
38import com.android.internal.location.gnssmetrics.GnssMetrics;
39import com.android.internal.os.BatterySipper;
40import com.android.internal.os.BatteryStatsHelper;
41
42import java.io.FileDescriptor;
43import java.io.PrintWriter;
44import java.util.ArrayList;
45import java.util.Collections;
46import java.util.Comparator;
47import java.util.Formatter;
48import java.util.HashMap;
49import java.util.List;
50import java.util.Map;
51
52/**
53 * A class providing access to battery usage statistics, including information on
54 * wakelocks, processes, packages, and services.  All times are represented in microseconds
55 * except where indicated otherwise.
56 * @hide
57 */
58public abstract class BatteryStats implements Parcelable {
59    private static final String TAG = "BatteryStats";
60
61    private static final boolean LOCAL_LOGV = false;
62    /** Fetching RPM stats is too slow to do each time screen changes, so disable it. */
63    protected static final boolean SCREEN_OFF_RPM_STATS_ENABLED = false;
64
65    /** @hide */
66    public static final String SERVICE_NAME = "batterystats";
67
68    /**
69     * A constant indicating a partial wake lock timer.
70     */
71    public static final int WAKE_TYPE_PARTIAL = 0;
72
73    /**
74     * A constant indicating a full wake lock timer.
75     */
76    public static final int WAKE_TYPE_FULL = 1;
77
78    /**
79     * A constant indicating a window wake lock timer.
80     */
81    public static final int WAKE_TYPE_WINDOW = 2;
82
83    /**
84     * A constant indicating a sensor timer.
85     */
86    public static final int SENSOR = 3;
87
88    /**
89     * A constant indicating a a wifi running timer
90     */
91    public static final int WIFI_RUNNING = 4;
92
93    /**
94     * A constant indicating a full wifi lock timer
95     */
96    public static final int FULL_WIFI_LOCK = 5;
97
98    /**
99     * A constant indicating a wifi scan
100     */
101    public static final int WIFI_SCAN = 6;
102
103    /**
104     * A constant indicating a wifi multicast timer
105     */
106    public static final int WIFI_MULTICAST_ENABLED = 7;
107
108    /**
109     * A constant indicating a video turn on timer
110     */
111    public static final int VIDEO_TURNED_ON = 8;
112
113    /**
114     * A constant indicating a vibrator on timer
115     */
116    public static final int VIBRATOR_ON = 9;
117
118    /**
119     * A constant indicating a foreground activity timer
120     */
121    public static final int FOREGROUND_ACTIVITY = 10;
122
123    /**
124     * A constant indicating a wifi batched scan is active
125     */
126    public static final int WIFI_BATCHED_SCAN = 11;
127
128    /**
129     * A constant indicating a process state timer
130     */
131    public static final int PROCESS_STATE = 12;
132
133    /**
134     * A constant indicating a sync timer
135     */
136    public static final int SYNC = 13;
137
138    /**
139     * A constant indicating a job timer
140     */
141    public static final int JOB = 14;
142
143    /**
144     * A constant indicating an audio turn on timer
145     */
146    public static final int AUDIO_TURNED_ON = 15;
147
148    /**
149     * A constant indicating a flashlight turn on timer
150     */
151    public static final int FLASHLIGHT_TURNED_ON = 16;
152
153    /**
154     * A constant indicating a camera turn on timer
155     */
156    public static final int CAMERA_TURNED_ON = 17;
157
158    /**
159     * A constant indicating a draw wake lock timer.
160     */
161    public static final int WAKE_TYPE_DRAW = 18;
162
163    /**
164     * A constant indicating a bluetooth scan timer.
165     */
166    public static final int BLUETOOTH_SCAN_ON = 19;
167
168    /**
169     * A constant indicating an aggregated partial wake lock timer.
170     */
171    public static final int AGGREGATED_WAKE_TYPE_PARTIAL = 20;
172
173    /**
174     * A constant indicating a bluetooth scan timer for unoptimized scans.
175     */
176    public static final int BLUETOOTH_UNOPTIMIZED_SCAN_ON = 21;
177
178    /**
179     * A constant indicating a foreground service timer
180     */
181    public static final int FOREGROUND_SERVICE = 22;
182
183    /**
184     * A constant indicating an aggregate wifi multicast timer
185     */
186     public static final int WIFI_AGGREGATE_MULTICAST_ENABLED = 23;
187
188    /**
189     * Include all of the data in the stats, including previously saved data.
190     */
191    public static final int STATS_SINCE_CHARGED = 0;
192
193    /**
194     * Include only the current run in the stats.
195     */
196    public static final int STATS_CURRENT = 1;
197
198    /**
199     * Include only the run since the last time the device was unplugged in the stats.
200     */
201    public static final int STATS_SINCE_UNPLUGGED = 2;
202
203    // NOTE: Update this list if you add/change any stats above.
204    // These characters are supposed to represent "total", "last", "current",
205    // and "unplugged". They were shortened for efficiency sake.
206    private static final String[] STAT_NAMES = { "l", "c", "u" };
207
208    /**
209     * Current version of checkin data format.
210     *
211     * New in version 19:
212     *   - Wakelock data (wl) gets current and max times.
213     * New in version 20:
214     *   - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs, Syncs.
215     * New in version 21:
216     *   - Actual (not just apportioned) Wakelock time is also recorded.
217     *   - Aggregated partial wakelock time (per uid, instead of per wakelock) is recorded.
218     *   - BLE scan result count
219     *   - CPU frequency time per uid
220     * New in version 22:
221     *   - BLE scan result background count, BLE unoptimized scan time
222     *   - Background partial wakelock time & count
223     * New in version 23:
224     *   - Logging smeared power model values
225     * New in version 24:
226     *   - Fixed bugs in background timers and BLE scan time
227     * New in version 25:
228     *   - Package wakeup alarms are now on screen-off timebase
229     * New in version 26:
230     *   - Resource power manager (rpm) states [but screenOffRpm is disabled from working properly]
231     * New in version 27:
232     *   - Always On Display (screen doze mode) time and power
233     * New in version 28:
234     *   - Light/Deep Doze power
235     *   - WiFi Multicast Wakelock statistics (count & duration)
236     * New in version 29:
237     *   - Process states re-ordered. TOP_SLEEPING now below BACKGROUND. HEAVY_WEIGHT introduced.
238     *   - CPU times per UID process state
239     * New in version 30:
240     *   - Uid.PROCESS_STATE_FOREGROUND_SERVICE only tracks
241     *   ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE.
242     */
243    static final int CHECKIN_VERSION = 30;
244
245    /**
246     * Old version, we hit 9 and ran out of room, need to remove.
247     */
248    private static final int BATTERY_STATS_CHECKIN_VERSION = 9;
249
250    private static final long BYTES_PER_KB = 1024;
251    private static final long BYTES_PER_MB = 1048576; // 1024^2
252    private static final long BYTES_PER_GB = 1073741824; //1024^3
253
254    private static final String VERSION_DATA = "vers";
255    private static final String UID_DATA = "uid";
256    private static final String WAKEUP_ALARM_DATA = "wua";
257    private static final String APK_DATA = "apk";
258    private static final String PROCESS_DATA = "pr";
259    private static final String CPU_DATA = "cpu";
260    private static final String GLOBAL_CPU_FREQ_DATA = "gcf";
261    private static final String CPU_TIMES_AT_FREQ_DATA = "ctf";
262    // rpm line is:
263    // BATTERY_STATS_CHECKIN_VERSION, uid, which, "rpm", state/voter name, total time, total count,
264    // screen-off time, screen-off count
265    private static final String RESOURCE_POWER_MANAGER_DATA = "rpm";
266    private static final String SENSOR_DATA = "sr";
267    private static final String VIBRATOR_DATA = "vib";
268    private static final String FOREGROUND_ACTIVITY_DATA = "fg";
269    // fgs line is:
270    // BATTERY_STATS_CHECKIN_VERSION, uid, category, "fgs",
271    // foreground service time, count
272    private static final String FOREGROUND_SERVICE_DATA = "fgs";
273    private static final String STATE_TIME_DATA = "st";
274    // wl line is:
275    // BATTERY_STATS_CHECKIN_VERSION, uid, which, "wl", name,
276    // full        totalTime, 'f',  count, current duration, max duration, total duration,
277    // partial     totalTime, 'p',  count, current duration, max duration, total duration,
278    // bg partial  totalTime, 'bp', count, current duration, max duration, total duration,
279    // window      totalTime, 'w',  count, current duration, max duration, total duration
280    // [Currently, full and window wakelocks have durations current = max = total = -1]
281    private static final String WAKELOCK_DATA = "wl";
282    // awl line is:
283    // BATTERY_STATS_CHECKIN_VERSION, uid, which, "awl",
284    // cumulative partial wakelock duration, cumulative background partial wakelock duration
285    private static final String AGGREGATED_WAKELOCK_DATA = "awl";
286    private static final String SYNC_DATA = "sy";
287    private static final String JOB_DATA = "jb";
288    private static final String JOB_COMPLETION_DATA = "jbc";
289    private static final String KERNEL_WAKELOCK_DATA = "kwl";
290    private static final String WAKEUP_REASON_DATA = "wr";
291    private static final String NETWORK_DATA = "nt";
292    private static final String USER_ACTIVITY_DATA = "ua";
293    private static final String BATTERY_DATA = "bt";
294    private static final String BATTERY_DISCHARGE_DATA = "dc";
295    private static final String BATTERY_LEVEL_DATA = "lv";
296    private static final String GLOBAL_WIFI_DATA = "gwfl";
297    private static final String WIFI_DATA = "wfl";
298    private static final String GLOBAL_WIFI_CONTROLLER_DATA = "gwfcd";
299    private static final String WIFI_CONTROLLER_DATA = "wfcd";
300    private static final String GLOBAL_BLUETOOTH_CONTROLLER_DATA = "gble";
301    private static final String BLUETOOTH_CONTROLLER_DATA = "ble";
302    private static final String BLUETOOTH_MISC_DATA = "blem";
303    private static final String MISC_DATA = "m";
304    private static final String GLOBAL_NETWORK_DATA = "gn";
305    private static final String GLOBAL_MODEM_CONTROLLER_DATA = "gmcd";
306    private static final String MODEM_CONTROLLER_DATA = "mcd";
307    private static final String HISTORY_STRING_POOL = "hsp";
308    private static final String HISTORY_DATA = "h";
309    private static final String SCREEN_BRIGHTNESS_DATA = "br";
310    private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
311    private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
312    private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
313    private static final String DATA_CONNECTION_TIME_DATA = "dct";
314    private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
315    private static final String WIFI_STATE_TIME_DATA = "wst";
316    private static final String WIFI_STATE_COUNT_DATA = "wsc";
317    private static final String WIFI_SUPPL_STATE_TIME_DATA = "wsst";
318    private static final String WIFI_SUPPL_STATE_COUNT_DATA = "wssc";
319    private static final String WIFI_SIGNAL_STRENGTH_TIME_DATA = "wsgt";
320    private static final String WIFI_SIGNAL_STRENGTH_COUNT_DATA = "wsgc";
321    private static final String POWER_USE_SUMMARY_DATA = "pws";
322    private static final String POWER_USE_ITEM_DATA = "pwi";
323    private static final String DISCHARGE_STEP_DATA = "dsd";
324    private static final String CHARGE_STEP_DATA = "csd";
325    private static final String DISCHARGE_TIME_REMAIN_DATA = "dtr";
326    private static final String CHARGE_TIME_REMAIN_DATA = "ctr";
327    private static final String FLASHLIGHT_DATA = "fla";
328    private static final String CAMERA_DATA = "cam";
329    private static final String VIDEO_DATA = "vid";
330    private static final String AUDIO_DATA = "aud";
331    private static final String WIFI_MULTICAST_TOTAL_DATA = "wmct";
332    private static final String WIFI_MULTICAST_DATA = "wmc";
333
334    public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
335
336    private final StringBuilder mFormatBuilder = new StringBuilder(32);
337    private final Formatter mFormatter = new Formatter(mFormatBuilder);
338
339    private static final String CELLULAR_CONTROLLER_NAME = "Cellular";
340    private static final String WIFI_CONTROLLER_NAME = "WiFi";
341
342    /**
343     * Indicates times spent by the uid at each cpu frequency in all process states.
344     *
345     * Other types might include times spent in foreground, background etc.
346     */
347    @VisibleForTesting
348    public static final String UID_TIMES_TYPE_ALL = "A";
349
350    /**
351     * State for keeping track of counting information.
352     */
353    public static abstract class Counter {
354
355        /**
356         * Returns the count associated with this Counter for the
357         * selected type of statistics.
358         *
359         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
360         */
361        public abstract int getCountLocked(int which);
362
363        /**
364         * Temporary for debugging.
365         */
366        public abstract void logState(Printer pw, String prefix);
367    }
368
369    /**
370     * State for keeping track of long counting information.
371     */
372    public static abstract class LongCounter {
373
374        /**
375         * Returns the count associated with this Counter for the
376         * selected type of statistics.
377         *
378         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
379         */
380        public abstract long getCountLocked(int which);
381
382        /**
383         * Temporary for debugging.
384         */
385        public abstract void logState(Printer pw, String prefix);
386    }
387
388    /**
389     * State for keeping track of array of long counting information.
390     */
391    public static abstract class LongCounterArray {
392        /**
393         * Returns the counts associated with this Counter for the
394         * selected type of statistics.
395         *
396         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
397         */
398        public abstract long[] getCountsLocked(int which);
399
400        /**
401         * Temporary for debugging.
402         */
403        public abstract void logState(Printer pw, String prefix);
404    }
405
406    /**
407     * Container class that aggregates counters for transmit, receive, and idle state of a
408     * radio controller.
409     */
410    public static abstract class ControllerActivityCounter {
411        /**
412         * @return a non-null {@link LongCounter} representing time spent (milliseconds) in the
413         * idle state.
414         */
415        public abstract LongCounter getIdleTimeCounter();
416
417        /**
418         * @return a non-null {@link LongCounter} representing time spent (milliseconds) in the
419         * scan state.
420         */
421        public abstract LongCounter getScanTimeCounter();
422
423
424        /**
425         * @return a non-null {@link LongCounter} representing time spent (milliseconds) in the
426         * receive state.
427         */
428        public abstract LongCounter getRxTimeCounter();
429
430        /**
431         * An array of {@link LongCounter}, representing various transmit levels, where each level
432         * may draw a different amount of power. The levels themselves are controller-specific.
433         * @return non-null array of {@link LongCounter}s representing time spent (milliseconds) in
434         * various transmit level states.
435         */
436        public abstract LongCounter[] getTxTimeCounters();
437
438        /**
439         * @return a non-null {@link LongCounter} representing the power consumed by the controller
440         * in all states, measured in milli-ampere-milliseconds (mAms). The counter may always
441         * yield a value of 0 if the device doesn't support power calculations.
442         */
443        public abstract LongCounter getPowerCounter();
444    }
445
446    /**
447     * State for keeping track of timing information.
448     */
449    public static abstract class Timer {
450
451        /**
452         * Returns the count associated with this Timer for the
453         * selected type of statistics.
454         *
455         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
456         */
457        public abstract int getCountLocked(int which);
458
459        /**
460         * Returns the total time in microseconds associated with this Timer for the
461         * selected type of statistics.
462         *
463         * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
464         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
465         * @return a time in microseconds
466         */
467        public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which);
468
469        /**
470         * Returns the total time in microseconds associated with this Timer since the
471         * 'mark' was last set.
472         *
473         * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
474         * @return a time in microseconds
475         */
476        public abstract long getTimeSinceMarkLocked(long elapsedRealtimeUs);
477
478        /**
479         * Returns the max duration if it is being tracked.
480         * Not all Timer subclasses track the max, total, and current durations.
481         */
482        public long getMaxDurationMsLocked(long elapsedRealtimeMs) {
483            return -1;
484        }
485
486        /**
487         * Returns the current time the timer has been active, if it is being tracked.
488         * Not all Timer subclasses track the max, total, and current durations.
489         */
490        public long getCurrentDurationMsLocked(long elapsedRealtimeMs) {
491            return -1;
492        }
493
494        /**
495         * Returns the total time the timer has been active, if it is being tracked.
496         *
497         * Returns the total cumulative duration (i.e. sum of past durations) that this timer has
498         * been on since reset.
499         * This may differ from getTotalTimeLocked(elapsedRealtimeUs, STATS_SINCE_CHARGED)/1000 since,
500         * depending on the Timer, getTotalTimeLocked may represent the total 'blamed' or 'pooled'
501         * time, rather than the actual time. By contrast, getTotalDurationMsLocked always gives
502         * the actual total time.
503         * Not all Timer subclasses track the max, total, and current durations.
504         */
505        public long getTotalDurationMsLocked(long elapsedRealtimeMs) {
506            return -1;
507        }
508
509        /**
510         * Returns the secondary Timer held by the Timer, if one exists. This secondary timer may be
511         * used, for example, for tracking background usage. Secondary timers are never pooled.
512         *
513         * Not all Timer subclasses have a secondary timer; those that don't return null.
514         */
515        public Timer getSubTimer() {
516            return null;
517        }
518
519        /**
520         * Returns whether the timer is currently running.  Some types of timers
521         * (e.g. BatchTimers) don't know whether the event is currently active,
522         * and report false.
523         */
524        public boolean isRunningLocked() {
525            return false;
526        }
527
528        /**
529         * Temporary for debugging.
530         */
531        public abstract void logState(Printer pw, String prefix);
532    }
533
534    /**
535     * Maps the ActivityManager procstate into corresponding BatteryStats procstate.
536     */
537    public static int mapToInternalProcessState(int procState) {
538        if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
539            return ActivityManager.PROCESS_STATE_NONEXISTENT;
540        } else if (procState == ActivityManager.PROCESS_STATE_TOP) {
541            return Uid.PROCESS_STATE_TOP;
542        } else if (procState == ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
543            // State when app has put itself in the foreground.
544            return Uid.PROCESS_STATE_FOREGROUND_SERVICE;
545        } else if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
546            // Persistent and other foreground states go here.
547            return Uid.PROCESS_STATE_FOREGROUND;
548        } else if (procState <= ActivityManager.PROCESS_STATE_RECEIVER) {
549            return Uid.PROCESS_STATE_BACKGROUND;
550        } else if (procState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
551            return Uid.PROCESS_STATE_TOP_SLEEPING;
552        } else if (procState <= ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
553            return Uid.PROCESS_STATE_HEAVY_WEIGHT;
554        } else {
555            return Uid.PROCESS_STATE_CACHED;
556        }
557    }
558
559    /**
560     * The statistics associated with a particular uid.
561     */
562    public static abstract class Uid {
563
564        /**
565         * Returns a mapping containing wakelock statistics.
566         *
567         * @return a Map from Strings to Uid.Wakelock objects.
568         */
569        public abstract ArrayMap<String, ? extends Wakelock> getWakelockStats();
570
571        /**
572         * Returns the WiFi Multicast Wakelock statistics.
573         *
574         * @return a Timer Object for the per uid Multicast statistics.
575         */
576        public abstract Timer getMulticastWakelockStats();
577
578        /**
579         * Returns a mapping containing sync statistics.
580         *
581         * @return a Map from Strings to Timer objects.
582         */
583        public abstract ArrayMap<String, ? extends Timer> getSyncStats();
584
585        /**
586         * Returns a mapping containing scheduled job statistics.
587         *
588         * @return a Map from Strings to Timer objects.
589         */
590        public abstract ArrayMap<String, ? extends Timer> getJobStats();
591
592        /**
593         * Returns statistics about how jobs have completed.
594         *
595         * @return A Map of String job names to completion type -> count mapping.
596         */
597        public abstract ArrayMap<String, SparseIntArray> getJobCompletionStats();
598
599        /**
600         * The statistics associated with a particular wake lock.
601         */
602        public static abstract class Wakelock {
603            public abstract Timer getWakeTime(int type);
604        }
605
606        /**
607         * The cumulative time the uid spent holding any partial wakelocks. This will generally
608         * differ from summing over the Wakelocks in getWakelockStats since the latter may have
609         * wakelocks that overlap in time (and therefore over-counts).
610         */
611        public abstract Timer getAggregatedPartialWakelockTimer();
612
613        /**
614         * Returns a mapping containing sensor statistics.
615         *
616         * @return a Map from Integer sensor ids to Uid.Sensor objects.
617         */
618        public abstract SparseArray<? extends Sensor> getSensorStats();
619
620        /**
621         * Returns a mapping containing active process data.
622         */
623        public abstract SparseArray<? extends Pid> getPidStats();
624
625        /**
626         * Returns a mapping containing process statistics.
627         *
628         * @return a Map from Strings to Uid.Proc objects.
629         */
630        public abstract ArrayMap<String, ? extends Proc> getProcessStats();
631
632        /**
633         * Returns a mapping containing package statistics.
634         *
635         * @return a Map from Strings to Uid.Pkg objects.
636         */
637        public abstract ArrayMap<String, ? extends Pkg> getPackageStats();
638
639        public abstract ControllerActivityCounter getWifiControllerActivity();
640        public abstract ControllerActivityCounter getBluetoothControllerActivity();
641        public abstract ControllerActivityCounter getModemControllerActivity();
642
643        /**
644         * {@hide}
645         */
646        public abstract int getUid();
647
648        public abstract void noteWifiRunningLocked(long elapsedRealtime);
649        public abstract void noteWifiStoppedLocked(long elapsedRealtime);
650        public abstract void noteFullWifiLockAcquiredLocked(long elapsedRealtime);
651        public abstract void noteFullWifiLockReleasedLocked(long elapsedRealtime);
652        public abstract void noteWifiScanStartedLocked(long elapsedRealtime);
653        public abstract void noteWifiScanStoppedLocked(long elapsedRealtime);
654        public abstract void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime);
655        public abstract void noteWifiBatchedScanStoppedLocked(long elapsedRealtime);
656        public abstract void noteWifiMulticastEnabledLocked(long elapsedRealtime);
657        public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime);
658        public abstract void noteActivityResumedLocked(long elapsedRealtime);
659        public abstract void noteActivityPausedLocked(long elapsedRealtime);
660        public abstract long getWifiRunningTime(long elapsedRealtimeUs, int which);
661        public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which);
662        public abstract long getWifiScanTime(long elapsedRealtimeUs, int which);
663        public abstract int getWifiScanCount(int which);
664        /**
665         * Returns the timer keeping track of wifi scans.
666         */
667        public abstract Timer getWifiScanTimer();
668        public abstract int getWifiScanBackgroundCount(int which);
669        public abstract long getWifiScanActualTime(long elapsedRealtimeUs);
670        public abstract long getWifiScanBackgroundTime(long elapsedRealtimeUs);
671        /**
672         * Returns the timer keeping track of background wifi scans.
673         */
674        public abstract Timer getWifiScanBackgroundTimer();
675        public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which);
676        public abstract int getWifiBatchedScanCount(int csphBin, int which);
677        public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which);
678        public abstract Timer getAudioTurnedOnTimer();
679        public abstract Timer getVideoTurnedOnTimer();
680        public abstract Timer getFlashlightTurnedOnTimer();
681        public abstract Timer getCameraTurnedOnTimer();
682        public abstract Timer getForegroundActivityTimer();
683
684        /**
685         * Returns the timer keeping track of Foreground Service time
686         */
687        public abstract Timer getForegroundServiceTimer();
688        public abstract Timer getBluetoothScanTimer();
689        public abstract Timer getBluetoothScanBackgroundTimer();
690        public abstract Timer getBluetoothUnoptimizedScanTimer();
691        public abstract Timer getBluetoothUnoptimizedScanBackgroundTimer();
692        public abstract Counter getBluetoothScanResultCounter();
693        public abstract Counter getBluetoothScanResultBgCounter();
694
695        public abstract long[] getCpuFreqTimes(int which);
696        public abstract long[] getScreenOffCpuFreqTimes(int which);
697        /**
698         * Returns cpu active time of an uid.
699         */
700        public abstract long getCpuActiveTime();
701        /**
702         * Returns cpu times of an uid on each cluster
703         */
704        public abstract long[] getCpuClusterTimes();
705
706        /**
707         * Returns cpu times of an uid at a particular process state.
708         */
709        public abstract long[] getCpuFreqTimes(int which, int procState);
710        /**
711         * Returns cpu times of an uid while the screen if off at a particular process state.
712         */
713        public abstract long[] getScreenOffCpuFreqTimes(int which, int procState);
714
715        // Note: the following times are disjoint.  They can be added together to find the
716        // total time a uid has had any processes running at all.
717
718        /**
719         * Time this uid has any processes in the top state.
720         */
721        public static final int PROCESS_STATE_TOP = 0;
722        /**
723         * Time this uid has any process with a started foreground service, but
724         * none in the "top" state.
725         */
726        public static final int PROCESS_STATE_FOREGROUND_SERVICE = 1;
727        /**
728         * Time this uid has any process in an active foreground state, but none in the
729         * "foreground service" or better state. Persistent and other foreground states go here.
730         */
731        public static final int PROCESS_STATE_FOREGROUND = 2;
732        /**
733         * Time this uid has any process in an active background state, but none in the
734         * "foreground" or better state.
735         */
736        public static final int PROCESS_STATE_BACKGROUND = 3;
737        /**
738         * Time this uid has any process that is top while the device is sleeping, but not
739         * active for any other reason.  We kind-of consider it a kind of cached process
740         * for execution restrictions.
741         */
742        public static final int PROCESS_STATE_TOP_SLEEPING = 4;
743        /**
744         * Time this uid has any process that is in the background but it has an activity
745         * marked as "can't save state".  This is essentially a cached process, though the
746         * system will try much harder than normal to avoid killing it.
747         */
748        public static final int PROCESS_STATE_HEAVY_WEIGHT = 5;
749        /**
750         * Time this uid has any processes that are sitting around cached, not in one of the
751         * other active states.
752         */
753        public static final int PROCESS_STATE_CACHED = 6;
754        /**
755         * Total number of process states we track.
756         */
757        public static final int NUM_PROCESS_STATE = 7;
758
759        // Used in dump
760        static final String[] PROCESS_STATE_NAMES = {
761                "Top", "Fg Service", "Foreground", "Background", "Top Sleeping", "Heavy Weight",
762                "Cached"
763        };
764
765        // Used in checkin dump
766        @VisibleForTesting
767        public static final String[] UID_PROCESS_TYPES = {
768                "T",  // TOP
769                "FS", // FOREGROUND_SERVICE
770                "F",  // FOREGROUND
771                "B",  // BACKGROUND
772                "TS", // TOP_SLEEPING
773                "HW",  // HEAVY_WEIGHT
774                "C"   // CACHED
775        };
776
777        /**
778         * When the process exits one of these states, we need to make sure cpu time in this state
779         * is not attributed to any non-critical process states.
780         */
781        public static final int[] CRITICAL_PROC_STATES = {
782            PROCESS_STATE_TOP, PROCESS_STATE_FOREGROUND_SERVICE, PROCESS_STATE_FOREGROUND
783        };
784
785        public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which);
786        public abstract Timer getProcessStateTimer(int state);
787
788        public abstract Timer getVibratorOnTimer();
789
790        public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5;
791
792        /**
793         * Note that these must match the constants in android.os.PowerManager.
794         * Also, if the user activity types change, the BatteryStatsImpl.VERSION must
795         * also be bumped.
796         */
797        static final String[] USER_ACTIVITY_TYPES = {
798            "other", "button", "touch", "accessibility"
799        };
800
801        public static final int NUM_USER_ACTIVITY_TYPES = 4;
802
803        public abstract void noteUserActivityLocked(int type);
804        public abstract boolean hasUserActivity();
805        public abstract int getUserActivityCount(int type, int which);
806
807        public abstract boolean hasNetworkActivity();
808        public abstract long getNetworkActivityBytes(int type, int which);
809        public abstract long getNetworkActivityPackets(int type, int which);
810        public abstract long getMobileRadioActiveTime(int which);
811        public abstract int getMobileRadioActiveCount(int which);
812
813        /**
814         * Get the total cpu time (in microseconds) this UID had processes executing in userspace.
815         */
816        public abstract long getUserCpuTimeUs(int which);
817
818        /**
819         * Get the total cpu time (in microseconds) this UID had processes executing kernel syscalls.
820         */
821        public abstract long getSystemCpuTimeUs(int which);
822
823        /**
824         * Returns the approximate cpu time (in microseconds) spent at a certain CPU speed for a
825         * given CPU cluster.
826         * @param cluster the index of the CPU cluster.
827         * @param step the index of the CPU speed. This is not the actual speed of the CPU.
828         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
829         * @see com.android.internal.os.PowerProfile#getNumCpuClusters()
830         * @see com.android.internal.os.PowerProfile#getNumSpeedStepsInCpuCluster(int)
831         */
832        public abstract long getTimeAtCpuSpeed(int cluster, int step, int which);
833
834        /**
835         * Returns the number of times this UID woke up the Application Processor to
836         * process a mobile radio packet.
837         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
838         */
839        public abstract long getMobileRadioApWakeupCount(int which);
840
841        /**
842         * Returns the number of times this UID woke up the Application Processor to
843         * process a WiFi packet.
844         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
845         */
846        public abstract long getWifiRadioApWakeupCount(int which);
847
848        public static abstract class Sensor {
849            /*
850             * FIXME: it's not correct to use this magic value because it
851             * could clash with a sensor handle (which are defined by
852             * the sensor HAL, and therefore out of our control
853             */
854            // Magic sensor number for the GPS.
855            public static final int GPS = -10000;
856
857            public abstract int getHandle();
858
859            public abstract Timer getSensorTime();
860
861            /** Returns a Timer for sensor usage when app is in the background. */
862            public abstract Timer getSensorBackgroundTime();
863        }
864
865        public class Pid {
866            public int mWakeNesting;
867            public long mWakeSumMs;
868            public long mWakeStartMs;
869        }
870
871        /**
872         * The statistics associated with a particular process.
873         */
874        public static abstract class Proc {
875
876            public static class ExcessivePower {
877                public static final int TYPE_WAKE = 1;
878                public static final int TYPE_CPU = 2;
879
880                public int type;
881                public long overTime;
882                public long usedTime;
883            }
884
885            /**
886             * Returns true if this process is still active in the battery stats.
887             */
888            public abstract boolean isActive();
889
890            /**
891             * Returns the total time (in milliseconds) spent executing in user code.
892             *
893             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
894             */
895            public abstract long getUserTime(int which);
896
897            /**
898             * Returns the total time (in milliseconds) spent executing in system code.
899             *
900             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
901             */
902            public abstract long getSystemTime(int which);
903
904            /**
905             * Returns the number of times the process has been started.
906             *
907             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
908             */
909            public abstract int getStarts(int which);
910
911            /**
912             * Returns the number of times the process has crashed.
913             *
914             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
915             */
916            public abstract int getNumCrashes(int which);
917
918            /**
919             * Returns the number of times the process has ANRed.
920             *
921             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
922             */
923            public abstract int getNumAnrs(int which);
924
925            /**
926             * Returns the cpu time (milliseconds) spent while the process was in the foreground.
927             * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
928             * @return foreground cpu time in microseconds
929             */
930            public abstract long getForegroundTime(int which);
931
932            public abstract int countExcessivePowers();
933
934            public abstract ExcessivePower getExcessivePower(int i);
935        }
936
937        /**
938         * The statistics associated with a particular package.
939         */
940        public static abstract class Pkg {
941
942            /**
943             * Returns information about all wakeup alarms that have been triggered for this
944             * package.  The mapping keys are tag names for the alarms, the counter contains
945             * the number of times the alarm was triggered while on battery.
946             */
947            public abstract ArrayMap<String, ? extends Counter> getWakeupAlarmStats();
948
949            /**
950             * Returns a mapping containing service statistics.
951             */
952            public abstract ArrayMap<String, ? extends Serv> getServiceStats();
953
954            /**
955             * The statistics associated with a particular service.
956             */
957            public static abstract class Serv {
958
959                /**
960                 * Returns the amount of time spent started.
961                 *
962                 * @param batteryUptime elapsed uptime on battery in microseconds.
963                 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
964                 * @return
965                 */
966                public abstract long getStartTime(long batteryUptime, int which);
967
968                /**
969                 * Returns the total number of times startService() has been called.
970                 *
971                 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
972                 */
973                public abstract int getStarts(int which);
974
975                /**
976                 * Returns the total number times the service has been launched.
977                 *
978                 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
979                 */
980                public abstract int getLaunches(int which);
981            }
982        }
983    }
984
985    public static final class LevelStepTracker {
986        public long mLastStepTime = -1;
987        public int mNumStepDurations;
988        public final long[] mStepDurations;
989
990        public LevelStepTracker(int maxLevelSteps) {
991            mStepDurations = new long[maxLevelSteps];
992        }
993
994        public LevelStepTracker(int numSteps, long[] steps) {
995            mNumStepDurations = numSteps;
996            mStepDurations = new long[numSteps];
997            System.arraycopy(steps, 0, mStepDurations, 0, numSteps);
998        }
999
1000        public long getDurationAt(int index) {
1001            return mStepDurations[index] & STEP_LEVEL_TIME_MASK;
1002        }
1003
1004        public int getLevelAt(int index) {
1005            return (int)((mStepDurations[index] & STEP_LEVEL_LEVEL_MASK)
1006                    >> STEP_LEVEL_LEVEL_SHIFT);
1007        }
1008
1009        public int getInitModeAt(int index) {
1010            return (int)((mStepDurations[index] & STEP_LEVEL_INITIAL_MODE_MASK)
1011                    >> STEP_LEVEL_INITIAL_MODE_SHIFT);
1012        }
1013
1014        public int getModModeAt(int index) {
1015            return (int)((mStepDurations[index] & STEP_LEVEL_MODIFIED_MODE_MASK)
1016                    >> STEP_LEVEL_MODIFIED_MODE_SHIFT);
1017        }
1018
1019        private void appendHex(long val, int topOffset, StringBuilder out) {
1020            boolean hasData = false;
1021            while (topOffset >= 0) {
1022                int digit = (int)( (val>>topOffset) & 0xf );
1023                topOffset -= 4;
1024                if (!hasData && digit == 0) {
1025                    continue;
1026                }
1027                hasData = true;
1028                if (digit >= 0 && digit <= 9) {
1029                    out.append((char)('0' + digit));
1030                } else {
1031                    out.append((char)('a' + digit - 10));
1032                }
1033            }
1034        }
1035
1036        public void encodeEntryAt(int index, StringBuilder out) {
1037            long item = mStepDurations[index];
1038            long duration = item & STEP_LEVEL_TIME_MASK;
1039            int level = (int)((item & STEP_LEVEL_LEVEL_MASK)
1040                    >> STEP_LEVEL_LEVEL_SHIFT);
1041            int initMode = (int)((item & STEP_LEVEL_INITIAL_MODE_MASK)
1042                    >> STEP_LEVEL_INITIAL_MODE_SHIFT);
1043            int modMode = (int)((item & STEP_LEVEL_MODIFIED_MODE_MASK)
1044                    >> STEP_LEVEL_MODIFIED_MODE_SHIFT);
1045            switch ((initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
1046                case Display.STATE_OFF: out.append('f'); break;
1047                case Display.STATE_ON: out.append('o'); break;
1048                case Display.STATE_DOZE: out.append('d'); break;
1049                case Display.STATE_DOZE_SUSPEND: out.append('z'); break;
1050            }
1051            if ((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) {
1052                out.append('p');
1053            }
1054            if ((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) {
1055                out.append('i');
1056            }
1057            switch ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
1058                case Display.STATE_OFF: out.append('F'); break;
1059                case Display.STATE_ON: out.append('O'); break;
1060                case Display.STATE_DOZE: out.append('D'); break;
1061                case Display.STATE_DOZE_SUSPEND: out.append('Z'); break;
1062            }
1063            if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) {
1064                out.append('P');
1065            }
1066            if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) {
1067                out.append('I');
1068            }
1069            out.append('-');
1070            appendHex(level, 4, out);
1071            out.append('-');
1072            appendHex(duration, STEP_LEVEL_LEVEL_SHIFT-4, out);
1073        }
1074
1075        public void decodeEntryAt(int index, String value) {
1076            final int N = value.length();
1077            int i = 0;
1078            char c;
1079            long out = 0;
1080            while (i < N && (c=value.charAt(i)) != '-') {
1081                i++;
1082                switch (c) {
1083                    case 'f': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
1084                        break;
1085                    case 'o': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
1086                        break;
1087                    case 'd': out |= (((long)Display.STATE_DOZE-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
1088                        break;
1089                    case 'z': out |= (((long)Display.STATE_DOZE_SUSPEND-1)
1090                            << STEP_LEVEL_INITIAL_MODE_SHIFT);
1091                        break;
1092                    case 'p': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE)
1093                            << STEP_LEVEL_INITIAL_MODE_SHIFT);
1094                        break;
1095                    case 'i': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE)
1096                            << STEP_LEVEL_INITIAL_MODE_SHIFT);
1097                        break;
1098                    case 'F': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
1099                        break;
1100                    case 'O': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
1101                        break;
1102                    case 'D': out |= (((long)Display.STATE_DOZE-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
1103                        break;
1104                    case 'Z': out |= (((long)Display.STATE_DOZE_SUSPEND-1)
1105                            << STEP_LEVEL_MODIFIED_MODE_SHIFT);
1106                        break;
1107                    case 'P': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE)
1108                            << STEP_LEVEL_MODIFIED_MODE_SHIFT);
1109                        break;
1110                    case 'I': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE)
1111                            << STEP_LEVEL_MODIFIED_MODE_SHIFT);
1112                        break;
1113                }
1114            }
1115            i++;
1116            long level = 0;
1117            while (i < N && (c=value.charAt(i)) != '-') {
1118                i++;
1119                level <<= 4;
1120                if (c >= '0' && c <= '9') {
1121                    level += c - '0';
1122                } else if (c >= 'a' && c <= 'f') {
1123                    level += c - 'a' + 10;
1124                } else if (c >= 'A' && c <= 'F') {
1125                    level += c - 'A' + 10;
1126                }
1127            }
1128            i++;
1129            out |= (level << STEP_LEVEL_LEVEL_SHIFT) & STEP_LEVEL_LEVEL_MASK;
1130            long duration = 0;
1131            while (i < N && (c=value.charAt(i)) != '-') {
1132                i++;
1133                duration <<= 4;
1134                if (c >= '0' && c <= '9') {
1135                    duration += c - '0';
1136                } else if (c >= 'a' && c <= 'f') {
1137                    duration += c - 'a' + 10;
1138                } else if (c >= 'A' && c <= 'F') {
1139                    duration += c - 'A' + 10;
1140                }
1141            }
1142            mStepDurations[index] = out | (duration & STEP_LEVEL_TIME_MASK);
1143        }
1144
1145        public void init() {
1146            mLastStepTime = -1;
1147            mNumStepDurations = 0;
1148        }
1149
1150        public void clearTime() {
1151            mLastStepTime = -1;
1152        }
1153
1154        public long computeTimePerLevel() {
1155            final long[] steps = mStepDurations;
1156            final int numSteps = mNumStepDurations;
1157
1158            // For now we'll do a simple average across all steps.
1159            if (numSteps <= 0) {
1160                return -1;
1161            }
1162            long total = 0;
1163            for (int i=0; i<numSteps; i++) {
1164                total += steps[i] & STEP_LEVEL_TIME_MASK;
1165            }
1166            return total / numSteps;
1167            /*
1168            long[] buckets = new long[numSteps];
1169            int numBuckets = 0;
1170            int numToAverage = 4;
1171            int i = 0;
1172            while (i < numSteps) {
1173                long totalTime = 0;
1174                int num = 0;
1175                for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
1176                    totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
1177                    num++;
1178                }
1179                buckets[numBuckets] = totalTime / num;
1180                numBuckets++;
1181                numToAverage *= 2;
1182                i += num;
1183            }
1184            if (numBuckets < 1) {
1185                return -1;
1186            }
1187            long averageTime = buckets[numBuckets-1];
1188            for (i=numBuckets-2; i>=0; i--) {
1189                averageTime = (averageTime + buckets[i]) / 2;
1190            }
1191            return averageTime;
1192            */
1193        }
1194
1195        public long computeTimeEstimate(long modesOfInterest, long modeValues,
1196                int[] outNumOfInterest) {
1197            final long[] steps = mStepDurations;
1198            final int count = mNumStepDurations;
1199            if (count <= 0) {
1200                return -1;
1201            }
1202            long total = 0;
1203            int numOfInterest = 0;
1204            for (int i=0; i<count; i++) {
1205                long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK)
1206                        >> STEP_LEVEL_INITIAL_MODE_SHIFT;
1207                long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK)
1208                        >> STEP_LEVEL_MODIFIED_MODE_SHIFT;
1209                // If the modes of interest didn't change during this step period...
1210                if ((modMode&modesOfInterest) == 0) {
1211                    // And the mode values during this period match those we are measuring...
1212                    if ((initMode&modesOfInterest) == modeValues) {
1213                        // Then this can be used to estimate the total time!
1214                        numOfInterest++;
1215                        total += steps[i] & STEP_LEVEL_TIME_MASK;
1216                    }
1217                }
1218            }
1219            if (numOfInterest <= 0) {
1220                return -1;
1221            }
1222
1223            if (outNumOfInterest != null) {
1224                outNumOfInterest[0] = numOfInterest;
1225            }
1226
1227            // The estimated time is the average time we spend in each level, multipled
1228            // by 100 -- the total number of battery levels
1229            return (total / numOfInterest) * 100;
1230        }
1231
1232        public void addLevelSteps(int numStepLevels, long modeBits, long elapsedRealtime) {
1233            int stepCount = mNumStepDurations;
1234            final long lastStepTime = mLastStepTime;
1235            if (lastStepTime >= 0 && numStepLevels > 0) {
1236                final long[] steps = mStepDurations;
1237                long duration = elapsedRealtime - lastStepTime;
1238                for (int i=0; i<numStepLevels; i++) {
1239                    System.arraycopy(steps, 0, steps, 1, steps.length-1);
1240                    long thisDuration = duration / (numStepLevels-i);
1241                    duration -= thisDuration;
1242                    if (thisDuration > STEP_LEVEL_TIME_MASK) {
1243                        thisDuration = STEP_LEVEL_TIME_MASK;
1244                    }
1245                    steps[0] = thisDuration | modeBits;
1246                }
1247                stepCount += numStepLevels;
1248                if (stepCount > steps.length) {
1249                    stepCount = steps.length;
1250                }
1251            }
1252            mNumStepDurations = stepCount;
1253            mLastStepTime = elapsedRealtime;
1254        }
1255
1256        public void readFromParcel(Parcel in) {
1257            final int N = in.readInt();
1258            if (N > mStepDurations.length) {
1259                throw new ParcelFormatException("more step durations than available: " + N);
1260            }
1261            mNumStepDurations = N;
1262            for (int i=0; i<N; i++) {
1263                mStepDurations[i] = in.readLong();
1264            }
1265        }
1266
1267        public void writeToParcel(Parcel out) {
1268            final int N = mNumStepDurations;
1269            out.writeInt(N);
1270            for (int i=0; i<N; i++) {
1271                out.writeLong(mStepDurations[i]);
1272            }
1273        }
1274    }
1275
1276    public static final class PackageChange {
1277        public String mPackageName;
1278        public boolean mUpdate;
1279        public long mVersionCode;
1280    }
1281
1282    public static final class DailyItem {
1283        public long mStartTime;
1284        public long mEndTime;
1285        public LevelStepTracker mDischargeSteps;
1286        public LevelStepTracker mChargeSteps;
1287        public ArrayList<PackageChange> mPackageChanges;
1288    }
1289
1290    public abstract DailyItem getDailyItemLocked(int daysAgo);
1291
1292    public abstract long getCurrentDailyStartTime();
1293
1294    public abstract long getNextMinDailyDeadline();
1295
1296    public abstract long getNextMaxDailyDeadline();
1297
1298    public abstract long[] getCpuFreqs();
1299
1300    public final static class HistoryTag {
1301        public String string;
1302        public int uid;
1303
1304        public int poolIdx;
1305
1306        public void setTo(HistoryTag o) {
1307            string = o.string;
1308            uid = o.uid;
1309            poolIdx = o.poolIdx;
1310        }
1311
1312        public void setTo(String _string, int _uid) {
1313            string = _string;
1314            uid = _uid;
1315            poolIdx = -1;
1316        }
1317
1318        public void writeToParcel(Parcel dest, int flags) {
1319            dest.writeString(string);
1320            dest.writeInt(uid);
1321        }
1322
1323        public void readFromParcel(Parcel src) {
1324            string = src.readString();
1325            uid = src.readInt();
1326            poolIdx = -1;
1327        }
1328
1329        @Override
1330        public boolean equals(Object o) {
1331            if (this == o) return true;
1332            if (o == null || getClass() != o.getClass()) return false;
1333
1334            HistoryTag that = (HistoryTag) o;
1335
1336            if (uid != that.uid) return false;
1337            if (!string.equals(that.string)) return false;
1338
1339            return true;
1340        }
1341
1342        @Override
1343        public int hashCode() {
1344            int result = string.hashCode();
1345            result = 31 * result + uid;
1346            return result;
1347        }
1348    }
1349
1350    /**
1351     * Optional detailed information that can go into a history step.  This is typically
1352     * generated each time the battery level changes.
1353     */
1354    public final static class HistoryStepDetails {
1355        // Time (in 1/100 second) spent in user space and the kernel since the last step.
1356        public int userTime;
1357        public int systemTime;
1358
1359        // Top three apps using CPU in the last step, with times in 1/100 second.
1360        public int appCpuUid1;
1361        public int appCpuUTime1;
1362        public int appCpuSTime1;
1363        public int appCpuUid2;
1364        public int appCpuUTime2;
1365        public int appCpuSTime2;
1366        public int appCpuUid3;
1367        public int appCpuUTime3;
1368        public int appCpuSTime3;
1369
1370        // Information from /proc/stat
1371        public int statUserTime;
1372        public int statSystemTime;
1373        public int statIOWaitTime;
1374        public int statIrqTime;
1375        public int statSoftIrqTime;
1376        public int statIdlTime;
1377
1378        // Platform-level low power state stats
1379        public String statPlatformIdleState;
1380        public String statSubsystemPowerState;
1381
1382        public HistoryStepDetails() {
1383            clear();
1384        }
1385
1386        public void clear() {
1387            userTime = systemTime = 0;
1388            appCpuUid1 = appCpuUid2 = appCpuUid3 = -1;
1389            appCpuUTime1 = appCpuSTime1 = appCpuUTime2 = appCpuSTime2
1390                    = appCpuUTime3 = appCpuSTime3 = 0;
1391        }
1392
1393        public void writeToParcel(Parcel out) {
1394            out.writeInt(userTime);
1395            out.writeInt(systemTime);
1396            out.writeInt(appCpuUid1);
1397            out.writeInt(appCpuUTime1);
1398            out.writeInt(appCpuSTime1);
1399            out.writeInt(appCpuUid2);
1400            out.writeInt(appCpuUTime2);
1401            out.writeInt(appCpuSTime2);
1402            out.writeInt(appCpuUid3);
1403            out.writeInt(appCpuUTime3);
1404            out.writeInt(appCpuSTime3);
1405            out.writeInt(statUserTime);
1406            out.writeInt(statSystemTime);
1407            out.writeInt(statIOWaitTime);
1408            out.writeInt(statIrqTime);
1409            out.writeInt(statSoftIrqTime);
1410            out.writeInt(statIdlTime);
1411            out.writeString(statPlatformIdleState);
1412            out.writeString(statSubsystemPowerState);
1413        }
1414
1415        public void readFromParcel(Parcel in) {
1416            userTime = in.readInt();
1417            systemTime = in.readInt();
1418            appCpuUid1 = in.readInt();
1419            appCpuUTime1 = in.readInt();
1420            appCpuSTime1 = in.readInt();
1421            appCpuUid2 = in.readInt();
1422            appCpuUTime2 = in.readInt();
1423            appCpuSTime2 = in.readInt();
1424            appCpuUid3 = in.readInt();
1425            appCpuUTime3 = in.readInt();
1426            appCpuSTime3 = in.readInt();
1427            statUserTime = in.readInt();
1428            statSystemTime = in.readInt();
1429            statIOWaitTime = in.readInt();
1430            statIrqTime = in.readInt();
1431            statSoftIrqTime = in.readInt();
1432            statIdlTime = in.readInt();
1433            statPlatformIdleState = in.readString();
1434            statSubsystemPowerState = in.readString();
1435        }
1436    }
1437
1438    public final static class HistoryItem implements Parcelable {
1439        public HistoryItem next;
1440
1441        // The time of this event in milliseconds, as per SystemClock.elapsedRealtime().
1442        public long time;
1443
1444        public static final byte CMD_UPDATE = 0;        // These can be written as deltas
1445        public static final byte CMD_NULL = -1;
1446        public static final byte CMD_START = 4;
1447        public static final byte CMD_CURRENT_TIME = 5;
1448        public static final byte CMD_OVERFLOW = 6;
1449        public static final byte CMD_RESET = 7;
1450        public static final byte CMD_SHUTDOWN = 8;
1451
1452        public byte cmd = CMD_NULL;
1453
1454        /**
1455         * Return whether the command code is a delta data update.
1456         */
1457        public boolean isDeltaData() {
1458            return cmd == CMD_UPDATE;
1459        }
1460
1461        public byte batteryLevel;
1462        public byte batteryStatus;
1463        public byte batteryHealth;
1464        public byte batteryPlugType;
1465
1466        public short batteryTemperature;
1467        public char batteryVoltage;
1468
1469        // The charge of the battery in micro-Ampere-hours.
1470        public int batteryChargeUAh;
1471
1472        // Constants from SCREEN_BRIGHTNESS_*
1473        public static final int STATE_BRIGHTNESS_SHIFT = 0;
1474        public static final int STATE_BRIGHTNESS_MASK = 0x7;
1475        // Constants from SIGNAL_STRENGTH_*
1476        public static final int STATE_PHONE_SIGNAL_STRENGTH_SHIFT = 3;
1477        public static final int STATE_PHONE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_PHONE_SIGNAL_STRENGTH_SHIFT;
1478        // Constants from ServiceState.STATE_*
1479        public static final int STATE_PHONE_STATE_SHIFT = 6;
1480        public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT;
1481        // Constants from DATA_CONNECTION_*
1482        public static final int STATE_DATA_CONNECTION_SHIFT = 9;
1483        public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT;
1484
1485        // These states always appear directly in the first int token
1486        // of a delta change; they should be ones that change relatively
1487        // frequently.
1488        public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
1489        public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
1490        public static final int STATE_GPS_ON_FLAG = 1<<29;
1491        public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
1492        public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
1493        public static final int STATE_WIFI_RADIO_ACTIVE_FLAG = 1<<26;
1494        public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
1495        // Do not use, this is used for coulomb delta count.
1496        private static final int STATE_RESERVED_0 = 1<<24;
1497        // These are on the lower bits used for the command; if they change
1498        // we need to write another int of data.
1499        public static final int STATE_SENSOR_ON_FLAG = 1<<23;
1500        public static final int STATE_AUDIO_ON_FLAG = 1<<22;
1501        public static final int STATE_PHONE_SCANNING_FLAG = 1<<21;
1502        public static final int STATE_SCREEN_ON_FLAG = 1<<20;       // consider moving to states2
1503        public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; // consider moving to states2
1504        public static final int STATE_SCREEN_DOZE_FLAG = 1 << 18;
1505        // empty slot
1506        public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<16;
1507
1508        public static final int MOST_INTERESTING_STATES =
1509                STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG | STATE_SCREEN_DOZE_FLAG;
1510
1511        public static final int SETTLE_TO_ZERO_STATES = 0xffff0000 & ~MOST_INTERESTING_STATES;
1512
1513        public int states;
1514
1515        // Constants from WIFI_SUPPL_STATE_*
1516        public static final int STATE2_WIFI_SUPPL_STATE_SHIFT = 0;
1517        public static final int STATE2_WIFI_SUPPL_STATE_MASK = 0xf;
1518        // Values for NUM_WIFI_SIGNAL_STRENGTH_BINS
1519        public static final int STATE2_WIFI_SIGNAL_STRENGTH_SHIFT = 4;
1520        public static final int STATE2_WIFI_SIGNAL_STRENGTH_MASK =
1521                0x7 << STATE2_WIFI_SIGNAL_STRENGTH_SHIFT;
1522        // Values for NUM_GPS_SIGNAL_QUALITY_LEVELS
1523        public static final int STATE2_GPS_SIGNAL_QUALITY_SHIFT = 7;
1524        public static final int STATE2_GPS_SIGNAL_QUALITY_MASK =
1525            0x1 << STATE2_GPS_SIGNAL_QUALITY_SHIFT;
1526
1527        public static final int STATE2_POWER_SAVE_FLAG = 1<<31;
1528        public static final int STATE2_VIDEO_ON_FLAG = 1<<30;
1529        public static final int STATE2_WIFI_RUNNING_FLAG = 1<<29;
1530        public static final int STATE2_WIFI_ON_FLAG = 1<<28;
1531        public static final int STATE2_FLASHLIGHT_FLAG = 1<<27;
1532        public static final int STATE2_DEVICE_IDLE_SHIFT = 25;
1533        public static final int STATE2_DEVICE_IDLE_MASK = 0x3 << STATE2_DEVICE_IDLE_SHIFT;
1534        public static final int STATE2_CHARGING_FLAG = 1<<24;
1535        public static final int STATE2_PHONE_IN_CALL_FLAG = 1<<23;
1536        public static final int STATE2_BLUETOOTH_ON_FLAG = 1<<22;
1537        public static final int STATE2_CAMERA_FLAG = 1<<21;
1538        public static final int STATE2_BLUETOOTH_SCAN_FLAG = 1 << 20;
1539
1540        public static final int MOST_INTERESTING_STATES2 =
1541                STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_MASK
1542                | STATE2_CHARGING_FLAG | STATE2_PHONE_IN_CALL_FLAG | STATE2_BLUETOOTH_ON_FLAG;
1543
1544        public static final int SETTLE_TO_ZERO_STATES2 = 0xffff0000 & ~MOST_INTERESTING_STATES2;
1545
1546        public int states2;
1547
1548        // The wake lock that was acquired at this point.
1549        public HistoryTag wakelockTag;
1550
1551        // Kernel wakeup reason at this point.
1552        public HistoryTag wakeReasonTag;
1553
1554        // Non-null when there is more detailed information at this step.
1555        public HistoryStepDetails stepDetails;
1556
1557        public static final int EVENT_FLAG_START = 0x8000;
1558        public static final int EVENT_FLAG_FINISH = 0x4000;
1559
1560        // No event in this item.
1561        public static final int EVENT_NONE = 0x0000;
1562        // Event is about a process that is running.
1563        public static final int EVENT_PROC = 0x0001;
1564        // Event is about an application package that is in the foreground.
1565        public static final int EVENT_FOREGROUND = 0x0002;
1566        // Event is about an application package that is at the top of the screen.
1567        public static final int EVENT_TOP = 0x0003;
1568        // Event is about active sync operations.
1569        public static final int EVENT_SYNC = 0x0004;
1570        // Events for all additional wake locks aquired/release within a wake block.
1571        // These are not generated by default.
1572        public static final int EVENT_WAKE_LOCK = 0x0005;
1573        // Event is about an application executing a scheduled job.
1574        public static final int EVENT_JOB = 0x0006;
1575        // Events for users running.
1576        public static final int EVENT_USER_RUNNING = 0x0007;
1577        // Events for foreground user.
1578        public static final int EVENT_USER_FOREGROUND = 0x0008;
1579        // Event for connectivity changed.
1580        public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009;
1581        // Event for becoming active taking us out of idle mode.
1582        public static final int EVENT_ACTIVE = 0x000a;
1583        // Event for a package being installed.
1584        public static final int EVENT_PACKAGE_INSTALLED = 0x000b;
1585        // Event for a package being uninstalled.
1586        public static final int EVENT_PACKAGE_UNINSTALLED = 0x000c;
1587        // Event for a package being uninstalled.
1588        public static final int EVENT_ALARM = 0x000d;
1589        // Record that we have decided we need to collect new stats data.
1590        public static final int EVENT_COLLECT_EXTERNAL_STATS = 0x000e;
1591        // Event for a package becoming inactive due to being unused for a period of time.
1592        public static final int EVENT_PACKAGE_INACTIVE = 0x000f;
1593        // Event for a package becoming active due to an interaction.
1594        public static final int EVENT_PACKAGE_ACTIVE = 0x0010;
1595        // Event for a package being on the temporary whitelist.
1596        public static final int EVENT_TEMP_WHITELIST = 0x0011;
1597        // Event for the screen waking up.
1598        public static final int EVENT_SCREEN_WAKE_UP = 0x0012;
1599        // Event for the UID that woke up the application processor.
1600        // Used for wakeups coming from WiFi, modem, etc.
1601        public static final int EVENT_WAKEUP_AP = 0x0013;
1602        // Event for reporting that a specific partial wake lock has been held for a long duration.
1603        public static final int EVENT_LONG_WAKE_LOCK = 0x0014;
1604
1605        // Number of event types.
1606        public static final int EVENT_COUNT = 0x0016;
1607        // Mask to extract out only the type part of the event.
1608        public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
1609
1610        public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
1611        public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
1612        public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START;
1613        public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
1614        public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
1615        public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
1616        public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
1617        public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
1618        public static final int EVENT_WAKE_LOCK_START = EVENT_WAKE_LOCK | EVENT_FLAG_START;
1619        public static final int EVENT_WAKE_LOCK_FINISH = EVENT_WAKE_LOCK | EVENT_FLAG_FINISH;
1620        public static final int EVENT_JOB_START = EVENT_JOB | EVENT_FLAG_START;
1621        public static final int EVENT_JOB_FINISH = EVENT_JOB | EVENT_FLAG_FINISH;
1622        public static final int EVENT_USER_RUNNING_START = EVENT_USER_RUNNING | EVENT_FLAG_START;
1623        public static final int EVENT_USER_RUNNING_FINISH = EVENT_USER_RUNNING | EVENT_FLAG_FINISH;
1624        public static final int EVENT_USER_FOREGROUND_START =
1625                EVENT_USER_FOREGROUND | EVENT_FLAG_START;
1626        public static final int EVENT_USER_FOREGROUND_FINISH =
1627                EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
1628        public static final int EVENT_ALARM_START = EVENT_ALARM | EVENT_FLAG_START;
1629        public static final int EVENT_ALARM_FINISH = EVENT_ALARM | EVENT_FLAG_FINISH;
1630        public static final int EVENT_TEMP_WHITELIST_START =
1631                EVENT_TEMP_WHITELIST | EVENT_FLAG_START;
1632        public static final int EVENT_TEMP_WHITELIST_FINISH =
1633                EVENT_TEMP_WHITELIST | EVENT_FLAG_FINISH;
1634        public static final int EVENT_LONG_WAKE_LOCK_START =
1635                EVENT_LONG_WAKE_LOCK | EVENT_FLAG_START;
1636        public static final int EVENT_LONG_WAKE_LOCK_FINISH =
1637                EVENT_LONG_WAKE_LOCK | EVENT_FLAG_FINISH;
1638
1639        // For CMD_EVENT.
1640        public int eventCode;
1641        public HistoryTag eventTag;
1642
1643        // Only set for CMD_CURRENT_TIME or CMD_RESET, as per System.currentTimeMillis().
1644        public long currentTime;
1645
1646        // Meta-data when reading.
1647        public int numReadInts;
1648
1649        // Pre-allocated objects.
1650        public final HistoryTag localWakelockTag = new HistoryTag();
1651        public final HistoryTag localWakeReasonTag = new HistoryTag();
1652        public final HistoryTag localEventTag = new HistoryTag();
1653
1654        public HistoryItem() {
1655        }
1656
1657        public HistoryItem(long time, Parcel src) {
1658            this.time = time;
1659            numReadInts = 2;
1660            readFromParcel(src);
1661        }
1662
1663        public int describeContents() {
1664            return 0;
1665        }
1666
1667        public void writeToParcel(Parcel dest, int flags) {
1668            dest.writeLong(time);
1669            int bat = (((int)cmd)&0xff)
1670                    | ((((int)batteryLevel)<<8)&0xff00)
1671                    | ((((int)batteryStatus)<<16)&0xf0000)
1672                    | ((((int)batteryHealth)<<20)&0xf00000)
1673                    | ((((int)batteryPlugType)<<24)&0xf000000)
1674                    | (wakelockTag != null ? 0x10000000 : 0)
1675                    | (wakeReasonTag != null ? 0x20000000 : 0)
1676                    | (eventCode != EVENT_NONE ? 0x40000000 : 0);
1677            dest.writeInt(bat);
1678            bat = (((int)batteryTemperature)&0xffff)
1679                    | ((((int)batteryVoltage)<<16)&0xffff0000);
1680            dest.writeInt(bat);
1681            dest.writeInt(batteryChargeUAh);
1682            dest.writeInt(states);
1683            dest.writeInt(states2);
1684            if (wakelockTag != null) {
1685                wakelockTag.writeToParcel(dest, flags);
1686            }
1687            if (wakeReasonTag != null) {
1688                wakeReasonTag.writeToParcel(dest, flags);
1689            }
1690            if (eventCode != EVENT_NONE) {
1691                dest.writeInt(eventCode);
1692                eventTag.writeToParcel(dest, flags);
1693            }
1694            if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
1695                dest.writeLong(currentTime);
1696            }
1697        }
1698
1699        public void readFromParcel(Parcel src) {
1700            int start = src.dataPosition();
1701            int bat = src.readInt();
1702            cmd = (byte)(bat&0xff);
1703            batteryLevel = (byte)((bat>>8)&0xff);
1704            batteryStatus = (byte)((bat>>16)&0xf);
1705            batteryHealth = (byte)((bat>>20)&0xf);
1706            batteryPlugType = (byte)((bat>>24)&0xf);
1707            int bat2 = src.readInt();
1708            batteryTemperature = (short)(bat2&0xffff);
1709            batteryVoltage = (char)((bat2>>16)&0xffff);
1710            batteryChargeUAh = src.readInt();
1711            states = src.readInt();
1712            states2 = src.readInt();
1713            if ((bat&0x10000000) != 0) {
1714                wakelockTag = localWakelockTag;
1715                wakelockTag.readFromParcel(src);
1716            } else {
1717                wakelockTag = null;
1718            }
1719            if ((bat&0x20000000) != 0) {
1720                wakeReasonTag = localWakeReasonTag;
1721                wakeReasonTag.readFromParcel(src);
1722            } else {
1723                wakeReasonTag = null;
1724            }
1725            if ((bat&0x40000000) != 0) {
1726                eventCode = src.readInt();
1727                eventTag = localEventTag;
1728                eventTag.readFromParcel(src);
1729            } else {
1730                eventCode = EVENT_NONE;
1731                eventTag = null;
1732            }
1733            if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
1734                currentTime = src.readLong();
1735            } else {
1736                currentTime = 0;
1737            }
1738            numReadInts += (src.dataPosition()-start)/4;
1739        }
1740
1741        public void clear() {
1742            time = 0;
1743            cmd = CMD_NULL;
1744            batteryLevel = 0;
1745            batteryStatus = 0;
1746            batteryHealth = 0;
1747            batteryPlugType = 0;
1748            batteryTemperature = 0;
1749            batteryVoltage = 0;
1750            batteryChargeUAh = 0;
1751            states = 0;
1752            states2 = 0;
1753            wakelockTag = null;
1754            wakeReasonTag = null;
1755            eventCode = EVENT_NONE;
1756            eventTag = null;
1757        }
1758
1759        public void setTo(HistoryItem o) {
1760            time = o.time;
1761            cmd = o.cmd;
1762            setToCommon(o);
1763        }
1764
1765        public void setTo(long time, byte cmd, HistoryItem o) {
1766            this.time = time;
1767            this.cmd = cmd;
1768            setToCommon(o);
1769        }
1770
1771        private void setToCommon(HistoryItem o) {
1772            batteryLevel = o.batteryLevel;
1773            batteryStatus = o.batteryStatus;
1774            batteryHealth = o.batteryHealth;
1775            batteryPlugType = o.batteryPlugType;
1776            batteryTemperature = o.batteryTemperature;
1777            batteryVoltage = o.batteryVoltage;
1778            batteryChargeUAh = o.batteryChargeUAh;
1779            states = o.states;
1780            states2 = o.states2;
1781            if (o.wakelockTag != null) {
1782                wakelockTag = localWakelockTag;
1783                wakelockTag.setTo(o.wakelockTag);
1784            } else {
1785                wakelockTag = null;
1786            }
1787            if (o.wakeReasonTag != null) {
1788                wakeReasonTag = localWakeReasonTag;
1789                wakeReasonTag.setTo(o.wakeReasonTag);
1790            } else {
1791                wakeReasonTag = null;
1792            }
1793            eventCode = o.eventCode;
1794            if (o.eventTag != null) {
1795                eventTag = localEventTag;
1796                eventTag.setTo(o.eventTag);
1797            } else {
1798                eventTag = null;
1799            }
1800            currentTime = o.currentTime;
1801        }
1802
1803        public boolean sameNonEvent(HistoryItem o) {
1804            return batteryLevel == o.batteryLevel
1805                    && batteryStatus == o.batteryStatus
1806                    && batteryHealth == o.batteryHealth
1807                    && batteryPlugType == o.batteryPlugType
1808                    && batteryTemperature == o.batteryTemperature
1809                    && batteryVoltage == o.batteryVoltage
1810                    && batteryChargeUAh == o.batteryChargeUAh
1811                    && states == o.states
1812                    && states2 == o.states2
1813                    && currentTime == o.currentTime;
1814        }
1815
1816        public boolean same(HistoryItem o) {
1817            if (!sameNonEvent(o) || eventCode != o.eventCode) {
1818                return false;
1819            }
1820            if (wakelockTag != o.wakelockTag) {
1821                if (wakelockTag == null || o.wakelockTag == null) {
1822                    return false;
1823                }
1824                if (!wakelockTag.equals(o.wakelockTag)) {
1825                    return false;
1826                }
1827            }
1828            if (wakeReasonTag != o.wakeReasonTag) {
1829                if (wakeReasonTag == null || o.wakeReasonTag == null) {
1830                    return false;
1831                }
1832                if (!wakeReasonTag.equals(o.wakeReasonTag)) {
1833                    return false;
1834                }
1835            }
1836            if (eventTag != o.eventTag) {
1837                if (eventTag == null || o.eventTag == null) {
1838                    return false;
1839                }
1840                if (!eventTag.equals(o.eventTag)) {
1841                    return false;
1842                }
1843            }
1844            return true;
1845        }
1846    }
1847
1848    public final static class HistoryEventTracker {
1849        private final HashMap<String, SparseIntArray>[] mActiveEvents
1850                = (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
1851
1852        public boolean updateState(int code, String name, int uid, int poolIdx) {
1853            if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
1854                int idx = code&HistoryItem.EVENT_TYPE_MASK;
1855                HashMap<String, SparseIntArray> active = mActiveEvents[idx];
1856                if (active == null) {
1857                    active = new HashMap<>();
1858                    mActiveEvents[idx] = active;
1859                }
1860                SparseIntArray uids = active.get(name);
1861                if (uids == null) {
1862                    uids = new SparseIntArray();
1863                    active.put(name, uids);
1864                }
1865                if (uids.indexOfKey(uid) >= 0) {
1866                    // Already set, nothing to do!
1867                    return false;
1868                }
1869                uids.put(uid, poolIdx);
1870            } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
1871                int idx = code&HistoryItem.EVENT_TYPE_MASK;
1872                HashMap<String, SparseIntArray> active = mActiveEvents[idx];
1873                if (active == null) {
1874                    // not currently active, nothing to do.
1875                    return false;
1876                }
1877                SparseIntArray uids = active.get(name);
1878                if (uids == null) {
1879                    // not currently active, nothing to do.
1880                    return false;
1881                }
1882                idx = uids.indexOfKey(uid);
1883                if (idx < 0) {
1884                    // not currently active, nothing to do.
1885                    return false;
1886                }
1887                uids.removeAt(idx);
1888                if (uids.size() <= 0) {
1889                    active.remove(name);
1890                }
1891            }
1892            return true;
1893        }
1894
1895        public void removeEvents(int code) {
1896            int idx = code&HistoryItem.EVENT_TYPE_MASK;
1897            mActiveEvents[idx] = null;
1898        }
1899
1900        public HashMap<String, SparseIntArray> getStateForEvent(int code) {
1901            return mActiveEvents[code];
1902        }
1903    }
1904
1905    public static final class BitDescription {
1906        public final int mask;
1907        public final int shift;
1908        public final String name;
1909        public final String shortName;
1910        public final String[] values;
1911        public final String[] shortValues;
1912
1913        public BitDescription(int mask, String name, String shortName) {
1914            this.mask = mask;
1915            this.shift = -1;
1916            this.name = name;
1917            this.shortName = shortName;
1918            this.values = null;
1919            this.shortValues = null;
1920        }
1921
1922        public BitDescription(int mask, int shift, String name, String shortName,
1923                String[] values, String[] shortValues) {
1924            this.mask = mask;
1925            this.shift = shift;
1926            this.name = name;
1927            this.shortName = shortName;
1928            this.values = values;
1929            this.shortValues = shortValues;
1930        }
1931    }
1932
1933    /**
1934     * Don't allow any more batching in to the current history event.  This
1935     * is called when printing partial histories, so to ensure that the next
1936     * history event will go in to a new batch after what was printed in the
1937     * last partial history.
1938     */
1939    public abstract void commitCurrentHistoryBatchLocked();
1940
1941    public abstract int getHistoryTotalSize();
1942
1943    public abstract int getHistoryUsedSize();
1944
1945    public abstract boolean startIteratingHistoryLocked();
1946
1947    public abstract int getHistoryStringPoolSize();
1948
1949    public abstract int getHistoryStringPoolBytes();
1950
1951    public abstract String getHistoryTagPoolString(int index);
1952
1953    public abstract int getHistoryTagPoolUid(int index);
1954
1955    public abstract boolean getNextHistoryLocked(HistoryItem out);
1956
1957    public abstract void finishIteratingHistoryLocked();
1958
1959    public abstract boolean startIteratingOldHistoryLocked();
1960
1961    public abstract boolean getNextOldHistoryLocked(HistoryItem out);
1962
1963    public abstract void finishIteratingOldHistoryLocked();
1964
1965    /**
1966     * Return the base time offset for the battery history.
1967     */
1968    public abstract long getHistoryBaseTime();
1969
1970    /**
1971     * Returns the number of times the device has been started.
1972     */
1973    public abstract int getStartCount();
1974
1975    /**
1976     * Returns the time in microseconds that the screen has been on while the device was
1977     * running on battery.
1978     *
1979     * {@hide}
1980     */
1981    public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
1982
1983    /**
1984     * Returns the number of times the screen was turned on.
1985     *
1986     * {@hide}
1987     */
1988    public abstract int getScreenOnCount(int which);
1989
1990    /**
1991     * Returns the time in microseconds that the screen has been dozing while the device was
1992     * running on battery.
1993     *
1994     * {@hide}
1995     */
1996    public abstract long getScreenDozeTime(long elapsedRealtimeUs, int which);
1997
1998    /**
1999     * Returns the number of times the screen was turned dozing.
2000     *
2001     * {@hide}
2002     */
2003    public abstract int getScreenDozeCount(int which);
2004
2005    public abstract long getInteractiveTime(long elapsedRealtimeUs, int which);
2006
2007    public static final int SCREEN_BRIGHTNESS_DARK = 0;
2008    public static final int SCREEN_BRIGHTNESS_DIM = 1;
2009    public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
2010    public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
2011    public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
2012
2013    static final String[] SCREEN_BRIGHTNESS_NAMES = {
2014        "dark", "dim", "medium", "light", "bright"
2015    };
2016
2017    static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
2018        "0", "1", "2", "3", "4"
2019    };
2020
2021    public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
2022
2023    /**
2024     * Returns the time in microseconds that the screen has been on with
2025     * the given brightness
2026     *
2027     * {@hide}
2028     */
2029    public abstract long getScreenBrightnessTime(int brightnessBin,
2030            long elapsedRealtimeUs, int which);
2031
2032    /**
2033     * Returns the {@link Timer} object that tracks the given screen brightness.
2034     *
2035     * {@hide}
2036     */
2037    public abstract Timer getScreenBrightnessTimer(int brightnessBin);
2038
2039    /**
2040     * Returns the time in microseconds that power save mode has been enabled while the device was
2041     * running on battery.
2042     *
2043     * {@hide}
2044     */
2045    public abstract long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which);
2046
2047    /**
2048     * Returns the number of times that power save mode was enabled.
2049     *
2050     * {@hide}
2051     */
2052    public abstract int getPowerSaveModeEnabledCount(int which);
2053
2054    /**
2055     * Constant for device idle mode: not active.
2056     */
2057    public static final int DEVICE_IDLE_MODE_OFF = 0;
2058
2059    /**
2060     * Constant for device idle mode: active in lightweight mode.
2061     */
2062    public static final int DEVICE_IDLE_MODE_LIGHT = 1;
2063
2064    /**
2065     * Constant for device idle mode: active in full mode.
2066     */
2067    public static final int DEVICE_IDLE_MODE_DEEP = 2;
2068
2069    /**
2070     * Returns the time in microseconds that device has been in idle mode while
2071     * running on battery.
2072     *
2073     * {@hide}
2074     */
2075    public abstract long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which);
2076
2077    /**
2078     * Returns the number of times that the devie has gone in to idle mode.
2079     *
2080     * {@hide}
2081     */
2082    public abstract int getDeviceIdleModeCount(int mode, int which);
2083
2084    /**
2085     * Return the longest duration we spent in a particular device idle mode (fully in the
2086     * mode, not in idle maintenance etc).
2087     */
2088    public abstract long getLongestDeviceIdleModeTime(int mode);
2089
2090    /**
2091     * Returns the time in microseconds that device has been in idling while on
2092     * battery.  This is broader than {@link #getDeviceIdleModeTime} -- it
2093     * counts all of the time that we consider the device to be idle, whether or not
2094     * it is currently in the actual device idle mode.
2095     *
2096     * {@hide}
2097     */
2098    public abstract long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which);
2099
2100    /**
2101     * Returns the number of times that the device has started idling.
2102     *
2103     * {@hide}
2104     */
2105    public abstract int getDeviceIdlingCount(int mode, int which);
2106
2107    /**
2108     * Returns the number of times that connectivity state changed.
2109     *
2110     * {@hide}
2111     */
2112    public abstract int getNumConnectivityChange(int which);
2113
2114
2115    /**
2116     * Returns the time in microseconds that the phone has been running with
2117     * the given GPS signal quality level
2118     *
2119     * {@hide}
2120     */
2121    public abstract long getGpsSignalQualityTime(int strengthBin,
2122        long elapsedRealtimeUs, int which);
2123
2124    /**
2125     * Returns the GPS battery drain in mA-ms
2126     *
2127     * {@hide}
2128     */
2129    public abstract long getGpsBatteryDrainMaMs();
2130
2131    /**
2132     * Returns the time in microseconds that the phone has been on while the device was
2133     * running on battery.
2134     *
2135     * {@hide}
2136     */
2137    public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
2138
2139    /**
2140     * Returns the number of times a phone call was activated.
2141     *
2142     * {@hide}
2143     */
2144    public abstract int getPhoneOnCount(int which);
2145
2146    /**
2147     * Returns the time in microseconds that the phone has been running with
2148     * the given signal strength.
2149     *
2150     * {@hide}
2151     */
2152    public abstract long getPhoneSignalStrengthTime(int strengthBin,
2153            long elapsedRealtimeUs, int which);
2154
2155    /**
2156     * Returns the time in microseconds that the phone has been trying to
2157     * acquire a signal.
2158     *
2159     * {@hide}
2160     */
2161    public abstract long getPhoneSignalScanningTime(
2162            long elapsedRealtimeUs, int which);
2163
2164    /**
2165     * Returns the {@link Timer} object that tracks how much the phone has been trying to
2166     * acquire a signal.
2167     *
2168     * {@hide}
2169     */
2170    public abstract Timer getPhoneSignalScanningTimer();
2171
2172    /**
2173     * Returns the number of times the phone has entered the given signal strength.
2174     *
2175     * {@hide}
2176     */
2177    public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
2178
2179    /**
2180     * Return the {@link Timer} object used to track the given signal strength's duration and
2181     * counts.
2182     */
2183    protected abstract Timer getPhoneSignalStrengthTimer(int strengthBin);
2184
2185    /**
2186     * Returns the time in microseconds that the mobile network has been active
2187     * (in a high power state).
2188     *
2189     * {@hide}
2190     */
2191    public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which);
2192
2193    /**
2194     * Returns the number of times that the mobile network has transitioned to the
2195     * active state.
2196     *
2197     * {@hide}
2198     */
2199    public abstract int getMobileRadioActiveCount(int which);
2200
2201    /**
2202     * Returns the time in microseconds that is the difference between the mobile radio
2203     * time we saw based on the elapsed timestamp when going down vs. the given time stamp
2204     * from the radio.
2205     *
2206     * {@hide}
2207     */
2208    public abstract long getMobileRadioActiveAdjustedTime(int which);
2209
2210    /**
2211     * Returns the time in microseconds that the mobile network has been active
2212     * (in a high power state) but not being able to blame on an app.
2213     *
2214     * {@hide}
2215     */
2216    public abstract long getMobileRadioActiveUnknownTime(int which);
2217
2218    /**
2219     * Return count of number of times radio was up that could not be blamed on apps.
2220     *
2221     * {@hide}
2222     */
2223    public abstract int getMobileRadioActiveUnknownCount(int which);
2224
2225    public static final int DATA_CONNECTION_NONE = 0;
2226    public static final int DATA_CONNECTION_GPRS = 1;
2227    public static final int DATA_CONNECTION_EDGE = 2;
2228    public static final int DATA_CONNECTION_UMTS = 3;
2229    public static final int DATA_CONNECTION_CDMA = 4;
2230    public static final int DATA_CONNECTION_EVDO_0 = 5;
2231    public static final int DATA_CONNECTION_EVDO_A = 6;
2232    public static final int DATA_CONNECTION_1xRTT = 7;
2233    public static final int DATA_CONNECTION_HSDPA = 8;
2234    public static final int DATA_CONNECTION_HSUPA = 9;
2235    public static final int DATA_CONNECTION_HSPA = 10;
2236    public static final int DATA_CONNECTION_IDEN = 11;
2237    public static final int DATA_CONNECTION_EVDO_B = 12;
2238    public static final int DATA_CONNECTION_LTE = 13;
2239    public static final int DATA_CONNECTION_EHRPD = 14;
2240    public static final int DATA_CONNECTION_HSPAP = 15;
2241    public static final int DATA_CONNECTION_OTHER = 16;
2242
2243    static final String[] DATA_CONNECTION_NAMES = {
2244        "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
2245        "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
2246        "ehrpd", "hspap", "other"
2247    };
2248
2249    public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
2250
2251    /**
2252     * Returns the time in microseconds that the phone has been running with
2253     * the given data connection.
2254     *
2255     * {@hide}
2256     */
2257    public abstract long getPhoneDataConnectionTime(int dataType,
2258            long elapsedRealtimeUs, int which);
2259
2260    /**
2261     * Returns the number of times the phone has entered the given data
2262     * connection type.
2263     *
2264     * {@hide}
2265     */
2266    public abstract int getPhoneDataConnectionCount(int dataType, int which);
2267
2268    /**
2269     * Returns the {@link Timer} object that tracks the phone's data connection type stats.
2270     */
2271    public abstract Timer getPhoneDataConnectionTimer(int dataType);
2272
2273    public static final int WIFI_SUPPL_STATE_INVALID = 0;
2274    public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1;
2275    public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2;
2276    public static final int WIFI_SUPPL_STATE_INACTIVE = 3;
2277    public static final int WIFI_SUPPL_STATE_SCANNING = 4;
2278    public static final int WIFI_SUPPL_STATE_AUTHENTICATING = 5;
2279    public static final int WIFI_SUPPL_STATE_ASSOCIATING = 6;
2280    public static final int WIFI_SUPPL_STATE_ASSOCIATED = 7;
2281    public static final int WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE = 8;
2282    public static final int WIFI_SUPPL_STATE_GROUP_HANDSHAKE = 9;
2283    public static final int WIFI_SUPPL_STATE_COMPLETED = 10;
2284    public static final int WIFI_SUPPL_STATE_DORMANT = 11;
2285    public static final int WIFI_SUPPL_STATE_UNINITIALIZED = 12;
2286
2287    public static final int NUM_WIFI_SUPPL_STATES = WIFI_SUPPL_STATE_UNINITIALIZED+1;
2288
2289    static final String[] WIFI_SUPPL_STATE_NAMES = {
2290        "invalid", "disconn", "disabled", "inactive", "scanning",
2291        "authenticating", "associating", "associated", "4-way-handshake",
2292        "group-handshake", "completed", "dormant", "uninit"
2293    };
2294
2295    static final String[] WIFI_SUPPL_STATE_SHORT_NAMES = {
2296        "inv", "dsc", "dis", "inact", "scan",
2297        "auth", "ascing", "asced", "4-way",
2298        "group", "compl", "dorm", "uninit"
2299    };
2300
2301    public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS = new BitDescription[] {
2302        new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
2303        new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
2304        new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
2305        new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
2306        new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
2307        new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
2308        new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
2309        new BitDescription(HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG, "wifi_radio", "Wr"),
2310        new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
2311        new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
2312        new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
2313        new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
2314        new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
2315        new BitDescription(HistoryItem.STATE_SCREEN_DOZE_FLAG, "screen_doze", "Sd"),
2316        new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
2317                HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
2318                DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
2319        new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
2320                HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
2321                new String[] {"in", "out", "emergency", "off"},
2322                new String[] {"in", "out", "em", "off"}),
2323        new BitDescription(HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK,
2324                HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT, "phone_signal_strength", "Pss",
2325                SignalStrength.SIGNAL_STRENGTH_NAMES,
2326                new String[] { "0", "1", "2", "3", "4" }),
2327        new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
2328                HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
2329                SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
2330    };
2331
2332    public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
2333            = new BitDescription[] {
2334        new BitDescription(HistoryItem.STATE2_POWER_SAVE_FLAG, "power_save", "ps"),
2335        new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
2336        new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Ww"),
2337        new BitDescription(HistoryItem.STATE2_WIFI_ON_FLAG, "wifi", "W"),
2338        new BitDescription(HistoryItem.STATE2_FLASHLIGHT_FLAG, "flashlight", "fl"),
2339        new BitDescription(HistoryItem.STATE2_DEVICE_IDLE_MASK,
2340                HistoryItem.STATE2_DEVICE_IDLE_SHIFT, "device_idle", "di",
2341                new String[] { "off", "light", "full", "???" },
2342                new String[] { "off", "light", "full", "???" }),
2343        new BitDescription(HistoryItem.STATE2_CHARGING_FLAG, "charging", "ch"),
2344        new BitDescription(HistoryItem.STATE2_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
2345        new BitDescription(HistoryItem.STATE2_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
2346        new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
2347                HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT, "wifi_signal_strength", "Wss",
2348                new String[] { "0", "1", "2", "3", "4" },
2349                new String[] { "0", "1", "2", "3", "4" }),
2350        new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK,
2351                HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp",
2352                WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES),
2353        new BitDescription(HistoryItem.STATE2_CAMERA_FLAG, "camera", "ca"),
2354        new BitDescription(HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG, "ble_scan", "bles"),
2355        new BitDescription(HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK,
2356            HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT, "gps_signal_quality", "Gss",
2357            new String[] { "poor", "good"}, new String[] { "poor", "good"}),
2358    };
2359
2360    public static final String[] HISTORY_EVENT_NAMES = new String[] {
2361            "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
2362            "active", "pkginst", "pkgunin", "alarm", "stats", "pkginactive", "pkgactive",
2363            "tmpwhitelist", "screenwake", "wakeupap", "longwake", "est_capacity"
2364    };
2365
2366    public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
2367            "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
2368            "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa", "Etw",
2369            "Esw", "Ewa", "Elw", "Eec"
2370    };
2371
2372    @FunctionalInterface
2373    public interface IntToString {
2374        String applyAsString(int val);
2375    }
2376
2377    private static final IntToString sUidToString = UserHandle::formatUid;
2378    private static final IntToString sIntToString = Integer::toString;
2379
2380    public static final IntToString[] HISTORY_EVENT_INT_FORMATTERS = new IntToString[] {
2381            sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sUidToString,
2382            sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sUidToString,
2383            sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sUidToString,
2384            sUidToString, sUidToString, sUidToString, sIntToString
2385    };
2386
2387    /**
2388     * Returns total time for WiFi Multicast Wakelock timer.
2389     * Note that this may be different from the sum of per uid timer values.
2390     *
2391     *  {@hide}
2392     */
2393    public abstract long getWifiMulticastWakelockTime(long elapsedRealtimeUs, int which);
2394
2395    /**
2396     * Returns total time for WiFi Multicast Wakelock timer
2397     * Note that this may be different from the sum of per uid timer values.
2398     *
2399     * {@hide}
2400     */
2401    public abstract int getWifiMulticastWakelockCount(int which);
2402
2403    /**
2404     * Returns the time in microseconds that wifi has been on while the device was
2405     * running on battery.
2406     *
2407     * {@hide}
2408     */
2409    public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
2410
2411    /**
2412     * Returns the time in microseconds that wifi has been active while the device was
2413     * running on battery.
2414     *
2415     * {@hide}
2416     */
2417    public abstract long getWifiActiveTime(long elapsedRealtimeUs, int which);
2418
2419    /**
2420     * Returns the time in microseconds that wifi has been on and the driver has
2421     * been in the running state while the device was running on battery.
2422     *
2423     * {@hide}
2424     */
2425    public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
2426
2427    public static final int WIFI_STATE_OFF = 0;
2428    public static final int WIFI_STATE_OFF_SCANNING = 1;
2429    public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
2430    public static final int WIFI_STATE_ON_DISCONNECTED = 3;
2431    public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
2432    public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
2433    public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
2434    public static final int WIFI_STATE_SOFT_AP = 7;
2435
2436    static final String[] WIFI_STATE_NAMES = {
2437        "off", "scanning", "no_net", "disconn",
2438        "sta", "p2p", "sta_p2p", "soft_ap"
2439    };
2440
2441    public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1;
2442
2443    /**
2444     * Returns the time in microseconds that WiFi has been running in the given state.
2445     *
2446     * {@hide}
2447     */
2448    public abstract long getWifiStateTime(int wifiState,
2449            long elapsedRealtimeUs, int which);
2450
2451    /**
2452     * Returns the number of times that WiFi has entered the given state.
2453     *
2454     * {@hide}
2455     */
2456    public abstract int getWifiStateCount(int wifiState, int which);
2457
2458    /**
2459     * Returns the {@link Timer} object that tracks the given WiFi state.
2460     *
2461     * {@hide}
2462     */
2463    public abstract Timer getWifiStateTimer(int wifiState);
2464
2465    /**
2466     * Returns the time in microseconds that the wifi supplicant has been
2467     * in a given state.
2468     *
2469     * {@hide}
2470     */
2471    public abstract long getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which);
2472
2473    /**
2474     * Returns the number of times that the wifi supplicant has transitioned
2475     * to a given state.
2476     *
2477     * {@hide}
2478     */
2479    public abstract int getWifiSupplStateCount(int state, int which);
2480
2481    /**
2482     * Returns the {@link Timer} object that tracks the given wifi supplicant state.
2483     *
2484     * {@hide}
2485     */
2486    public abstract Timer getWifiSupplStateTimer(int state);
2487
2488    public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5;
2489
2490    /**
2491     * Returns the time in microseconds that WIFI has been running with
2492     * the given signal strength.
2493     *
2494     * {@hide}
2495     */
2496    public abstract long getWifiSignalStrengthTime(int strengthBin,
2497            long elapsedRealtimeUs, int which);
2498
2499    /**
2500     * Returns the number of times WIFI has entered the given signal strength.
2501     *
2502     * {@hide}
2503     */
2504    public abstract int getWifiSignalStrengthCount(int strengthBin, int which);
2505
2506    /**
2507     * Returns the {@link Timer} object that tracks the given WIFI signal strength.
2508     *
2509     * {@hide}
2510     */
2511    public abstract Timer getWifiSignalStrengthTimer(int strengthBin);
2512
2513    /**
2514     * Returns the time in microseconds that the flashlight has been on while the device was
2515     * running on battery.
2516     *
2517     * {@hide}
2518     */
2519    public abstract long getFlashlightOnTime(long elapsedRealtimeUs, int which);
2520
2521    /**
2522     * Returns the number of times that the flashlight has been turned on while the device was
2523     * running on battery.
2524     *
2525     * {@hide}
2526     */
2527    public abstract long getFlashlightOnCount(int which);
2528
2529    /**
2530     * Returns the time in microseconds that the camera has been on while the device was
2531     * running on battery.
2532     *
2533     * {@hide}
2534     */
2535    public abstract long getCameraOnTime(long elapsedRealtimeUs, int which);
2536
2537    /**
2538     * Returns the time in microseconds that bluetooth scans were running while the device was
2539     * on battery.
2540     *
2541     * {@hide}
2542     */
2543    public abstract long getBluetoothScanTime(long elapsedRealtimeUs, int which);
2544
2545    public static final int NETWORK_MOBILE_RX_DATA = 0;
2546    public static final int NETWORK_MOBILE_TX_DATA = 1;
2547    public static final int NETWORK_WIFI_RX_DATA = 2;
2548    public static final int NETWORK_WIFI_TX_DATA = 3;
2549    public static final int NETWORK_BT_RX_DATA = 4;
2550    public static final int NETWORK_BT_TX_DATA = 5;
2551    public static final int NETWORK_MOBILE_BG_RX_DATA = 6;
2552    public static final int NETWORK_MOBILE_BG_TX_DATA = 7;
2553    public static final int NETWORK_WIFI_BG_RX_DATA = 8;
2554    public static final int NETWORK_WIFI_BG_TX_DATA = 9;
2555    public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_BG_TX_DATA + 1;
2556
2557    public abstract long getNetworkActivityBytes(int type, int which);
2558    public abstract long getNetworkActivityPackets(int type, int which);
2559
2560    /**
2561     * Returns true if the BatteryStats object has detailed WiFi power reports.
2562     * When true, calling {@link #getWifiControllerActivity()} will yield the
2563     * actual power data.
2564     */
2565    public abstract boolean hasWifiActivityReporting();
2566
2567    /**
2568     * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
2569     * in various radio controller states, such as transmit, receive, and idle.
2570     * @return non-null {@link ControllerActivityCounter}
2571     */
2572    public abstract ControllerActivityCounter getWifiControllerActivity();
2573
2574    /**
2575     * Returns true if the BatteryStats object has detailed bluetooth power reports.
2576     * When true, calling {@link #getBluetoothControllerActivity()} will yield the
2577     * actual power data.
2578     */
2579    public abstract boolean hasBluetoothActivityReporting();
2580
2581    /**
2582     * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
2583     * in various radio controller states, such as transmit, receive, and idle.
2584     * @return non-null {@link ControllerActivityCounter}
2585     */
2586    public abstract ControllerActivityCounter getBluetoothControllerActivity();
2587
2588    /**
2589     * Returns true if the BatteryStats object has detailed modem power reports.
2590     * When true, calling {@link #getModemControllerActivity()} will yield the
2591     * actual power data.
2592     */
2593    public abstract boolean hasModemActivityReporting();
2594
2595    /**
2596     * Returns a {@link ControllerActivityCounter} which is an aggregate of the times spent
2597     * in various radio controller states, such as transmit, receive, and idle.
2598     * @return non-null {@link ControllerActivityCounter}
2599     */
2600    public abstract ControllerActivityCounter getModemControllerActivity();
2601
2602    /**
2603     * Return the wall clock time when battery stats data collection started.
2604     */
2605    public abstract long getStartClockTime();
2606
2607    /**
2608     * Return platform version tag that we were running in when the battery stats started.
2609     */
2610    public abstract String getStartPlatformVersion();
2611
2612    /**
2613     * Return platform version tag that we were running in when the battery stats ended.
2614     */
2615    public abstract String getEndPlatformVersion();
2616
2617    /**
2618     * Return the internal version code of the parcelled format.
2619     */
2620    public abstract int getParcelVersion();
2621
2622    /**
2623     * Return whether we are currently running on battery.
2624     */
2625    public abstract boolean getIsOnBattery();
2626
2627    /**
2628     * Returns a SparseArray containing the statistics for each uid.
2629     */
2630    public abstract SparseArray<? extends Uid> getUidStats();
2631
2632    /**
2633     * Returns the current battery uptime in microseconds.
2634     *
2635     * @param curTime the amount of elapsed realtime in microseconds.
2636     */
2637    public abstract long getBatteryUptime(long curTime);
2638
2639    /**
2640     * Returns the current battery realtime in microseconds.
2641     *
2642     * @param curTime the amount of elapsed realtime in microseconds.
2643     */
2644    public abstract long getBatteryRealtime(long curTime);
2645
2646    /**
2647     * Returns the battery percentage level at the last time the device was unplugged from power, or
2648     * the last time it booted on battery power.
2649     */
2650    public abstract int getDischargeStartLevel();
2651
2652    /**
2653     * Returns the current battery percentage level if we are in a discharge cycle, otherwise
2654     * returns the level at the last plug event.
2655     */
2656    public abstract int getDischargeCurrentLevel();
2657
2658    /**
2659     * Get the amount the battery has discharged since the stats were
2660     * last reset after charging, as a lower-end approximation.
2661     */
2662    public abstract int getLowDischargeAmountSinceCharge();
2663
2664    /**
2665     * Get the amount the battery has discharged since the stats were
2666     * last reset after charging, as an upper-end approximation.
2667     */
2668    public abstract int getHighDischargeAmountSinceCharge();
2669
2670    /**
2671     * Retrieve the discharge amount over the selected discharge period <var>which</var>.
2672     */
2673    public abstract int getDischargeAmount(int which);
2674
2675    /**
2676     * Get the amount the battery has discharged while the screen was on,
2677     * since the last time power was unplugged.
2678     */
2679    public abstract int getDischargeAmountScreenOn();
2680
2681    /**
2682     * Get the amount the battery has discharged while the screen was on,
2683     * since the last time the device was charged.
2684     */
2685    public abstract int getDischargeAmountScreenOnSinceCharge();
2686
2687    /**
2688     * Get the amount the battery has discharged while the screen was off,
2689     * since the last time power was unplugged.
2690     */
2691    public abstract int getDischargeAmountScreenOff();
2692
2693    /**
2694     * Get the amount the battery has discharged while the screen was off,
2695     * since the last time the device was charged.
2696     */
2697    public abstract int getDischargeAmountScreenOffSinceCharge();
2698
2699    /**
2700     * Get the amount the battery has discharged while the screen was dozing,
2701     * since the last time power was unplugged.
2702     */
2703    public abstract int getDischargeAmountScreenDoze();
2704
2705    /**
2706     * Get the amount the battery has discharged while the screen was dozing,
2707     * since the last time the device was charged.
2708     */
2709    public abstract int getDischargeAmountScreenDozeSinceCharge();
2710
2711    /**
2712     * Returns the total, last, or current battery uptime in microseconds.
2713     *
2714     * @param curTime the elapsed realtime in microseconds.
2715     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2716     */
2717    public abstract long computeBatteryUptime(long curTime, int which);
2718
2719    /**
2720     * Returns the total, last, or current battery realtime in microseconds.
2721     *
2722     * @param curTime the current elapsed realtime in microseconds.
2723     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2724     */
2725    public abstract long computeBatteryRealtime(long curTime, int which);
2726
2727    /**
2728     * Returns the total, last, or current battery screen off/doze uptime in microseconds.
2729     *
2730     * @param curTime the elapsed realtime in microseconds.
2731     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2732     */
2733    public abstract long computeBatteryScreenOffUptime(long curTime, int which);
2734
2735    /**
2736     * Returns the total, last, or current battery screen off/doze realtime in microseconds.
2737     *
2738     * @param curTime the current elapsed realtime in microseconds.
2739     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2740     */
2741    public abstract long computeBatteryScreenOffRealtime(long curTime, int which);
2742
2743    /**
2744     * Returns the total, last, or current uptime in microseconds.
2745     *
2746     * @param curTime the current elapsed realtime in microseconds.
2747     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2748     */
2749    public abstract long computeUptime(long curTime, int which);
2750
2751    /**
2752     * Returns the total, last, or current realtime in microseconds.
2753     *
2754     * @param curTime the current elapsed realtime in microseconds.
2755     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2756     */
2757    public abstract long computeRealtime(long curTime, int which);
2758
2759    /**
2760     * Compute an approximation for how much run time (in microseconds) is remaining on
2761     * the battery.  Returns -1 if no time can be computed: either there is not
2762     * enough current data to make a decision, or the battery is currently
2763     * charging.
2764     *
2765     * @param curTime The current elepsed realtime in microseconds.
2766     */
2767    public abstract long computeBatteryTimeRemaining(long curTime);
2768
2769    // The part of a step duration that is the actual time.
2770    public static final long STEP_LEVEL_TIME_MASK = 0x000000ffffffffffL;
2771
2772    // Bits in a step duration that are the new battery level we are at.
2773    public static final long STEP_LEVEL_LEVEL_MASK = 0x0000ff0000000000L;
2774    public static final int STEP_LEVEL_LEVEL_SHIFT = 40;
2775
2776    // Bits in a step duration that are the initial mode we were in at that step.
2777    public static final long STEP_LEVEL_INITIAL_MODE_MASK = 0x00ff000000000000L;
2778    public static final int STEP_LEVEL_INITIAL_MODE_SHIFT = 48;
2779
2780    // Bits in a step duration that indicate which modes changed during that step.
2781    public static final long STEP_LEVEL_MODIFIED_MODE_MASK = 0xff00000000000000L;
2782    public static final int STEP_LEVEL_MODIFIED_MODE_SHIFT = 56;
2783
2784    // Step duration mode: the screen is on, off, dozed, etc; value is Display.STATE_* - 1.
2785    public static final int STEP_LEVEL_MODE_SCREEN_STATE = 0x03;
2786
2787    // The largest value for screen state that is tracked in battery states. Any values above
2788    // this should be mapped back to one of the tracked values before being tracked here.
2789    public static final int MAX_TRACKED_SCREEN_STATE = Display.STATE_DOZE_SUSPEND;
2790
2791    // Step duration mode: power save is on.
2792    public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04;
2793
2794    // Step duration mode: device is currently in idle mode.
2795    public static final int STEP_LEVEL_MODE_DEVICE_IDLE = 0x08;
2796
2797    public static final int[] STEP_LEVEL_MODES_OF_INTEREST = new int[] {
2798            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2799            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE,
2800            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
2801            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2802            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2803            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2804            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2805            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2806            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE,
2807            STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
2808    };
2809    public static final int[] STEP_LEVEL_MODE_VALUES = new int[] {
2810            (Display.STATE_OFF-1),
2811            (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE,
2812            (Display.STATE_OFF-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
2813            (Display.STATE_ON-1),
2814            (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE,
2815            (Display.STATE_DOZE-1),
2816            (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE,
2817            (Display.STATE_DOZE_SUSPEND-1),
2818            (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE,
2819            (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
2820    };
2821    public static final String[] STEP_LEVEL_MODE_LABELS = new String[] {
2822            "screen off",
2823            "screen off power save",
2824            "screen off device idle",
2825            "screen on",
2826            "screen on power save",
2827            "screen doze",
2828            "screen doze power save",
2829            "screen doze-suspend",
2830            "screen doze-suspend power save",
2831            "screen doze-suspend device idle",
2832    };
2833
2834    /**
2835     * Return the amount of battery discharge while the screen was off, measured in
2836     * micro-Ampere-hours. This will be non-zero only if the device's battery has
2837     * a coulomb counter.
2838     */
2839    public abstract long getUahDischargeScreenOff(int which);
2840
2841    /**
2842     * Return the amount of battery discharge while the screen was in doze mode, measured in
2843     * micro-Ampere-hours. This will be non-zero only if the device's battery has
2844     * a coulomb counter.
2845     */
2846    public abstract long getUahDischargeScreenDoze(int which);
2847
2848    /**
2849     * Return the amount of battery discharge  measured in micro-Ampere-hours. This will be
2850     * non-zero only if the device's battery has a coulomb counter.
2851     */
2852    public abstract long getUahDischarge(int which);
2853
2854    /**
2855     * @return the amount of battery discharge while the device is in light idle mode, measured in
2856     * micro-Ampere-hours.
2857     */
2858    public abstract long getUahDischargeLightDoze(int which);
2859
2860    /**
2861     * @return the amount of battery discharge while the device is in deep idle mode, measured in
2862     * micro-Ampere-hours.
2863     */
2864    public abstract long getUahDischargeDeepDoze(int which);
2865
2866    /**
2867     * Returns the estimated real battery capacity, which may be less than the capacity
2868     * declared by the PowerProfile.
2869     * @return The estimated battery capacity in mAh.
2870     */
2871    public abstract int getEstimatedBatteryCapacity();
2872
2873    /**
2874     * @return The minimum learned battery capacity in uAh.
2875     */
2876    public abstract int getMinLearnedBatteryCapacity();
2877
2878    /**
2879     * @return The maximum learned battery capacity in uAh.
2880     */
2881    public abstract int getMaxLearnedBatteryCapacity() ;
2882
2883    /**
2884     * Return the array of discharge step durations.
2885     */
2886    public abstract LevelStepTracker getDischargeLevelStepTracker();
2887
2888    /**
2889     * Return the array of daily discharge step durations.
2890     */
2891    public abstract LevelStepTracker getDailyDischargeLevelStepTracker();
2892
2893    /**
2894     * Compute an approximation for how much time (in microseconds) remains until the battery
2895     * is fully charged.  Returns -1 if no time can be computed: either there is not
2896     * enough current data to make a decision, or the battery is currently
2897     * discharging.
2898     *
2899     * @param curTime The current elepsed realtime in microseconds.
2900     */
2901    public abstract long computeChargeTimeRemaining(long curTime);
2902
2903    /**
2904     * Return the array of charge step durations.
2905     */
2906    public abstract LevelStepTracker getChargeLevelStepTracker();
2907
2908    /**
2909     * Return the array of daily charge step durations.
2910     */
2911    public abstract LevelStepTracker getDailyChargeLevelStepTracker();
2912
2913    public abstract ArrayList<PackageChange> getDailyPackageChanges();
2914
2915    public abstract Map<String, ? extends Timer> getWakeupReasonStats();
2916
2917    public abstract Map<String, ? extends Timer> getKernelWakelockStats();
2918
2919    /**
2920     * Returns Timers tracking the total time of each Resource Power Manager state and voter.
2921     */
2922    public abstract Map<String, ? extends Timer> getRpmStats();
2923    /**
2924     * Returns Timers tracking the screen-off time of each Resource Power Manager state and voter.
2925     */
2926    public abstract Map<String, ? extends Timer> getScreenOffRpmStats();
2927
2928
2929    public abstract LongSparseArray<? extends Timer> getKernelMemoryStats();
2930
2931    public abstract void writeToParcelWithoutUids(Parcel out, int flags);
2932
2933    private final static void formatTimeRaw(StringBuilder out, long seconds) {
2934        long days = seconds / (60 * 60 * 24);
2935        if (days != 0) {
2936            out.append(days);
2937            out.append("d ");
2938        }
2939        long used = days * 60 * 60 * 24;
2940
2941        long hours = (seconds - used) / (60 * 60);
2942        if (hours != 0 || used != 0) {
2943            out.append(hours);
2944            out.append("h ");
2945        }
2946        used += hours * 60 * 60;
2947
2948        long mins = (seconds-used) / 60;
2949        if (mins != 0 || used != 0) {
2950            out.append(mins);
2951            out.append("m ");
2952        }
2953        used += mins * 60;
2954
2955        if (seconds != 0 || used != 0) {
2956            out.append(seconds-used);
2957            out.append("s ");
2958        }
2959    }
2960
2961    public final static void formatTimeMs(StringBuilder sb, long time) {
2962        long sec = time / 1000;
2963        formatTimeRaw(sb, sec);
2964        sb.append(time - (sec * 1000));
2965        sb.append("ms ");
2966    }
2967
2968    public final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
2969        long sec = time / 1000;
2970        formatTimeRaw(sb, sec);
2971        sb.append(time - (sec * 1000));
2972        sb.append("ms");
2973    }
2974
2975    public final String formatRatioLocked(long num, long den) {
2976        if (den == 0L) {
2977            return "--%";
2978        }
2979        float perc = ((float)num) / ((float)den) * 100;
2980        mFormatBuilder.setLength(0);
2981        mFormatter.format("%.1f%%", perc);
2982        return mFormatBuilder.toString();
2983    }
2984
2985    final String formatBytesLocked(long bytes) {
2986        mFormatBuilder.setLength(0);
2987
2988        if (bytes < BYTES_PER_KB) {
2989            return bytes + "B";
2990        } else if (bytes < BYTES_PER_MB) {
2991            mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
2992            return mFormatBuilder.toString();
2993        } else if (bytes < BYTES_PER_GB){
2994            mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
2995            return mFormatBuilder.toString();
2996        } else {
2997            mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
2998            return mFormatBuilder.toString();
2999        }
3000    }
3001
3002    private static long roundUsToMs(long timeUs) {
3003        return (timeUs + 500) / 1000;
3004    }
3005
3006    private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) {
3007        if (timer != null) {
3008            // Convert from microseconds to milliseconds with rounding
3009            long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
3010            long totalTimeMillis = (totalTimeMicros + 500) / 1000;
3011            return totalTimeMillis;
3012        }
3013        return 0;
3014    }
3015
3016    /**
3017     *
3018     * @param sb a StringBuilder object.
3019     * @param timer a Timer object contining the wakelock times.
3020     * @param elapsedRealtimeUs the current on-battery time in microseconds.
3021     * @param name the name of the wakelock.
3022     * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3023     * @param linePrefix a String to be prepended to each line of output.
3024     * @return the line prefix
3025     */
3026    private static final String printWakeLock(StringBuilder sb, Timer timer,
3027            long elapsedRealtimeUs, String name, int which, String linePrefix) {
3028
3029        if (timer != null) {
3030            long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which);
3031
3032            int count = timer.getCountLocked(which);
3033            if (totalTimeMillis != 0) {
3034                sb.append(linePrefix);
3035                formatTimeMs(sb, totalTimeMillis);
3036                if (name != null) {
3037                    sb.append(name);
3038                    sb.append(' ');
3039                }
3040                sb.append('(');
3041                sb.append(count);
3042                sb.append(" times)");
3043                final long maxDurationMs = timer.getMaxDurationMsLocked(elapsedRealtimeUs/1000);
3044                if (maxDurationMs >= 0) {
3045                    sb.append(" max=");
3046                    sb.append(maxDurationMs);
3047                }
3048                // Put actual time if it is available and different from totalTimeMillis.
3049                final long totalDurMs = timer.getTotalDurationMsLocked(elapsedRealtimeUs/1000);
3050                if (totalDurMs > totalTimeMillis) {
3051                    sb.append(" actual=");
3052                    sb.append(totalDurMs);
3053                }
3054                if (timer.isRunningLocked()) {
3055                    final long currentMs = timer.getCurrentDurationMsLocked(elapsedRealtimeUs/1000);
3056                    if (currentMs >= 0) {
3057                        sb.append(" (running for ");
3058                        sb.append(currentMs);
3059                        sb.append("ms)");
3060                    } else {
3061                        sb.append(" (running)");
3062                    }
3063                }
3064
3065                return ", ";
3066            }
3067        }
3068        return linePrefix;
3069    }
3070
3071    /**
3072     * Prints details about a timer, if its total time was greater than 0.
3073     *
3074     * @param pw a PrintWriter object to print to.
3075     * @param sb a StringBuilder object.
3076     * @param timer a Timer object contining the wakelock times.
3077     * @param rawRealtimeUs the current on-battery time in microseconds.
3078     * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3079     * @param prefix a String to be prepended to each line of output.
3080     * @param type the name of the timer.
3081     * @return true if anything was printed.
3082     */
3083    private static final boolean printTimer(PrintWriter pw, StringBuilder sb, Timer timer,
3084            long rawRealtimeUs, int which, String prefix, String type) {
3085        if (timer != null) {
3086            // Convert from microseconds to milliseconds with rounding
3087            final long totalTimeMs = (timer.getTotalTimeLocked(
3088                    rawRealtimeUs, which) + 500) / 1000;
3089            final int count = timer.getCountLocked(which);
3090            if (totalTimeMs != 0) {
3091                sb.setLength(0);
3092                sb.append(prefix);
3093                sb.append("    ");
3094                sb.append(type);
3095                sb.append(": ");
3096                formatTimeMs(sb, totalTimeMs);
3097                sb.append("realtime (");
3098                sb.append(count);
3099                sb.append(" times)");
3100                final long maxDurationMs = timer.getMaxDurationMsLocked(rawRealtimeUs/1000);
3101                if (maxDurationMs >= 0) {
3102                    sb.append(" max=");
3103                    sb.append(maxDurationMs);
3104                }
3105                if (timer.isRunningLocked()) {
3106                    final long currentMs = timer.getCurrentDurationMsLocked(rawRealtimeUs/1000);
3107                    if (currentMs >= 0) {
3108                        sb.append(" (running for ");
3109                        sb.append(currentMs);
3110                        sb.append("ms)");
3111                    } else {
3112                        sb.append(" (running)");
3113                    }
3114                }
3115                pw.println(sb.toString());
3116                return true;
3117            }
3118        }
3119        return false;
3120    }
3121
3122    /**
3123     * Checkin version of wakelock printer. Prints simple comma-separated list.
3124     *
3125     * @param sb a StringBuilder object.
3126     * @param timer a Timer object contining the wakelock times.
3127     * @param elapsedRealtimeUs the current time in microseconds.
3128     * @param name the name of the wakelock.
3129     * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
3130     * @param linePrefix a String to be prepended to each line of output.
3131     * @return the line prefix
3132     */
3133    private static final String printWakeLockCheckin(StringBuilder sb, Timer timer,
3134            long elapsedRealtimeUs, String name, int which, String linePrefix) {
3135        long totalTimeMicros = 0;
3136        int count = 0;
3137        long max = 0;
3138        long current = 0;
3139        long totalDuration = 0;
3140        if (timer != null) {
3141            totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
3142            count = timer.getCountLocked(which);
3143            current = timer.getCurrentDurationMsLocked(elapsedRealtimeUs/1000);
3144            max = timer.getMaxDurationMsLocked(elapsedRealtimeUs/1000);
3145            totalDuration = timer.getTotalDurationMsLocked(elapsedRealtimeUs/1000);
3146        }
3147        sb.append(linePrefix);
3148        sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
3149        sb.append(',');
3150        sb.append(name != null ? name + "," : "");
3151        sb.append(count);
3152        sb.append(',');
3153        sb.append(current);
3154        sb.append(',');
3155        sb.append(max);
3156        // Partial, full, and window wakelocks are pooled, so totalDuration is meaningful (albeit
3157        // not always tracked). Kernel wakelocks (which have name == null) have no notion of
3158        // totalDuration independent of totalTimeMicros (since they are not pooled).
3159        if (name != null) {
3160            sb.append(',');
3161            sb.append(totalDuration);
3162        }
3163        return ",";
3164    }
3165
3166    private static final void dumpLineHeader(PrintWriter pw, int uid, String category,
3167                                             String type) {
3168        pw.print(BATTERY_STATS_CHECKIN_VERSION);
3169        pw.print(',');
3170        pw.print(uid);
3171        pw.print(',');
3172        pw.print(category);
3173        pw.print(',');
3174        pw.print(type);
3175    }
3176
3177    /**
3178     * Dump a comma-separated line of values for terse checkin mode.
3179     *
3180     * @param pw the PageWriter to dump log to
3181     * @param category category of data (e.g. "total", "last", "unplugged", "current" )
3182     * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
3183     * @param args type-dependent data arguments
3184     */
3185    private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
3186           Object... args ) {
3187        dumpLineHeader(pw, uid, category, type);
3188        for (Object arg : args) {
3189            pw.print(',');
3190            pw.print(arg);
3191        }
3192        pw.println();
3193    }
3194
3195    /**
3196     * Dump a given timer stat for terse checkin mode.
3197     *
3198     * @param pw the PageWriter to dump log to
3199     * @param uid the UID to log
3200     * @param category category of data (e.g. "total", "last", "unplugged", "current" )
3201     * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
3202     * @param timer a {@link Timer} to dump stats for
3203     * @param rawRealtime the current elapsed realtime of the system in microseconds
3204     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
3205     */
3206    private static final void dumpTimer(PrintWriter pw, int uid, String category, String type,
3207                                        Timer timer, long rawRealtime, int which) {
3208        if (timer != null) {
3209            // Convert from microseconds to milliseconds with rounding
3210            final long totalTime = roundUsToMs(timer.getTotalTimeLocked(rawRealtime, which));
3211            final int count = timer.getCountLocked(which);
3212            if (totalTime != 0 || count != 0) {
3213                dumpLine(pw, uid, category, type, totalTime, count);
3214            }
3215        }
3216    }
3217
3218    /**
3219     * Dump a given timer stat to the proto stream.
3220     *
3221     * @param proto the ProtoOutputStream to log to
3222     * @param fieldId type of data, the field to save to (e.g. AggregatedBatteryStats.WAKELOCK)
3223     * @param timer a {@link Timer} to dump stats for
3224     * @param rawRealtimeUs the current elapsed realtime of the system in microseconds
3225     * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
3226     */
3227    private static void dumpTimer(ProtoOutputStream proto, long fieldId,
3228                                        Timer timer, long rawRealtimeUs, int which) {
3229        if (timer == null) {
3230            return;
3231        }
3232        // Convert from microseconds to milliseconds with rounding
3233        final long timeMs = roundUsToMs(timer.getTotalTimeLocked(rawRealtimeUs, which));
3234        final int count = timer.getCountLocked(which);
3235        final long maxDurationMs = timer.getMaxDurationMsLocked(rawRealtimeUs / 1000);
3236        final long curDurationMs = timer.getCurrentDurationMsLocked(rawRealtimeUs / 1000);
3237        final long totalDurationMs = timer.getTotalDurationMsLocked(rawRealtimeUs / 1000);
3238        if (timeMs != 0 || count != 0 || maxDurationMs != -1 || curDurationMs != -1
3239                || totalDurationMs != -1) {
3240            final long token = proto.start(fieldId);
3241            proto.write(TimerProto.DURATION_MS, timeMs);
3242            proto.write(TimerProto.COUNT, count);
3243            // These values will be -1 for timers that don't implement the functionality.
3244            if (maxDurationMs != -1) {
3245                proto.write(TimerProto.MAX_DURATION_MS, maxDurationMs);
3246            }
3247            if (curDurationMs != -1) {
3248                proto.write(TimerProto.CURRENT_DURATION_MS, curDurationMs);
3249            }
3250            if (totalDurationMs != -1) {
3251                proto.write(TimerProto.TOTAL_DURATION_MS, totalDurationMs);
3252            }
3253            proto.end(token);
3254        }
3255    }
3256
3257    /**
3258     * Checks if the ControllerActivityCounter has any data worth dumping.
3259     */
3260    private static boolean controllerActivityHasData(ControllerActivityCounter counter, int which) {
3261        if (counter == null) {
3262            return false;
3263        }
3264
3265        if (counter.getIdleTimeCounter().getCountLocked(which) != 0
3266                || counter.getRxTimeCounter().getCountLocked(which) != 0
3267                || counter.getPowerCounter().getCountLocked(which) != 0) {
3268            return true;
3269        }
3270
3271        for (LongCounter c : counter.getTxTimeCounters()) {
3272            if (c.getCountLocked(which) != 0) {
3273                return true;
3274            }
3275        }
3276        return false;
3277    }
3278
3279    /**
3280     * Dumps the ControllerActivityCounter if it has any data worth dumping.
3281     * The order of the arguments in the final check in line is:
3282     *
3283     * idle, rx, power, tx...
3284     *
3285     * where tx... is one or more transmit level times.
3286     */
3287    private static final void dumpControllerActivityLine(PrintWriter pw, int uid, String category,
3288                                                         String type,
3289                                                         ControllerActivityCounter counter,
3290                                                         int which) {
3291        if (!controllerActivityHasData(counter, which)) {
3292            return;
3293        }
3294
3295        dumpLineHeader(pw, uid, category, type);
3296        pw.print(",");
3297        pw.print(counter.getIdleTimeCounter().getCountLocked(which));
3298        pw.print(",");
3299        pw.print(counter.getRxTimeCounter().getCountLocked(which));
3300        pw.print(",");
3301        pw.print(counter.getPowerCounter().getCountLocked(which) / (1000 * 60 * 60));
3302        for (LongCounter c : counter.getTxTimeCounters()) {
3303            pw.print(",");
3304            pw.print(c.getCountLocked(which));
3305        }
3306        pw.println();
3307    }
3308
3309    /**
3310     * Dumps the ControllerActivityCounter if it has any data worth dumping.
3311     */
3312    private static void dumpControllerActivityProto(ProtoOutputStream proto, long fieldId,
3313                                                    ControllerActivityCounter counter,
3314                                                    int which) {
3315        if (!controllerActivityHasData(counter, which)) {
3316            return;
3317        }
3318
3319        final long cToken = proto.start(fieldId);
3320
3321        proto.write(ControllerActivityProto.IDLE_DURATION_MS,
3322                counter.getIdleTimeCounter().getCountLocked(which));
3323        proto.write(ControllerActivityProto.RX_DURATION_MS,
3324                counter.getRxTimeCounter().getCountLocked(which));
3325        proto.write(ControllerActivityProto.POWER_MAH,
3326                counter.getPowerCounter().getCountLocked(which) / (1000 * 60 * 60));
3327
3328        long tToken;
3329        LongCounter[] txCounters = counter.getTxTimeCounters();
3330        for (int i = 0; i < txCounters.length; ++i) {
3331            LongCounter c = txCounters[i];
3332            tToken = proto.start(ControllerActivityProto.TX);
3333            proto.write(ControllerActivityProto.TxLevel.LEVEL, i);
3334            proto.write(ControllerActivityProto.TxLevel.DURATION_MS, c.getCountLocked(which));
3335            proto.end(tToken);
3336        }
3337
3338        proto.end(cToken);
3339    }
3340
3341    private final void printControllerActivityIfInteresting(PrintWriter pw, StringBuilder sb,
3342                                                            String prefix, String controllerName,
3343                                                            ControllerActivityCounter counter,
3344                                                            int which) {
3345        if (controllerActivityHasData(counter, which)) {
3346            printControllerActivity(pw, sb, prefix, controllerName, counter, which);
3347        }
3348    }
3349
3350    private final void printControllerActivity(PrintWriter pw, StringBuilder sb, String prefix,
3351                                               String controllerName,
3352                                               ControllerActivityCounter counter, int which) {
3353        final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
3354        final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
3355        final long powerDrainMaMs = counter.getPowerCounter().getCountLocked(which);
3356        // Battery real time
3357        final long totalControllerActivityTimeMs
3358            = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
3359        long totalTxTimeMs = 0;
3360        for (LongCounter txState : counter.getTxTimeCounters()) {
3361            totalTxTimeMs += txState.getCountLocked(which);
3362        }
3363        final long sleepTimeMs
3364            = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + totalTxTimeMs);
3365
3366        if (controllerName.equals(WIFI_CONTROLLER_NAME)) {
3367            final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which);
3368            sb.setLength(0);
3369            sb.append(prefix);
3370            sb.append("     ");
3371            sb.append(controllerName);
3372            sb.append(" Scan time:  ");
3373            formatTimeMs(sb, scanTimeMs);
3374            sb.append("(");
3375            sb.append(formatRatioLocked(scanTimeMs, totalControllerActivityTimeMs));
3376            sb.append(")");
3377            pw.println(sb.toString());
3378        }
3379
3380        sb.setLength(0);
3381        sb.append(prefix);
3382        sb.append("     ");
3383        sb.append(controllerName);
3384        sb.append(" Sleep time:  ");
3385        formatTimeMs(sb, sleepTimeMs);
3386        sb.append("(");
3387        sb.append(formatRatioLocked(sleepTimeMs, totalControllerActivityTimeMs));
3388        sb.append(")");
3389        pw.println(sb.toString());
3390
3391        sb.setLength(0);
3392        sb.append(prefix);
3393        sb.append("     ");
3394        sb.append(controllerName);
3395        sb.append(" Idle time:   ");
3396        formatTimeMs(sb, idleTimeMs);
3397        sb.append("(");
3398        sb.append(formatRatioLocked(idleTimeMs, totalControllerActivityTimeMs));
3399        sb.append(")");
3400        pw.println(sb.toString());
3401
3402        sb.setLength(0);
3403        sb.append(prefix);
3404        sb.append("     ");
3405        sb.append(controllerName);
3406        sb.append(" Rx time:     ");
3407        formatTimeMs(sb, rxTimeMs);
3408        sb.append("(");
3409        sb.append(formatRatioLocked(rxTimeMs, totalControllerActivityTimeMs));
3410        sb.append(")");
3411        pw.println(sb.toString());
3412
3413        sb.setLength(0);
3414        sb.append(prefix);
3415        sb.append("     ");
3416        sb.append(controllerName);
3417        sb.append(" Tx time:     ");
3418
3419        String [] powerLevel;
3420        switch(controllerName) {
3421            case CELLULAR_CONTROLLER_NAME:
3422                powerLevel = new String[] {
3423                    "   less than 0dBm: ",
3424                    "   0dBm to 8dBm: ",
3425                    "   8dBm to 15dBm: ",
3426                    "   15dBm to 20dBm: ",
3427                    "   above 20dBm: "};
3428                break;
3429            default:
3430                powerLevel = new String[] {"[0]", "[1]", "[2]", "[3]", "[4]"};
3431                break;
3432        }
3433        final int numTxLvls = Math.min(counter.getTxTimeCounters().length, powerLevel.length);
3434        if (numTxLvls > 1) {
3435            pw.println(sb.toString());
3436            for (int lvl = 0; lvl < numTxLvls; lvl++) {
3437                final long txLvlTimeMs = counter.getTxTimeCounters()[lvl].getCountLocked(which);
3438                sb.setLength(0);
3439                sb.append(prefix);
3440                sb.append("    ");
3441                sb.append(powerLevel[lvl]);
3442                sb.append(" ");
3443                formatTimeMs(sb, txLvlTimeMs);
3444                sb.append("(");
3445                sb.append(formatRatioLocked(txLvlTimeMs, totalControllerActivityTimeMs));
3446                sb.append(")");
3447                pw.println(sb.toString());
3448            }
3449        } else {
3450            final long txLvlTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which);
3451            formatTimeMs(sb, txLvlTimeMs);
3452            sb.append("(");
3453            sb.append(formatRatioLocked(txLvlTimeMs, totalControllerActivityTimeMs));
3454            sb.append(")");
3455            pw.println(sb.toString());
3456        }
3457
3458        if (powerDrainMaMs > 0) {
3459            sb.setLength(0);
3460            sb.append(prefix);
3461            sb.append("     ");
3462            sb.append(controllerName);
3463            sb.append(" Battery drain: ").append(
3464                BatteryStatsHelper.makemAh(powerDrainMaMs / (double) (1000*60*60)));
3465            sb.append("mAh");
3466            pw.println(sb.toString());
3467        }
3468    }
3469
3470    /**
3471     * Temporary for settings.
3472     */
3473    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
3474        dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
3475    }
3476
3477    /**
3478     * Checkin server version of dump to produce more compact, computer-readable log.
3479     *
3480     * NOTE: all times are expressed in microseconds, unless specified otherwise.
3481     */
3482    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
3483            boolean wifiOnly) {
3484        final long rawUptime = SystemClock.uptimeMillis() * 1000;
3485        final long rawRealtimeMs = SystemClock.elapsedRealtime();
3486        final long rawRealtime = rawRealtimeMs * 1000;
3487        final long batteryUptime = getBatteryUptime(rawUptime);
3488        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
3489        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
3490        final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
3491        final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
3492                which);
3493        final long totalRealtime = computeRealtime(rawRealtime, which);
3494        final long totalUptime = computeUptime(rawUptime, which);
3495        final long screenOnTime = getScreenOnTime(rawRealtime, which);
3496        final long screenDozeTime = getScreenDozeTime(rawRealtime, which);
3497        final long interactiveTime = getInteractiveTime(rawRealtime, which);
3498        final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
3499        final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT,
3500                rawRealtime, which);
3501        final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP,
3502                rawRealtime, which);
3503        final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT,
3504                rawRealtime, which);
3505        final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP,
3506                rawRealtime, which);
3507        final int connChanges = getNumConnectivityChange(which);
3508        final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
3509        final long dischargeCount = getUahDischarge(which);
3510        final long dischargeScreenOffCount = getUahDischargeScreenOff(which);
3511        final long dischargeScreenDozeCount = getUahDischargeScreenDoze(which);
3512        final long dischargeLightDozeCount = getUahDischargeLightDoze(which);
3513        final long dischargeDeepDozeCount = getUahDischargeDeepDoze(which);
3514
3515        final StringBuilder sb = new StringBuilder(128);
3516
3517        final SparseArray<? extends Uid> uidStats = getUidStats();
3518        final int NU = uidStats.size();
3519
3520        final String category = STAT_NAMES[which];
3521
3522        // Dump "battery" stat
3523        dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
3524                which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
3525                whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
3526                totalRealtime / 1000, totalUptime / 1000,
3527                getStartClockTime(),
3528                whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000,
3529                getEstimatedBatteryCapacity(),
3530                getMinLearnedBatteryCapacity(), getMaxLearnedBatteryCapacity(),
3531                screenDozeTime / 1000);
3532
3533
3534        // Calculate wakelock times across all uids.
3535        long fullWakeLockTimeTotal = 0;
3536        long partialWakeLockTimeTotal = 0;
3537
3538        for (int iu = 0; iu < NU; iu++) {
3539            final Uid u = uidStats.valueAt(iu);
3540
3541            final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
3542                    = u.getWakelockStats();
3543            for (int iw=wakelocks.size()-1; iw>=0; iw--) {
3544                final Uid.Wakelock wl = wakelocks.valueAt(iw);
3545
3546                final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
3547                if (fullWakeTimer != null) {
3548                    fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
3549                            which);
3550                }
3551
3552                final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
3553                if (partialWakeTimer != null) {
3554                    partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
3555                        rawRealtime, which);
3556                }
3557            }
3558        }
3559
3560        // Dump network stats
3561        final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
3562        final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
3563        final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
3564        final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
3565        final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
3566        final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
3567        final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
3568        final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
3569        final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
3570        final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
3571        dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
3572                mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
3573                mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets,
3574                btRxTotalBytes, btTxTotalBytes);
3575
3576        // Dump Modem controller stats
3577        dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_MODEM_CONTROLLER_DATA,
3578                getModemControllerActivity(), which);
3579
3580        // Dump Wifi controller stats
3581        final long wifiOnTime = getWifiOnTime(rawRealtime, which);
3582        final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
3583        dumpLine(pw, 0 /* uid */, category, GLOBAL_WIFI_DATA, wifiOnTime / 1000,
3584                wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */ 0, 0, 0);
3585
3586        dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_WIFI_CONTROLLER_DATA,
3587                getWifiControllerActivity(), which);
3588
3589        // Dump Bluetooth controller stats
3590        dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_BLUETOOTH_CONTROLLER_DATA,
3591                getBluetoothControllerActivity(), which);
3592
3593        // Dump misc stats
3594        dumpLine(pw, 0 /* uid */, category, MISC_DATA,
3595                screenOnTime / 1000, phoneOnTime / 1000,
3596                fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000,
3597                getMobileRadioActiveTime(rawRealtime, which) / 1000,
3598                getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000,
3599                powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeFullTime / 1000,
3600                getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which), deviceIdlingTime / 1000,
3601                getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which),
3602                getMobileRadioActiveCount(which),
3603                getMobileRadioActiveUnknownTime(which) / 1000, deviceIdleModeLightTime / 1000,
3604                getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which), deviceLightIdlingTime / 1000,
3605                getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which),
3606                getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT),
3607                getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
3608
3609        // Dump screen brightness stats
3610        Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
3611        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3612            args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
3613        }
3614        dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
3615
3616        // Dump signal strength stats
3617        args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
3618        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
3619            args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
3620        }
3621        dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
3622        dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
3623                getPhoneSignalScanningTime(rawRealtime, which) / 1000);
3624        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
3625            args[i] = getPhoneSignalStrengthCount(i, which);
3626        }
3627        dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
3628
3629        // Dump network type stats
3630        args = new Object[NUM_DATA_CONNECTION_TYPES];
3631        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3632            args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
3633        }
3634        dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
3635        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3636            args[i] = getPhoneDataConnectionCount(i, which);
3637        }
3638        dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
3639
3640        // Dump wifi state stats
3641        args = new Object[NUM_WIFI_STATES];
3642        for (int i=0; i<NUM_WIFI_STATES; i++) {
3643            args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
3644        }
3645        dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args);
3646        for (int i=0; i<NUM_WIFI_STATES; i++) {
3647            args[i] = getWifiStateCount(i, which);
3648        }
3649        dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args);
3650
3651        // Dump wifi suppl state stats
3652        args = new Object[NUM_WIFI_SUPPL_STATES];
3653        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
3654            args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
3655        }
3656        dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_TIME_DATA, args);
3657        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
3658            args[i] = getWifiSupplStateCount(i, which);
3659        }
3660        dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_COUNT_DATA, args);
3661
3662        // Dump wifi signal strength stats
3663        args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
3664        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
3665            args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
3666        }
3667        dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
3668        for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
3669            args[i] = getWifiSignalStrengthCount(i, which);
3670        }
3671        dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
3672
3673        // Dump Multicast total stats
3674        final long multicastWakeLockTimeTotalMicros =
3675                getWifiMulticastWakelockTime(rawRealtime, which);
3676        final int multicastWakeLockCountTotal = getWifiMulticastWakelockCount(which);
3677        dumpLine(pw, 0 /* uid */, category, WIFI_MULTICAST_TOTAL_DATA,
3678                multicastWakeLockTimeTotalMicros / 1000,
3679                multicastWakeLockCountTotal);
3680
3681        if (which == STATS_SINCE_UNPLUGGED) {
3682            dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
3683                    getDischargeCurrentLevel());
3684        }
3685
3686        if (which == STATS_SINCE_UNPLUGGED) {
3687            dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
3688                    getDischargeStartLevel()-getDischargeCurrentLevel(),
3689                    getDischargeStartLevel()-getDischargeCurrentLevel(),
3690                    getDischargeAmountScreenOn(), getDischargeAmountScreenOff(),
3691                    dischargeCount / 1000, dischargeScreenOffCount / 1000,
3692                    getDischargeAmountScreenDoze(), dischargeScreenDozeCount / 1000,
3693                    dischargeLightDozeCount / 1000, dischargeDeepDozeCount / 1000);
3694        } else {
3695            dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
3696                    getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
3697                    getDischargeAmountScreenOnSinceCharge(),
3698                    getDischargeAmountScreenOffSinceCharge(),
3699                    dischargeCount / 1000, dischargeScreenOffCount / 1000,
3700                    getDischargeAmountScreenDozeSinceCharge(), dischargeScreenDozeCount / 1000,
3701                    dischargeLightDozeCount / 1000, dischargeDeepDozeCount / 1000);
3702        }
3703
3704        if (reqUid < 0) {
3705            final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
3706            if (kernelWakelocks.size() > 0) {
3707                for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
3708                    sb.setLength(0);
3709                    printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
3710                    dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA,
3711                            "\"" + ent.getKey() + "\"", sb.toString());
3712                }
3713            }
3714            final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
3715            if (wakeupReasons.size() > 0) {
3716                for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
3717                    // Not doing the regular wake lock formatting to remain compatible
3718                    // with the old checkin format.
3719                    long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which);
3720                    int count = ent.getValue().getCountLocked(which);
3721                    dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA,
3722                            "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count);
3723                }
3724            }
3725        }
3726
3727        final Map<String, ? extends Timer> rpmStats = getRpmStats();
3728        final Map<String, ? extends Timer> screenOffRpmStats = getScreenOffRpmStats();
3729        if (rpmStats.size() > 0) {
3730            for (Map.Entry<String, ? extends Timer> ent : rpmStats.entrySet()) {
3731                sb.setLength(0);
3732                Timer totalTimer = ent.getValue();
3733                long timeMs = (totalTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
3734                int count = totalTimer.getCountLocked(which);
3735                Timer screenOffTimer = screenOffRpmStats.get(ent.getKey());
3736                long screenOffTimeMs = screenOffTimer != null
3737                        ? (screenOffTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
3738                int screenOffCount = screenOffTimer != null
3739                        ? screenOffTimer.getCountLocked(which) : 0;
3740                if (SCREEN_OFF_RPM_STATS_ENABLED) {
3741                    dumpLine(pw, 0 /* uid */, category, RESOURCE_POWER_MANAGER_DATA,
3742                            "\"" + ent.getKey() + "\"", timeMs, count, screenOffTimeMs,
3743                            screenOffCount);
3744                } else {
3745                    dumpLine(pw, 0 /* uid */, category, RESOURCE_POWER_MANAGER_DATA,
3746                            "\"" + ent.getKey() + "\"", timeMs, count);
3747                }
3748            }
3749        }
3750
3751        final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
3752        helper.create(this);
3753        helper.refreshStats(which, UserHandle.USER_ALL);
3754        final List<BatterySipper> sippers = helper.getUsageList();
3755        if (sippers != null && sippers.size() > 0) {
3756            dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
3757                    BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
3758                    BatteryStatsHelper.makemAh(helper.getComputedPower()),
3759                    BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
3760                    BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
3761            int uid = 0;
3762            for (int i=0; i<sippers.size(); i++) {
3763                final BatterySipper bs = sippers.get(i);
3764                String label;
3765                switch (bs.drainType) {
3766                    case IDLE:
3767                        label="idle";
3768                        break;
3769                    case CELL:
3770                        label="cell";
3771                        break;
3772                    case PHONE:
3773                        label="phone";
3774                        break;
3775                    case WIFI:
3776                        label="wifi";
3777                        break;
3778                    case BLUETOOTH:
3779                        label="blue";
3780                        break;
3781                    case SCREEN:
3782                        label="scrn";
3783                        break;
3784                    case FLASHLIGHT:
3785                        label="flashlight";
3786                        break;
3787                    case APP:
3788                        uid = bs.uidObj.getUid();
3789                        label = "uid";
3790                        break;
3791                    case USER:
3792                        uid = UserHandle.getUid(bs.userId, 0);
3793                        label = "user";
3794                        break;
3795                    case UNACCOUNTED:
3796                        label = "unacc";
3797                        break;
3798                    case OVERCOUNTED:
3799                        label = "over";
3800                        break;
3801                    case CAMERA:
3802                        label = "camera";
3803                        break;
3804                    case MEMORY:
3805                        label = "memory";
3806                        break;
3807                    default:
3808                        label = "???";
3809                }
3810                dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
3811                        BatteryStatsHelper.makemAh(bs.totalPowerMah),
3812                        bs.shouldHide ? 1 : 0,
3813                        BatteryStatsHelper.makemAh(bs.screenPowerMah),
3814                        BatteryStatsHelper.makemAh(bs.proportionalSmearMah));
3815            }
3816        }
3817
3818        final long[] cpuFreqs = getCpuFreqs();
3819        if (cpuFreqs != null) {
3820            sb.setLength(0);
3821            for (int i = 0; i < cpuFreqs.length; ++i) {
3822                sb.append((i == 0 ? "" : ",") + cpuFreqs[i]);
3823            }
3824            dumpLine(pw, 0 /* uid */, category, GLOBAL_CPU_FREQ_DATA, sb.toString());
3825        }
3826
3827        // Dump stats per UID.
3828        for (int iu = 0; iu < NU; iu++) {
3829            final int uid = uidStats.keyAt(iu);
3830            if (reqUid >= 0 && uid != reqUid) {
3831                continue;
3832            }
3833            final Uid u = uidStats.valueAt(iu);
3834
3835            // Dump Network stats per uid, if any
3836            final long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
3837            final long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
3838            final long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
3839            final long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
3840            final long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
3841            final long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
3842            final long mobileActiveTime = u.getMobileRadioActiveTime(which);
3843            final int mobileActiveCount = u.getMobileRadioActiveCount(which);
3844            final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
3845            final long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
3846            final long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
3847            final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
3848            final long btBytesRx = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
3849            final long btBytesTx = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
3850            // Background data transfers
3851            final long mobileBytesBgRx = u.getNetworkActivityBytes(NETWORK_MOBILE_BG_RX_DATA,
3852                    which);
3853            final long mobileBytesBgTx = u.getNetworkActivityBytes(NETWORK_MOBILE_BG_TX_DATA,
3854                    which);
3855            final long wifiBytesBgRx = u.getNetworkActivityBytes(NETWORK_WIFI_BG_RX_DATA, which);
3856            final long wifiBytesBgTx = u.getNetworkActivityBytes(NETWORK_WIFI_BG_TX_DATA, which);
3857            final long mobilePacketsBgRx = u.getNetworkActivityPackets(NETWORK_MOBILE_BG_RX_DATA,
3858                    which);
3859            final long mobilePacketsBgTx = u.getNetworkActivityPackets(NETWORK_MOBILE_BG_TX_DATA,
3860                    which);
3861            final long wifiPacketsBgRx = u.getNetworkActivityPackets(NETWORK_WIFI_BG_RX_DATA,
3862                    which);
3863            final long wifiPacketsBgTx = u.getNetworkActivityPackets(NETWORK_WIFI_BG_TX_DATA,
3864                    which);
3865
3866            if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
3867                    || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
3868                    || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0
3869                    || btBytesRx > 0 || btBytesTx > 0 || mobileWakeup > 0 || wifiWakeup > 0
3870                    || mobileBytesBgRx > 0 || mobileBytesBgTx > 0 || wifiBytesBgRx > 0
3871                    || wifiBytesBgTx > 0
3872                    || mobilePacketsBgRx > 0 || mobilePacketsBgTx > 0 || wifiPacketsBgRx > 0
3873                    || wifiPacketsBgTx > 0) {
3874                dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
3875                        wifiBytesRx, wifiBytesTx,
3876                        mobilePacketsRx, mobilePacketsTx,
3877                        wifiPacketsRx, wifiPacketsTx,
3878                        mobileActiveTime, mobileActiveCount,
3879                        btBytesRx, btBytesTx, mobileWakeup, wifiWakeup,
3880                        mobileBytesBgRx, mobileBytesBgTx, wifiBytesBgRx, wifiBytesBgTx,
3881                        mobilePacketsBgRx, mobilePacketsBgTx, wifiPacketsBgRx, wifiPacketsBgTx
3882                        );
3883            }
3884
3885            // Dump modem controller data, per UID.
3886            dumpControllerActivityLine(pw, uid, category, MODEM_CONTROLLER_DATA,
3887                    u.getModemControllerActivity(), which);
3888
3889            // Dump Wifi controller data, per UID.
3890            final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
3891            final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
3892            final int wifiScanCount = u.getWifiScanCount(which);
3893            final int wifiScanCountBg = u.getWifiScanBackgroundCount(which);
3894            // Note that 'ActualTime' are unpooled and always since reset (regardless of 'which')
3895            final long wifiScanActualTimeMs = (u.getWifiScanActualTime(rawRealtime) + 500) / 1000;
3896            final long wifiScanActualTimeMsBg = (u.getWifiScanBackgroundTime(rawRealtime) + 500)
3897                    / 1000;
3898            final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
3899            if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
3900                    || wifiScanCountBg != 0 || wifiScanActualTimeMs != 0
3901                    || wifiScanActualTimeMsBg != 0 || uidWifiRunningTime != 0) {
3902                dumpLine(pw, uid, category, WIFI_DATA, fullWifiLockOnTime, wifiScanTime,
3903                        uidWifiRunningTime, wifiScanCount,
3904                        /* legacy fields follow, keep at 0 */ 0, 0, 0,
3905                        wifiScanCountBg, wifiScanActualTimeMs, wifiScanActualTimeMsBg);
3906            }
3907
3908            dumpControllerActivityLine(pw, uid, category, WIFI_CONTROLLER_DATA,
3909                    u.getWifiControllerActivity(), which);
3910
3911            final Timer bleTimer = u.getBluetoothScanTimer();
3912            if (bleTimer != null) {
3913                // Convert from microseconds to milliseconds with rounding
3914                final long totalTime = (bleTimer.getTotalTimeLocked(rawRealtime, which) + 500)
3915                        / 1000;
3916                if (totalTime != 0) {
3917                    final int count = bleTimer.getCountLocked(which);
3918                    final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
3919                    final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
3920                    // 'actualTime' are unpooled and always since reset (regardless of 'which')
3921                    final long actualTime = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
3922                    final long actualTimeBg = bleTimerBg != null ?
3923                            bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
3924                    // Result counters
3925                    final int resultCount = u.getBluetoothScanResultCounter() != null ?
3926                            u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
3927                    final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
3928                            u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
3929                    // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
3930                    final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
3931                    final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
3932                            unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
3933                    final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
3934                            unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
3935                    // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
3936                    final Timer unoptimizedScanTimerBg =
3937                            u.getBluetoothUnoptimizedScanBackgroundTimer();
3938                    final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
3939                            unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
3940                    final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
3941                            unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
3942
3943                    dumpLine(pw, uid, category, BLUETOOTH_MISC_DATA, totalTime, count,
3944                            countBg, actualTime, actualTimeBg, resultCount, resultCountBg,
3945                            unoptimizedScanTotalTime, unoptimizedScanTotalTimeBg,
3946                            unoptimizedScanMaxTime, unoptimizedScanMaxTimeBg);
3947                }
3948            }
3949
3950            dumpControllerActivityLine(pw, uid, category, BLUETOOTH_CONTROLLER_DATA,
3951                    u.getBluetoothControllerActivity(), which);
3952
3953            if (u.hasUserActivity()) {
3954                args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
3955                boolean hasData = false;
3956                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3957                    int val = u.getUserActivityCount(i, which);
3958                    args[i] = val;
3959                    if (val != 0) hasData = true;
3960                }
3961                if (hasData) {
3962                    dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args);
3963                }
3964            }
3965
3966            if (u.getAggregatedPartialWakelockTimer() != null) {
3967                final Timer timer = u.getAggregatedPartialWakelockTimer();
3968                // Times are since reset (regardless of 'which')
3969                final long totTimeMs = timer.getTotalDurationMsLocked(rawRealtimeMs);
3970                final Timer bgTimer = timer.getSubTimer();
3971                final long bgTimeMs = bgTimer != null ?
3972                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
3973                dumpLine(pw, uid, category, AGGREGATED_WAKELOCK_DATA, totTimeMs, bgTimeMs);
3974            }
3975
3976            final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
3977            for (int iw=wakelocks.size()-1; iw>=0; iw--) {
3978                final Uid.Wakelock wl = wakelocks.valueAt(iw);
3979                String linePrefix = "";
3980                sb.setLength(0);
3981                linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
3982                        rawRealtime, "f", which, linePrefix);
3983                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
3984                linePrefix = printWakeLockCheckin(sb, pTimer,
3985                        rawRealtime, "p", which, linePrefix);
3986                linePrefix = printWakeLockCheckin(sb, pTimer != null ? pTimer.getSubTimer() : null,
3987                        rawRealtime, "bp", which, linePrefix);
3988                linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
3989                        rawRealtime, "w", which, linePrefix);
3990
3991                // Only log if we had at least one wakelock...
3992                if (sb.length() > 0) {
3993                    String name = wakelocks.keyAt(iw);
3994                    if (name.indexOf(',') >= 0) {
3995                        name = name.replace(',', '_');
3996                    }
3997                    if (name.indexOf('\n') >= 0) {
3998                        name = name.replace('\n', '_');
3999                    }
4000                    if (name.indexOf('\r') >= 0) {
4001                        name = name.replace('\r', '_');
4002                    }
4003                    dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
4004                }
4005            }
4006
4007            // WiFi Multicast Wakelock Statistics
4008            final Timer mcTimer = u.getMulticastWakelockStats();
4009            if (mcTimer != null) {
4010                final long totalMcWakelockTimeMs =
4011                        mcTimer.getTotalTimeLocked(rawRealtime, which) / 1000 ;
4012                final int countMcWakelock = mcTimer.getCountLocked(which);
4013                if(totalMcWakelockTimeMs > 0) {
4014                    dumpLine(pw, uid, category, WIFI_MULTICAST_DATA,
4015                            totalMcWakelockTimeMs, countMcWakelock);
4016                }
4017            }
4018
4019            final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
4020            for (int isy=syncs.size()-1; isy>=0; isy--) {
4021                final Timer timer = syncs.valueAt(isy);
4022                // Convert from microseconds to milliseconds with rounding
4023                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
4024                final int count = timer.getCountLocked(which);
4025                final Timer bgTimer = timer.getSubTimer();
4026                final long bgTime = bgTimer != null ?
4027                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
4028                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
4029                if (totalTime != 0) {
4030                    dumpLine(pw, uid, category, SYNC_DATA, "\"" + syncs.keyAt(isy) + "\"",
4031                            totalTime, count, bgTime, bgCount);
4032                }
4033            }
4034
4035            final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
4036            for (int ij=jobs.size()-1; ij>=0; ij--) {
4037                final Timer timer = jobs.valueAt(ij);
4038                // Convert from microseconds to milliseconds with rounding
4039                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
4040                final int count = timer.getCountLocked(which);
4041                final Timer bgTimer = timer.getSubTimer();
4042                final long bgTime = bgTimer != null ?
4043                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
4044                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
4045                if (totalTime != 0) {
4046                    dumpLine(pw, uid, category, JOB_DATA, "\"" + jobs.keyAt(ij) + "\"",
4047                            totalTime, count, bgTime, bgCount);
4048                }
4049            }
4050
4051            final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
4052            for (int ic=completions.size()-1; ic>=0; ic--) {
4053                SparseIntArray types = completions.valueAt(ic);
4054                if (types != null) {
4055                    dumpLine(pw, uid, category, JOB_COMPLETION_DATA,
4056                            "\"" + completions.keyAt(ic) + "\"",
4057                            types.get(JobParameters.REASON_CANCELED, 0),
4058                            types.get(JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED, 0),
4059                            types.get(JobParameters.REASON_PREEMPT, 0),
4060                            types.get(JobParameters.REASON_TIMEOUT, 0),
4061                            types.get(JobParameters.REASON_DEVICE_IDLE, 0));
4062                }
4063            }
4064
4065            dumpTimer(pw, uid, category, FLASHLIGHT_DATA, u.getFlashlightTurnedOnTimer(),
4066                    rawRealtime, which);
4067            dumpTimer(pw, uid, category, CAMERA_DATA, u.getCameraTurnedOnTimer(),
4068                    rawRealtime, which);
4069            dumpTimer(pw, uid, category, VIDEO_DATA, u.getVideoTurnedOnTimer(),
4070                    rawRealtime, which);
4071            dumpTimer(pw, uid, category, AUDIO_DATA, u.getAudioTurnedOnTimer(),
4072                    rawRealtime, which);
4073
4074            final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
4075            final int NSE = sensors.size();
4076            for (int ise=0; ise<NSE; ise++) {
4077                final Uid.Sensor se = sensors.valueAt(ise);
4078                final int sensorNumber = sensors.keyAt(ise);
4079                final Timer timer = se.getSensorTime();
4080                if (timer != null) {
4081                    // Convert from microseconds to milliseconds with rounding
4082                    final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
4083                            / 1000;
4084                    if (totalTime != 0) {
4085                        final int count = timer.getCountLocked(which);
4086                        final Timer bgTimer = se.getSensorBackgroundTime();
4087                        final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
4088                        // 'actualTime' are unpooled and always since reset (regardless of 'which')
4089                        final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
4090                        final long bgActualTime = bgTimer != null ?
4091                                bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4092                        dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime,
4093                                count, bgCount, actualTime, bgActualTime);
4094                    }
4095                }
4096            }
4097
4098            dumpTimer(pw, uid, category, VIBRATOR_DATA, u.getVibratorOnTimer(),
4099                    rawRealtime, which);
4100
4101            dumpTimer(pw, uid, category, FOREGROUND_ACTIVITY_DATA, u.getForegroundActivityTimer(),
4102                    rawRealtime, which);
4103
4104            dumpTimer(pw, uid, category, FOREGROUND_SERVICE_DATA, u.getForegroundServiceTimer(),
4105                    rawRealtime, which);
4106
4107            final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
4108            long totalStateTime = 0;
4109            for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
4110                final long time = u.getProcessStateTime(ips, rawRealtime, which);
4111                totalStateTime += time;
4112                stateTimes[ips] = (time + 500) / 1000;
4113            }
4114            if (totalStateTime > 0) {
4115                dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
4116            }
4117
4118            final long userCpuTimeUs = u.getUserCpuTimeUs(which);
4119            final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
4120            if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
4121                dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000,
4122                        0 /* old cpu power, keep for compatibility */);
4123            }
4124
4125            // If the cpuFreqs is null, then don't bother checking for cpu freq times.
4126            if (cpuFreqs != null) {
4127                final long[] cpuFreqTimeMs = u.getCpuFreqTimes(which);
4128                // If total cpuFreqTimes is null, then we don't need to check for
4129                // screenOffCpuFreqTimes.
4130                if (cpuFreqTimeMs != null && cpuFreqTimeMs.length == cpuFreqs.length) {
4131                    sb.setLength(0);
4132                    for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
4133                        sb.append((i == 0 ? "" : ",") + cpuFreqTimeMs[i]);
4134                    }
4135                    final long[] screenOffCpuFreqTimeMs = u.getScreenOffCpuFreqTimes(which);
4136                    if (screenOffCpuFreqTimeMs != null) {
4137                        for (int i = 0; i < screenOffCpuFreqTimeMs.length; ++i) {
4138                            sb.append("," + screenOffCpuFreqTimeMs[i]);
4139                        }
4140                    } else {
4141                        for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
4142                            sb.append(",0");
4143                        }
4144                    }
4145                    dumpLine(pw, uid, category, CPU_TIMES_AT_FREQ_DATA, UID_TIMES_TYPE_ALL,
4146                            cpuFreqTimeMs.length, sb.toString());
4147                }
4148
4149                for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
4150                    final long[] timesMs = u.getCpuFreqTimes(which, procState);
4151                    if (timesMs != null && timesMs.length == cpuFreqs.length) {
4152                        sb.setLength(0);
4153                        for (int i = 0; i < timesMs.length; ++i) {
4154                            sb.append((i == 0 ? "" : ",") + timesMs[i]);
4155                        }
4156                        final long[] screenOffTimesMs = u.getScreenOffCpuFreqTimes(
4157                                which, procState);
4158                        if (screenOffTimesMs != null) {
4159                            for (int i = 0; i < screenOffTimesMs.length; ++i) {
4160                                sb.append("," + screenOffTimesMs[i]);
4161                            }
4162                        } else {
4163                            for (int i = 0; i < timesMs.length; ++i) {
4164                                sb.append(",0");
4165                            }
4166                        }
4167                        dumpLine(pw, uid, category, CPU_TIMES_AT_FREQ_DATA,
4168                                Uid.UID_PROCESS_TYPES[procState], timesMs.length, sb.toString());
4169                    }
4170                }
4171            }
4172
4173            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
4174                    = u.getProcessStats();
4175            for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
4176                final Uid.Proc ps = processStats.valueAt(ipr);
4177
4178                final long userMillis = ps.getUserTime(which);
4179                final long systemMillis = ps.getSystemTime(which);
4180                final long foregroundMillis = ps.getForegroundTime(which);
4181                final int starts = ps.getStarts(which);
4182                final int numCrashes = ps.getNumCrashes(which);
4183                final int numAnrs = ps.getNumAnrs(which);
4184
4185                if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
4186                        || starts != 0 || numAnrs != 0 || numCrashes != 0) {
4187                    dumpLine(pw, uid, category, PROCESS_DATA, "\"" + processStats.keyAt(ipr) + "\"",
4188                            userMillis, systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
4189                }
4190            }
4191
4192            final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
4193                    = u.getPackageStats();
4194            for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
4195                final Uid.Pkg ps = packageStats.valueAt(ipkg);
4196                int wakeups = 0;
4197                final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
4198                for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
4199                    int count = alarms.valueAt(iwa).getCountLocked(which);
4200                    wakeups += count;
4201                    String name = alarms.keyAt(iwa).replace(',', '_');
4202                    dumpLine(pw, uid, category, WAKEUP_ALARM_DATA, name, count);
4203                }
4204                final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
4205                for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
4206                    final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
4207                    final long startTime = ss.getStartTime(batteryUptime, which);
4208                    final int starts = ss.getStarts(which);
4209                    final int launches = ss.getLaunches(which);
4210                    if (startTime != 0 || starts != 0 || launches != 0) {
4211                        dumpLine(pw, uid, category, APK_DATA,
4212                                wakeups, // wakeup alarms
4213                                packageStats.keyAt(ipkg), // Apk
4214                                serviceStats.keyAt(isvc), // service
4215                                startTime / 1000, // time spent started, in ms
4216                                starts,
4217                                launches);
4218                    }
4219                }
4220            }
4221        }
4222    }
4223
4224    static final class TimerEntry {
4225        final String mName;
4226        final int mId;
4227        final BatteryStats.Timer mTimer;
4228        final long mTime;
4229        TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
4230            mName = name;
4231            mId = id;
4232            mTimer = timer;
4233            mTime = time;
4234        }
4235    }
4236
4237    private void printmAh(PrintWriter printer, double power) {
4238        printer.print(BatteryStatsHelper.makemAh(power));
4239    }
4240
4241    private void printmAh(StringBuilder sb, double power) {
4242        sb.append(BatteryStatsHelper.makemAh(power));
4243    }
4244
4245    /**
4246     * Temporary for settings.
4247     */
4248    public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which,
4249            int reqUid) {
4250        dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
4251    }
4252
4253    @SuppressWarnings("unused")
4254    public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
4255            int reqUid, boolean wifiOnly) {
4256        final long rawUptime = SystemClock.uptimeMillis() * 1000;
4257        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
4258        final long rawRealtimeMs = (rawRealtime + 500) / 1000;
4259        final long batteryUptime = getBatteryUptime(rawUptime);
4260
4261        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
4262        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
4263        final long totalRealtime = computeRealtime(rawRealtime, which);
4264        final long totalUptime = computeUptime(rawUptime, which);
4265        final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
4266        final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
4267                which);
4268        final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
4269        final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
4270        final long screenDozeTime = getScreenDozeTime(rawRealtime, which);
4271
4272        final StringBuilder sb = new StringBuilder(128);
4273
4274        final SparseArray<? extends Uid> uidStats = getUidStats();
4275        final int NU = uidStats.size();
4276
4277        final int estimatedBatteryCapacity = getEstimatedBatteryCapacity();
4278        if (estimatedBatteryCapacity > 0) {
4279            sb.setLength(0);
4280            sb.append(prefix);
4281                sb.append("  Estimated battery capacity: ");
4282                sb.append(BatteryStatsHelper.makemAh(estimatedBatteryCapacity));
4283                sb.append(" mAh");
4284            pw.println(sb.toString());
4285        }
4286
4287        final int minLearnedBatteryCapacity = getMinLearnedBatteryCapacity();
4288        if (minLearnedBatteryCapacity > 0) {
4289            sb.setLength(0);
4290            sb.append(prefix);
4291                sb.append("  Min learned battery capacity: ");
4292                sb.append(BatteryStatsHelper.makemAh(minLearnedBatteryCapacity / 1000));
4293                sb.append(" mAh");
4294            pw.println(sb.toString());
4295        }
4296        final int maxLearnedBatteryCapacity = getMaxLearnedBatteryCapacity();
4297        if (maxLearnedBatteryCapacity > 0) {
4298            sb.setLength(0);
4299            sb.append(prefix);
4300                sb.append("  Max learned battery capacity: ");
4301                sb.append(BatteryStatsHelper.makemAh(maxLearnedBatteryCapacity / 1000));
4302                sb.append(" mAh");
4303            pw.println(sb.toString());
4304        }
4305
4306        sb.setLength(0);
4307        sb.append(prefix);
4308        sb.append("  Time on battery: ");
4309        formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
4310        sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
4311        sb.append(") realtime, ");
4312        formatTimeMs(sb, whichBatteryUptime / 1000);
4313        sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, whichBatteryRealtime));
4314        sb.append(") uptime");
4315        pw.println(sb.toString());
4316
4317        sb.setLength(0);
4318        sb.append(prefix);
4319        sb.append("  Time on battery screen off: ");
4320        formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("(");
4321        sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, whichBatteryRealtime));
4322        sb.append(") realtime, ");
4323        formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
4324        sb.append("(");
4325        sb.append(formatRatioLocked(whichBatteryScreenOffUptime, whichBatteryRealtime));
4326        sb.append(") uptime");
4327        pw.println(sb.toString());
4328
4329        sb.setLength(0);
4330        sb.append(prefix);
4331        sb.append("  Time on battery screen doze: ");
4332        formatTimeMs(sb, screenDozeTime / 1000); sb.append("(");
4333        sb.append(formatRatioLocked(screenDozeTime, whichBatteryRealtime));
4334        sb.append(")");
4335        pw.println(sb.toString());
4336
4337        sb.setLength(0);
4338        sb.append(prefix);
4339                sb.append("  Total run time: ");
4340                formatTimeMs(sb, totalRealtime / 1000);
4341                sb.append("realtime, ");
4342                formatTimeMs(sb, totalUptime / 1000);
4343                sb.append("uptime");
4344        pw.println(sb.toString());
4345        if (batteryTimeRemaining >= 0) {
4346            sb.setLength(0);
4347            sb.append(prefix);
4348                    sb.append("  Battery time remaining: ");
4349                    formatTimeMs(sb, batteryTimeRemaining / 1000);
4350            pw.println(sb.toString());
4351        }
4352        if (chargeTimeRemaining >= 0) {
4353            sb.setLength(0);
4354            sb.append(prefix);
4355                    sb.append("  Charge time remaining: ");
4356                    formatTimeMs(sb, chargeTimeRemaining / 1000);
4357            pw.println(sb.toString());
4358        }
4359
4360        final long dischargeCount = getUahDischarge(which);
4361        if (dischargeCount >= 0) {
4362            sb.setLength(0);
4363            sb.append(prefix);
4364                sb.append("  Discharge: ");
4365                sb.append(BatteryStatsHelper.makemAh(dischargeCount / 1000.0));
4366                sb.append(" mAh");
4367            pw.println(sb.toString());
4368        }
4369
4370        final long dischargeScreenOffCount = getUahDischargeScreenOff(which);
4371        if (dischargeScreenOffCount >= 0) {
4372            sb.setLength(0);
4373            sb.append(prefix);
4374                sb.append("  Screen off discharge: ");
4375                sb.append(BatteryStatsHelper.makemAh(dischargeScreenOffCount / 1000.0));
4376                sb.append(" mAh");
4377            pw.println(sb.toString());
4378        }
4379
4380        final long dischargeScreenDozeCount = getUahDischargeScreenDoze(which);
4381        if (dischargeScreenDozeCount >= 0) {
4382            sb.setLength(0);
4383            sb.append(prefix);
4384            sb.append("  Screen doze discharge: ");
4385            sb.append(BatteryStatsHelper.makemAh(dischargeScreenDozeCount / 1000.0));
4386            sb.append(" mAh");
4387            pw.println(sb.toString());
4388        }
4389
4390        final long dischargeScreenOnCount =
4391                dischargeCount - dischargeScreenOffCount - dischargeScreenDozeCount;
4392        if (dischargeScreenOnCount >= 0) {
4393            sb.setLength(0);
4394            sb.append(prefix);
4395                sb.append("  Screen on discharge: ");
4396                sb.append(BatteryStatsHelper.makemAh(dischargeScreenOnCount / 1000.0));
4397                sb.append(" mAh");
4398            pw.println(sb.toString());
4399        }
4400
4401        final long dischargeLightDozeCount = getUahDischargeLightDoze(which);
4402        if (dischargeLightDozeCount >= 0) {
4403            sb.setLength(0);
4404            sb.append(prefix);
4405            sb.append("  Device light doze discharge: ");
4406            sb.append(BatteryStatsHelper.makemAh(dischargeLightDozeCount / 1000.0));
4407            sb.append(" mAh");
4408            pw.println(sb.toString());
4409        }
4410
4411        final long dischargeDeepDozeCount = getUahDischargeDeepDoze(which);
4412        if (dischargeDeepDozeCount >= 0) {
4413            sb.setLength(0);
4414            sb.append(prefix);
4415            sb.append("  Device deep doze discharge: ");
4416            sb.append(BatteryStatsHelper.makemAh(dischargeDeepDozeCount / 1000.0));
4417            sb.append(" mAh");
4418            pw.println(sb.toString());
4419        }
4420
4421        pw.print("  Start clock time: ");
4422        pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
4423
4424        final long screenOnTime = getScreenOnTime(rawRealtime, which);
4425        final long interactiveTime = getInteractiveTime(rawRealtime, which);
4426        final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
4427        final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT,
4428                rawRealtime, which);
4429        final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP,
4430                rawRealtime, which);
4431        final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT,
4432                rawRealtime, which);
4433        final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP,
4434                rawRealtime, which);
4435        final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
4436        final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
4437        final long wifiOnTime = getWifiOnTime(rawRealtime, which);
4438        sb.setLength(0);
4439        sb.append(prefix);
4440                sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
4441                sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
4442                sb.append(") "); sb.append(getScreenOnCount(which));
4443                sb.append("x, Interactive: "); formatTimeMs(sb, interactiveTime / 1000);
4444                sb.append("("); sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime));
4445                sb.append(")");
4446        pw.println(sb.toString());
4447        sb.setLength(0);
4448        sb.append(prefix);
4449        sb.append("  Screen brightnesses:");
4450        boolean didOne = false;
4451        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4452            final long time = getScreenBrightnessTime(i, rawRealtime, which);
4453            if (time == 0) {
4454                continue;
4455            }
4456            sb.append("\n    ");
4457            sb.append(prefix);
4458            didOne = true;
4459            sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
4460            sb.append(" ");
4461            formatTimeMs(sb, time/1000);
4462            sb.append("(");
4463            sb.append(formatRatioLocked(time, screenOnTime));
4464            sb.append(")");
4465        }
4466        if (!didOne) sb.append(" (no activity)");
4467        pw.println(sb.toString());
4468        if (powerSaveModeEnabledTime != 0) {
4469            sb.setLength(0);
4470            sb.append(prefix);
4471                    sb.append("  Power save mode enabled: ");
4472                    formatTimeMs(sb, powerSaveModeEnabledTime / 1000);
4473                    sb.append("(");
4474                    sb.append(formatRatioLocked(powerSaveModeEnabledTime, whichBatteryRealtime));
4475                    sb.append(")");
4476            pw.println(sb.toString());
4477        }
4478        if (deviceLightIdlingTime != 0) {
4479            sb.setLength(0);
4480            sb.append(prefix);
4481                    sb.append("  Device light idling: ");
4482                    formatTimeMs(sb, deviceLightIdlingTime / 1000);
4483                    sb.append("(");
4484                    sb.append(formatRatioLocked(deviceLightIdlingTime, whichBatteryRealtime));
4485                    sb.append(") "); sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which));
4486                    sb.append("x");
4487            pw.println(sb.toString());
4488        }
4489        if (deviceIdleModeLightTime != 0) {
4490            sb.setLength(0);
4491            sb.append(prefix);
4492                    sb.append("  Idle mode light time: ");
4493                    formatTimeMs(sb, deviceIdleModeLightTime / 1000);
4494                    sb.append("(");
4495                    sb.append(formatRatioLocked(deviceIdleModeLightTime, whichBatteryRealtime));
4496                    sb.append(") ");
4497                    sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which));
4498                    sb.append("x");
4499                    sb.append(" -- longest ");
4500                    formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
4501            pw.println(sb.toString());
4502        }
4503        if (deviceIdlingTime != 0) {
4504            sb.setLength(0);
4505            sb.append(prefix);
4506                    sb.append("  Device full idling: ");
4507                    formatTimeMs(sb, deviceIdlingTime / 1000);
4508                    sb.append("(");
4509                    sb.append(formatRatioLocked(deviceIdlingTime, whichBatteryRealtime));
4510                    sb.append(") "); sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which));
4511                    sb.append("x");
4512            pw.println(sb.toString());
4513        }
4514        if (deviceIdleModeFullTime != 0) {
4515            sb.setLength(0);
4516            sb.append(prefix);
4517                    sb.append("  Idle mode full time: ");
4518                    formatTimeMs(sb, deviceIdleModeFullTime / 1000);
4519                    sb.append("(");
4520                    sb.append(formatRatioLocked(deviceIdleModeFullTime, whichBatteryRealtime));
4521                    sb.append(") ");
4522                    sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which));
4523                    sb.append("x");
4524                    sb.append(" -- longest ");
4525                    formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
4526            pw.println(sb.toString());
4527        }
4528        if (phoneOnTime != 0) {
4529            sb.setLength(0);
4530            sb.append(prefix);
4531                    sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
4532                    sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
4533                    sb.append(") "); sb.append(getPhoneOnCount(which)); sb.append("x");
4534        }
4535        final int connChanges = getNumConnectivityChange(which);
4536        if (connChanges != 0) {
4537            pw.print(prefix);
4538            pw.print("  Connectivity changes: "); pw.println(connChanges);
4539        }
4540
4541        // Calculate wakelock times across all uids.
4542        long fullWakeLockTimeTotalMicros = 0;
4543        long partialWakeLockTimeTotalMicros = 0;
4544
4545        final ArrayList<TimerEntry> timers = new ArrayList<>();
4546
4547        for (int iu = 0; iu < NU; iu++) {
4548            final Uid u = uidStats.valueAt(iu);
4549
4550            final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
4551                    = u.getWakelockStats();
4552            for (int iw=wakelocks.size()-1; iw>=0; iw--) {
4553                final Uid.Wakelock wl = wakelocks.valueAt(iw);
4554
4555                final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
4556                if (fullWakeTimer != null) {
4557                    fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
4558                            rawRealtime, which);
4559                }
4560
4561                final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
4562                if (partialWakeTimer != null) {
4563                    final long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
4564                            rawRealtime, which);
4565                    if (totalTimeMicros > 0) {
4566                        if (reqUid < 0) {
4567                            // Only show the ordered list of all wake
4568                            // locks if the caller is not asking for data
4569                            // about a specific uid.
4570                            timers.add(new TimerEntry(wakelocks.keyAt(iw), u.getUid(),
4571                                    partialWakeTimer, totalTimeMicros));
4572                        }
4573                        partialWakeLockTimeTotalMicros += totalTimeMicros;
4574                    }
4575                }
4576            }
4577        }
4578
4579        final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
4580        final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
4581        final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
4582        final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
4583        final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
4584        final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
4585        final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
4586        final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
4587        final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
4588        final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
4589
4590        if (fullWakeLockTimeTotalMicros != 0) {
4591            sb.setLength(0);
4592            sb.append(prefix);
4593                    sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
4594                            (fullWakeLockTimeTotalMicros + 500) / 1000);
4595            pw.println(sb.toString());
4596        }
4597
4598        if (partialWakeLockTimeTotalMicros != 0) {
4599            sb.setLength(0);
4600            sb.append(prefix);
4601                    sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
4602                            (partialWakeLockTimeTotalMicros + 500) / 1000);
4603            pw.println(sb.toString());
4604        }
4605
4606        final long multicastWakeLockTimeTotalMicros =
4607                getWifiMulticastWakelockTime(rawRealtime, which);
4608        final int multicastWakeLockCountTotal = getWifiMulticastWakelockCount(which);
4609        if (multicastWakeLockTimeTotalMicros != 0) {
4610            sb.setLength(0);
4611            sb.append(prefix);
4612            sb.append("  Total WiFi Multicast wakelock Count: ");
4613            sb.append(multicastWakeLockCountTotal);
4614            pw.println(sb.toString());
4615
4616            sb.setLength(0);
4617            sb.append(prefix);
4618            sb.append("  Total WiFi Multicast wakelock time: ");
4619            formatTimeMsNoSpace(sb, (multicastWakeLockTimeTotalMicros + 500) / 1000);
4620            pw.println(sb.toString());
4621        }
4622
4623        pw.println("");
4624        pw.print(prefix);
4625        sb.setLength(0);
4626        sb.append(prefix);
4627        sb.append("  CONNECTIVITY POWER SUMMARY START");
4628        pw.println(sb.toString());
4629
4630        pw.print(prefix);
4631        sb.setLength(0);
4632        sb.append(prefix);
4633        sb.append("  Logging duration for connectivity statistics: ");
4634        formatTimeMs(sb, whichBatteryRealtime / 1000);
4635        pw.println(sb.toString());
4636
4637        sb.setLength(0);
4638        sb.append(prefix);
4639        sb.append("  Cellular Statistics:");
4640        pw.println(sb.toString());
4641
4642        pw.print(prefix);
4643        sb.setLength(0);
4644        sb.append(prefix);
4645        sb.append("     Cellular kernel active time: ");
4646        final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
4647        formatTimeMs(sb, mobileActiveTime / 1000);
4648        sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
4649        sb.append(")");
4650        pw.println(sb.toString());
4651
4652        pw.print("     Cellular data received: "); pw.println(formatBytesLocked(mobileRxTotalBytes));
4653        pw.print("     Cellular data sent: "); pw.println(formatBytesLocked(mobileTxTotalBytes));
4654        pw.print("     Cellular packets received: "); pw.println(mobileRxTotalPackets);
4655        pw.print("     Cellular packets sent: "); pw.println(mobileTxTotalPackets);
4656
4657        sb.setLength(0);
4658        sb.append(prefix);
4659        sb.append("     Cellular Radio Access Technology:");
4660        didOne = false;
4661        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4662            final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
4663            if (time == 0) {
4664                continue;
4665            }
4666            sb.append("\n       ");
4667            sb.append(prefix);
4668            didOne = true;
4669            sb.append(DATA_CONNECTION_NAMES[i]);
4670            sb.append(" ");
4671            formatTimeMs(sb, time/1000);
4672            sb.append("(");
4673            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4674            sb.append(") ");
4675        }
4676        if (!didOne) sb.append(" (no activity)");
4677        pw.println(sb.toString());
4678
4679        sb.setLength(0);
4680        sb.append(prefix);
4681        sb.append("     Cellular Rx signal strength (RSRP):");
4682        final String[] cellularRxSignalStrengthDescription = new String[]{
4683            "very poor (less than -128dBm): ",
4684            "poor (-128dBm to -118dBm): ",
4685            "moderate (-118dBm to -108dBm): ",
4686            "good (-108dBm to -98dBm): ",
4687            "great (greater than -98dBm): "};
4688        didOne = false;
4689        final int numCellularRxBins = Math.min(SignalStrength.NUM_SIGNAL_STRENGTH_BINS,
4690            cellularRxSignalStrengthDescription.length);
4691        for (int i=0; i<numCellularRxBins; i++) {
4692            final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
4693            if (time == 0) {
4694                continue;
4695            }
4696            sb.append("\n       ");
4697            sb.append(prefix);
4698            didOne = true;
4699            sb.append(cellularRxSignalStrengthDescription[i]);
4700            sb.append(" ");
4701            formatTimeMs(sb, time/1000);
4702            sb.append("(");
4703            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4704            sb.append(") ");
4705        }
4706        if (!didOne) sb.append(" (no activity)");
4707        pw.println(sb.toString());
4708
4709        printControllerActivity(pw, sb, prefix, CELLULAR_CONTROLLER_NAME,
4710            getModemControllerActivity(), which);
4711
4712        pw.print(prefix);
4713        sb.setLength(0);
4714        sb.append(prefix);
4715        sb.append("  Wifi Statistics:");
4716        pw.println(sb.toString());
4717
4718        pw.print(prefix);
4719        sb.setLength(0);
4720        sb.append(prefix);
4721        sb.append("     Wifi kernel active time: ");
4722        final long wifiActiveTime = getWifiActiveTime(rawRealtime, which);
4723        formatTimeMs(sb, wifiActiveTime / 1000);
4724        sb.append("("); sb.append(formatRatioLocked(wifiActiveTime, whichBatteryRealtime));
4725        sb.append(")");
4726        pw.println(sb.toString());
4727
4728        pw.print("     Wifi data received: "); pw.println(formatBytesLocked(wifiRxTotalBytes));
4729        pw.print("     Wifi data sent: "); pw.println(formatBytesLocked(wifiTxTotalBytes));
4730        pw.print("     Wifi packets received: "); pw.println(wifiRxTotalPackets);
4731        pw.print("     Wifi packets sent: "); pw.println(wifiTxTotalPackets);
4732
4733        sb.setLength(0);
4734        sb.append(prefix);
4735        sb.append("     Wifi states:");
4736        didOne = false;
4737        for (int i=0; i<NUM_WIFI_STATES; i++) {
4738            final long time = getWifiStateTime(i, rawRealtime, which);
4739            if (time == 0) {
4740                continue;
4741            }
4742            sb.append("\n       ");
4743            didOne = true;
4744            sb.append(WIFI_STATE_NAMES[i]);
4745            sb.append(" ");
4746            formatTimeMs(sb, time/1000);
4747            sb.append("(");
4748            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4749            sb.append(") ");
4750        }
4751        if (!didOne) sb.append(" (no activity)");
4752        pw.println(sb.toString());
4753
4754        sb.setLength(0);
4755        sb.append(prefix);
4756        sb.append("     Wifi supplicant states:");
4757        didOne = false;
4758        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
4759            final long time = getWifiSupplStateTime(i, rawRealtime, which);
4760            if (time == 0) {
4761                continue;
4762            }
4763            sb.append("\n       ");
4764            didOne = true;
4765            sb.append(WIFI_SUPPL_STATE_NAMES[i]);
4766            sb.append(" ");
4767            formatTimeMs(sb, time/1000);
4768            sb.append("(");
4769            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4770            sb.append(") ");
4771        }
4772        if (!didOne) sb.append(" (no activity)");
4773        pw.println(sb.toString());
4774
4775        sb.setLength(0);
4776        sb.append(prefix);
4777        sb.append("     Wifi Rx signal strength (RSSI):");
4778        final String[] wifiRxSignalStrengthDescription = new String[]{
4779            "very poor (less than -88.75dBm): ",
4780            "poor (-88.75 to -77.5dBm): ",
4781            "moderate (-77.5dBm to -66.25dBm): ",
4782            "good (-66.25dBm to -55dBm): ",
4783            "great (greater than -55dBm): "};
4784        didOne = false;
4785        final int numWifiRxBins = Math.min(NUM_WIFI_SIGNAL_STRENGTH_BINS,
4786            wifiRxSignalStrengthDescription.length);
4787        for (int i=0; i<numWifiRxBins; i++) {
4788            final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
4789            if (time == 0) {
4790                continue;
4791            }
4792            sb.append("\n    ");
4793            sb.append(prefix);
4794            didOne = true;
4795            sb.append("     ");
4796            sb.append(wifiRxSignalStrengthDescription[i]);
4797            formatTimeMs(sb, time/1000);
4798            sb.append("(");
4799            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4800            sb.append(") ");
4801        }
4802        if (!didOne) sb.append(" (no activity)");
4803        pw.println(sb.toString());
4804
4805        printControllerActivity(pw, sb, prefix, WIFI_CONTROLLER_NAME,
4806            getWifiControllerActivity(), which);
4807
4808        pw.print(prefix);
4809        sb.setLength(0);
4810        sb.append(prefix);
4811        sb.append("  GPS Statistics:");
4812        pw.println(sb.toString());
4813
4814        sb.setLength(0);
4815        sb.append(prefix);
4816        sb.append("     GPS signal quality (Top 4 Average CN0):");
4817        final String[] gpsSignalQualityDescription = new String[]{
4818            "poor (less than 20 dBHz): ",
4819            "good (greater than 20 dBHz): "};
4820        final int numGpsSignalQualityBins = Math.min(GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS,
4821            gpsSignalQualityDescription.length);
4822        for (int i=0; i<numGpsSignalQualityBins; i++) {
4823            final long time = getGpsSignalQualityTime(i, rawRealtime, which);
4824            sb.append("\n    ");
4825            sb.append(prefix);
4826            sb.append("  ");
4827            sb.append(gpsSignalQualityDescription[i]);
4828            formatTimeMs(sb, time/1000);
4829            sb.append("(");
4830            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4831            sb.append(") ");
4832        }
4833        pw.println(sb.toString());
4834
4835        final long gpsBatteryDrainMaMs = getGpsBatteryDrainMaMs();
4836        if (gpsBatteryDrainMaMs > 0) {
4837            pw.print(prefix);
4838            sb.setLength(0);
4839            sb.append(prefix);
4840            sb.append("     Battery Drain (mAh): ");
4841            sb.append(Double.toString(((double) gpsBatteryDrainMaMs)/(3600 * 1000)));
4842            pw.println(sb.toString());
4843        }
4844
4845        pw.print(prefix);
4846        sb.setLength(0);
4847        sb.append(prefix);
4848        sb.append("  CONNECTIVITY POWER SUMMARY END");
4849        pw.println(sb.toString());
4850        pw.println("");
4851
4852        pw.print(prefix);
4853        pw.print("  Bluetooth total received: "); pw.print(formatBytesLocked(btRxTotalBytes));
4854        pw.print(", sent: "); pw.println(formatBytesLocked(btTxTotalBytes));
4855
4856        final long bluetoothScanTimeMs = getBluetoothScanTime(rawRealtime, which) / 1000;
4857        sb.setLength(0);
4858        sb.append(prefix);
4859        sb.append("  Bluetooth scan time: "); formatTimeMs(sb, bluetoothScanTimeMs);
4860        pw.println(sb.toString());
4861
4862        printControllerActivity(pw, sb, prefix, "Bluetooth", getBluetoothControllerActivity(),
4863                which);
4864
4865        pw.println();
4866
4867        if (which == STATS_SINCE_UNPLUGGED) {
4868            if (getIsOnBattery()) {
4869                pw.print(prefix); pw.println("  Device is currently unplugged");
4870                pw.print(prefix); pw.print("    Discharge cycle start level: ");
4871                        pw.println(getDischargeStartLevel());
4872                pw.print(prefix); pw.print("    Discharge cycle current level: ");
4873                        pw.println(getDischargeCurrentLevel());
4874            } else {
4875                pw.print(prefix); pw.println("  Device is currently plugged into power");
4876                pw.print(prefix); pw.print("    Last discharge cycle start level: ");
4877                        pw.println(getDischargeStartLevel());
4878                pw.print(prefix); pw.print("    Last discharge cycle end level: ");
4879                        pw.println(getDischargeCurrentLevel());
4880            }
4881            pw.print(prefix); pw.print("    Amount discharged while screen on: ");
4882            pw.println(getDischargeAmountScreenOn());
4883            pw.print(prefix); pw.print("    Amount discharged while screen off: ");
4884            pw.println(getDischargeAmountScreenOff());
4885            pw.print(prefix); pw.print("    Amount discharged while screen doze: ");
4886            pw.println(getDischargeAmountScreenDoze());
4887            pw.println(" ");
4888        } else {
4889            pw.print(prefix); pw.println("  Device battery use since last full charge");
4890            pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
4891            pw.println(getLowDischargeAmountSinceCharge());
4892            pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
4893            pw.println(getHighDischargeAmountSinceCharge());
4894            pw.print(prefix); pw.print("    Amount discharged while screen on: ");
4895            pw.println(getDischargeAmountScreenOnSinceCharge());
4896            pw.print(prefix); pw.print("    Amount discharged while screen off: ");
4897            pw.println(getDischargeAmountScreenOffSinceCharge());
4898            pw.print(prefix); pw.print("    Amount discharged while screen doze: ");
4899            pw.println(getDischargeAmountScreenDozeSinceCharge());
4900            pw.println();
4901        }
4902
4903        final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
4904        helper.create(this);
4905        helper.refreshStats(which, UserHandle.USER_ALL);
4906        List<BatterySipper> sippers = helper.getUsageList();
4907        if (sippers != null && sippers.size() > 0) {
4908            pw.print(prefix); pw.println("  Estimated power use (mAh):");
4909            pw.print(prefix); pw.print("    Capacity: ");
4910                    printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
4911                    pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
4912                    pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower());
4913                    if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
4914                        pw.print("-"); printmAh(pw, helper.getMaxDrainedPower());
4915                    }
4916                    pw.println();
4917            for (int i=0; i<sippers.size(); i++) {
4918                final BatterySipper bs = sippers.get(i);
4919                pw.print(prefix);
4920                switch (bs.drainType) {
4921                    case IDLE:
4922                        pw.print("    Idle: ");
4923                        break;
4924                    case CELL:
4925                        pw.print("    Cell standby: ");
4926                        break;
4927                    case PHONE:
4928                        pw.print("    Phone calls: ");
4929                        break;
4930                    case WIFI:
4931                        pw.print("    Wifi: ");
4932                        break;
4933                    case BLUETOOTH:
4934                        pw.print("    Bluetooth: ");
4935                        break;
4936                    case SCREEN:
4937                        pw.print("    Screen: ");
4938                        break;
4939                    case FLASHLIGHT:
4940                        pw.print("    Flashlight: ");
4941                        break;
4942                    case APP:
4943                        pw.print("    Uid ");
4944                        UserHandle.formatUid(pw, bs.uidObj.getUid());
4945                        pw.print(": ");
4946                        break;
4947                    case USER:
4948                        pw.print("    User "); pw.print(bs.userId);
4949                        pw.print(": ");
4950                        break;
4951                    case UNACCOUNTED:
4952                        pw.print("    Unaccounted: ");
4953                        break;
4954                    case OVERCOUNTED:
4955                        pw.print("    Over-counted: ");
4956                        break;
4957                    case CAMERA:
4958                        pw.print("    Camera: ");
4959                        break;
4960                    default:
4961                        pw.print("    ???: ");
4962                        break;
4963                }
4964                printmAh(pw, bs.totalPowerMah);
4965
4966                if (bs.usagePowerMah != bs.totalPowerMah) {
4967                    // If the usage (generic power) isn't the whole amount, we list out
4968                    // what components are involved in the calculation.
4969
4970                    pw.print(" (");
4971                    if (bs.usagePowerMah != 0) {
4972                        pw.print(" usage=");
4973                        printmAh(pw, bs.usagePowerMah);
4974                    }
4975                    if (bs.cpuPowerMah != 0) {
4976                        pw.print(" cpu=");
4977                        printmAh(pw, bs.cpuPowerMah);
4978                    }
4979                    if (bs.wakeLockPowerMah != 0) {
4980                        pw.print(" wake=");
4981                        printmAh(pw, bs.wakeLockPowerMah);
4982                    }
4983                    if (bs.mobileRadioPowerMah != 0) {
4984                        pw.print(" radio=");
4985                        printmAh(pw, bs.mobileRadioPowerMah);
4986                    }
4987                    if (bs.wifiPowerMah != 0) {
4988                        pw.print(" wifi=");
4989                        printmAh(pw, bs.wifiPowerMah);
4990                    }
4991                    if (bs.bluetoothPowerMah != 0) {
4992                        pw.print(" bt=");
4993                        printmAh(pw, bs.bluetoothPowerMah);
4994                    }
4995                    if (bs.gpsPowerMah != 0) {
4996                        pw.print(" gps=");
4997                        printmAh(pw, bs.gpsPowerMah);
4998                    }
4999                    if (bs.sensorPowerMah != 0) {
5000                        pw.print(" sensor=");
5001                        printmAh(pw, bs.sensorPowerMah);
5002                    }
5003                    if (bs.cameraPowerMah != 0) {
5004                        pw.print(" camera=");
5005                        printmAh(pw, bs.cameraPowerMah);
5006                    }
5007                    if (bs.flashlightPowerMah != 0) {
5008                        pw.print(" flash=");
5009                        printmAh(pw, bs.flashlightPowerMah);
5010                    }
5011                    pw.print(" )");
5012                }
5013
5014                // If there is additional smearing information, include it.
5015                if (bs.totalSmearedPowerMah != bs.totalPowerMah) {
5016                    pw.print(" Including smearing: ");
5017                    printmAh(pw, bs.totalSmearedPowerMah);
5018                    pw.print(" (");
5019                    if (bs.screenPowerMah != 0) {
5020                        pw.print(" screen=");
5021                        printmAh(pw, bs.screenPowerMah);
5022                    }
5023                    if (bs.proportionalSmearMah != 0) {
5024                        pw.print(" proportional=");
5025                        printmAh(pw, bs.proportionalSmearMah);
5026                    }
5027                    pw.print(" )");
5028                }
5029                if (bs.shouldHide) {
5030                    pw.print(" Excluded from smearing");
5031                }
5032
5033                pw.println();
5034            }
5035            pw.println();
5036        }
5037
5038        sippers = helper.getMobilemsppList();
5039        if (sippers != null && sippers.size() > 0) {
5040            pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
5041            long totalTime = 0;
5042            for (int i=0; i<sippers.size(); i++) {
5043                final BatterySipper bs = sippers.get(i);
5044                sb.setLength(0);
5045                sb.append(prefix); sb.append("    Uid ");
5046                UserHandle.formatUid(sb, bs.uidObj.getUid());
5047                sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
5048                sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
5049                sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
5050                sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
5051                pw.println(sb.toString());
5052                totalTime += bs.mobileActive;
5053            }
5054            sb.setLength(0);
5055            sb.append(prefix);
5056            sb.append("    TOTAL TIME: ");
5057            formatTimeMs(sb, totalTime);
5058            sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
5059            sb.append(")");
5060            pw.println(sb.toString());
5061            pw.println();
5062        }
5063
5064        final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
5065            @Override
5066            public int compare(TimerEntry lhs, TimerEntry rhs) {
5067                long lhsTime = lhs.mTime;
5068                long rhsTime = rhs.mTime;
5069                if (lhsTime < rhsTime) {
5070                    return 1;
5071                }
5072                if (lhsTime > rhsTime) {
5073                    return -1;
5074                }
5075                return 0;
5076            }
5077        };
5078
5079        if (reqUid < 0) {
5080            final Map<String, ? extends BatteryStats.Timer> kernelWakelocks
5081                    = getKernelWakelockStats();
5082            if (kernelWakelocks.size() > 0) {
5083                final ArrayList<TimerEntry> ktimers = new ArrayList<>();
5084                for (Map.Entry<String, ? extends BatteryStats.Timer> ent
5085                        : kernelWakelocks.entrySet()) {
5086                    final BatteryStats.Timer timer = ent.getValue();
5087                    final long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
5088                    if (totalTimeMillis > 0) {
5089                        ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
5090                    }
5091                }
5092                if (ktimers.size() > 0) {
5093                    Collections.sort(ktimers, timerComparator);
5094                    pw.print(prefix); pw.println("  All kernel wake locks:");
5095                    for (int i=0; i<ktimers.size(); i++) {
5096                        final TimerEntry timer = ktimers.get(i);
5097                        String linePrefix = ": ";
5098                        sb.setLength(0);
5099                        sb.append(prefix);
5100                        sb.append("  Kernel Wake lock ");
5101                        sb.append(timer.mName);
5102                        linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null,
5103                                which, linePrefix);
5104                        if (!linePrefix.equals(": ")) {
5105                            sb.append(" realtime");
5106                            // Only print out wake locks that were held
5107                            pw.println(sb.toString());
5108                        }
5109                    }
5110                    pw.println();
5111                }
5112            }
5113
5114            if (timers.size() > 0) {
5115                Collections.sort(timers, timerComparator);
5116                pw.print(prefix); pw.println("  All partial wake locks:");
5117                for (int i=0; i<timers.size(); i++) {
5118                    TimerEntry timer = timers.get(i);
5119                    sb.setLength(0);
5120                    sb.append("  Wake lock ");
5121                    UserHandle.formatUid(sb, timer.mId);
5122                    sb.append(" ");
5123                    sb.append(timer.mName);
5124                    printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
5125                    sb.append(" realtime");
5126                    pw.println(sb.toString());
5127                }
5128                timers.clear();
5129                pw.println();
5130            }
5131
5132            final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
5133            if (wakeupReasons.size() > 0) {
5134                pw.print(prefix); pw.println("  All wakeup reasons:");
5135                final ArrayList<TimerEntry> reasons = new ArrayList<>();
5136                for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
5137                    final Timer timer = ent.getValue();
5138                    reasons.add(new TimerEntry(ent.getKey(), 0, timer,
5139                            timer.getCountLocked(which)));
5140                }
5141                Collections.sort(reasons, timerComparator);
5142                for (int i=0; i<reasons.size(); i++) {
5143                    TimerEntry timer = reasons.get(i);
5144                    String linePrefix = ": ";
5145                    sb.setLength(0);
5146                    sb.append(prefix);
5147                    sb.append("  Wakeup reason ");
5148                    sb.append(timer.mName);
5149                    printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
5150                    sb.append(" realtime");
5151                    pw.println(sb.toString());
5152                }
5153                pw.println();
5154            }
5155        }
5156
5157        final LongSparseArray<? extends Timer> mMemoryStats = getKernelMemoryStats();
5158        if (mMemoryStats.size() > 0) {
5159            pw.println("  Memory Stats");
5160            for (int i = 0; i < mMemoryStats.size(); i++) {
5161                sb.setLength(0);
5162                sb.append("  Bandwidth ");
5163                sb.append(mMemoryStats.keyAt(i));
5164                sb.append(" Time ");
5165                sb.append(mMemoryStats.valueAt(i).getTotalTimeLocked(rawRealtime, which));
5166                pw.println(sb.toString());
5167            }
5168            pw.println();
5169        }
5170
5171        final Map<String, ? extends Timer> rpmStats = getRpmStats();
5172        if (rpmStats.size() > 0) {
5173            pw.print(prefix); pw.println("  Resource Power Manager Stats");
5174            if (rpmStats.size() > 0) {
5175                for (Map.Entry<String, ? extends Timer> ent : rpmStats.entrySet()) {
5176                    final String timerName = ent.getKey();
5177                    final Timer timer = ent.getValue();
5178                    printTimer(pw, sb, timer, rawRealtime, which, prefix, timerName);
5179                }
5180            }
5181            pw.println();
5182        }
5183        if (SCREEN_OFF_RPM_STATS_ENABLED) {
5184            final Map<String, ? extends Timer> screenOffRpmStats = getScreenOffRpmStats();
5185            if (screenOffRpmStats.size() > 0) {
5186                pw.print(prefix);
5187                pw.println("  Resource Power Manager Stats for when screen was off");
5188                if (screenOffRpmStats.size() > 0) {
5189                    for (Map.Entry<String, ? extends Timer> ent : screenOffRpmStats.entrySet()) {
5190                        final String timerName = ent.getKey();
5191                        final Timer timer = ent.getValue();
5192                        printTimer(pw, sb, timer, rawRealtime, which, prefix, timerName);
5193                    }
5194                }
5195                pw.println();
5196            }
5197        }
5198
5199        final long[] cpuFreqs = getCpuFreqs();
5200        if (cpuFreqs != null) {
5201            sb.setLength(0);
5202            sb.append("  CPU freqs:");
5203            for (int i = 0; i < cpuFreqs.length; ++i) {
5204                sb.append(" " + cpuFreqs[i]);
5205            }
5206            pw.println(sb.toString());
5207            pw.println();
5208        }
5209
5210        for (int iu=0; iu<NU; iu++) {
5211            final int uid = uidStats.keyAt(iu);
5212            if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
5213                continue;
5214            }
5215
5216            final Uid u = uidStats.valueAt(iu);
5217
5218            pw.print(prefix);
5219            pw.print("  ");
5220            UserHandle.formatUid(pw, uid);
5221            pw.println(":");
5222            boolean uidActivity = false;
5223
5224            final long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
5225            final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
5226            final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
5227            final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
5228            final long btRxBytes = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
5229            final long btTxBytes = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
5230
5231            final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
5232            final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
5233            final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
5234            final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
5235
5236            final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
5237            final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
5238
5239            final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
5240            final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
5241            final int wifiScanCount = u.getWifiScanCount(which);
5242            final int wifiScanCountBg = u.getWifiScanBackgroundCount(which);
5243            // 'actualTime' are unpooled and always since reset (regardless of 'which')
5244            final long wifiScanActualTime = u.getWifiScanActualTime(rawRealtime);
5245            final long wifiScanActualTimeBg = u.getWifiScanBackgroundTime(rawRealtime);
5246            final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
5247
5248            final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
5249            final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
5250
5251            if (mobileRxBytes > 0 || mobileTxBytes > 0
5252                    || mobileRxPackets > 0 || mobileTxPackets > 0) {
5253                pw.print(prefix); pw.print("    Mobile network: ");
5254                        pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
5255                        pw.print(formatBytesLocked(mobileTxBytes));
5256                        pw.print(" sent (packets "); pw.print(mobileRxPackets);
5257                        pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
5258            }
5259            if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
5260                sb.setLength(0);
5261                sb.append(prefix); sb.append("    Mobile radio active: ");
5262                formatTimeMs(sb, uidMobileActiveTime / 1000);
5263                sb.append("(");
5264                sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
5265                sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
5266                long packets = mobileRxPackets + mobileTxPackets;
5267                if (packets == 0) {
5268                    packets = 1;
5269                }
5270                sb.append(" @ ");
5271                sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
5272                sb.append(" mspp");
5273                pw.println(sb.toString());
5274            }
5275
5276            if (mobileWakeup > 0) {
5277                sb.setLength(0);
5278                sb.append(prefix);
5279                sb.append("    Mobile radio AP wakeups: ");
5280                sb.append(mobileWakeup);
5281                pw.println(sb.toString());
5282            }
5283
5284            printControllerActivityIfInteresting(pw, sb, prefix + "  ",
5285                CELLULAR_CONTROLLER_NAME, u.getModemControllerActivity(), which);
5286
5287            if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
5288                pw.print(prefix); pw.print("    Wi-Fi network: ");
5289                        pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
5290                        pw.print(formatBytesLocked(wifiTxBytes));
5291                        pw.print(" sent (packets "); pw.print(wifiRxPackets);
5292                        pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
5293            }
5294
5295            if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
5296                    || wifiScanCountBg != 0 || wifiScanActualTime != 0 || wifiScanActualTimeBg != 0
5297                    || uidWifiRunningTime != 0) {
5298                sb.setLength(0);
5299                sb.append(prefix); sb.append("    Wifi Running: ");
5300                        formatTimeMs(sb, uidWifiRunningTime / 1000);
5301                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
5302                                whichBatteryRealtime)); sb.append(")\n");
5303                sb.append(prefix); sb.append("    Full Wifi Lock: ");
5304                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
5305                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
5306                                whichBatteryRealtime)); sb.append(")\n");
5307                sb.append(prefix); sb.append("    Wifi Scan (blamed): ");
5308                        formatTimeMs(sb, wifiScanTime / 1000);
5309                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
5310                                whichBatteryRealtime)); sb.append(") ");
5311                                sb.append(wifiScanCount);
5312                                sb.append("x\n");
5313                // actual and background times are unpooled and since reset (regardless of 'which')
5314                sb.append(prefix); sb.append("    Wifi Scan (actual): ");
5315                        formatTimeMs(sb, wifiScanActualTime / 1000);
5316                        sb.append("("); sb.append(formatRatioLocked(wifiScanActualTime,
5317                                computeBatteryRealtime(rawRealtime, STATS_SINCE_CHARGED)));
5318                                sb.append(") ");
5319                                sb.append(wifiScanCount);
5320                                sb.append("x\n");
5321                sb.append(prefix); sb.append("    Background Wifi Scan: ");
5322                        formatTimeMs(sb, wifiScanActualTimeBg / 1000);
5323                        sb.append("("); sb.append(formatRatioLocked(wifiScanActualTimeBg,
5324                                computeBatteryRealtime(rawRealtime, STATS_SINCE_CHARGED)));
5325                                sb.append(") ");
5326                                sb.append(wifiScanCountBg);
5327                                sb.append("x");
5328                pw.println(sb.toString());
5329            }
5330
5331            if (wifiWakeup > 0) {
5332                sb.setLength(0);
5333                sb.append(prefix);
5334                sb.append("    WiFi AP wakeups: ");
5335                sb.append(wifiWakeup);
5336                pw.println(sb.toString());
5337            }
5338
5339            printControllerActivityIfInteresting(pw, sb, prefix + "  ", WIFI_CONTROLLER_NAME,
5340                    u.getWifiControllerActivity(), which);
5341
5342            if (btRxBytes > 0 || btTxBytes > 0) {
5343                pw.print(prefix); pw.print("    Bluetooth network: ");
5344                pw.print(formatBytesLocked(btRxBytes)); pw.print(" received, ");
5345                pw.print(formatBytesLocked(btTxBytes));
5346                pw.println(" sent");
5347            }
5348
5349            final Timer bleTimer = u.getBluetoothScanTimer();
5350            if (bleTimer != null) {
5351                // Convert from microseconds to milliseconds with rounding
5352                final long totalTimeMs = (bleTimer.getTotalTimeLocked(rawRealtime, which) + 500)
5353                        / 1000;
5354                if (totalTimeMs != 0) {
5355                    final int count = bleTimer.getCountLocked(which);
5356                    final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
5357                    final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
5358                    // 'actualTime' are unpooled and always since reset (regardless of 'which')
5359                    final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
5360                    final long actualTimeMsBg = bleTimerBg != null ?
5361                            bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5362                    // Result counters
5363                    final int resultCount = u.getBluetoothScanResultCounter() != null ?
5364                            u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
5365                    final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
5366                            u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
5367                    // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
5368                    final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
5369                    final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
5370                            unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5371                    final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
5372                            unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
5373                    // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
5374                    final Timer unoptimizedScanTimerBg =
5375                            u.getBluetoothUnoptimizedScanBackgroundTimer();
5376                    final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
5377                            unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5378                    final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
5379                            unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
5380
5381                    sb.setLength(0);
5382                    if (actualTimeMs != totalTimeMs) {
5383                        sb.append(prefix);
5384                        sb.append("    Bluetooth Scan (total blamed realtime): ");
5385                        formatTimeMs(sb, totalTimeMs);
5386                        sb.append(" (");
5387                        sb.append(count);
5388                        sb.append(" times)");
5389                        if (bleTimer.isRunningLocked()) {
5390                            sb.append(" (currently running)");
5391                        }
5392                        sb.append("\n");
5393                    }
5394
5395                    sb.append(prefix);
5396                    sb.append("    Bluetooth Scan (total actual realtime): ");
5397                    formatTimeMs(sb, actualTimeMs); // since reset, ignores 'which'
5398                    sb.append(" (");
5399                    sb.append(count);
5400                    sb.append(" times)");
5401                    if (bleTimer.isRunningLocked()) {
5402                            sb.append(" (currently running)");
5403                    }
5404                    sb.append("\n");
5405                    if (actualTimeMsBg > 0 || countBg > 0) {
5406                        sb.append(prefix);
5407                        sb.append("    Bluetooth Scan (background realtime): ");
5408                        formatTimeMs(sb, actualTimeMsBg); // since reset, ignores 'which'
5409                        sb.append(" (");
5410                        sb.append(countBg);
5411                        sb.append(" times)");
5412                        if (bleTimerBg != null && bleTimerBg.isRunningLocked()) {
5413                            sb.append(" (currently running in background)");
5414                        }
5415                        sb.append("\n");
5416                    }
5417
5418                    sb.append(prefix);
5419                    sb.append("    Bluetooth Scan Results: ");
5420                    sb.append(resultCount);
5421                    sb.append(" (");
5422                    sb.append(resultCountBg);
5423                    sb.append(" in background)");
5424
5425                    if (unoptimizedScanTotalTime > 0 || unoptimizedScanTotalTimeBg > 0) {
5426                        sb.append("\n");
5427                        sb.append(prefix);
5428                        sb.append("    Unoptimized Bluetooth Scan (realtime): ");
5429                        formatTimeMs(sb, unoptimizedScanTotalTime); // since reset, ignores 'which'
5430                        sb.append(" (max ");
5431                        formatTimeMs(sb, unoptimizedScanMaxTime); // since reset, ignores 'which'
5432                        sb.append(")");
5433                        if (unoptimizedScanTimer != null
5434                                && unoptimizedScanTimer.isRunningLocked()) {
5435                            sb.append(" (currently running unoptimized)");
5436                        }
5437                        if (unoptimizedScanTimerBg != null && unoptimizedScanTotalTimeBg > 0) {
5438                            sb.append("\n");
5439                            sb.append(prefix);
5440                            sb.append("    Unoptimized Bluetooth Scan (background realtime): ");
5441                            formatTimeMs(sb, unoptimizedScanTotalTimeBg); // since reset
5442                            sb.append(" (max ");
5443                            formatTimeMs(sb, unoptimizedScanMaxTimeBg); // since reset
5444                            sb.append(")");
5445                            if (unoptimizedScanTimerBg.isRunningLocked()) {
5446                                sb.append(" (currently running unoptimized in background)");
5447                            }
5448                        }
5449                    }
5450                    pw.println(sb.toString());
5451                    uidActivity = true;
5452                }
5453            }
5454
5455
5456
5457            if (u.hasUserActivity()) {
5458                boolean hasData = false;
5459                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5460                    final int val = u.getUserActivityCount(i, which);
5461                    if (val != 0) {
5462                        if (!hasData) {
5463                            sb.setLength(0);
5464                            sb.append("    User activity: ");
5465                            hasData = true;
5466                        } else {
5467                            sb.append(", ");
5468                        }
5469                        sb.append(val);
5470                        sb.append(" ");
5471                        sb.append(Uid.USER_ACTIVITY_TYPES[i]);
5472                    }
5473                }
5474                if (hasData) {
5475                    pw.println(sb.toString());
5476                }
5477            }
5478
5479            final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
5480                    = u.getWakelockStats();
5481            long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
5482            long totalDrawWakelock = 0;
5483            int countWakelock = 0;
5484            for (int iw=wakelocks.size()-1; iw>=0; iw--) {
5485                final Uid.Wakelock wl = wakelocks.valueAt(iw);
5486                String linePrefix = ": ";
5487                sb.setLength(0);
5488                sb.append(prefix);
5489                sb.append("    Wake lock ");
5490                sb.append(wakelocks.keyAt(iw));
5491                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
5492                        "full", which, linePrefix);
5493                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
5494                linePrefix = printWakeLock(sb, pTimer, rawRealtime,
5495                        "partial", which, linePrefix);
5496                linePrefix = printWakeLock(sb, pTimer != null ? pTimer.getSubTimer() : null,
5497                        rawRealtime, "background partial", which, linePrefix);
5498                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
5499                        "window", which, linePrefix);
5500                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
5501                        "draw", which, linePrefix);
5502                sb.append(" realtime");
5503                pw.println(sb.toString());
5504                uidActivity = true;
5505                countWakelock++;
5506
5507                totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
5508                        rawRealtime, which);
5509                totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
5510                        rawRealtime, which);
5511                totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
5512                        rawRealtime, which);
5513                totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW),
5514                        rawRealtime, which);
5515            }
5516            if (countWakelock > 1) {
5517                // get unpooled partial wakelock quantities (unlike totalPartialWakelock, which is
5518                // pooled and therefore just a lower bound)
5519                long actualTotalPartialWakelock = 0;
5520                long actualBgPartialWakelock = 0;
5521                if (u.getAggregatedPartialWakelockTimer() != null) {
5522                    final Timer aggTimer = u.getAggregatedPartialWakelockTimer();
5523                    // Convert from microseconds to milliseconds with rounding
5524                    actualTotalPartialWakelock =
5525                            aggTimer.getTotalDurationMsLocked(rawRealtimeMs);
5526                    final Timer bgAggTimer = aggTimer.getSubTimer();
5527                    actualBgPartialWakelock = bgAggTimer != null ?
5528                            bgAggTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5529                }
5530
5531                if (actualTotalPartialWakelock != 0 || actualBgPartialWakelock != 0 ||
5532                        totalFullWakelock != 0 || totalPartialWakelock != 0 ||
5533                        totalWindowWakelock != 0) {
5534                    sb.setLength(0);
5535                    sb.append(prefix);
5536                    sb.append("    TOTAL wake: ");
5537                    boolean needComma = false;
5538                    if (totalFullWakelock != 0) {
5539                        needComma = true;
5540                        formatTimeMs(sb, totalFullWakelock);
5541                        sb.append("full");
5542                    }
5543                    if (totalPartialWakelock != 0) {
5544                        if (needComma) {
5545                            sb.append(", ");
5546                        }
5547                        needComma = true;
5548                        formatTimeMs(sb, totalPartialWakelock);
5549                        sb.append("blamed partial");
5550                    }
5551                    if (actualTotalPartialWakelock != 0) {
5552                        if (needComma) {
5553                            sb.append(", ");
5554                        }
5555                        needComma = true;
5556                        formatTimeMs(sb, actualTotalPartialWakelock);
5557                        sb.append("actual partial");
5558                    }
5559                    if (actualBgPartialWakelock != 0) {
5560                        if (needComma) {
5561                            sb.append(", ");
5562                        }
5563                        needComma = true;
5564                        formatTimeMs(sb, actualBgPartialWakelock);
5565                        sb.append("actual background partial");
5566                    }
5567                    if (totalWindowWakelock != 0) {
5568                        if (needComma) {
5569                            sb.append(", ");
5570                        }
5571                        needComma = true;
5572                        formatTimeMs(sb, totalWindowWakelock);
5573                        sb.append("window");
5574                    }
5575                    if (totalDrawWakelock != 0) {
5576                        if (needComma) {
5577                            sb.append(",");
5578                        }
5579                        needComma = true;
5580                        formatTimeMs(sb, totalDrawWakelock);
5581                        sb.append("draw");
5582                    }
5583                    sb.append(" realtime");
5584                    pw.println(sb.toString());
5585                }
5586            }
5587
5588            // Calculate multicast wakelock stats
5589            final Timer mcTimer = u.getMulticastWakelockStats();
5590            if (mcTimer != null) {
5591                final long multicastWakeLockTimeMicros = mcTimer.getTotalTimeLocked(rawRealtime, which);
5592                final int multicastWakeLockCount = mcTimer.getCountLocked(which);
5593
5594                if (multicastWakeLockTimeMicros > 0) {
5595                    sb.setLength(0);
5596                    sb.append(prefix);
5597                    sb.append("    WiFi Multicast Wakelock");
5598                    sb.append(" count = ");
5599                    sb.append(multicastWakeLockCount);
5600                    sb.append(" time = ");
5601                    formatTimeMsNoSpace(sb, (multicastWakeLockTimeMicros + 500) / 1000);
5602                    pw.println(sb.toString());
5603                }
5604            }
5605
5606            final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
5607            for (int isy=syncs.size()-1; isy>=0; isy--) {
5608                final Timer timer = syncs.valueAt(isy);
5609                // Convert from microseconds to milliseconds with rounding
5610                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
5611                final int count = timer.getCountLocked(which);
5612                final Timer bgTimer = timer.getSubTimer();
5613                final long bgTime = bgTimer != null ?
5614                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
5615                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
5616                sb.setLength(0);
5617                sb.append(prefix);
5618                sb.append("    Sync ");
5619                sb.append(syncs.keyAt(isy));
5620                sb.append(": ");
5621                if (totalTime != 0) {
5622                    formatTimeMs(sb, totalTime);
5623                    sb.append("realtime (");
5624                    sb.append(count);
5625                    sb.append(" times)");
5626                    if (bgTime > 0) {
5627                        sb.append(", ");
5628                        formatTimeMs(sb, bgTime);
5629                        sb.append("background (");
5630                        sb.append(bgCount);
5631                        sb.append(" times)");
5632                    }
5633                } else {
5634                    sb.append("(not used)");
5635                }
5636                pw.println(sb.toString());
5637                uidActivity = true;
5638            }
5639
5640            final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
5641            for (int ij=jobs.size()-1; ij>=0; ij--) {
5642                final Timer timer = jobs.valueAt(ij);
5643                // Convert from microseconds to milliseconds with rounding
5644                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
5645                final int count = timer.getCountLocked(which);
5646                final Timer bgTimer = timer.getSubTimer();
5647                final long bgTime = bgTimer != null ?
5648                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
5649                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
5650                sb.setLength(0);
5651                sb.append(prefix);
5652                sb.append("    Job ");
5653                sb.append(jobs.keyAt(ij));
5654                sb.append(": ");
5655                if (totalTime != 0) {
5656                    formatTimeMs(sb, totalTime);
5657                    sb.append("realtime (");
5658                    sb.append(count);
5659                    sb.append(" times)");
5660                    if (bgTime > 0) {
5661                        sb.append(", ");
5662                        formatTimeMs(sb, bgTime);
5663                        sb.append("background (");
5664                        sb.append(bgCount);
5665                        sb.append(" times)");
5666                    }
5667                } else {
5668                    sb.append("(not used)");
5669                }
5670                pw.println(sb.toString());
5671                uidActivity = true;
5672            }
5673
5674            final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
5675            for (int ic=completions.size()-1; ic>=0; ic--) {
5676                SparseIntArray types = completions.valueAt(ic);
5677                if (types != null) {
5678                    pw.print(prefix);
5679                    pw.print("    Job Completions ");
5680                    pw.print(completions.keyAt(ic));
5681                    pw.print(":");
5682                    for (int it=0; it<types.size(); it++) {
5683                        pw.print(" ");
5684                        pw.print(JobParameters.getReasonName(types.keyAt(it)));
5685                        pw.print("(");
5686                        pw.print(types.valueAt(it));
5687                        pw.print("x)");
5688                    }
5689                    pw.println();
5690                }
5691            }
5692
5693            uidActivity |= printTimer(pw, sb, u.getFlashlightTurnedOnTimer(), rawRealtime, which,
5694                    prefix, "Flashlight");
5695            uidActivity |= printTimer(pw, sb, u.getCameraTurnedOnTimer(), rawRealtime, which,
5696                    prefix, "Camera");
5697            uidActivity |= printTimer(pw, sb, u.getVideoTurnedOnTimer(), rawRealtime, which,
5698                    prefix, "Video");
5699            uidActivity |= printTimer(pw, sb, u.getAudioTurnedOnTimer(), rawRealtime, which,
5700                    prefix, "Audio");
5701
5702            final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
5703            final int NSE = sensors.size();
5704            for (int ise=0; ise<NSE; ise++) {
5705                final Uid.Sensor se = sensors.valueAt(ise);
5706                final int sensorNumber = sensors.keyAt(ise);
5707                sb.setLength(0);
5708                sb.append(prefix);
5709                sb.append("    Sensor ");
5710                int handle = se.getHandle();
5711                if (handle == Uid.Sensor.GPS) {
5712                    sb.append("GPS");
5713                } else {
5714                    sb.append(handle);
5715                }
5716                sb.append(": ");
5717
5718                final Timer timer = se.getSensorTime();
5719                if (timer != null) {
5720                    // Convert from microseconds to milliseconds with rounding
5721                    final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
5722                            / 1000;
5723                    final int count = timer.getCountLocked(which);
5724                    final Timer bgTimer = se.getSensorBackgroundTime();
5725                    final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
5726                    // 'actualTime' are unpooled and always since reset (regardless of 'which')
5727                    final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
5728                    final long bgActualTime = bgTimer != null ?
5729                            bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5730
5731                    //timer.logState();
5732                    if (totalTime != 0) {
5733                        if (actualTime != totalTime) {
5734                            formatTimeMs(sb, totalTime);
5735                            sb.append("blamed realtime, ");
5736                        }
5737
5738                        formatTimeMs(sb, actualTime); // since reset, regardless of 'which'
5739                        sb.append("realtime (");
5740                        sb.append(count);
5741                        sb.append(" times)");
5742
5743                        if (bgActualTime != 0 || bgCount > 0) {
5744                            sb.append(", ");
5745                            formatTimeMs(sb, bgActualTime); // since reset, regardless of 'which'
5746                            sb.append("background (");
5747                            sb.append(bgCount);
5748                            sb.append(" times)");
5749                        }
5750                    } else {
5751                        sb.append("(not used)");
5752                    }
5753                } else {
5754                    sb.append("(not used)");
5755                }
5756
5757                pw.println(sb.toString());
5758                uidActivity = true;
5759            }
5760
5761            uidActivity |= printTimer(pw, sb, u.getVibratorOnTimer(), rawRealtime, which, prefix,
5762                    "Vibrator");
5763            uidActivity |= printTimer(pw, sb, u.getForegroundActivityTimer(), rawRealtime, which,
5764                    prefix, "Foreground activities");
5765            uidActivity |= printTimer(pw, sb, u.getForegroundServiceTimer(), rawRealtime, which,
5766                    prefix, "Foreground services");
5767
5768            long totalStateTime = 0;
5769            for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
5770                long time = u.getProcessStateTime(ips, rawRealtime, which);
5771                if (time > 0) {
5772                    totalStateTime += time;
5773                    sb.setLength(0);
5774                    sb.append(prefix);
5775                    sb.append("    ");
5776                    sb.append(Uid.PROCESS_STATE_NAMES[ips]);
5777                    sb.append(" for: ");
5778                    formatTimeMs(sb, (time + 500) / 1000);
5779                    pw.println(sb.toString());
5780                    uidActivity = true;
5781                }
5782            }
5783            if (totalStateTime > 0) {
5784                sb.setLength(0);
5785                sb.append(prefix);
5786                sb.append("    Total running: ");
5787                formatTimeMs(sb, (totalStateTime + 500) / 1000);
5788                pw.println(sb.toString());
5789            }
5790
5791            final long userCpuTimeUs = u.getUserCpuTimeUs(which);
5792            final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
5793            if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
5794                sb.setLength(0);
5795                sb.append(prefix);
5796                sb.append("    Total cpu time: u=");
5797                formatTimeMs(sb, userCpuTimeUs / 1000);
5798                sb.append("s=");
5799                formatTimeMs(sb, systemCpuTimeUs / 1000);
5800                pw.println(sb.toString());
5801            }
5802
5803            final long[] cpuFreqTimes = u.getCpuFreqTimes(which);
5804            if (cpuFreqTimes != null) {
5805                sb.setLength(0);
5806                sb.append("    Total cpu time per freq:");
5807                for (int i = 0; i < cpuFreqTimes.length; ++i) {
5808                    sb.append(" " + cpuFreqTimes[i]);
5809                }
5810                pw.println(sb.toString());
5811            }
5812            final long[] screenOffCpuFreqTimes = u.getScreenOffCpuFreqTimes(which);
5813            if (screenOffCpuFreqTimes != null) {
5814                sb.setLength(0);
5815                sb.append("    Total screen-off cpu time per freq:");
5816                for (int i = 0; i < screenOffCpuFreqTimes.length; ++i) {
5817                    sb.append(" " + screenOffCpuFreqTimes[i]);
5818                }
5819                pw.println(sb.toString());
5820            }
5821
5822            for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
5823                final long[] cpuTimes = u.getCpuFreqTimes(which, procState);
5824                if (cpuTimes != null) {
5825                    sb.setLength(0);
5826                    sb.append("    Cpu times per freq at state "
5827                            + Uid.PROCESS_STATE_NAMES[procState] + ":");
5828                    for (int i = 0; i < cpuTimes.length; ++i) {
5829                        sb.append(" " + cpuTimes[i]);
5830                    }
5831                    pw.println(sb.toString());
5832                }
5833
5834                final long[] screenOffCpuTimes = u.getScreenOffCpuFreqTimes(which, procState);
5835                if (screenOffCpuTimes != null) {
5836                    sb.setLength(0);
5837                    sb.append("   Screen-off cpu times per freq at state "
5838                            + Uid.PROCESS_STATE_NAMES[procState] + ":");
5839                    for (int i = 0; i < screenOffCpuTimes.length; ++i) {
5840                        sb.append(" " + screenOffCpuTimes[i]);
5841                    }
5842                    pw.println(sb.toString());
5843                }
5844            }
5845
5846            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
5847                    = u.getProcessStats();
5848            for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
5849                final Uid.Proc ps = processStats.valueAt(ipr);
5850                long userTime;
5851                long systemTime;
5852                long foregroundTime;
5853                int starts;
5854                int numExcessive;
5855
5856                userTime = ps.getUserTime(which);
5857                systemTime = ps.getSystemTime(which);
5858                foregroundTime = ps.getForegroundTime(which);
5859                starts = ps.getStarts(which);
5860                final int numCrashes = ps.getNumCrashes(which);
5861                final int numAnrs = ps.getNumAnrs(which);
5862                numExcessive = which == STATS_SINCE_CHARGED
5863                        ? ps.countExcessivePowers() : 0;
5864
5865                if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
5866                        || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
5867                    sb.setLength(0);
5868                    sb.append(prefix); sb.append("    Proc ");
5869                            sb.append(processStats.keyAt(ipr)); sb.append(":\n");
5870                    sb.append(prefix); sb.append("      CPU: ");
5871                            formatTimeMs(sb, userTime); sb.append("usr + ");
5872                            formatTimeMs(sb, systemTime); sb.append("krn ; ");
5873                            formatTimeMs(sb, foregroundTime); sb.append("fg");
5874                    if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
5875                        sb.append("\n"); sb.append(prefix); sb.append("      ");
5876                        boolean hasOne = false;
5877                        if (starts != 0) {
5878                            hasOne = true;
5879                            sb.append(starts); sb.append(" starts");
5880                        }
5881                        if (numCrashes != 0) {
5882                            if (hasOne) {
5883                                sb.append(", ");
5884                            }
5885                            hasOne = true;
5886                            sb.append(numCrashes); sb.append(" crashes");
5887                        }
5888                        if (numAnrs != 0) {
5889                            if (hasOne) {
5890                                sb.append(", ");
5891                            }
5892                            sb.append(numAnrs); sb.append(" anrs");
5893                        }
5894                    }
5895                    pw.println(sb.toString());
5896                    for (int e=0; e<numExcessive; e++) {
5897                        Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
5898                        if (ew != null) {
5899                            pw.print(prefix); pw.print("      * Killed for ");
5900                                    if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
5901                                        pw.print("cpu");
5902                                    } else {
5903                                        pw.print("unknown");
5904                                    }
5905                                    pw.print(" use: ");
5906                                    TimeUtils.formatDuration(ew.usedTime, pw);
5907                                    pw.print(" over ");
5908                                    TimeUtils.formatDuration(ew.overTime, pw);
5909                                    if (ew.overTime != 0) {
5910                                        pw.print(" (");
5911                                        pw.print((ew.usedTime*100)/ew.overTime);
5912                                        pw.println("%)");
5913                                    }
5914                        }
5915                    }
5916                    uidActivity = true;
5917                }
5918            }
5919
5920            final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
5921                    = u.getPackageStats();
5922            for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
5923                pw.print(prefix); pw.print("    Apk "); pw.print(packageStats.keyAt(ipkg));
5924                pw.println(":");
5925                boolean apkActivity = false;
5926                final Uid.Pkg ps = packageStats.valueAt(ipkg);
5927                final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
5928                for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
5929                    pw.print(prefix); pw.print("      Wakeup alarm ");
5930                            pw.print(alarms.keyAt(iwa)); pw.print(": ");
5931                            pw.print(alarms.valueAt(iwa).getCountLocked(which));
5932                            pw.println(" times");
5933                    apkActivity = true;
5934                }
5935                final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
5936                for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
5937                    final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
5938                    final long startTime = ss.getStartTime(batteryUptime, which);
5939                    final int starts = ss.getStarts(which);
5940                    final int launches = ss.getLaunches(which);
5941                    if (startTime != 0 || starts != 0 || launches != 0) {
5942                        sb.setLength(0);
5943                        sb.append(prefix); sb.append("      Service ");
5944                                sb.append(serviceStats.keyAt(isvc)); sb.append(":\n");
5945                        sb.append(prefix); sb.append("        Created for: ");
5946                                formatTimeMs(sb, startTime / 1000);
5947                                sb.append("uptime\n");
5948                        sb.append(prefix); sb.append("        Starts: ");
5949                                sb.append(starts);
5950                                sb.append(", launches: "); sb.append(launches);
5951                        pw.println(sb.toString());
5952                        apkActivity = true;
5953                    }
5954                }
5955                if (!apkActivity) {
5956                    pw.print(prefix); pw.println("      (nothing executed)");
5957                }
5958                uidActivity = true;
5959            }
5960            if (!uidActivity) {
5961                pw.print(prefix); pw.println("    (nothing executed)");
5962            }
5963        }
5964    }
5965
5966    static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag,
5967            BitDescription[] descriptions, boolean longNames) {
5968        int diff = oldval ^ newval;
5969        if (diff == 0) return;
5970        boolean didWake = false;
5971        for (int i=0; i<descriptions.length; i++) {
5972            BitDescription bd = descriptions[i];
5973            if ((diff&bd.mask) != 0) {
5974                pw.print(longNames ? " " : ",");
5975                if (bd.shift < 0) {
5976                    pw.print((newval&bd.mask) != 0 ? "+" : "-");
5977                    pw.print(longNames ? bd.name : bd.shortName);
5978                    if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
5979                        didWake = true;
5980                        pw.print("=");
5981                        if (longNames) {
5982                            UserHandle.formatUid(pw, wakelockTag.uid);
5983                            pw.print(":\"");
5984                            pw.print(wakelockTag.string);
5985                            pw.print("\"");
5986                        } else {
5987                            pw.print(wakelockTag.poolIdx);
5988                        }
5989                    }
5990                } else {
5991                    pw.print(longNames ? bd.name : bd.shortName);
5992                    pw.print("=");
5993                    int val = (newval&bd.mask)>>bd.shift;
5994                    if (bd.values != null && val >= 0 && val < bd.values.length) {
5995                        pw.print(longNames? bd.values[val] : bd.shortValues[val]);
5996                    } else {
5997                        pw.print(val);
5998                    }
5999                }
6000            }
6001        }
6002        if (!didWake && wakelockTag != null) {
6003            pw.print(longNames ? " wake_lock=" : ",w=");
6004            if (longNames) {
6005                UserHandle.formatUid(pw, wakelockTag.uid);
6006                pw.print(":\"");
6007                pw.print(wakelockTag.string);
6008                pw.print("\"");
6009            } else {
6010                pw.print(wakelockTag.poolIdx);
6011            }
6012        }
6013    }
6014
6015    public void prepareForDumpLocked() {
6016        // We don't need to require subclasses implement this.
6017    }
6018
6019    public static class HistoryPrinter {
6020        int oldState = 0;
6021        int oldState2 = 0;
6022        int oldLevel = -1;
6023        int oldStatus = -1;
6024        int oldHealth = -1;
6025        int oldPlug = -1;
6026        int oldTemp = -1;
6027        int oldVolt = -1;
6028        int oldChargeMAh = -1;
6029        long lastTime = -1;
6030
6031        void reset() {
6032            oldState = oldState2 = 0;
6033            oldLevel = -1;
6034            oldStatus = -1;
6035            oldHealth = -1;
6036            oldPlug = -1;
6037            oldTemp = -1;
6038            oldVolt = -1;
6039            oldChargeMAh = -1;
6040        }
6041
6042        public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
6043                boolean verbose) {
6044            if (!checkin) {
6045                pw.print("  ");
6046                TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
6047                pw.print(" (");
6048                pw.print(rec.numReadInts);
6049                pw.print(") ");
6050            } else {
6051                pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
6052                pw.print(HISTORY_DATA); pw.print(',');
6053                if (lastTime < 0) {
6054                    pw.print(rec.time - baseTime);
6055                } else {
6056                    pw.print(rec.time - lastTime);
6057                }
6058                lastTime = rec.time;
6059            }
6060            if (rec.cmd == HistoryItem.CMD_START) {
6061                if (checkin) {
6062                    pw.print(":");
6063                }
6064                pw.println("START");
6065                reset();
6066            } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
6067                    || rec.cmd == HistoryItem.CMD_RESET) {
6068                if (checkin) {
6069                    pw.print(":");
6070                }
6071                if (rec.cmd == HistoryItem.CMD_RESET) {
6072                    pw.print("RESET:");
6073                    reset();
6074                }
6075                pw.print("TIME:");
6076                if (checkin) {
6077                    pw.println(rec.currentTime);
6078                } else {
6079                    pw.print(" ");
6080                    pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6081                            rec.currentTime).toString());
6082                }
6083            } else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) {
6084                if (checkin) {
6085                    pw.print(":");
6086                }
6087                pw.println("SHUTDOWN");
6088            } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
6089                if (checkin) {
6090                    pw.print(":");
6091                }
6092                pw.println("*OVERFLOW*");
6093            } else {
6094                if (!checkin) {
6095                    if (rec.batteryLevel < 10) pw.print("00");
6096                    else if (rec.batteryLevel < 100) pw.print("0");
6097                    pw.print(rec.batteryLevel);
6098                    if (verbose) {
6099                        pw.print(" ");
6100                        if (rec.states < 0) ;
6101                        else if (rec.states < 0x10) pw.print("0000000");
6102                        else if (rec.states < 0x100) pw.print("000000");
6103                        else if (rec.states < 0x1000) pw.print("00000");
6104                        else if (rec.states < 0x10000) pw.print("0000");
6105                        else if (rec.states < 0x100000) pw.print("000");
6106                        else if (rec.states < 0x1000000) pw.print("00");
6107                        else if (rec.states < 0x10000000) pw.print("0");
6108                        pw.print(Integer.toHexString(rec.states));
6109                    }
6110                } else {
6111                    if (oldLevel != rec.batteryLevel) {
6112                        oldLevel = rec.batteryLevel;
6113                        pw.print(",Bl="); pw.print(rec.batteryLevel);
6114                    }
6115                }
6116                if (oldStatus != rec.batteryStatus) {
6117                    oldStatus = rec.batteryStatus;
6118                    pw.print(checkin ? ",Bs=" : " status=");
6119                    switch (oldStatus) {
6120                        case BatteryManager.BATTERY_STATUS_UNKNOWN:
6121                            pw.print(checkin ? "?" : "unknown");
6122                            break;
6123                        case BatteryManager.BATTERY_STATUS_CHARGING:
6124                            pw.print(checkin ? "c" : "charging");
6125                            break;
6126                        case BatteryManager.BATTERY_STATUS_DISCHARGING:
6127                            pw.print(checkin ? "d" : "discharging");
6128                            break;
6129                        case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
6130                            pw.print(checkin ? "n" : "not-charging");
6131                            break;
6132                        case BatteryManager.BATTERY_STATUS_FULL:
6133                            pw.print(checkin ? "f" : "full");
6134                            break;
6135                        default:
6136                            pw.print(oldStatus);
6137                            break;
6138                    }
6139                }
6140                if (oldHealth != rec.batteryHealth) {
6141                    oldHealth = rec.batteryHealth;
6142                    pw.print(checkin ? ",Bh=" : " health=");
6143                    switch (oldHealth) {
6144                        case BatteryManager.BATTERY_HEALTH_UNKNOWN:
6145                            pw.print(checkin ? "?" : "unknown");
6146                            break;
6147                        case BatteryManager.BATTERY_HEALTH_GOOD:
6148                            pw.print(checkin ? "g" : "good");
6149                            break;
6150                        case BatteryManager.BATTERY_HEALTH_OVERHEAT:
6151                            pw.print(checkin ? "h" : "overheat");
6152                            break;
6153                        case BatteryManager.BATTERY_HEALTH_DEAD:
6154                            pw.print(checkin ? "d" : "dead");
6155                            break;
6156                        case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
6157                            pw.print(checkin ? "v" : "over-voltage");
6158                            break;
6159                        case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
6160                            pw.print(checkin ? "f" : "failure");
6161                            break;
6162                        case BatteryManager.BATTERY_HEALTH_COLD:
6163                            pw.print(checkin ? "c" : "cold");
6164                            break;
6165                        default:
6166                            pw.print(oldHealth);
6167                            break;
6168                    }
6169                }
6170                if (oldPlug != rec.batteryPlugType) {
6171                    oldPlug = rec.batteryPlugType;
6172                    pw.print(checkin ? ",Bp=" : " plug=");
6173                    switch (oldPlug) {
6174                        case 0:
6175                            pw.print(checkin ? "n" : "none");
6176                            break;
6177                        case BatteryManager.BATTERY_PLUGGED_AC:
6178                            pw.print(checkin ? "a" : "ac");
6179                            break;
6180                        case BatteryManager.BATTERY_PLUGGED_USB:
6181                            pw.print(checkin ? "u" : "usb");
6182                            break;
6183                        case BatteryManager.BATTERY_PLUGGED_WIRELESS:
6184                            pw.print(checkin ? "w" : "wireless");
6185                            break;
6186                        default:
6187                            pw.print(oldPlug);
6188                            break;
6189                    }
6190                }
6191                if (oldTemp != rec.batteryTemperature) {
6192                    oldTemp = rec.batteryTemperature;
6193                    pw.print(checkin ? ",Bt=" : " temp=");
6194                    pw.print(oldTemp);
6195                }
6196                if (oldVolt != rec.batteryVoltage) {
6197                    oldVolt = rec.batteryVoltage;
6198                    pw.print(checkin ? ",Bv=" : " volt=");
6199                    pw.print(oldVolt);
6200                }
6201                final int chargeMAh = rec.batteryChargeUAh / 1000;
6202                if (oldChargeMAh != chargeMAh) {
6203                    oldChargeMAh = chargeMAh;
6204                    pw.print(checkin ? ",Bcc=" : " charge=");
6205                    pw.print(oldChargeMAh);
6206                }
6207                printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
6208                        HISTORY_STATE_DESCRIPTIONS, !checkin);
6209                printBitDescriptions(pw, oldState2, rec.states2, null,
6210                        HISTORY_STATE2_DESCRIPTIONS, !checkin);
6211                if (rec.wakeReasonTag != null) {
6212                    if (checkin) {
6213                        pw.print(",wr=");
6214                        pw.print(rec.wakeReasonTag.poolIdx);
6215                    } else {
6216                        pw.print(" wake_reason=");
6217                        pw.print(rec.wakeReasonTag.uid);
6218                        pw.print(":\"");
6219                        pw.print(rec.wakeReasonTag.string);
6220                        pw.print("\"");
6221                    }
6222                }
6223                if (rec.eventCode != HistoryItem.EVENT_NONE) {
6224                    pw.print(checkin ? "," : " ");
6225                    if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
6226                        pw.print("+");
6227                    } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
6228                        pw.print("-");
6229                    }
6230                    String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
6231                            : HISTORY_EVENT_NAMES;
6232                    int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
6233                            | HistoryItem.EVENT_FLAG_FINISH);
6234                    if (idx >= 0 && idx < eventNames.length) {
6235                        pw.print(eventNames[idx]);
6236                    } else {
6237                        pw.print(checkin ? "Ev" : "event");
6238                        pw.print(idx);
6239                    }
6240                    pw.print("=");
6241                    if (checkin) {
6242                        pw.print(rec.eventTag.poolIdx);
6243                    } else {
6244                        pw.append(HISTORY_EVENT_INT_FORMATTERS[idx]
6245                                .applyAsString(rec.eventTag.uid));
6246                        pw.print(":\"");
6247                        pw.print(rec.eventTag.string);
6248                        pw.print("\"");
6249                    }
6250                }
6251                pw.println();
6252                if (rec.stepDetails != null) {
6253                    if (!checkin) {
6254                        pw.print("                 Details: cpu=");
6255                        pw.print(rec.stepDetails.userTime);
6256                        pw.print("u+");
6257                        pw.print(rec.stepDetails.systemTime);
6258                        pw.print("s");
6259                        if (rec.stepDetails.appCpuUid1 >= 0) {
6260                            pw.print(" (");
6261                            printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid1,
6262                                    rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
6263                            if (rec.stepDetails.appCpuUid2 >= 0) {
6264                                pw.print(", ");
6265                                printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid2,
6266                                        rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
6267                            }
6268                            if (rec.stepDetails.appCpuUid3 >= 0) {
6269                                pw.print(", ");
6270                                printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid3,
6271                                        rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
6272                            }
6273                            pw.print(')');
6274                        }
6275                        pw.println();
6276                        pw.print("                          /proc/stat=");
6277                        pw.print(rec.stepDetails.statUserTime);
6278                        pw.print(" usr, ");
6279                        pw.print(rec.stepDetails.statSystemTime);
6280                        pw.print(" sys, ");
6281                        pw.print(rec.stepDetails.statIOWaitTime);
6282                        pw.print(" io, ");
6283                        pw.print(rec.stepDetails.statIrqTime);
6284                        pw.print(" irq, ");
6285                        pw.print(rec.stepDetails.statSoftIrqTime);
6286                        pw.print(" sirq, ");
6287                        pw.print(rec.stepDetails.statIdlTime);
6288                        pw.print(" idle");
6289                        int totalRun = rec.stepDetails.statUserTime + rec.stepDetails.statSystemTime
6290                                + rec.stepDetails.statIOWaitTime + rec.stepDetails.statIrqTime
6291                                + rec.stepDetails.statSoftIrqTime;
6292                        int total = totalRun + rec.stepDetails.statIdlTime;
6293                        if (total > 0) {
6294                            pw.print(" (");
6295                            float perc = ((float)totalRun) / ((float)total) * 100;
6296                            pw.print(String.format("%.1f%%", perc));
6297                            pw.print(" of ");
6298                            StringBuilder sb = new StringBuilder(64);
6299                            formatTimeMsNoSpace(sb, total*10);
6300                            pw.print(sb);
6301                            pw.print(")");
6302                        }
6303                        pw.print(", PlatformIdleStat ");
6304                        pw.print(rec.stepDetails.statPlatformIdleState);
6305                        pw.println();
6306
6307                        pw.print(", SubsystemPowerState ");
6308                        pw.print(rec.stepDetails.statSubsystemPowerState);
6309                        pw.println();
6310                    } else {
6311                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
6312                        pw.print(HISTORY_DATA); pw.print(",0,Dcpu=");
6313                        pw.print(rec.stepDetails.userTime);
6314                        pw.print(":");
6315                        pw.print(rec.stepDetails.systemTime);
6316                        if (rec.stepDetails.appCpuUid1 >= 0) {
6317                            printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid1,
6318                                    rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
6319                            if (rec.stepDetails.appCpuUid2 >= 0) {
6320                                printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid2,
6321                                        rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
6322                            }
6323                            if (rec.stepDetails.appCpuUid3 >= 0) {
6324                                printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid3,
6325                                        rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
6326                            }
6327                        }
6328                        pw.println();
6329                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
6330                        pw.print(HISTORY_DATA); pw.print(",0,Dpst=");
6331                        pw.print(rec.stepDetails.statUserTime);
6332                        pw.print(',');
6333                        pw.print(rec.stepDetails.statSystemTime);
6334                        pw.print(',');
6335                        pw.print(rec.stepDetails.statIOWaitTime);
6336                        pw.print(',');
6337                        pw.print(rec.stepDetails.statIrqTime);
6338                        pw.print(',');
6339                        pw.print(rec.stepDetails.statSoftIrqTime);
6340                        pw.print(',');
6341                        pw.print(rec.stepDetails.statIdlTime);
6342                        pw.print(',');
6343                        if (rec.stepDetails.statPlatformIdleState != null) {
6344                            pw.print(rec.stepDetails.statPlatformIdleState);
6345                            if (rec.stepDetails.statSubsystemPowerState != null) {
6346                                pw.print(',');
6347                            }
6348                        }
6349
6350                        if (rec.stepDetails.statSubsystemPowerState != null) {
6351                            pw.print(rec.stepDetails.statSubsystemPowerState);
6352                        }
6353                        pw.println();
6354                    }
6355                }
6356                oldState = rec.states;
6357                oldState2 = rec.states2;
6358            }
6359        }
6360
6361        private void printStepCpuUidDetails(PrintWriter pw, int uid, int utime, int stime) {
6362            UserHandle.formatUid(pw, uid);
6363            pw.print("=");
6364            pw.print(utime);
6365            pw.print("u+");
6366            pw.print(stime);
6367            pw.print("s");
6368        }
6369
6370        private void printStepCpuUidCheckinDetails(PrintWriter pw, int uid, int utime, int stime) {
6371            pw.print('/');
6372            pw.print(uid);
6373            pw.print(":");
6374            pw.print(utime);
6375            pw.print(":");
6376            pw.print(stime);
6377        }
6378    }
6379
6380    private void printSizeValue(PrintWriter pw, long size) {
6381        float result = size;
6382        String suffix = "";
6383        if (result >= 10*1024) {
6384            suffix = "KB";
6385            result = result / 1024;
6386        }
6387        if (result >= 10*1024) {
6388            suffix = "MB";
6389            result = result / 1024;
6390        }
6391        if (result >= 10*1024) {
6392            suffix = "GB";
6393            result = result / 1024;
6394        }
6395        if (result >= 10*1024) {
6396            suffix = "TB";
6397            result = result / 1024;
6398        }
6399        if (result >= 10*1024) {
6400            suffix = "PB";
6401            result = result / 1024;
6402        }
6403        pw.print((int)result);
6404        pw.print(suffix);
6405    }
6406
6407    private static boolean dumpTimeEstimate(PrintWriter pw, String label1, String label2,
6408            String label3, long estimatedTime) {
6409        if (estimatedTime < 0) {
6410            return false;
6411        }
6412        pw.print(label1);
6413        pw.print(label2);
6414        pw.print(label3);
6415        StringBuilder sb = new StringBuilder(64);
6416        formatTimeMs(sb, estimatedTime);
6417        pw.print(sb);
6418        pw.println();
6419        return true;
6420    }
6421
6422    private static boolean dumpDurationSteps(PrintWriter pw, String prefix, String header,
6423            LevelStepTracker steps, boolean checkin) {
6424        if (steps == null) {
6425            return false;
6426        }
6427        int count = steps.mNumStepDurations;
6428        if (count <= 0) {
6429            return false;
6430        }
6431        if (!checkin) {
6432            pw.println(header);
6433        }
6434        String[] lineArgs = new String[5];
6435        for (int i=0; i<count; i++) {
6436            long duration = steps.getDurationAt(i);
6437            int level = steps.getLevelAt(i);
6438            long initMode = steps.getInitModeAt(i);
6439            long modMode = steps.getModModeAt(i);
6440            if (checkin) {
6441                lineArgs[0] = Long.toString(duration);
6442                lineArgs[1] = Integer.toString(level);
6443                if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
6444                    switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
6445                        case Display.STATE_OFF: lineArgs[2] = "s-"; break;
6446                        case Display.STATE_ON: lineArgs[2] = "s+"; break;
6447                        case Display.STATE_DOZE: lineArgs[2] = "sd"; break;
6448                        case Display.STATE_DOZE_SUSPEND: lineArgs[2] = "sds"; break;
6449                        default: lineArgs[2] = "?"; break;
6450                    }
6451                } else {
6452                    lineArgs[2] = "";
6453                }
6454                if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
6455                    lineArgs[3] = (initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 ? "p+" : "p-";
6456                } else {
6457                    lineArgs[3] = "";
6458                }
6459                if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
6460                    lineArgs[4] = (initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0 ? "i+" : "i-";
6461                } else {
6462                    lineArgs[4] = "";
6463                }
6464                dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs);
6465            } else {
6466                pw.print(prefix);
6467                pw.print("#"); pw.print(i); pw.print(": ");
6468                TimeUtils.formatDuration(duration, pw);
6469                pw.print(" to "); pw.print(level);
6470                boolean haveModes = false;
6471                if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
6472                    pw.print(" (");
6473                    switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
6474                        case Display.STATE_OFF: pw.print("screen-off"); break;
6475                        case Display.STATE_ON: pw.print("screen-on"); break;
6476                        case Display.STATE_DOZE: pw.print("screen-doze"); break;
6477                        case Display.STATE_DOZE_SUSPEND: pw.print("screen-doze-suspend"); break;
6478                        default: pw.print("screen-?"); break;
6479                    }
6480                    haveModes = true;
6481                }
6482                if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
6483                    pw.print(haveModes ? ", " : " (");
6484                    pw.print((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0
6485                            ? "power-save-on" : "power-save-off");
6486                    haveModes = true;
6487                }
6488                if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
6489                    pw.print(haveModes ? ", " : " (");
6490                    pw.print((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0
6491                            ? "device-idle-on" : "device-idle-off");
6492                    haveModes = true;
6493                }
6494                if (haveModes) {
6495                    pw.print(")");
6496                }
6497                pw.println();
6498            }
6499        }
6500        return true;
6501    }
6502
6503    private static void dumpDurationSteps(ProtoOutputStream proto, long fieldId,
6504            LevelStepTracker steps) {
6505        if (steps == null) {
6506            return;
6507        }
6508        int count = steps.mNumStepDurations;
6509        for (int i = 0; i < count; ++i) {
6510            long token = proto.start(fieldId);
6511            proto.write(SystemProto.BatteryLevelStep.DURATION_MS, steps.getDurationAt(i));
6512            proto.write(SystemProto.BatteryLevelStep.LEVEL, steps.getLevelAt(i));
6513
6514            final long initMode = steps.getInitModeAt(i);
6515            final long modMode = steps.getModModeAt(i);
6516
6517            int ds = SystemProto.BatteryLevelStep.DS_MIXED;
6518            if ((modMode & STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
6519                switch ((int) (initMode & STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
6520                    case Display.STATE_OFF:
6521                        ds = SystemProto.BatteryLevelStep.DS_OFF;
6522                        break;
6523                    case Display.STATE_ON:
6524                        ds = SystemProto.BatteryLevelStep.DS_ON;
6525                        break;
6526                    case Display.STATE_DOZE:
6527                        ds = SystemProto.BatteryLevelStep.DS_DOZE;
6528                        break;
6529                    case Display.STATE_DOZE_SUSPEND:
6530                        ds = SystemProto.BatteryLevelStep.DS_DOZE_SUSPEND;
6531                        break;
6532                    default:
6533                        ds = SystemProto.BatteryLevelStep.DS_ERROR;
6534                        break;
6535                }
6536            }
6537            proto.write(SystemProto.BatteryLevelStep.DISPLAY_STATE, ds);
6538
6539            int psm = SystemProto.BatteryLevelStep.PSM_MIXED;
6540            if ((modMode & STEP_LEVEL_MODE_POWER_SAVE) == 0) {
6541                psm = (initMode & STEP_LEVEL_MODE_POWER_SAVE) != 0
6542                    ? SystemProto.BatteryLevelStep.PSM_ON : SystemProto.BatteryLevelStep.PSM_OFF;
6543            }
6544            proto.write(SystemProto.BatteryLevelStep.POWER_SAVE_MODE, psm);
6545
6546            int im = SystemProto.BatteryLevelStep.IM_MIXED;
6547            if ((modMode & STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
6548                im = (initMode & STEP_LEVEL_MODE_DEVICE_IDLE) != 0
6549                    ? SystemProto.BatteryLevelStep.IM_ON : SystemProto.BatteryLevelStep.IM_OFF;
6550            }
6551            proto.write(SystemProto.BatteryLevelStep.IDLE_MODE, im);
6552
6553            proto.end(token);
6554        }
6555    }
6556
6557    public static final int DUMP_CHARGED_ONLY = 1<<1;
6558    public static final int DUMP_DAILY_ONLY = 1<<2;
6559    public static final int DUMP_HISTORY_ONLY = 1<<3;
6560    public static final int DUMP_INCLUDE_HISTORY = 1<<4;
6561    public static final int DUMP_VERBOSE = 1<<5;
6562    public static final int DUMP_DEVICE_WIFI_ONLY = 1<<6;
6563
6564    private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
6565        final HistoryPrinter hprinter = new HistoryPrinter();
6566        final HistoryItem rec = new HistoryItem();
6567        long lastTime = -1;
6568        long baseTime = -1;
6569        boolean printed = false;
6570        HistoryEventTracker tracker = null;
6571        while (getNextHistoryLocked(rec)) {
6572            lastTime = rec.time;
6573            if (baseTime < 0) {
6574                baseTime = lastTime;
6575            }
6576            if (rec.time >= histStart) {
6577                if (histStart >= 0 && !printed) {
6578                    if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
6579                            || rec.cmd == HistoryItem.CMD_RESET
6580                            || rec.cmd == HistoryItem.CMD_START
6581                            || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
6582                        printed = true;
6583                        hprinter.printNextItem(pw, rec, baseTime, checkin,
6584                                (flags&DUMP_VERBOSE) != 0);
6585                        rec.cmd = HistoryItem.CMD_UPDATE;
6586                    } else if (rec.currentTime != 0) {
6587                        printed = true;
6588                        byte cmd = rec.cmd;
6589                        rec.cmd = HistoryItem.CMD_CURRENT_TIME;
6590                        hprinter.printNextItem(pw, rec, baseTime, checkin,
6591                                (flags&DUMP_VERBOSE) != 0);
6592                        rec.cmd = cmd;
6593                    }
6594                    if (tracker != null) {
6595                        if (rec.cmd != HistoryItem.CMD_UPDATE) {
6596                            hprinter.printNextItem(pw, rec, baseTime, checkin,
6597                                    (flags&DUMP_VERBOSE) != 0);
6598                            rec.cmd = HistoryItem.CMD_UPDATE;
6599                        }
6600                        int oldEventCode = rec.eventCode;
6601                        HistoryTag oldEventTag = rec.eventTag;
6602                        rec.eventTag = new HistoryTag();
6603                        for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
6604                            HashMap<String, SparseIntArray> active
6605                                    = tracker.getStateForEvent(i);
6606                            if (active == null) {
6607                                continue;
6608                            }
6609                            for (HashMap.Entry<String, SparseIntArray> ent
6610                                    : active.entrySet()) {
6611                                SparseIntArray uids = ent.getValue();
6612                                for (int j=0; j<uids.size(); j++) {
6613                                    rec.eventCode = i;
6614                                    rec.eventTag.string = ent.getKey();
6615                                    rec.eventTag.uid = uids.keyAt(j);
6616                                    rec.eventTag.poolIdx = uids.valueAt(j);
6617                                    hprinter.printNextItem(pw, rec, baseTime, checkin,
6618                                            (flags&DUMP_VERBOSE) != 0);
6619                                    rec.wakeReasonTag = null;
6620                                    rec.wakelockTag = null;
6621                                }
6622                            }
6623                        }
6624                        rec.eventCode = oldEventCode;
6625                        rec.eventTag = oldEventTag;
6626                        tracker = null;
6627                    }
6628                }
6629                hprinter.printNextItem(pw, rec, baseTime, checkin,
6630                        (flags&DUMP_VERBOSE) != 0);
6631            } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) {
6632                // This is an attempt to aggregate the previous state and generate
6633                // fake events to reflect that state at the point where we start
6634                // printing real events.  It doesn't really work right, so is turned off.
6635                if (tracker == null) {
6636                    tracker = new HistoryEventTracker();
6637                }
6638                tracker.updateState(rec.eventCode, rec.eventTag.string,
6639                        rec.eventTag.uid, rec.eventTag.poolIdx);
6640            }
6641        }
6642        if (histStart >= 0) {
6643            commitCurrentHistoryBatchLocked();
6644            pw.print(checkin ? "NEXT: " : "  NEXT: "); pw.println(lastTime+1);
6645        }
6646    }
6647
6648    private void dumpDailyLevelStepSummary(PrintWriter pw, String prefix, String label,
6649            LevelStepTracker steps, StringBuilder tmpSb, int[] tmpOutInt) {
6650        if (steps == null) {
6651            return;
6652        }
6653        long timeRemaining = steps.computeTimeEstimate(0, 0, tmpOutInt);
6654        if (timeRemaining >= 0) {
6655            pw.print(prefix); pw.print(label); pw.print(" total time: ");
6656            tmpSb.setLength(0);
6657            formatTimeMs(tmpSb, timeRemaining);
6658            pw.print(tmpSb);
6659            pw.print(" (from "); pw.print(tmpOutInt[0]);
6660            pw.println(" steps)");
6661        }
6662        for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
6663            long estimatedTime = steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
6664                    STEP_LEVEL_MODE_VALUES[i], tmpOutInt);
6665            if (estimatedTime > 0) {
6666                pw.print(prefix); pw.print(label); pw.print(" ");
6667                pw.print(STEP_LEVEL_MODE_LABELS[i]);
6668                pw.print(" time: ");
6669                tmpSb.setLength(0);
6670                formatTimeMs(tmpSb, estimatedTime);
6671                pw.print(tmpSb);
6672                pw.print(" (from "); pw.print(tmpOutInt[0]);
6673                pw.println(" steps)");
6674            }
6675        }
6676    }
6677
6678    private void dumpDailyPackageChanges(PrintWriter pw, String prefix,
6679            ArrayList<PackageChange> changes) {
6680        if (changes == null) {
6681            return;
6682        }
6683        pw.print(prefix); pw.println("Package changes:");
6684        for (int i=0; i<changes.size(); i++) {
6685            PackageChange pc = changes.get(i);
6686            if (pc.mUpdate) {
6687                pw.print(prefix); pw.print("  Update "); pw.print(pc.mPackageName);
6688                pw.print(" vers="); pw.println(pc.mVersionCode);
6689            } else {
6690                pw.print(prefix); pw.print("  Uninstall "); pw.println(pc.mPackageName);
6691            }
6692        }
6693    }
6694
6695    /**
6696     * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
6697     *
6698     * @param pw a Printer to receive the dump output.
6699     */
6700    @SuppressWarnings("unused")
6701    public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
6702        prepareForDumpLocked();
6703
6704        final boolean filtering = (flags
6705                & (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
6706
6707        if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
6708            final long historyTotalSize = getHistoryTotalSize();
6709            final long historyUsedSize = getHistoryUsedSize();
6710            if (startIteratingHistoryLocked()) {
6711                try {
6712                    pw.print("Battery History (");
6713                    pw.print((100*historyUsedSize)/historyTotalSize);
6714                    pw.print("% used, ");
6715                    printSizeValue(pw, historyUsedSize);
6716                    pw.print(" used of ");
6717                    printSizeValue(pw, historyTotalSize);
6718                    pw.print(", ");
6719                    pw.print(getHistoryStringPoolSize());
6720                    pw.print(" strings using ");
6721                    printSizeValue(pw, getHistoryStringPoolBytes());
6722                    pw.println("):");
6723                    dumpHistoryLocked(pw, flags, histStart, false);
6724                    pw.println();
6725                } finally {
6726                    finishIteratingHistoryLocked();
6727                }
6728            }
6729
6730            if (startIteratingOldHistoryLocked()) {
6731                try {
6732                    final HistoryItem rec = new HistoryItem();
6733                    pw.println("Old battery History:");
6734                    HistoryPrinter hprinter = new HistoryPrinter();
6735                    long baseTime = -1;
6736                    while (getNextOldHistoryLocked(rec)) {
6737                        if (baseTime < 0) {
6738                            baseTime = rec.time;
6739                        }
6740                        hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0);
6741                    }
6742                    pw.println();
6743                } finally {
6744                    finishIteratingOldHistoryLocked();
6745                }
6746            }
6747        }
6748
6749        if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
6750            return;
6751        }
6752
6753        if (!filtering) {
6754            SparseArray<? extends Uid> uidStats = getUidStats();
6755            final int NU = uidStats.size();
6756            boolean didPid = false;
6757            long nowRealtime = SystemClock.elapsedRealtime();
6758            for (int i=0; i<NU; i++) {
6759                Uid uid = uidStats.valueAt(i);
6760                SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
6761                if (pids != null) {
6762                    for (int j=0; j<pids.size(); j++) {
6763                        Uid.Pid pid = pids.valueAt(j);
6764                        if (!didPid) {
6765                            pw.println("Per-PID Stats:");
6766                            didPid = true;
6767                        }
6768                        long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
6769                                ? (nowRealtime - pid.mWakeStartMs) : 0);
6770                        pw.print("  PID "); pw.print(pids.keyAt(j));
6771                                pw.print(" wake time: ");
6772                                TimeUtils.formatDuration(time, pw);
6773                                pw.println("");
6774                    }
6775                }
6776            }
6777            if (didPid) {
6778                pw.println();
6779            }
6780        }
6781
6782        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
6783            if (dumpDurationSteps(pw, "  ", "Discharge step durations:",
6784                    getDischargeLevelStepTracker(), false)) {
6785                long timeRemaining = computeBatteryTimeRemaining(
6786                    SystemClock.elapsedRealtime() * 1000);
6787                if (timeRemaining >= 0) {
6788                    pw.print("  Estimated discharge time remaining: ");
6789                    TimeUtils.formatDuration(timeRemaining / 1000, pw);
6790                    pw.println();
6791                }
6792                final LevelStepTracker steps = getDischargeLevelStepTracker();
6793                for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
6794                    dumpTimeEstimate(pw, "  Estimated ", STEP_LEVEL_MODE_LABELS[i], " time: ",
6795                            steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
6796                                    STEP_LEVEL_MODE_VALUES[i], null));
6797                }
6798                pw.println();
6799            }
6800            if (dumpDurationSteps(pw, "  ", "Charge step durations:",
6801                    getChargeLevelStepTracker(), false)) {
6802                long timeRemaining = computeChargeTimeRemaining(
6803                    SystemClock.elapsedRealtime() * 1000);
6804                if (timeRemaining >= 0) {
6805                    pw.print("  Estimated charge time remaining: ");
6806                    TimeUtils.formatDuration(timeRemaining / 1000, pw);
6807                    pw.println();
6808                }
6809                pw.println();
6810            }
6811        }
6812        if (!filtering || (flags & DUMP_DAILY_ONLY) != 0) {
6813            pw.println("Daily stats:");
6814            pw.print("  Current start time: ");
6815            pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6816                    getCurrentDailyStartTime()).toString());
6817            pw.print("  Next min deadline: ");
6818            pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6819                    getNextMinDailyDeadline()).toString());
6820            pw.print("  Next max deadline: ");
6821            pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6822                    getNextMaxDailyDeadline()).toString());
6823            StringBuilder sb = new StringBuilder(64);
6824            int[] outInt = new int[1];
6825            LevelStepTracker dsteps = getDailyDischargeLevelStepTracker();
6826            LevelStepTracker csteps = getDailyChargeLevelStepTracker();
6827            ArrayList<PackageChange> pkgc = getDailyPackageChanges();
6828            if (dsteps.mNumStepDurations > 0 || csteps.mNumStepDurations > 0 || pkgc != null) {
6829                if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
6830                    if (dumpDurationSteps(pw, "    ", "  Current daily discharge step durations:",
6831                            dsteps, false)) {
6832                        dumpDailyLevelStepSummary(pw, "      ", "Discharge", dsteps,
6833                                sb, outInt);
6834                    }
6835                    if (dumpDurationSteps(pw, "    ", "  Current daily charge step durations:",
6836                            csteps, false)) {
6837                        dumpDailyLevelStepSummary(pw, "      ", "Charge", csteps,
6838                                sb, outInt);
6839                    }
6840                    dumpDailyPackageChanges(pw, "    ", pkgc);
6841                } else {
6842                    pw.println("  Current daily steps:");
6843                    dumpDailyLevelStepSummary(pw, "    ", "Discharge", dsteps,
6844                            sb, outInt);
6845                    dumpDailyLevelStepSummary(pw, "    ", "Charge", csteps,
6846                            sb, outInt);
6847                }
6848            }
6849            DailyItem dit;
6850            int curIndex = 0;
6851            while ((dit=getDailyItemLocked(curIndex)) != null) {
6852                curIndex++;
6853                if ((flags&DUMP_DAILY_ONLY) != 0) {
6854                    pw.println();
6855                }
6856                pw.print("  Daily from ");
6857                pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mStartTime).toString());
6858                pw.print(" to ");
6859                pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mEndTime).toString());
6860                pw.println(":");
6861                if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
6862                    if (dumpDurationSteps(pw, "      ",
6863                            "    Discharge step durations:", dit.mDischargeSteps, false)) {
6864                        dumpDailyLevelStepSummary(pw, "        ", "Discharge", dit.mDischargeSteps,
6865                                sb, outInt);
6866                    }
6867                    if (dumpDurationSteps(pw, "      ",
6868                            "    Charge step durations:", dit.mChargeSteps, false)) {
6869                        dumpDailyLevelStepSummary(pw, "        ", "Charge", dit.mChargeSteps,
6870                                sb, outInt);
6871                    }
6872                    dumpDailyPackageChanges(pw, "    ", dit.mPackageChanges);
6873                } else {
6874                    dumpDailyLevelStepSummary(pw, "    ", "Discharge", dit.mDischargeSteps,
6875                            sb, outInt);
6876                    dumpDailyLevelStepSummary(pw, "    ", "Charge", dit.mChargeSteps,
6877                            sb, outInt);
6878                }
6879            }
6880            pw.println();
6881        }
6882        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
6883            pw.println("Statistics since last charge:");
6884            pw.println("  System starts: " + getStartCount()
6885                    + ", currently on battery: " + getIsOnBattery());
6886            dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
6887                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
6888            pw.println();
6889        }
6890    }
6891
6892    // This is called from BatteryStatsService.
6893    @SuppressWarnings("unused")
6894    public void dumpCheckinLocked(Context context, PrintWriter pw,
6895            List<ApplicationInfo> apps, int flags, long histStart) {
6896        prepareForDumpLocked();
6897
6898        dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
6899                CHECKIN_VERSION, getParcelVersion(), getStartPlatformVersion(),
6900                getEndPlatformVersion());
6901
6902        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
6903
6904        if ((flags & (DUMP_INCLUDE_HISTORY | DUMP_HISTORY_ONLY)) != 0) {
6905            if (startIteratingHistoryLocked()) {
6906                try {
6907                    for (int i=0; i<getHistoryStringPoolSize(); i++) {
6908                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
6909                        pw.print(HISTORY_STRING_POOL); pw.print(',');
6910                        pw.print(i);
6911                        pw.print(",");
6912                        pw.print(getHistoryTagPoolUid(i));
6913                        pw.print(",\"");
6914                        String str = getHistoryTagPoolString(i);
6915                        str = str.replace("\\", "\\\\");
6916                        str = str.replace("\"", "\\\"");
6917                        pw.print(str);
6918                        pw.print("\"");
6919                        pw.println();
6920                    }
6921                    dumpHistoryLocked(pw, flags, histStart, true);
6922                } finally {
6923                    finishIteratingHistoryLocked();
6924                }
6925            }
6926        }
6927
6928        if ((flags & DUMP_HISTORY_ONLY) != 0) {
6929            return;
6930        }
6931
6932        if (apps != null) {
6933            SparseArray<Pair<ArrayList<String>, MutableBoolean>> uids = new SparseArray<>();
6934            for (int i=0; i<apps.size(); i++) {
6935                ApplicationInfo ai = apps.get(i);
6936                Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(
6937                        UserHandle.getAppId(ai.uid));
6938                if (pkgs == null) {
6939                    pkgs = new Pair<>(new ArrayList<String>(), new MutableBoolean(false));
6940                    uids.put(UserHandle.getAppId(ai.uid), pkgs);
6941                }
6942                pkgs.first.add(ai.packageName);
6943            }
6944            SparseArray<? extends Uid> uidStats = getUidStats();
6945            final int NU = uidStats.size();
6946            String[] lineArgs = new String[2];
6947            for (int i=0; i<NU; i++) {
6948                int uid = UserHandle.getAppId(uidStats.keyAt(i));
6949                Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(uid);
6950                if (pkgs != null && !pkgs.second.value) {
6951                    pkgs.second.value = true;
6952                    for (int j=0; j<pkgs.first.size(); j++) {
6953                        lineArgs[0] = Integer.toString(uid);
6954                        lineArgs[1] = pkgs.first.get(j);
6955                        dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
6956                                (Object[])lineArgs);
6957                    }
6958                }
6959            }
6960        }
6961        if ((flags & DUMP_DAILY_ONLY) == 0) {
6962            dumpDurationSteps(pw, "", DISCHARGE_STEP_DATA, getDischargeLevelStepTracker(), true);
6963            String[] lineArgs = new String[1];
6964            long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime() * 1000);
6965            if (timeRemaining >= 0) {
6966                lineArgs[0] = Long.toString(timeRemaining);
6967                dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA,
6968                        (Object[])lineArgs);
6969            }
6970            dumpDurationSteps(pw, "", CHARGE_STEP_DATA, getChargeLevelStepTracker(), true);
6971            timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime() * 1000);
6972            if (timeRemaining >= 0) {
6973                lineArgs[0] = Long.toString(timeRemaining);
6974                dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA,
6975                        (Object[])lineArgs);
6976            }
6977            dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
6978                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
6979        }
6980    }
6981
6982    /** Dump #STATS_SINCE_CHARGED batterystats data to a proto. @hide */
6983    public void dumpProtoLocked(Context context, FileDescriptor fd, List<ApplicationInfo> apps,
6984            int flags) {
6985        final ProtoOutputStream proto = new ProtoOutputStream(fd);
6986        final long bToken = proto.start(BatteryStatsServiceDumpProto.BATTERYSTATS);
6987        prepareForDumpLocked();
6988
6989        proto.write(BatteryStatsProto.REPORT_VERSION, CHECKIN_VERSION);
6990        proto.write(BatteryStatsProto.PARCEL_VERSION, getParcelVersion());
6991        proto.write(BatteryStatsProto.START_PLATFORM_VERSION, getStartPlatformVersion());
6992        proto.write(BatteryStatsProto.END_PLATFORM_VERSION, getEndPlatformVersion());
6993
6994        // History intentionally not included in proto dump.
6995
6996        if ((flags & (DUMP_HISTORY_ONLY | DUMP_DAILY_ONLY)) == 0) {
6997            final BatteryStatsHelper helper = new BatteryStatsHelper(context, false,
6998                    (flags & DUMP_DEVICE_WIFI_ONLY) != 0);
6999            helper.create(this);
7000            helper.refreshStats(STATS_SINCE_CHARGED, UserHandle.USER_ALL);
7001
7002            dumpProtoAppsLocked(proto, helper, apps);
7003            dumpProtoSystemLocked(proto, helper);
7004        }
7005
7006        proto.end(bToken);
7007        proto.flush();
7008    }
7009
7010    private void dumpProtoAppsLocked(ProtoOutputStream proto, BatteryStatsHelper helper,
7011            List<ApplicationInfo> apps) {
7012        final int which = STATS_SINCE_CHARGED;
7013        final long rawUptimeUs = SystemClock.uptimeMillis() * 1000;
7014        final long rawRealtimeMs = SystemClock.elapsedRealtime();
7015        final long rawRealtimeUs = rawRealtimeMs * 1000;
7016        final long batteryUptimeUs = getBatteryUptime(rawUptimeUs);
7017
7018        SparseArray<ArrayList<String>> aidToPackages = new SparseArray<>();
7019        if (apps != null) {
7020            for (int i = 0; i < apps.size(); ++i) {
7021                ApplicationInfo ai = apps.get(i);
7022                int aid = UserHandle.getAppId(ai.uid);
7023                ArrayList<String> pkgs = aidToPackages.get(aid);
7024                if (pkgs == null) {
7025                    pkgs = new ArrayList<String>();
7026                    aidToPackages.put(aid, pkgs);
7027                }
7028                pkgs.add(ai.packageName);
7029            }
7030        }
7031
7032        SparseArray<BatterySipper> uidToSipper = new SparseArray<>();
7033        final List<BatterySipper> sippers = helper.getUsageList();
7034        if (sippers != null) {
7035            for (int i = 0; i < sippers.size(); ++i) {
7036                final BatterySipper bs = sippers.get(i);
7037                if (bs.drainType != BatterySipper.DrainType.APP) {
7038                    // Others are handled by dumpProtoSystemLocked()
7039                    continue;
7040                }
7041                uidToSipper.put(bs.uidObj.getUid(), bs);
7042            }
7043        }
7044
7045        SparseArray<? extends Uid> uidStats = getUidStats();
7046        final int n = uidStats.size();
7047        for (int iu = 0; iu < n; ++iu) {
7048            final long uTkn = proto.start(BatteryStatsProto.UIDS);
7049            final Uid u = uidStats.valueAt(iu);
7050
7051            final int uid = uidStats.keyAt(iu);
7052            proto.write(UidProto.UID, uid);
7053
7054            // Print packages and apk stats (UID_DATA & APK_DATA)
7055            ArrayList<String> pkgs = aidToPackages.get(UserHandle.getAppId(uid));
7056            if (pkgs == null) {
7057                pkgs = new ArrayList<String>();
7058            }
7059            final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats =
7060                    u.getPackageStats();
7061            for (int ipkg = packageStats.size() - 1; ipkg >= 0; --ipkg) {
7062                String pkg = packageStats.keyAt(ipkg);
7063                final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats =
7064                        packageStats.valueAt(ipkg).getServiceStats();
7065                if (serviceStats.size() == 0) {
7066                    // Due to the way ActivityManagerService logs wakeup alarms, some packages (for
7067                    // example, "android") may be included in the packageStats that aren't part of
7068                    // the UID. If they don't have any services, then they shouldn't be listed here.
7069                    // These packages won't be a part in the pkgs List.
7070                    continue;
7071                }
7072
7073                final long pToken = proto.start(UidProto.PACKAGES);
7074                proto.write(UidProto.Package.NAME, pkg);
7075                // Remove from the packages list since we're logging it here.
7076                pkgs.remove(pkg);
7077
7078                for (int isvc = serviceStats.size() - 1; isvc >= 0; --isvc) {
7079                    final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
7080                    long sToken = proto.start(UidProto.Package.SERVICES);
7081
7082                    proto.write(UidProto.Package.Service.NAME, serviceStats.keyAt(isvc));
7083                    proto.write(UidProto.Package.Service.START_DURATION_MS,
7084                            roundUsToMs(ss.getStartTime(batteryUptimeUs, which)));
7085                    proto.write(UidProto.Package.Service.START_COUNT, ss.getStarts(which));
7086                    proto.write(UidProto.Package.Service.LAUNCH_COUNT, ss.getLaunches(which));
7087
7088                    proto.end(sToken);
7089                }
7090                proto.end(pToken);
7091            }
7092            // Print any remaining packages that weren't in the packageStats map. pkgs is pulled
7093            // from PackageManager data. Packages are only included in packageStats if there was
7094            // specific data tracked for them (services and wakeup alarms, etc.).
7095            for (String p : pkgs) {
7096                final long pToken = proto.start(UidProto.PACKAGES);
7097                proto.write(UidProto.Package.NAME, p);
7098                proto.end(pToken);
7099            }
7100
7101            // Total wakelock data (AGGREGATED_WAKELOCK_DATA)
7102            if (u.getAggregatedPartialWakelockTimer() != null) {
7103                final Timer timer = u.getAggregatedPartialWakelockTimer();
7104                // Times are since reset (regardless of 'which')
7105                final long totTimeMs = timer.getTotalDurationMsLocked(rawRealtimeMs);
7106                final Timer bgTimer = timer.getSubTimer();
7107                final long bgTimeMs = bgTimer != null
7108                        ? bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
7109                final long awToken = proto.start(UidProto.AGGREGATED_WAKELOCK);
7110                proto.write(UidProto.AggregatedWakelock.PARTIAL_DURATION_MS, totTimeMs);
7111                proto.write(UidProto.AggregatedWakelock.BACKGROUND_PARTIAL_DURATION_MS, bgTimeMs);
7112                proto.end(awToken);
7113            }
7114
7115            // Audio (AUDIO_DATA)
7116            dumpTimer(proto, UidProto.AUDIO, u.getAudioTurnedOnTimer(), rawRealtimeUs, which);
7117
7118            // Bluetooth Controller (BLUETOOTH_CONTROLLER_DATA)
7119            dumpControllerActivityProto(proto, UidProto.BLUETOOTH_CONTROLLER,
7120                    u.getBluetoothControllerActivity(), which);
7121
7122            // BLE scans (BLUETOOTH_MISC_DATA) (uses totalDurationMsLocked and MaxDurationMsLocked)
7123            final Timer bleTimer = u.getBluetoothScanTimer();
7124            if (bleTimer != null) {
7125                final long bmToken = proto.start(UidProto.BLUETOOTH_MISC);
7126
7127                dumpTimer(proto, UidProto.BluetoothMisc.APPORTIONED_BLE_SCAN, bleTimer,
7128                        rawRealtimeUs, which);
7129                dumpTimer(proto, UidProto.BluetoothMisc.BACKGROUND_BLE_SCAN,
7130                        u.getBluetoothScanBackgroundTimer(), rawRealtimeUs, which);
7131                // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
7132                dumpTimer(proto, UidProto.BluetoothMisc.UNOPTIMIZED_BLE_SCAN,
7133                        u.getBluetoothUnoptimizedScanTimer(), rawRealtimeUs, which);
7134                // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
7135                dumpTimer(proto, UidProto.BluetoothMisc.BACKGROUND_UNOPTIMIZED_BLE_SCAN,
7136                        u.getBluetoothUnoptimizedScanBackgroundTimer(), rawRealtimeUs, which);
7137                // Result counters
7138                proto.write(UidProto.BluetoothMisc.BLE_SCAN_RESULT_COUNT,
7139                        u.getBluetoothScanResultCounter() != null
7140                            ? u.getBluetoothScanResultCounter().getCountLocked(which) : 0);
7141                proto.write(UidProto.BluetoothMisc.BACKGROUND_BLE_SCAN_RESULT_COUNT,
7142                        u.getBluetoothScanResultBgCounter() != null
7143                            ? u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0);
7144
7145                proto.end(bmToken);
7146            }
7147
7148            // Camera (CAMERA_DATA)
7149            dumpTimer(proto, UidProto.CAMERA, u.getCameraTurnedOnTimer(), rawRealtimeUs, which);
7150
7151            // CPU stats (CPU_DATA & CPU_TIMES_AT_FREQ_DATA)
7152            final long cpuToken = proto.start(UidProto.CPU);
7153            proto.write(UidProto.Cpu.USER_DURATION_MS, roundUsToMs(u.getUserCpuTimeUs(which)));
7154            proto.write(UidProto.Cpu.SYSTEM_DURATION_MS, roundUsToMs(u.getSystemCpuTimeUs(which)));
7155
7156            final long[] cpuFreqs = getCpuFreqs();
7157            if (cpuFreqs != null) {
7158                final long[] cpuFreqTimeMs = u.getCpuFreqTimes(which);
7159                // If total cpuFreqTimes is null, then we don't need to check for
7160                // screenOffCpuFreqTimes.
7161                if (cpuFreqTimeMs != null && cpuFreqTimeMs.length == cpuFreqs.length) {
7162                    long[] screenOffCpuFreqTimeMs = u.getScreenOffCpuFreqTimes(which);
7163                    if (screenOffCpuFreqTimeMs == null) {
7164                        screenOffCpuFreqTimeMs = new long[cpuFreqTimeMs.length];
7165                    }
7166                    for (int ic = 0; ic < cpuFreqTimeMs.length; ++ic) {
7167                        long cToken = proto.start(UidProto.Cpu.BY_FREQUENCY);
7168                        proto.write(UidProto.Cpu.ByFrequency.FREQUENCY_INDEX, ic + 1);
7169                        proto.write(UidProto.Cpu.ByFrequency.TOTAL_DURATION_MS,
7170                                cpuFreqTimeMs[ic]);
7171                        proto.write(UidProto.Cpu.ByFrequency.SCREEN_OFF_DURATION_MS,
7172                                screenOffCpuFreqTimeMs[ic]);
7173                        proto.end(cToken);
7174                    }
7175                }
7176            }
7177
7178            for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
7179                final long[] timesMs = u.getCpuFreqTimes(which, procState);
7180                if (timesMs != null && timesMs.length == cpuFreqs.length) {
7181                    long[] screenOffTimesMs = u.getScreenOffCpuFreqTimes(which, procState);
7182                    if (screenOffTimesMs == null) {
7183                        screenOffTimesMs = new long[timesMs.length];
7184                    }
7185                    final long procToken = proto.start(UidProto.Cpu.BY_PROCESS_STATE);
7186                    proto.write(UidProto.Cpu.ByProcessState.PROCESS_STATE, procState);
7187                    for (int ic = 0; ic < timesMs.length; ++ic) {
7188                        long cToken = proto.start(UidProto.Cpu.ByProcessState.BY_FREQUENCY);
7189                        proto.write(UidProto.Cpu.ByFrequency.FREQUENCY_INDEX, ic + 1);
7190                        proto.write(UidProto.Cpu.ByFrequency.TOTAL_DURATION_MS,
7191                                timesMs[ic]);
7192                        proto.write(UidProto.Cpu.ByFrequency.SCREEN_OFF_DURATION_MS,
7193                                screenOffTimesMs[ic]);
7194                        proto.end(cToken);
7195                    }
7196                    proto.end(procToken);
7197                }
7198            }
7199            proto.end(cpuToken);
7200
7201            // Flashlight (FLASHLIGHT_DATA)
7202            dumpTimer(proto, UidProto.FLASHLIGHT, u.getFlashlightTurnedOnTimer(),
7203                    rawRealtimeUs, which);
7204
7205            // Foreground activity (FOREGROUND_ACTIVITY_DATA)
7206            dumpTimer(proto, UidProto.FOREGROUND_ACTIVITY, u.getForegroundActivityTimer(),
7207                    rawRealtimeUs, which);
7208
7209            // Foreground service (FOREGROUND_SERVICE_DATA)
7210            dumpTimer(proto, UidProto.FOREGROUND_SERVICE, u.getForegroundServiceTimer(),
7211                    rawRealtimeUs, which);
7212
7213            // Job completion (JOB_COMPLETION_DATA)
7214            final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
7215            final int[] reasons = new int[]{
7216                JobParameters.REASON_CANCELED,
7217                JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED,
7218                JobParameters.REASON_PREEMPT,
7219                JobParameters.REASON_TIMEOUT,
7220                JobParameters.REASON_DEVICE_IDLE,
7221            };
7222            for (int ic = 0; ic < completions.size(); ++ic) {
7223                SparseIntArray types = completions.valueAt(ic);
7224                if (types != null) {
7225                    final long jcToken = proto.start(UidProto.JOB_COMPLETION);
7226
7227                    proto.write(UidProto.JobCompletion.NAME, completions.keyAt(ic));
7228
7229                    for (int r : reasons) {
7230                        long rToken = proto.start(UidProto.JobCompletion.REASON_COUNT);
7231                        proto.write(UidProto.JobCompletion.ReasonCount.NAME, r);
7232                        proto.write(UidProto.JobCompletion.ReasonCount.COUNT, types.get(r, 0));
7233                        proto.end(rToken);
7234                    }
7235
7236                    proto.end(jcToken);
7237                }
7238            }
7239
7240            // Scheduled jobs (JOB_DATA)
7241            final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
7242            for (int ij = jobs.size() - 1; ij >= 0; --ij) {
7243                final Timer timer = jobs.valueAt(ij);
7244                final Timer bgTimer = timer.getSubTimer();
7245                final long jToken = proto.start(UidProto.JOBS);
7246
7247                proto.write(UidProto.Job.NAME, jobs.keyAt(ij));
7248                // Background uses totalDurationMsLocked, while total uses totalTimeLocked
7249                dumpTimer(proto, UidProto.Job.TOTAL, timer, rawRealtimeUs, which);
7250                dumpTimer(proto, UidProto.Job.BACKGROUND, bgTimer, rawRealtimeUs, which);
7251
7252                proto.end(jToken);
7253            }
7254
7255            // Modem Controller (MODEM_CONTROLLER_DATA)
7256            dumpControllerActivityProto(proto, UidProto.MODEM_CONTROLLER,
7257                    u.getModemControllerActivity(), which);
7258
7259            // Network stats (NETWORK_DATA)
7260            final long nToken = proto.start(UidProto.NETWORK);
7261            proto.write(UidProto.Network.MOBILE_BYTES_RX,
7262                    u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which));
7263            proto.write(UidProto.Network.MOBILE_BYTES_TX,
7264                    u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which));
7265            proto.write(UidProto.Network.WIFI_BYTES_RX,
7266                    u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
7267            proto.write(UidProto.Network.WIFI_BYTES_TX,
7268                    u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
7269            proto.write(UidProto.Network.BT_BYTES_RX,
7270                    u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which));
7271            proto.write(UidProto.Network.BT_BYTES_TX,
7272                    u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which));
7273            proto.write(UidProto.Network.MOBILE_PACKETS_RX,
7274                    u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which));
7275            proto.write(UidProto.Network.MOBILE_PACKETS_TX,
7276                    u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which));
7277            proto.write(UidProto.Network.WIFI_PACKETS_RX,
7278                    u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
7279            proto.write(UidProto.Network.WIFI_PACKETS_TX,
7280                    u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
7281            proto.write(UidProto.Network.MOBILE_ACTIVE_DURATION_MS,
7282                    roundUsToMs(u.getMobileRadioActiveTime(which)));
7283            proto.write(UidProto.Network.MOBILE_ACTIVE_COUNT,
7284                    u.getMobileRadioActiveCount(which));
7285            proto.write(UidProto.Network.MOBILE_WAKEUP_COUNT,
7286                    u.getMobileRadioApWakeupCount(which));
7287            proto.write(UidProto.Network.WIFI_WAKEUP_COUNT,
7288                    u.getWifiRadioApWakeupCount(which));
7289            proto.write(UidProto.Network.MOBILE_BYTES_BG_RX,
7290                    u.getNetworkActivityBytes(NETWORK_MOBILE_BG_RX_DATA, which));
7291            proto.write(UidProto.Network.MOBILE_BYTES_BG_TX,
7292                    u.getNetworkActivityBytes(NETWORK_MOBILE_BG_TX_DATA, which));
7293            proto.write(UidProto.Network.WIFI_BYTES_BG_RX,
7294                    u.getNetworkActivityBytes(NETWORK_WIFI_BG_RX_DATA, which));
7295            proto.write(UidProto.Network.WIFI_BYTES_BG_TX,
7296                    u.getNetworkActivityBytes(NETWORK_WIFI_BG_TX_DATA, which));
7297            proto.write(UidProto.Network.MOBILE_PACKETS_BG_RX,
7298                    u.getNetworkActivityPackets(NETWORK_MOBILE_BG_RX_DATA, which));
7299            proto.write(UidProto.Network.MOBILE_PACKETS_BG_TX,
7300                    u.getNetworkActivityPackets(NETWORK_MOBILE_BG_TX_DATA, which));
7301            proto.write(UidProto.Network.WIFI_PACKETS_BG_RX,
7302                    u.getNetworkActivityPackets(NETWORK_WIFI_BG_RX_DATA, which));
7303            proto.write(UidProto.Network.WIFI_PACKETS_BG_TX,
7304                    u.getNetworkActivityPackets(NETWORK_WIFI_BG_TX_DATA, which));
7305            proto.end(nToken);
7306
7307            // Power use item (POWER_USE_ITEM_DATA)
7308            BatterySipper bs = uidToSipper.get(uid);
7309            if (bs != null) {
7310                final long bsToken = proto.start(UidProto.POWER_USE_ITEM);
7311                proto.write(UidProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah);
7312                proto.write(UidProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide);
7313                proto.write(UidProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah);
7314                proto.write(UidProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH,
7315                        bs.proportionalSmearMah);
7316                proto.end(bsToken);
7317            }
7318
7319            // Processes (PROCESS_DATA)
7320            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats =
7321                    u.getProcessStats();
7322            for (int ipr = processStats.size() - 1; ipr >= 0; --ipr) {
7323                final Uid.Proc ps = processStats.valueAt(ipr);
7324                final long prToken = proto.start(UidProto.PROCESS);
7325
7326                proto.write(UidProto.Process.NAME, processStats.keyAt(ipr));
7327                proto.write(UidProto.Process.USER_DURATION_MS, ps.getUserTime(which));
7328                proto.write(UidProto.Process.SYSTEM_DURATION_MS, ps.getSystemTime(which));
7329                proto.write(UidProto.Process.FOREGROUND_DURATION_MS, ps.getForegroundTime(which));
7330                proto.write(UidProto.Process.START_COUNT, ps.getStarts(which));
7331                proto.write(UidProto.Process.ANR_COUNT, ps.getNumAnrs(which));
7332                proto.write(UidProto.Process.CRASH_COUNT, ps.getNumCrashes(which));
7333
7334                proto.end(prToken);
7335            }
7336
7337            // Sensors (SENSOR_DATA)
7338            final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
7339            for (int ise = 0; ise < sensors.size(); ++ise) {
7340                final Uid.Sensor se = sensors.valueAt(ise);
7341                final Timer timer = se.getSensorTime();
7342                if (timer == null) {
7343                    continue;
7344                }
7345                final Timer bgTimer = se.getSensorBackgroundTime();
7346                final int sensorNumber = sensors.keyAt(ise);
7347                final long seToken = proto.start(UidProto.SENSORS);
7348
7349                proto.write(UidProto.Sensor.ID, sensorNumber);
7350                // Background uses totalDurationMsLocked, while total uses totalTimeLocked
7351                dumpTimer(proto, UidProto.Sensor.APPORTIONED, timer, rawRealtimeUs, which);
7352                dumpTimer(proto, UidProto.Sensor.BACKGROUND, bgTimer, rawRealtimeUs, which);
7353
7354                proto.end(seToken);
7355            }
7356
7357            // State times (STATE_TIME_DATA)
7358            for (int ips = 0; ips < Uid.NUM_PROCESS_STATE; ++ips) {
7359                long durMs = roundUsToMs(u.getProcessStateTime(ips, rawRealtimeUs, which));
7360                if (durMs == 0) {
7361                    continue;
7362                }
7363                final long stToken = proto.start(UidProto.STATES);
7364                proto.write(UidProto.StateTime.STATE, ips);
7365                proto.write(UidProto.StateTime.DURATION_MS, durMs);
7366                proto.end(stToken);
7367            }
7368
7369            // Syncs (SYNC_DATA)
7370            final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
7371            for (int isy = syncs.size() - 1; isy >= 0; --isy) {
7372                final Timer timer = syncs.valueAt(isy);
7373                final Timer bgTimer = timer.getSubTimer();
7374                final long syToken = proto.start(UidProto.SYNCS);
7375
7376                proto.write(UidProto.Sync.NAME, syncs.keyAt(isy));
7377                // Background uses totalDurationMsLocked, while total uses totalTimeLocked
7378                dumpTimer(proto, UidProto.Sync.TOTAL, timer, rawRealtimeUs, which);
7379                dumpTimer(proto, UidProto.Sync.BACKGROUND, bgTimer, rawRealtimeUs, which);
7380
7381                proto.end(syToken);
7382            }
7383
7384            // User activity (USER_ACTIVITY_DATA)
7385            if (u.hasUserActivity()) {
7386                for (int i = 0; i < Uid.NUM_USER_ACTIVITY_TYPES; ++i) {
7387                    int val = u.getUserActivityCount(i, which);
7388                    if (val != 0) {
7389                        final long uaToken = proto.start(UidProto.USER_ACTIVITY);
7390                        proto.write(UidProto.UserActivity.NAME, i);
7391                        proto.write(UidProto.UserActivity.COUNT, val);
7392                        proto.end(uaToken);
7393                    }
7394                }
7395            }
7396
7397            // Vibrator (VIBRATOR_DATA)
7398            dumpTimer(proto, UidProto.VIBRATOR, u.getVibratorOnTimer(), rawRealtimeUs, which);
7399
7400            // Video (VIDEO_DATA)
7401            dumpTimer(proto, UidProto.VIDEO, u.getVideoTurnedOnTimer(), rawRealtimeUs, which);
7402
7403            // Wakelocks (WAKELOCK_DATA)
7404            final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
7405            for (int iw = wakelocks.size() - 1; iw >= 0; --iw) {
7406                final Uid.Wakelock wl = wakelocks.valueAt(iw);
7407                final long wToken = proto.start(UidProto.WAKELOCKS);
7408                proto.write(UidProto.Wakelock.NAME, wakelocks.keyAt(iw));
7409                dumpTimer(proto, UidProto.Wakelock.FULL, wl.getWakeTime(WAKE_TYPE_FULL),
7410                        rawRealtimeUs, which);
7411                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
7412                if (pTimer != null) {
7413                    dumpTimer(proto, UidProto.Wakelock.PARTIAL, pTimer, rawRealtimeUs, which);
7414                    dumpTimer(proto, UidProto.Wakelock.BACKGROUND_PARTIAL, pTimer.getSubTimer(),
7415                            rawRealtimeUs, which);
7416                }
7417                dumpTimer(proto, UidProto.Wakelock.WINDOW, wl.getWakeTime(WAKE_TYPE_WINDOW),
7418                        rawRealtimeUs, which);
7419                proto.end(wToken);
7420            }
7421
7422            // Wifi Multicast Wakelock (WIFI_MULTICAST_WAKELOCK_DATA)
7423            dumpTimer(proto, UidProto.WIFI_MULTICAST_WAKELOCK, u.getMulticastWakelockStats(),
7424                    rawRealtimeUs, which);
7425
7426            // Wakeup alarms (WAKEUP_ALARM_DATA)
7427            for (int ipkg = packageStats.size() - 1; ipkg >= 0; --ipkg) {
7428                final Uid.Pkg ps = packageStats.valueAt(ipkg);
7429                final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
7430                for (int iwa = alarms.size() - 1; iwa >= 0; --iwa) {
7431                    final long waToken = proto.start(UidProto.WAKEUP_ALARM);
7432                    proto.write(UidProto.WakeupAlarm.NAME, alarms.keyAt(iwa));
7433                    proto.write(UidProto.WakeupAlarm.COUNT,
7434                            alarms.valueAt(iwa).getCountLocked(which));
7435                    proto.end(waToken);
7436                }
7437            }
7438
7439            // Wifi Controller (WIFI_CONTROLLER_DATA)
7440            dumpControllerActivityProto(proto, UidProto.WIFI_CONTROLLER,
7441                    u.getWifiControllerActivity(), which);
7442
7443            // Wifi data (WIFI_DATA)
7444            final long wToken = proto.start(UidProto.WIFI);
7445            proto.write(UidProto.Wifi.FULL_WIFI_LOCK_DURATION_MS,
7446                    roundUsToMs(u.getFullWifiLockTime(rawRealtimeUs, which)));
7447            dumpTimer(proto, UidProto.Wifi.APPORTIONED_SCAN, u.getWifiScanTimer(),
7448                    rawRealtimeUs, which);
7449            proto.write(UidProto.Wifi.RUNNING_DURATION_MS,
7450                    roundUsToMs(u.getWifiRunningTime(rawRealtimeUs, which)));
7451            dumpTimer(proto, UidProto.Wifi.BACKGROUND_SCAN, u.getWifiScanBackgroundTimer(),
7452                    rawRealtimeUs, which);
7453            proto.end(wToken);
7454
7455            proto.end(uTkn);
7456        }
7457    }
7458
7459    private void dumpProtoSystemLocked(ProtoOutputStream proto, BatteryStatsHelper helper) {
7460        final long sToken = proto.start(BatteryStatsProto.SYSTEM);
7461        final long rawUptimeUs = SystemClock.uptimeMillis() * 1000;
7462        final long rawRealtimeMs = SystemClock.elapsedRealtime();
7463        final long rawRealtimeUs = rawRealtimeMs * 1000;
7464        final int which = STATS_SINCE_CHARGED;
7465
7466        // Battery data (BATTERY_DATA)
7467        final long bToken = proto.start(SystemProto.BATTERY);
7468        proto.write(SystemProto.Battery.START_CLOCK_TIME_MS, getStartClockTime());
7469        proto.write(SystemProto.Battery.START_COUNT, getStartCount());
7470        proto.write(SystemProto.Battery.TOTAL_REALTIME_MS,
7471                computeRealtime(rawRealtimeUs, which) / 1000);
7472        proto.write(SystemProto.Battery.TOTAL_UPTIME_MS,
7473                computeUptime(rawUptimeUs, which) / 1000);
7474        proto.write(SystemProto.Battery.BATTERY_REALTIME_MS,
7475                computeBatteryRealtime(rawRealtimeUs, which) / 1000);
7476        proto.write(SystemProto.Battery.BATTERY_UPTIME_MS,
7477                computeBatteryUptime(rawUptimeUs, which) / 1000);
7478        proto.write(SystemProto.Battery.SCREEN_OFF_REALTIME_MS,
7479                computeBatteryScreenOffRealtime(rawRealtimeUs, which) / 1000);
7480        proto.write(SystemProto.Battery.SCREEN_OFF_UPTIME_MS,
7481                computeBatteryScreenOffUptime(rawUptimeUs, which) / 1000);
7482        proto.write(SystemProto.Battery.SCREEN_DOZE_DURATION_MS,
7483                getScreenDozeTime(rawRealtimeUs, which) / 1000);
7484        proto.write(SystemProto.Battery.ESTIMATED_BATTERY_CAPACITY_MAH,
7485                getEstimatedBatteryCapacity());
7486        proto.write(SystemProto.Battery.MIN_LEARNED_BATTERY_CAPACITY_UAH,
7487                getMinLearnedBatteryCapacity());
7488        proto.write(SystemProto.Battery.MAX_LEARNED_BATTERY_CAPACITY_UAH,
7489                getMaxLearnedBatteryCapacity());
7490        proto.end(bToken);
7491
7492        // Battery discharge (BATTERY_DISCHARGE_DATA)
7493        final long bdToken = proto.start(SystemProto.BATTERY_DISCHARGE);
7494        proto.write(SystemProto.BatteryDischarge.LOWER_BOUND_SINCE_CHARGE,
7495                getLowDischargeAmountSinceCharge());
7496        proto.write(SystemProto.BatteryDischarge.UPPER_BOUND_SINCE_CHARGE,
7497                getHighDischargeAmountSinceCharge());
7498        proto.write(SystemProto.BatteryDischarge.SCREEN_ON_SINCE_CHARGE,
7499                getDischargeAmountScreenOnSinceCharge());
7500        proto.write(SystemProto.BatteryDischarge.SCREEN_OFF_SINCE_CHARGE,
7501                getDischargeAmountScreenOffSinceCharge());
7502        proto.write(SystemProto.BatteryDischarge.SCREEN_DOZE_SINCE_CHARGE,
7503                getDischargeAmountScreenDozeSinceCharge());
7504        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH,
7505                getUahDischarge(which) / 1000);
7506        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_SCREEN_OFF,
7507                getUahDischargeScreenOff(which) / 1000);
7508        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_SCREEN_DOZE,
7509                getUahDischargeScreenDoze(which) / 1000);
7510        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_LIGHT_DOZE,
7511                getUahDischargeLightDoze(which) / 1000);
7512        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_DEEP_DOZE,
7513                getUahDischargeDeepDoze(which) / 1000);
7514        proto.end(bdToken);
7515
7516        // Time remaining
7517        long timeRemainingUs = computeChargeTimeRemaining(rawRealtimeUs);
7518        // These are part of a oneof, so we should only set one of them.
7519        if (timeRemainingUs >= 0) {
7520            // Charge time remaining (CHARGE_TIME_REMAIN_DATA)
7521            proto.write(SystemProto.CHARGE_TIME_REMAINING_MS, timeRemainingUs / 1000);
7522        } else {
7523            timeRemainingUs = computeBatteryTimeRemaining(rawRealtimeUs);
7524            // Discharge time remaining (DISCHARGE_TIME_REMAIN_DATA)
7525            if (timeRemainingUs >= 0) {
7526                proto.write(SystemProto.DISCHARGE_TIME_REMAINING_MS, timeRemainingUs / 1000);
7527            } else {
7528                proto.write(SystemProto.DISCHARGE_TIME_REMAINING_MS, -1);
7529            }
7530        }
7531
7532        // Charge step (CHARGE_STEP_DATA)
7533        dumpDurationSteps(proto, SystemProto.CHARGE_STEP, getChargeLevelStepTracker());
7534
7535        // Phone data connection (DATA_CONNECTION_TIME_DATA and DATA_CONNECTION_COUNT_DATA)
7536        for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; ++i) {
7537            final long pdcToken = proto.start(SystemProto.DATA_CONNECTION);
7538            proto.write(SystemProto.DataConnection.NAME, i);
7539            dumpTimer(proto, SystemProto.DataConnection.TOTAL, getPhoneDataConnectionTimer(i),
7540                    rawRealtimeUs, which);
7541            proto.end(pdcToken);
7542        }
7543
7544        // Discharge step (DISCHARGE_STEP_DATA)
7545        dumpDurationSteps(proto, SystemProto.DISCHARGE_STEP, getDischargeLevelStepTracker());
7546
7547        // CPU frequencies (GLOBAL_CPU_FREQ_DATA)
7548        final long[] cpuFreqs = getCpuFreqs();
7549        if (cpuFreqs != null) {
7550            for (long i : cpuFreqs) {
7551                proto.write(SystemProto.CPU_FREQUENCY, i);
7552            }
7553        }
7554
7555        // Bluetooth controller (GLOBAL_BLUETOOTH_CONTROLLER_DATA)
7556        dumpControllerActivityProto(proto, SystemProto.GLOBAL_BLUETOOTH_CONTROLLER,
7557                getBluetoothControllerActivity(), which);
7558
7559        // Modem controller (GLOBAL_MODEM_CONTROLLER_DATA)
7560        dumpControllerActivityProto(proto, SystemProto.GLOBAL_MODEM_CONTROLLER,
7561                getModemControllerActivity(), which);
7562
7563        // Global network data (GLOBAL_NETWORK_DATA)
7564        final long gnToken = proto.start(SystemProto.GLOBAL_NETWORK);
7565        proto.write(SystemProto.GlobalNetwork.MOBILE_BYTES_RX,
7566                getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which));
7567        proto.write(SystemProto.GlobalNetwork.MOBILE_BYTES_TX,
7568                getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which));
7569        proto.write(SystemProto.GlobalNetwork.MOBILE_PACKETS_RX,
7570                getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which));
7571        proto.write(SystemProto.GlobalNetwork.MOBILE_PACKETS_TX,
7572                getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which));
7573        proto.write(SystemProto.GlobalNetwork.WIFI_BYTES_RX,
7574                getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
7575        proto.write(SystemProto.GlobalNetwork.WIFI_BYTES_TX,
7576                getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
7577        proto.write(SystemProto.GlobalNetwork.WIFI_PACKETS_RX,
7578                getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
7579        proto.write(SystemProto.GlobalNetwork.WIFI_PACKETS_TX,
7580                getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
7581        proto.write(SystemProto.GlobalNetwork.BT_BYTES_RX,
7582                getNetworkActivityBytes(NETWORK_BT_RX_DATA, which));
7583        proto.write(SystemProto.GlobalNetwork.BT_BYTES_TX,
7584                getNetworkActivityBytes(NETWORK_BT_TX_DATA, which));
7585        proto.end(gnToken);
7586
7587        // Wifi controller (GLOBAL_WIFI_CONTROLLER_DATA)
7588        dumpControllerActivityProto(proto, SystemProto.GLOBAL_WIFI_CONTROLLER,
7589                getWifiControllerActivity(), which);
7590
7591
7592        // Global wifi (GLOBAL_WIFI_DATA)
7593        final long gwToken = proto.start(SystemProto.GLOBAL_WIFI);
7594        proto.write(SystemProto.GlobalWifi.ON_DURATION_MS,
7595                getWifiOnTime(rawRealtimeUs, which) / 1000);
7596        proto.write(SystemProto.GlobalWifi.RUNNING_DURATION_MS,
7597                getGlobalWifiRunningTime(rawRealtimeUs, which) / 1000);
7598        proto.end(gwToken);
7599
7600        // Kernel wakelock (KERNEL_WAKELOCK_DATA)
7601        final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
7602        for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
7603            final long kwToken = proto.start(SystemProto.KERNEL_WAKELOCK);
7604            proto.write(SystemProto.KernelWakelock.NAME, ent.getKey());
7605            dumpTimer(proto, SystemProto.KernelWakelock.TOTAL, ent.getValue(),
7606                    rawRealtimeUs, which);
7607            proto.end(kwToken);
7608        }
7609
7610        // Misc (MISC_DATA)
7611        // Calculate wakelock times across all uids.
7612        long fullWakeLockTimeTotalUs = 0;
7613        long partialWakeLockTimeTotalUs = 0;
7614
7615        final SparseArray<? extends Uid> uidStats = getUidStats();
7616        for (int iu = 0; iu < uidStats.size(); iu++) {
7617            final Uid u = uidStats.valueAt(iu);
7618
7619            final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks =
7620                    u.getWakelockStats();
7621            for (int iw = wakelocks.size() - 1; iw >= 0; --iw) {
7622                final Uid.Wakelock wl = wakelocks.valueAt(iw);
7623
7624                final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
7625                if (fullWakeTimer != null) {
7626                    fullWakeLockTimeTotalUs += fullWakeTimer.getTotalTimeLocked(rawRealtimeUs,
7627                            which);
7628                }
7629
7630                final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
7631                if (partialWakeTimer != null) {
7632                    partialWakeLockTimeTotalUs += partialWakeTimer.getTotalTimeLocked(
7633                        rawRealtimeUs, which);
7634                }
7635            }
7636        }
7637        final long mToken = proto.start(SystemProto.MISC);
7638        proto.write(SystemProto.Misc.SCREEN_ON_DURATION_MS,
7639                getScreenOnTime(rawRealtimeUs, which) / 1000);
7640        proto.write(SystemProto.Misc.PHONE_ON_DURATION_MS,
7641                getPhoneOnTime(rawRealtimeUs, which) / 1000);
7642        proto.write(SystemProto.Misc.FULL_WAKELOCK_TOTAL_DURATION_MS,
7643                fullWakeLockTimeTotalUs / 1000);
7644        proto.write(SystemProto.Misc.PARTIAL_WAKELOCK_TOTAL_DURATION_MS,
7645                partialWakeLockTimeTotalUs / 1000);
7646        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_DURATION_MS,
7647                getMobileRadioActiveTime(rawRealtimeUs, which) / 1000);
7648        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_ADJUSTED_TIME_MS,
7649                getMobileRadioActiveAdjustedTime(which) / 1000);
7650        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_COUNT,
7651                getMobileRadioActiveCount(which));
7652        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_UNKNOWN_DURATION_MS,
7653                getMobileRadioActiveUnknownTime(which) / 1000);
7654        proto.write(SystemProto.Misc.INTERACTIVE_DURATION_MS,
7655                getInteractiveTime(rawRealtimeUs, which) / 1000);
7656        proto.write(SystemProto.Misc.BATTERY_SAVER_MODE_ENABLED_DURATION_MS,
7657                getPowerSaveModeEnabledTime(rawRealtimeUs, which) / 1000);
7658        proto.write(SystemProto.Misc.NUM_CONNECTIVITY_CHANGES,
7659                getNumConnectivityChange(which));
7660        proto.write(SystemProto.Misc.DEEP_DOZE_ENABLED_DURATION_MS,
7661                getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP, rawRealtimeUs, which) / 1000);
7662        proto.write(SystemProto.Misc.DEEP_DOZE_COUNT,
7663                getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which));
7664        proto.write(SystemProto.Misc.DEEP_DOZE_IDLING_DURATION_MS,
7665                getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP, rawRealtimeUs, which) / 1000);
7666        proto.write(SystemProto.Misc.DEEP_DOZE_IDLING_COUNT,
7667                getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which));
7668        proto.write(SystemProto.Misc.LONGEST_DEEP_DOZE_DURATION_MS,
7669                getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
7670        proto.write(SystemProto.Misc.LIGHT_DOZE_ENABLED_DURATION_MS,
7671                getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT, rawRealtimeUs, which) / 1000);
7672        proto.write(SystemProto.Misc.LIGHT_DOZE_COUNT,
7673                getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which));
7674        proto.write(SystemProto.Misc.LIGHT_DOZE_IDLING_DURATION_MS,
7675                getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT, rawRealtimeUs, which) / 1000);
7676        proto.write(SystemProto.Misc.LIGHT_DOZE_IDLING_COUNT,
7677                getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which));
7678        proto.write(SystemProto.Misc.LONGEST_LIGHT_DOZE_DURATION_MS,
7679                getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
7680        proto.end(mToken);
7681
7682        // Wifi multicast wakelock total stats (WIFI_MULTICAST_WAKELOCK_TOTAL_DATA)
7683        final long multicastWakeLockTimeTotalUs =
7684                getWifiMulticastWakelockTime(rawRealtimeUs, which);
7685        final int multicastWakeLockCountTotal = getWifiMulticastWakelockCount(which);
7686        final long wmctToken = proto.start(SystemProto.WIFI_MULTICAST_WAKELOCK_TOTAL);
7687        proto.write(SystemProto.WifiMulticastWakelockTotal.DURATION_MS,
7688                multicastWakeLockTimeTotalUs / 1000);
7689        proto.write(SystemProto.WifiMulticastWakelockTotal.COUNT,
7690                multicastWakeLockCountTotal);
7691        proto.end(wmctToken);
7692
7693        // Power use item (POWER_USE_ITEM_DATA)
7694        final List<BatterySipper> sippers = helper.getUsageList();
7695        if (sippers != null) {
7696            for (int i = 0; i < sippers.size(); ++i) {
7697                final BatterySipper bs = sippers.get(i);
7698                int n = SystemProto.PowerUseItem.UNKNOWN_SIPPER;
7699                int uid = 0;
7700                switch (bs.drainType) {
7701                    case IDLE:
7702                        n = SystemProto.PowerUseItem.IDLE;
7703                        break;
7704                    case CELL:
7705                        n = SystemProto.PowerUseItem.CELL;
7706                        break;
7707                    case PHONE:
7708                        n = SystemProto.PowerUseItem.PHONE;
7709                        break;
7710                    case WIFI:
7711                        n = SystemProto.PowerUseItem.WIFI;
7712                        break;
7713                    case BLUETOOTH:
7714                        n = SystemProto.PowerUseItem.BLUETOOTH;
7715                        break;
7716                    case SCREEN:
7717                        n = SystemProto.PowerUseItem.SCREEN;
7718                        break;
7719                    case FLASHLIGHT:
7720                        n = SystemProto.PowerUseItem.FLASHLIGHT;
7721                        break;
7722                    case APP:
7723                        // dumpProtoAppsLocked will handle this.
7724                        continue;
7725                    case USER:
7726                        n = SystemProto.PowerUseItem.USER;
7727                        uid = UserHandle.getUid(bs.userId, 0);
7728                        break;
7729                    case UNACCOUNTED:
7730                        n = SystemProto.PowerUseItem.UNACCOUNTED;
7731                        break;
7732                    case OVERCOUNTED:
7733                        n = SystemProto.PowerUseItem.OVERCOUNTED;
7734                        break;
7735                    case CAMERA:
7736                        n = SystemProto.PowerUseItem.CAMERA;
7737                        break;
7738                    case MEMORY:
7739                        n = SystemProto.PowerUseItem.MEMORY;
7740                        break;
7741                }
7742                final long puiToken = proto.start(SystemProto.POWER_USE_ITEM);
7743                proto.write(SystemProto.PowerUseItem.NAME, n);
7744                proto.write(SystemProto.PowerUseItem.UID, uid);
7745                proto.write(SystemProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah);
7746                proto.write(SystemProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide);
7747                proto.write(SystemProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah);
7748                proto.write(SystemProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH,
7749                        bs.proportionalSmearMah);
7750                proto.end(puiToken);
7751            }
7752        }
7753
7754        // Power use summary (POWER_USE_SUMMARY_DATA)
7755        final long pusToken = proto.start(SystemProto.POWER_USE_SUMMARY);
7756        proto.write(SystemProto.PowerUseSummary.BATTERY_CAPACITY_MAH,
7757                helper.getPowerProfile().getBatteryCapacity());
7758        proto.write(SystemProto.PowerUseSummary.COMPUTED_POWER_MAH, helper.getComputedPower());
7759        proto.write(SystemProto.PowerUseSummary.MIN_DRAINED_POWER_MAH, helper.getMinDrainedPower());
7760        proto.write(SystemProto.PowerUseSummary.MAX_DRAINED_POWER_MAH, helper.getMaxDrainedPower());
7761        proto.end(pusToken);
7762
7763        // RPM stats (RESOURCE_POWER_MANAGER_DATA)
7764        final Map<String, ? extends Timer> rpmStats = getRpmStats();
7765        final Map<String, ? extends Timer> screenOffRpmStats = getScreenOffRpmStats();
7766        for (Map.Entry<String, ? extends Timer> ent : rpmStats.entrySet()) {
7767            final long rpmToken = proto.start(SystemProto.RESOURCE_POWER_MANAGER);
7768            proto.write(SystemProto.ResourcePowerManager.NAME, ent.getKey());
7769            dumpTimer(proto, SystemProto.ResourcePowerManager.TOTAL,
7770                    ent.getValue(), rawRealtimeUs, which);
7771            dumpTimer(proto, SystemProto.ResourcePowerManager.SCREEN_OFF,
7772                    screenOffRpmStats.get(ent.getKey()), rawRealtimeUs, which);
7773            proto.end(rpmToken);
7774        }
7775
7776        // Screen brightness (SCREEN_BRIGHTNESS_DATA)
7777        for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; ++i) {
7778            final long sbToken = proto.start(SystemProto.SCREEN_BRIGHTNESS);
7779            proto.write(SystemProto.ScreenBrightness.NAME, i);
7780            dumpTimer(proto, SystemProto.ScreenBrightness.TOTAL, getScreenBrightnessTimer(i),
7781                    rawRealtimeUs, which);
7782            proto.end(sbToken);
7783        }
7784
7785        // Signal scanning time (SIGNAL_SCANNING_TIME_DATA)
7786        dumpTimer(proto, SystemProto.SIGNAL_SCANNING, getPhoneSignalScanningTimer(), rawRealtimeUs,
7787                which);
7788
7789        // Phone signal strength (SIGNAL_STRENGTH_TIME_DATA and SIGNAL_STRENGTH_COUNT_DATA)
7790        for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; ++i) {
7791            final long pssToken = proto.start(SystemProto.PHONE_SIGNAL_STRENGTH);
7792            proto.write(SystemProto.PhoneSignalStrength.NAME, i);
7793            dumpTimer(proto, SystemProto.PhoneSignalStrength.TOTAL, getPhoneSignalStrengthTimer(i),
7794                    rawRealtimeUs, which);
7795            proto.end(pssToken);
7796        }
7797
7798        // Wakeup reasons (WAKEUP_REASON_DATA)
7799        final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
7800        for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
7801            final long wrToken = proto.start(SystemProto.WAKEUP_REASON);
7802            proto.write(SystemProto.WakeupReason.NAME, ent.getKey());
7803            dumpTimer(proto, SystemProto.WakeupReason.TOTAL, ent.getValue(), rawRealtimeUs, which);
7804            proto.end(wrToken);
7805        }
7806
7807        // Wifi signal strength (WIFI_SIGNAL_STRENGTH_TIME_DATA and WIFI_SIGNAL_STRENGTH_COUNT_DATA)
7808        for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; ++i) {
7809            final long wssToken = proto.start(SystemProto.WIFI_SIGNAL_STRENGTH);
7810            proto.write(SystemProto.WifiSignalStrength.NAME, i);
7811            dumpTimer(proto, SystemProto.WifiSignalStrength.TOTAL, getWifiSignalStrengthTimer(i),
7812                    rawRealtimeUs, which);
7813            proto.end(wssToken);
7814        }
7815
7816        // Wifi state (WIFI_STATE_TIME_DATA and WIFI_STATE_COUNT_DATA)
7817        for (int i = 0; i < NUM_WIFI_STATES; ++i) {
7818            final long wsToken = proto.start(SystemProto.WIFI_STATE);
7819            proto.write(SystemProto.WifiState.NAME, i);
7820            dumpTimer(proto, SystemProto.WifiState.TOTAL, getWifiStateTimer(i),
7821                    rawRealtimeUs, which);
7822            proto.end(wsToken);
7823        }
7824
7825        // Wifi supplicant state (WIFI_SUPPL_STATE_TIME_DATA and WIFI_SUPPL_STATE_COUNT_DATA)
7826        for (int i = 0; i < NUM_WIFI_SUPPL_STATES; ++i) {
7827            final long wssToken = proto.start(SystemProto.WIFI_SUPPLICANT_STATE);
7828            proto.write(SystemProto.WifiSupplicantState.NAME, i);
7829            dumpTimer(proto, SystemProto.WifiSupplicantState.TOTAL, getWifiSupplStateTimer(i),
7830                    rawRealtimeUs, which);
7831            proto.end(wssToken);
7832        }
7833
7834        proto.end(sToken);
7835    }
7836}
7837