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