BatteryStats.java revision 926a97cd3f1b0d569c296660cdd012bb2ece108e
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 IDLE:
3818                        label="idle";
3819                        break;
3820                    case CELL:
3821                        label="cell";
3822                        break;
3823                    case PHONE:
3824                        label="phone";
3825                        break;
3826                    case WIFI:
3827                        label="wifi";
3828                        break;
3829                    case BLUETOOTH:
3830                        label="blue";
3831                        break;
3832                    case SCREEN:
3833                        label="scrn";
3834                        break;
3835                    case FLASHLIGHT:
3836                        label="flashlight";
3837                        break;
3838                    case APP:
3839                        uid = bs.uidObj.getUid();
3840                        label = "uid";
3841                        break;
3842                    case USER:
3843                        uid = UserHandle.getUid(bs.userId, 0);
3844                        label = "user";
3845                        break;
3846                    case UNACCOUNTED:
3847                        label = "unacc";
3848                        break;
3849                    case OVERCOUNTED:
3850                        label = "over";
3851                        break;
3852                    case CAMERA:
3853                        label = "camera";
3854                        break;
3855                    case MEMORY:
3856                        label = "memory";
3857                        break;
3858                    default:
3859                        label = "???";
3860                }
3861                dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
3862                        BatteryStatsHelper.makemAh(bs.totalPowerMah),
3863                        bs.shouldHide ? 1 : 0,
3864                        BatteryStatsHelper.makemAh(bs.screenPowerMah),
3865                        BatteryStatsHelper.makemAh(bs.proportionalSmearMah));
3866            }
3867        }
3868
3869        final long[] cpuFreqs = getCpuFreqs();
3870        if (cpuFreqs != null) {
3871            sb.setLength(0);
3872            for (int i = 0; i < cpuFreqs.length; ++i) {
3873                sb.append((i == 0 ? "" : ",") + cpuFreqs[i]);
3874            }
3875            dumpLine(pw, 0 /* uid */, category, GLOBAL_CPU_FREQ_DATA, sb.toString());
3876        }
3877
3878        // Dump stats per UID.
3879        for (int iu = 0; iu < NU; iu++) {
3880            final int uid = uidStats.keyAt(iu);
3881            if (reqUid >= 0 && uid != reqUid) {
3882                continue;
3883            }
3884            final Uid u = uidStats.valueAt(iu);
3885
3886            // Dump Network stats per uid, if any
3887            final long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
3888            final long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
3889            final long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
3890            final long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
3891            final long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
3892            final long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
3893            final long mobileActiveTime = u.getMobileRadioActiveTime(which);
3894            final int mobileActiveCount = u.getMobileRadioActiveCount(which);
3895            final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
3896            final long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
3897            final long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
3898            final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
3899            final long btBytesRx = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
3900            final long btBytesTx = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
3901            // Background data transfers
3902            final long mobileBytesBgRx = u.getNetworkActivityBytes(NETWORK_MOBILE_BG_RX_DATA,
3903                    which);
3904            final long mobileBytesBgTx = u.getNetworkActivityBytes(NETWORK_MOBILE_BG_TX_DATA,
3905                    which);
3906            final long wifiBytesBgRx = u.getNetworkActivityBytes(NETWORK_WIFI_BG_RX_DATA, which);
3907            final long wifiBytesBgTx = u.getNetworkActivityBytes(NETWORK_WIFI_BG_TX_DATA, which);
3908            final long mobilePacketsBgRx = u.getNetworkActivityPackets(NETWORK_MOBILE_BG_RX_DATA,
3909                    which);
3910            final long mobilePacketsBgTx = u.getNetworkActivityPackets(NETWORK_MOBILE_BG_TX_DATA,
3911                    which);
3912            final long wifiPacketsBgRx = u.getNetworkActivityPackets(NETWORK_WIFI_BG_RX_DATA,
3913                    which);
3914            final long wifiPacketsBgTx = u.getNetworkActivityPackets(NETWORK_WIFI_BG_TX_DATA,
3915                    which);
3916
3917            if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
3918                    || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
3919                    || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0
3920                    || btBytesRx > 0 || btBytesTx > 0 || mobileWakeup > 0 || wifiWakeup > 0
3921                    || mobileBytesBgRx > 0 || mobileBytesBgTx > 0 || wifiBytesBgRx > 0
3922                    || wifiBytesBgTx > 0
3923                    || mobilePacketsBgRx > 0 || mobilePacketsBgTx > 0 || wifiPacketsBgRx > 0
3924                    || wifiPacketsBgTx > 0) {
3925                dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
3926                        wifiBytesRx, wifiBytesTx,
3927                        mobilePacketsRx, mobilePacketsTx,
3928                        wifiPacketsRx, wifiPacketsTx,
3929                        mobileActiveTime, mobileActiveCount,
3930                        btBytesRx, btBytesTx, mobileWakeup, wifiWakeup,
3931                        mobileBytesBgRx, mobileBytesBgTx, wifiBytesBgRx, wifiBytesBgTx,
3932                        mobilePacketsBgRx, mobilePacketsBgTx, wifiPacketsBgRx, wifiPacketsBgTx
3933                        );
3934            }
3935
3936            // Dump modem controller data, per UID.
3937            dumpControllerActivityLine(pw, uid, category, MODEM_CONTROLLER_DATA,
3938                    u.getModemControllerActivity(), which);
3939
3940            // Dump Wifi controller data, per UID.
3941            final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
3942            final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
3943            final int wifiScanCount = u.getWifiScanCount(which);
3944            final int wifiScanCountBg = u.getWifiScanBackgroundCount(which);
3945            // Note that 'ActualTime' are unpooled and always since reset (regardless of 'which')
3946            final long wifiScanActualTimeMs = (u.getWifiScanActualTime(rawRealtime) + 500) / 1000;
3947            final long wifiScanActualTimeMsBg = (u.getWifiScanBackgroundTime(rawRealtime) + 500)
3948                    / 1000;
3949            final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
3950            if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
3951                    || wifiScanCountBg != 0 || wifiScanActualTimeMs != 0
3952                    || wifiScanActualTimeMsBg != 0 || uidWifiRunningTime != 0) {
3953                dumpLine(pw, uid, category, WIFI_DATA, fullWifiLockOnTime, wifiScanTime,
3954                        uidWifiRunningTime, wifiScanCount,
3955                        /* legacy fields follow, keep at 0 */ 0, 0, 0,
3956                        wifiScanCountBg, wifiScanActualTimeMs, wifiScanActualTimeMsBg);
3957            }
3958
3959            dumpControllerActivityLine(pw, uid, category, WIFI_CONTROLLER_DATA,
3960                    u.getWifiControllerActivity(), which);
3961
3962            final Timer bleTimer = u.getBluetoothScanTimer();
3963            if (bleTimer != null) {
3964                // Convert from microseconds to milliseconds with rounding
3965                final long totalTime = (bleTimer.getTotalTimeLocked(rawRealtime, which) + 500)
3966                        / 1000;
3967                if (totalTime != 0) {
3968                    final int count = bleTimer.getCountLocked(which);
3969                    final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
3970                    final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
3971                    // 'actualTime' are unpooled and always since reset (regardless of 'which')
3972                    final long actualTime = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
3973                    final long actualTimeBg = bleTimerBg != null ?
3974                            bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
3975                    // Result counters
3976                    final int resultCount = u.getBluetoothScanResultCounter() != null ?
3977                            u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
3978                    final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
3979                            u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
3980                    // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
3981                    final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
3982                    final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
3983                            unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
3984                    final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
3985                            unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
3986                    // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
3987                    final Timer unoptimizedScanTimerBg =
3988                            u.getBluetoothUnoptimizedScanBackgroundTimer();
3989                    final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
3990                            unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
3991                    final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
3992                            unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
3993
3994                    dumpLine(pw, uid, category, BLUETOOTH_MISC_DATA, totalTime, count,
3995                            countBg, actualTime, actualTimeBg, resultCount, resultCountBg,
3996                            unoptimizedScanTotalTime, unoptimizedScanTotalTimeBg,
3997                            unoptimizedScanMaxTime, unoptimizedScanMaxTimeBg);
3998                }
3999            }
4000
4001            dumpControllerActivityLine(pw, uid, category, BLUETOOTH_CONTROLLER_DATA,
4002                    u.getBluetoothControllerActivity(), which);
4003
4004            if (u.hasUserActivity()) {
4005                args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
4006                boolean hasData = false;
4007                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
4008                    int val = u.getUserActivityCount(i, which);
4009                    args[i] = val;
4010                    if (val != 0) hasData = true;
4011                }
4012                if (hasData) {
4013                    dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args);
4014                }
4015            }
4016
4017            if (u.getAggregatedPartialWakelockTimer() != null) {
4018                final Timer timer = u.getAggregatedPartialWakelockTimer();
4019                // Times are since reset (regardless of 'which')
4020                final long totTimeMs = timer.getTotalDurationMsLocked(rawRealtimeMs);
4021                final Timer bgTimer = timer.getSubTimer();
4022                final long bgTimeMs = bgTimer != null ?
4023                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4024                dumpLine(pw, uid, category, AGGREGATED_WAKELOCK_DATA, totTimeMs, bgTimeMs);
4025            }
4026
4027            final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
4028            for (int iw=wakelocks.size()-1; iw>=0; iw--) {
4029                final Uid.Wakelock wl = wakelocks.valueAt(iw);
4030                String linePrefix = "";
4031                sb.setLength(0);
4032                linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
4033                        rawRealtime, "f", which, linePrefix);
4034                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
4035                linePrefix = printWakeLockCheckin(sb, pTimer,
4036                        rawRealtime, "p", which, linePrefix);
4037                linePrefix = printWakeLockCheckin(sb, pTimer != null ? pTimer.getSubTimer() : null,
4038                        rawRealtime, "bp", which, linePrefix);
4039                linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
4040                        rawRealtime, "w", which, linePrefix);
4041
4042                // Only log if we had at least one wakelock...
4043                if (sb.length() > 0) {
4044                    String name = wakelocks.keyAt(iw);
4045                    if (name.indexOf(',') >= 0) {
4046                        name = name.replace(',', '_');
4047                    }
4048                    if (name.indexOf('\n') >= 0) {
4049                        name = name.replace('\n', '_');
4050                    }
4051                    if (name.indexOf('\r') >= 0) {
4052                        name = name.replace('\r', '_');
4053                    }
4054                    dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
4055                }
4056            }
4057
4058            // WiFi Multicast Wakelock Statistics
4059            final Timer mcTimer = u.getMulticastWakelockStats();
4060            if (mcTimer != null) {
4061                final long totalMcWakelockTimeMs =
4062                        mcTimer.getTotalTimeLocked(rawRealtime, which) / 1000 ;
4063                final int countMcWakelock = mcTimer.getCountLocked(which);
4064                if(totalMcWakelockTimeMs > 0) {
4065                    dumpLine(pw, uid, category, WIFI_MULTICAST_DATA,
4066                            totalMcWakelockTimeMs, countMcWakelock);
4067                }
4068            }
4069
4070            final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
4071            for (int isy=syncs.size()-1; isy>=0; isy--) {
4072                final Timer timer = syncs.valueAt(isy);
4073                // Convert from microseconds to milliseconds with rounding
4074                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
4075                final int count = timer.getCountLocked(which);
4076                final Timer bgTimer = timer.getSubTimer();
4077                final long bgTime = bgTimer != null ?
4078                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
4079                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
4080                if (totalTime != 0) {
4081                    dumpLine(pw, uid, category, SYNC_DATA, "\"" + syncs.keyAt(isy) + "\"",
4082                            totalTime, count, bgTime, bgCount);
4083                }
4084            }
4085
4086            final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
4087            for (int ij=jobs.size()-1; ij>=0; ij--) {
4088                final Timer timer = jobs.valueAt(ij);
4089                // Convert from microseconds to milliseconds with rounding
4090                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
4091                final int count = timer.getCountLocked(which);
4092                final Timer bgTimer = timer.getSubTimer();
4093                final long bgTime = bgTimer != null ?
4094                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
4095                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
4096                if (totalTime != 0) {
4097                    dumpLine(pw, uid, category, JOB_DATA, "\"" + jobs.keyAt(ij) + "\"",
4098                            totalTime, count, bgTime, bgCount);
4099                }
4100            }
4101
4102            final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
4103            for (int ic=completions.size()-1; ic>=0; ic--) {
4104                SparseIntArray types = completions.valueAt(ic);
4105                if (types != null) {
4106                    dumpLine(pw, uid, category, JOB_COMPLETION_DATA,
4107                            "\"" + completions.keyAt(ic) + "\"",
4108                            types.get(JobParameters.REASON_CANCELED, 0),
4109                            types.get(JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED, 0),
4110                            types.get(JobParameters.REASON_PREEMPT, 0),
4111                            types.get(JobParameters.REASON_TIMEOUT, 0),
4112                            types.get(JobParameters.REASON_DEVICE_IDLE, 0));
4113                }
4114            }
4115
4116            // Dump deferred jobs stats
4117            u.getDeferredJobsCheckinLineLocked(sb, which);
4118            if (sb.length() > 0) {
4119                dumpLine(pw, uid, category, JOBS_DEFERRED_DATA, sb.toString());
4120            }
4121
4122            dumpTimer(pw, uid, category, FLASHLIGHT_DATA, u.getFlashlightTurnedOnTimer(),
4123                    rawRealtime, which);
4124            dumpTimer(pw, uid, category, CAMERA_DATA, u.getCameraTurnedOnTimer(),
4125                    rawRealtime, which);
4126            dumpTimer(pw, uid, category, VIDEO_DATA, u.getVideoTurnedOnTimer(),
4127                    rawRealtime, which);
4128            dumpTimer(pw, uid, category, AUDIO_DATA, u.getAudioTurnedOnTimer(),
4129                    rawRealtime, which);
4130
4131            final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
4132            final int NSE = sensors.size();
4133            for (int ise=0; ise<NSE; ise++) {
4134                final Uid.Sensor se = sensors.valueAt(ise);
4135                final int sensorNumber = sensors.keyAt(ise);
4136                final Timer timer = se.getSensorTime();
4137                if (timer != null) {
4138                    // Convert from microseconds to milliseconds with rounding
4139                    final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
4140                            / 1000;
4141                    if (totalTime != 0) {
4142                        final int count = timer.getCountLocked(which);
4143                        final Timer bgTimer = se.getSensorBackgroundTime();
4144                        final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
4145                        // 'actualTime' are unpooled and always since reset (regardless of 'which')
4146                        final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
4147                        final long bgActualTime = bgTimer != null ?
4148                                bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
4149                        dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime,
4150                                count, bgCount, actualTime, bgActualTime);
4151                    }
4152                }
4153            }
4154
4155            dumpTimer(pw, uid, category, VIBRATOR_DATA, u.getVibratorOnTimer(),
4156                    rawRealtime, which);
4157
4158            dumpTimer(pw, uid, category, FOREGROUND_ACTIVITY_DATA, u.getForegroundActivityTimer(),
4159                    rawRealtime, which);
4160
4161            dumpTimer(pw, uid, category, FOREGROUND_SERVICE_DATA, u.getForegroundServiceTimer(),
4162                    rawRealtime, which);
4163
4164            final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
4165            long totalStateTime = 0;
4166            for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
4167                final long time = u.getProcessStateTime(ips, rawRealtime, which);
4168                totalStateTime += time;
4169                stateTimes[ips] = (time + 500) / 1000;
4170            }
4171            if (totalStateTime > 0) {
4172                dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
4173            }
4174
4175            final long userCpuTimeUs = u.getUserCpuTimeUs(which);
4176            final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
4177            if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
4178                dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000,
4179                        0 /* old cpu power, keep for compatibility */);
4180            }
4181
4182            // If the cpuFreqs is null, then don't bother checking for cpu freq times.
4183            if (cpuFreqs != null) {
4184                final long[] cpuFreqTimeMs = u.getCpuFreqTimes(which);
4185                // If total cpuFreqTimes is null, then we don't need to check for
4186                // screenOffCpuFreqTimes.
4187                if (cpuFreqTimeMs != null && cpuFreqTimeMs.length == cpuFreqs.length) {
4188                    sb.setLength(0);
4189                    for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
4190                        sb.append((i == 0 ? "" : ",") + cpuFreqTimeMs[i]);
4191                    }
4192                    final long[] screenOffCpuFreqTimeMs = u.getScreenOffCpuFreqTimes(which);
4193                    if (screenOffCpuFreqTimeMs != null) {
4194                        for (int i = 0; i < screenOffCpuFreqTimeMs.length; ++i) {
4195                            sb.append("," + screenOffCpuFreqTimeMs[i]);
4196                        }
4197                    } else {
4198                        for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
4199                            sb.append(",0");
4200                        }
4201                    }
4202                    dumpLine(pw, uid, category, CPU_TIMES_AT_FREQ_DATA, UID_TIMES_TYPE_ALL,
4203                            cpuFreqTimeMs.length, sb.toString());
4204                }
4205
4206                for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
4207                    final long[] timesMs = u.getCpuFreqTimes(which, procState);
4208                    if (timesMs != null && timesMs.length == cpuFreqs.length) {
4209                        sb.setLength(0);
4210                        for (int i = 0; i < timesMs.length; ++i) {
4211                            sb.append((i == 0 ? "" : ",") + timesMs[i]);
4212                        }
4213                        final long[] screenOffTimesMs = u.getScreenOffCpuFreqTimes(
4214                                which, procState);
4215                        if (screenOffTimesMs != null) {
4216                            for (int i = 0; i < screenOffTimesMs.length; ++i) {
4217                                sb.append("," + screenOffTimesMs[i]);
4218                            }
4219                        } else {
4220                            for (int i = 0; i < timesMs.length; ++i) {
4221                                sb.append(",0");
4222                            }
4223                        }
4224                        dumpLine(pw, uid, category, CPU_TIMES_AT_FREQ_DATA,
4225                                Uid.UID_PROCESS_TYPES[procState], timesMs.length, sb.toString());
4226                    }
4227                }
4228            }
4229
4230            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
4231                    = u.getProcessStats();
4232            for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
4233                final Uid.Proc ps = processStats.valueAt(ipr);
4234
4235                final long userMillis = ps.getUserTime(which);
4236                final long systemMillis = ps.getSystemTime(which);
4237                final long foregroundMillis = ps.getForegroundTime(which);
4238                final int starts = ps.getStarts(which);
4239                final int numCrashes = ps.getNumCrashes(which);
4240                final int numAnrs = ps.getNumAnrs(which);
4241
4242                if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
4243                        || starts != 0 || numAnrs != 0 || numCrashes != 0) {
4244                    dumpLine(pw, uid, category, PROCESS_DATA, "\"" + processStats.keyAt(ipr) + "\"",
4245                            userMillis, systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
4246                }
4247            }
4248
4249            final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
4250                    = u.getPackageStats();
4251            for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
4252                final Uid.Pkg ps = packageStats.valueAt(ipkg);
4253                int wakeups = 0;
4254                final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
4255                for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
4256                    int count = alarms.valueAt(iwa).getCountLocked(which);
4257                    wakeups += count;
4258                    String name = alarms.keyAt(iwa).replace(',', '_');
4259                    dumpLine(pw, uid, category, WAKEUP_ALARM_DATA, name, count);
4260                }
4261                final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
4262                for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
4263                    final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
4264                    final long startTime = ss.getStartTime(batteryUptime, which);
4265                    final int starts = ss.getStarts(which);
4266                    final int launches = ss.getLaunches(which);
4267                    if (startTime != 0 || starts != 0 || launches != 0) {
4268                        dumpLine(pw, uid, category, APK_DATA,
4269                                wakeups, // wakeup alarms
4270                                packageStats.keyAt(ipkg), // Apk
4271                                serviceStats.keyAt(isvc), // service
4272                                startTime / 1000, // time spent started, in ms
4273                                starts,
4274                                launches);
4275                    }
4276                }
4277            }
4278        }
4279    }
4280
4281    static final class TimerEntry {
4282        final String mName;
4283        final int mId;
4284        final BatteryStats.Timer mTimer;
4285        final long mTime;
4286        TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
4287            mName = name;
4288            mId = id;
4289            mTimer = timer;
4290            mTime = time;
4291        }
4292    }
4293
4294    private void printmAh(PrintWriter printer, double power) {
4295        printer.print(BatteryStatsHelper.makemAh(power));
4296    }
4297
4298    private void printmAh(StringBuilder sb, double power) {
4299        sb.append(BatteryStatsHelper.makemAh(power));
4300    }
4301
4302    /**
4303     * Temporary for settings.
4304     */
4305    public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which,
4306            int reqUid) {
4307        dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
4308    }
4309
4310    @SuppressWarnings("unused")
4311    public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
4312            int reqUid, boolean wifiOnly) {
4313        final long rawUptime = SystemClock.uptimeMillis() * 1000;
4314        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
4315        final long rawRealtimeMs = (rawRealtime + 500) / 1000;
4316        final long batteryUptime = getBatteryUptime(rawUptime);
4317
4318        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
4319        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
4320        final long totalRealtime = computeRealtime(rawRealtime, which);
4321        final long totalUptime = computeUptime(rawUptime, which);
4322        final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
4323        final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
4324                which);
4325        final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
4326        final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
4327        final long screenDozeTime = getScreenDozeTime(rawRealtime, which);
4328
4329        final StringBuilder sb = new StringBuilder(128);
4330
4331        final SparseArray<? extends Uid> uidStats = getUidStats();
4332        final int NU = uidStats.size();
4333
4334        final int estimatedBatteryCapacity = getEstimatedBatteryCapacity();
4335        if (estimatedBatteryCapacity > 0) {
4336            sb.setLength(0);
4337            sb.append(prefix);
4338                sb.append("  Estimated battery capacity: ");
4339                sb.append(BatteryStatsHelper.makemAh(estimatedBatteryCapacity));
4340                sb.append(" mAh");
4341            pw.println(sb.toString());
4342        }
4343
4344        final int minLearnedBatteryCapacity = getMinLearnedBatteryCapacity();
4345        if (minLearnedBatteryCapacity > 0) {
4346            sb.setLength(0);
4347            sb.append(prefix);
4348                sb.append("  Min learned battery capacity: ");
4349                sb.append(BatteryStatsHelper.makemAh(minLearnedBatteryCapacity / 1000));
4350                sb.append(" mAh");
4351            pw.println(sb.toString());
4352        }
4353        final int maxLearnedBatteryCapacity = getMaxLearnedBatteryCapacity();
4354        if (maxLearnedBatteryCapacity > 0) {
4355            sb.setLength(0);
4356            sb.append(prefix);
4357                sb.append("  Max learned battery capacity: ");
4358                sb.append(BatteryStatsHelper.makemAh(maxLearnedBatteryCapacity / 1000));
4359                sb.append(" mAh");
4360            pw.println(sb.toString());
4361        }
4362
4363        sb.setLength(0);
4364        sb.append(prefix);
4365        sb.append("  Time on battery: ");
4366        formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
4367        sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
4368        sb.append(") realtime, ");
4369        formatTimeMs(sb, whichBatteryUptime / 1000);
4370        sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, whichBatteryRealtime));
4371        sb.append(") uptime");
4372        pw.println(sb.toString());
4373
4374        sb.setLength(0);
4375        sb.append(prefix);
4376        sb.append("  Time on battery screen off: ");
4377        formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("(");
4378        sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, whichBatteryRealtime));
4379        sb.append(") realtime, ");
4380        formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
4381        sb.append("(");
4382        sb.append(formatRatioLocked(whichBatteryScreenOffUptime, whichBatteryRealtime));
4383        sb.append(") uptime");
4384        pw.println(sb.toString());
4385
4386        sb.setLength(0);
4387        sb.append(prefix);
4388        sb.append("  Time on battery screen doze: ");
4389        formatTimeMs(sb, screenDozeTime / 1000); sb.append("(");
4390        sb.append(formatRatioLocked(screenDozeTime, whichBatteryRealtime));
4391        sb.append(")");
4392        pw.println(sb.toString());
4393
4394        sb.setLength(0);
4395        sb.append(prefix);
4396                sb.append("  Total run time: ");
4397                formatTimeMs(sb, totalRealtime / 1000);
4398                sb.append("realtime, ");
4399                formatTimeMs(sb, totalUptime / 1000);
4400                sb.append("uptime");
4401        pw.println(sb.toString());
4402        if (batteryTimeRemaining >= 0) {
4403            sb.setLength(0);
4404            sb.append(prefix);
4405                    sb.append("  Battery time remaining: ");
4406                    formatTimeMs(sb, batteryTimeRemaining / 1000);
4407            pw.println(sb.toString());
4408        }
4409        if (chargeTimeRemaining >= 0) {
4410            sb.setLength(0);
4411            sb.append(prefix);
4412                    sb.append("  Charge time remaining: ");
4413                    formatTimeMs(sb, chargeTimeRemaining / 1000);
4414            pw.println(sb.toString());
4415        }
4416
4417        final long dischargeCount = getUahDischarge(which);
4418        if (dischargeCount >= 0) {
4419            sb.setLength(0);
4420            sb.append(prefix);
4421                sb.append("  Discharge: ");
4422                sb.append(BatteryStatsHelper.makemAh(dischargeCount / 1000.0));
4423                sb.append(" mAh");
4424            pw.println(sb.toString());
4425        }
4426
4427        final long dischargeScreenOffCount = getUahDischargeScreenOff(which);
4428        if (dischargeScreenOffCount >= 0) {
4429            sb.setLength(0);
4430            sb.append(prefix);
4431                sb.append("  Screen off discharge: ");
4432                sb.append(BatteryStatsHelper.makemAh(dischargeScreenOffCount / 1000.0));
4433                sb.append(" mAh");
4434            pw.println(sb.toString());
4435        }
4436
4437        final long dischargeScreenDozeCount = getUahDischargeScreenDoze(which);
4438        if (dischargeScreenDozeCount >= 0) {
4439            sb.setLength(0);
4440            sb.append(prefix);
4441            sb.append("  Screen doze discharge: ");
4442            sb.append(BatteryStatsHelper.makemAh(dischargeScreenDozeCount / 1000.0));
4443            sb.append(" mAh");
4444            pw.println(sb.toString());
4445        }
4446
4447        final long dischargeScreenOnCount =
4448                dischargeCount - dischargeScreenOffCount - dischargeScreenDozeCount;
4449        if (dischargeScreenOnCount >= 0) {
4450            sb.setLength(0);
4451            sb.append(prefix);
4452                sb.append("  Screen on discharge: ");
4453                sb.append(BatteryStatsHelper.makemAh(dischargeScreenOnCount / 1000.0));
4454                sb.append(" mAh");
4455            pw.println(sb.toString());
4456        }
4457
4458        final long dischargeLightDozeCount = getUahDischargeLightDoze(which);
4459        if (dischargeLightDozeCount >= 0) {
4460            sb.setLength(0);
4461            sb.append(prefix);
4462            sb.append("  Device light doze discharge: ");
4463            sb.append(BatteryStatsHelper.makemAh(dischargeLightDozeCount / 1000.0));
4464            sb.append(" mAh");
4465            pw.println(sb.toString());
4466        }
4467
4468        final long dischargeDeepDozeCount = getUahDischargeDeepDoze(which);
4469        if (dischargeDeepDozeCount >= 0) {
4470            sb.setLength(0);
4471            sb.append(prefix);
4472            sb.append("  Device deep doze discharge: ");
4473            sb.append(BatteryStatsHelper.makemAh(dischargeDeepDozeCount / 1000.0));
4474            sb.append(" mAh");
4475            pw.println(sb.toString());
4476        }
4477
4478        pw.print("  Start clock time: ");
4479        pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
4480
4481        final long screenOnTime = getScreenOnTime(rawRealtime, which);
4482        final long interactiveTime = getInteractiveTime(rawRealtime, which);
4483        final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
4484        final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT,
4485                rawRealtime, which);
4486        final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP,
4487                rawRealtime, which);
4488        final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT,
4489                rawRealtime, which);
4490        final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP,
4491                rawRealtime, which);
4492        final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
4493        final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
4494        final long wifiOnTime = getWifiOnTime(rawRealtime, which);
4495        sb.setLength(0);
4496        sb.append(prefix);
4497                sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
4498                sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
4499                sb.append(") "); sb.append(getScreenOnCount(which));
4500                sb.append("x, Interactive: "); formatTimeMs(sb, interactiveTime / 1000);
4501                sb.append("("); sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime));
4502                sb.append(")");
4503        pw.println(sb.toString());
4504        sb.setLength(0);
4505        sb.append(prefix);
4506        sb.append("  Screen brightnesses:");
4507        boolean didOne = false;
4508        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4509            final long time = getScreenBrightnessTime(i, rawRealtime, which);
4510            if (time == 0) {
4511                continue;
4512            }
4513            sb.append("\n    ");
4514            sb.append(prefix);
4515            didOne = true;
4516            sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
4517            sb.append(" ");
4518            formatTimeMs(sb, time/1000);
4519            sb.append("(");
4520            sb.append(formatRatioLocked(time, screenOnTime));
4521            sb.append(")");
4522        }
4523        if (!didOne) sb.append(" (no activity)");
4524        pw.println(sb.toString());
4525        if (powerSaveModeEnabledTime != 0) {
4526            sb.setLength(0);
4527            sb.append(prefix);
4528                    sb.append("  Power save mode enabled: ");
4529                    formatTimeMs(sb, powerSaveModeEnabledTime / 1000);
4530                    sb.append("(");
4531                    sb.append(formatRatioLocked(powerSaveModeEnabledTime, whichBatteryRealtime));
4532                    sb.append(")");
4533            pw.println(sb.toString());
4534        }
4535        if (deviceLightIdlingTime != 0) {
4536            sb.setLength(0);
4537            sb.append(prefix);
4538                    sb.append("  Device light idling: ");
4539                    formatTimeMs(sb, deviceLightIdlingTime / 1000);
4540                    sb.append("(");
4541                    sb.append(formatRatioLocked(deviceLightIdlingTime, whichBatteryRealtime));
4542                    sb.append(") "); sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which));
4543                    sb.append("x");
4544            pw.println(sb.toString());
4545        }
4546        if (deviceIdleModeLightTime != 0) {
4547            sb.setLength(0);
4548            sb.append(prefix);
4549                    sb.append("  Idle mode light time: ");
4550                    formatTimeMs(sb, deviceIdleModeLightTime / 1000);
4551                    sb.append("(");
4552                    sb.append(formatRatioLocked(deviceIdleModeLightTime, whichBatteryRealtime));
4553                    sb.append(") ");
4554                    sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which));
4555                    sb.append("x");
4556                    sb.append(" -- longest ");
4557                    formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
4558            pw.println(sb.toString());
4559        }
4560        if (deviceIdlingTime != 0) {
4561            sb.setLength(0);
4562            sb.append(prefix);
4563                    sb.append("  Device full idling: ");
4564                    formatTimeMs(sb, deviceIdlingTime / 1000);
4565                    sb.append("(");
4566                    sb.append(formatRatioLocked(deviceIdlingTime, whichBatteryRealtime));
4567                    sb.append(") "); sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which));
4568                    sb.append("x");
4569            pw.println(sb.toString());
4570        }
4571        if (deviceIdleModeFullTime != 0) {
4572            sb.setLength(0);
4573            sb.append(prefix);
4574                    sb.append("  Idle mode full time: ");
4575                    formatTimeMs(sb, deviceIdleModeFullTime / 1000);
4576                    sb.append("(");
4577                    sb.append(formatRatioLocked(deviceIdleModeFullTime, whichBatteryRealtime));
4578                    sb.append(") ");
4579                    sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which));
4580                    sb.append("x");
4581                    sb.append(" -- longest ");
4582                    formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
4583            pw.println(sb.toString());
4584        }
4585        if (phoneOnTime != 0) {
4586            sb.setLength(0);
4587            sb.append(prefix);
4588                    sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
4589                    sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
4590                    sb.append(") "); sb.append(getPhoneOnCount(which)); sb.append("x");
4591        }
4592        final int connChanges = getNumConnectivityChange(which);
4593        if (connChanges != 0) {
4594            pw.print(prefix);
4595            pw.print("  Connectivity changes: "); pw.println(connChanges);
4596        }
4597
4598        // Calculate wakelock times across all uids.
4599        long fullWakeLockTimeTotalMicros = 0;
4600        long partialWakeLockTimeTotalMicros = 0;
4601
4602        final ArrayList<TimerEntry> timers = new ArrayList<>();
4603
4604        for (int iu = 0; iu < NU; iu++) {
4605            final Uid u = uidStats.valueAt(iu);
4606
4607            final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
4608                    = u.getWakelockStats();
4609            for (int iw=wakelocks.size()-1; iw>=0; iw--) {
4610                final Uid.Wakelock wl = wakelocks.valueAt(iw);
4611
4612                final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
4613                if (fullWakeTimer != null) {
4614                    fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
4615                            rawRealtime, which);
4616                }
4617
4618                final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
4619                if (partialWakeTimer != null) {
4620                    final long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
4621                            rawRealtime, which);
4622                    if (totalTimeMicros > 0) {
4623                        if (reqUid < 0) {
4624                            // Only show the ordered list of all wake
4625                            // locks if the caller is not asking for data
4626                            // about a specific uid.
4627                            timers.add(new TimerEntry(wakelocks.keyAt(iw), u.getUid(),
4628                                    partialWakeTimer, totalTimeMicros));
4629                        }
4630                        partialWakeLockTimeTotalMicros += totalTimeMicros;
4631                    }
4632                }
4633            }
4634        }
4635
4636        final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
4637        final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
4638        final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
4639        final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
4640        final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
4641        final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
4642        final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
4643        final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
4644        final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
4645        final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
4646
4647        if (fullWakeLockTimeTotalMicros != 0) {
4648            sb.setLength(0);
4649            sb.append(prefix);
4650                    sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
4651                            (fullWakeLockTimeTotalMicros + 500) / 1000);
4652            pw.println(sb.toString());
4653        }
4654
4655        if (partialWakeLockTimeTotalMicros != 0) {
4656            sb.setLength(0);
4657            sb.append(prefix);
4658                    sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
4659                            (partialWakeLockTimeTotalMicros + 500) / 1000);
4660            pw.println(sb.toString());
4661        }
4662
4663        final long multicastWakeLockTimeTotalMicros =
4664                getWifiMulticastWakelockTime(rawRealtime, which);
4665        final int multicastWakeLockCountTotal = getWifiMulticastWakelockCount(which);
4666        if (multicastWakeLockTimeTotalMicros != 0) {
4667            sb.setLength(0);
4668            sb.append(prefix);
4669            sb.append("  Total WiFi Multicast wakelock Count: ");
4670            sb.append(multicastWakeLockCountTotal);
4671            pw.println(sb.toString());
4672
4673            sb.setLength(0);
4674            sb.append(prefix);
4675            sb.append("  Total WiFi Multicast wakelock time: ");
4676            formatTimeMsNoSpace(sb, (multicastWakeLockTimeTotalMicros + 500) / 1000);
4677            pw.println(sb.toString());
4678        }
4679
4680        pw.println("");
4681        pw.print(prefix);
4682        sb.setLength(0);
4683        sb.append(prefix);
4684        sb.append("  CONNECTIVITY POWER SUMMARY START");
4685        pw.println(sb.toString());
4686
4687        pw.print(prefix);
4688        sb.setLength(0);
4689        sb.append(prefix);
4690        sb.append("  Logging duration for connectivity statistics: ");
4691        formatTimeMs(sb, whichBatteryRealtime / 1000);
4692        pw.println(sb.toString());
4693
4694        sb.setLength(0);
4695        sb.append(prefix);
4696        sb.append("  Cellular Statistics:");
4697        pw.println(sb.toString());
4698
4699        pw.print(prefix);
4700        sb.setLength(0);
4701        sb.append(prefix);
4702        sb.append("     Cellular kernel active time: ");
4703        final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
4704        formatTimeMs(sb, mobileActiveTime / 1000);
4705        sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
4706        sb.append(")");
4707        pw.println(sb.toString());
4708
4709        pw.print("     Cellular data received: "); pw.println(formatBytesLocked(mobileRxTotalBytes));
4710        pw.print("     Cellular data sent: "); pw.println(formatBytesLocked(mobileTxTotalBytes));
4711        pw.print("     Cellular packets received: "); pw.println(mobileRxTotalPackets);
4712        pw.print("     Cellular packets sent: "); pw.println(mobileTxTotalPackets);
4713
4714        sb.setLength(0);
4715        sb.append(prefix);
4716        sb.append("     Cellular Radio Access Technology:");
4717        didOne = false;
4718        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4719            final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
4720            if (time == 0) {
4721                continue;
4722            }
4723            sb.append("\n       ");
4724            sb.append(prefix);
4725            didOne = true;
4726            sb.append(DATA_CONNECTION_NAMES[i]);
4727            sb.append(" ");
4728            formatTimeMs(sb, time/1000);
4729            sb.append("(");
4730            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4731            sb.append(") ");
4732        }
4733        if (!didOne) sb.append(" (no activity)");
4734        pw.println(sb.toString());
4735
4736        sb.setLength(0);
4737        sb.append(prefix);
4738        sb.append("     Cellular Rx signal strength (RSRP):");
4739        final String[] cellularRxSignalStrengthDescription = new String[]{
4740            "very poor (less than -128dBm): ",
4741            "poor (-128dBm to -118dBm): ",
4742            "moderate (-118dBm to -108dBm): ",
4743            "good (-108dBm to -98dBm): ",
4744            "great (greater than -98dBm): "};
4745        didOne = false;
4746        final int numCellularRxBins = Math.min(SignalStrength.NUM_SIGNAL_STRENGTH_BINS,
4747            cellularRxSignalStrengthDescription.length);
4748        for (int i=0; i<numCellularRxBins; i++) {
4749            final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
4750            if (time == 0) {
4751                continue;
4752            }
4753            sb.append("\n       ");
4754            sb.append(prefix);
4755            didOne = true;
4756            sb.append(cellularRxSignalStrengthDescription[i]);
4757            sb.append(" ");
4758            formatTimeMs(sb, time/1000);
4759            sb.append("(");
4760            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4761            sb.append(") ");
4762        }
4763        if (!didOne) sb.append(" (no activity)");
4764        pw.println(sb.toString());
4765
4766        printControllerActivity(pw, sb, prefix, CELLULAR_CONTROLLER_NAME,
4767            getModemControllerActivity(), which);
4768
4769        pw.print(prefix);
4770        sb.setLength(0);
4771        sb.append(prefix);
4772        sb.append("  Wifi Statistics:");
4773        pw.println(sb.toString());
4774
4775        pw.print(prefix);
4776        sb.setLength(0);
4777        sb.append(prefix);
4778        sb.append("     Wifi kernel active time: ");
4779        final long wifiActiveTime = getWifiActiveTime(rawRealtime, which);
4780        formatTimeMs(sb, wifiActiveTime / 1000);
4781        sb.append("("); sb.append(formatRatioLocked(wifiActiveTime, whichBatteryRealtime));
4782        sb.append(")");
4783        pw.println(sb.toString());
4784
4785        pw.print("     Wifi data received: "); pw.println(formatBytesLocked(wifiRxTotalBytes));
4786        pw.print("     Wifi data sent: "); pw.println(formatBytesLocked(wifiTxTotalBytes));
4787        pw.print("     Wifi packets received: "); pw.println(wifiRxTotalPackets);
4788        pw.print("     Wifi packets sent: "); pw.println(wifiTxTotalPackets);
4789
4790        sb.setLength(0);
4791        sb.append(prefix);
4792        sb.append("     Wifi states:");
4793        didOne = false;
4794        for (int i=0; i<NUM_WIFI_STATES; i++) {
4795            final long time = getWifiStateTime(i, rawRealtime, which);
4796            if (time == 0) {
4797                continue;
4798            }
4799            sb.append("\n       ");
4800            didOne = true;
4801            sb.append(WIFI_STATE_NAMES[i]);
4802            sb.append(" ");
4803            formatTimeMs(sb, time/1000);
4804            sb.append("(");
4805            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4806            sb.append(") ");
4807        }
4808        if (!didOne) sb.append(" (no activity)");
4809        pw.println(sb.toString());
4810
4811        sb.setLength(0);
4812        sb.append(prefix);
4813        sb.append("     Wifi supplicant states:");
4814        didOne = false;
4815        for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
4816            final long time = getWifiSupplStateTime(i, rawRealtime, which);
4817            if (time == 0) {
4818                continue;
4819            }
4820            sb.append("\n       ");
4821            didOne = true;
4822            sb.append(WIFI_SUPPL_STATE_NAMES[i]);
4823            sb.append(" ");
4824            formatTimeMs(sb, time/1000);
4825            sb.append("(");
4826            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4827            sb.append(") ");
4828        }
4829        if (!didOne) sb.append(" (no activity)");
4830        pw.println(sb.toString());
4831
4832        sb.setLength(0);
4833        sb.append(prefix);
4834        sb.append("     Wifi Rx signal strength (RSSI):");
4835        final String[] wifiRxSignalStrengthDescription = new String[]{
4836            "very poor (less than -88.75dBm): ",
4837            "poor (-88.75 to -77.5dBm): ",
4838            "moderate (-77.5dBm to -66.25dBm): ",
4839            "good (-66.25dBm to -55dBm): ",
4840            "great (greater than -55dBm): "};
4841        didOne = false;
4842        final int numWifiRxBins = Math.min(NUM_WIFI_SIGNAL_STRENGTH_BINS,
4843            wifiRxSignalStrengthDescription.length);
4844        for (int i=0; i<numWifiRxBins; i++) {
4845            final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
4846            if (time == 0) {
4847                continue;
4848            }
4849            sb.append("\n    ");
4850            sb.append(prefix);
4851            didOne = true;
4852            sb.append("     ");
4853            sb.append(wifiRxSignalStrengthDescription[i]);
4854            formatTimeMs(sb, time/1000);
4855            sb.append("(");
4856            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4857            sb.append(") ");
4858        }
4859        if (!didOne) sb.append(" (no activity)");
4860        pw.println(sb.toString());
4861
4862        printControllerActivity(pw, sb, prefix, WIFI_CONTROLLER_NAME,
4863            getWifiControllerActivity(), which);
4864
4865        pw.print(prefix);
4866        sb.setLength(0);
4867        sb.append(prefix);
4868        sb.append("  GPS Statistics:");
4869        pw.println(sb.toString());
4870
4871        sb.setLength(0);
4872        sb.append(prefix);
4873        sb.append("     GPS signal quality (Top 4 Average CN0):");
4874        final String[] gpsSignalQualityDescription = new String[]{
4875            "poor (less than 20 dBHz): ",
4876            "good (greater than 20 dBHz): "};
4877        final int numGpsSignalQualityBins = Math.min(GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS,
4878            gpsSignalQualityDescription.length);
4879        for (int i=0; i<numGpsSignalQualityBins; i++) {
4880            final long time = getGpsSignalQualityTime(i, rawRealtime, which);
4881            sb.append("\n    ");
4882            sb.append(prefix);
4883            sb.append("  ");
4884            sb.append(gpsSignalQualityDescription[i]);
4885            formatTimeMs(sb, time/1000);
4886            sb.append("(");
4887            sb.append(formatRatioLocked(time, whichBatteryRealtime));
4888            sb.append(") ");
4889        }
4890        pw.println(sb.toString());
4891
4892        final long gpsBatteryDrainMaMs = getGpsBatteryDrainMaMs();
4893        if (gpsBatteryDrainMaMs > 0) {
4894            pw.print(prefix);
4895            sb.setLength(0);
4896            sb.append(prefix);
4897            sb.append("     Battery Drain (mAh): ");
4898            sb.append(Double.toString(((double) gpsBatteryDrainMaMs)/(3600 * 1000)));
4899            pw.println(sb.toString());
4900        }
4901
4902        pw.print(prefix);
4903        sb.setLength(0);
4904        sb.append(prefix);
4905        sb.append("  CONNECTIVITY POWER SUMMARY END");
4906        pw.println(sb.toString());
4907        pw.println("");
4908
4909        pw.print(prefix);
4910        pw.print("  Bluetooth total received: "); pw.print(formatBytesLocked(btRxTotalBytes));
4911        pw.print(", sent: "); pw.println(formatBytesLocked(btTxTotalBytes));
4912
4913        final long bluetoothScanTimeMs = getBluetoothScanTime(rawRealtime, which) / 1000;
4914        sb.setLength(0);
4915        sb.append(prefix);
4916        sb.append("  Bluetooth scan time: "); formatTimeMs(sb, bluetoothScanTimeMs);
4917        pw.println(sb.toString());
4918
4919        printControllerActivity(pw, sb, prefix, "Bluetooth", getBluetoothControllerActivity(),
4920                which);
4921
4922        pw.println();
4923
4924        if (which == STATS_SINCE_UNPLUGGED) {
4925            if (getIsOnBattery()) {
4926                pw.print(prefix); pw.println("  Device is currently unplugged");
4927                pw.print(prefix); pw.print("    Discharge cycle start level: ");
4928                        pw.println(getDischargeStartLevel());
4929                pw.print(prefix); pw.print("    Discharge cycle current level: ");
4930                        pw.println(getDischargeCurrentLevel());
4931            } else {
4932                pw.print(prefix); pw.println("  Device is currently plugged into power");
4933                pw.print(prefix); pw.print("    Last discharge cycle start level: ");
4934                        pw.println(getDischargeStartLevel());
4935                pw.print(prefix); pw.print("    Last discharge cycle end level: ");
4936                        pw.println(getDischargeCurrentLevel());
4937            }
4938            pw.print(prefix); pw.print("    Amount discharged while screen on: ");
4939            pw.println(getDischargeAmountScreenOn());
4940            pw.print(prefix); pw.print("    Amount discharged while screen off: ");
4941            pw.println(getDischargeAmountScreenOff());
4942            pw.print(prefix); pw.print("    Amount discharged while screen doze: ");
4943            pw.println(getDischargeAmountScreenDoze());
4944            pw.println(" ");
4945        } else {
4946            pw.print(prefix); pw.println("  Device battery use since last full charge");
4947            pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
4948            pw.println(getLowDischargeAmountSinceCharge());
4949            pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
4950            pw.println(getHighDischargeAmountSinceCharge());
4951            pw.print(prefix); pw.print("    Amount discharged while screen on: ");
4952            pw.println(getDischargeAmountScreenOnSinceCharge());
4953            pw.print(prefix); pw.print("    Amount discharged while screen off: ");
4954            pw.println(getDischargeAmountScreenOffSinceCharge());
4955            pw.print(prefix); pw.print("    Amount discharged while screen doze: ");
4956            pw.println(getDischargeAmountScreenDozeSinceCharge());
4957            pw.println();
4958        }
4959
4960        final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
4961        helper.create(this);
4962        helper.refreshStats(which, UserHandle.USER_ALL);
4963        List<BatterySipper> sippers = helper.getUsageList();
4964        if (sippers != null && sippers.size() > 0) {
4965            pw.print(prefix); pw.println("  Estimated power use (mAh):");
4966            pw.print(prefix); pw.print("    Capacity: ");
4967                    printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
4968                    pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
4969                    pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower());
4970                    if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
4971                        pw.print("-"); printmAh(pw, helper.getMaxDrainedPower());
4972                    }
4973                    pw.println();
4974            for (int i=0; i<sippers.size(); i++) {
4975                final BatterySipper bs = sippers.get(i);
4976                pw.print(prefix);
4977                switch (bs.drainType) {
4978                    case IDLE:
4979                        pw.print("    Idle: ");
4980                        break;
4981                    case CELL:
4982                        pw.print("    Cell standby: ");
4983                        break;
4984                    case PHONE:
4985                        pw.print("    Phone calls: ");
4986                        break;
4987                    case WIFI:
4988                        pw.print("    Wifi: ");
4989                        break;
4990                    case BLUETOOTH:
4991                        pw.print("    Bluetooth: ");
4992                        break;
4993                    case SCREEN:
4994                        pw.print("    Screen: ");
4995                        break;
4996                    case FLASHLIGHT:
4997                        pw.print("    Flashlight: ");
4998                        break;
4999                    case APP:
5000                        pw.print("    Uid ");
5001                        UserHandle.formatUid(pw, bs.uidObj.getUid());
5002                        pw.print(": ");
5003                        break;
5004                    case USER:
5005                        pw.print("    User "); pw.print(bs.userId);
5006                        pw.print(": ");
5007                        break;
5008                    case UNACCOUNTED:
5009                        pw.print("    Unaccounted: ");
5010                        break;
5011                    case OVERCOUNTED:
5012                        pw.print("    Over-counted: ");
5013                        break;
5014                    case CAMERA:
5015                        pw.print("    Camera: ");
5016                        break;
5017                    default:
5018                        pw.print("    ???: ");
5019                        break;
5020                }
5021                printmAh(pw, bs.totalPowerMah);
5022
5023                if (bs.usagePowerMah != bs.totalPowerMah) {
5024                    // If the usage (generic power) isn't the whole amount, we list out
5025                    // what components are involved in the calculation.
5026
5027                    pw.print(" (");
5028                    if (bs.usagePowerMah != 0) {
5029                        pw.print(" usage=");
5030                        printmAh(pw, bs.usagePowerMah);
5031                    }
5032                    if (bs.cpuPowerMah != 0) {
5033                        pw.print(" cpu=");
5034                        printmAh(pw, bs.cpuPowerMah);
5035                    }
5036                    if (bs.wakeLockPowerMah != 0) {
5037                        pw.print(" wake=");
5038                        printmAh(pw, bs.wakeLockPowerMah);
5039                    }
5040                    if (bs.mobileRadioPowerMah != 0) {
5041                        pw.print(" radio=");
5042                        printmAh(pw, bs.mobileRadioPowerMah);
5043                    }
5044                    if (bs.wifiPowerMah != 0) {
5045                        pw.print(" wifi=");
5046                        printmAh(pw, bs.wifiPowerMah);
5047                    }
5048                    if (bs.bluetoothPowerMah != 0) {
5049                        pw.print(" bt=");
5050                        printmAh(pw, bs.bluetoothPowerMah);
5051                    }
5052                    if (bs.gpsPowerMah != 0) {
5053                        pw.print(" gps=");
5054                        printmAh(pw, bs.gpsPowerMah);
5055                    }
5056                    if (bs.sensorPowerMah != 0) {
5057                        pw.print(" sensor=");
5058                        printmAh(pw, bs.sensorPowerMah);
5059                    }
5060                    if (bs.cameraPowerMah != 0) {
5061                        pw.print(" camera=");
5062                        printmAh(pw, bs.cameraPowerMah);
5063                    }
5064                    if (bs.flashlightPowerMah != 0) {
5065                        pw.print(" flash=");
5066                        printmAh(pw, bs.flashlightPowerMah);
5067                    }
5068                    pw.print(" )");
5069                }
5070
5071                // If there is additional smearing information, include it.
5072                if (bs.totalSmearedPowerMah != bs.totalPowerMah) {
5073                    pw.print(" Including smearing: ");
5074                    printmAh(pw, bs.totalSmearedPowerMah);
5075                    pw.print(" (");
5076                    if (bs.screenPowerMah != 0) {
5077                        pw.print(" screen=");
5078                        printmAh(pw, bs.screenPowerMah);
5079                    }
5080                    if (bs.proportionalSmearMah != 0) {
5081                        pw.print(" proportional=");
5082                        printmAh(pw, bs.proportionalSmearMah);
5083                    }
5084                    pw.print(" )");
5085                }
5086                if (bs.shouldHide) {
5087                    pw.print(" Excluded from smearing");
5088                }
5089
5090                pw.println();
5091            }
5092            pw.println();
5093        }
5094
5095        sippers = helper.getMobilemsppList();
5096        if (sippers != null && sippers.size() > 0) {
5097            pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
5098            long totalTime = 0;
5099            for (int i=0; i<sippers.size(); i++) {
5100                final BatterySipper bs = sippers.get(i);
5101                sb.setLength(0);
5102                sb.append(prefix); sb.append("    Uid ");
5103                UserHandle.formatUid(sb, bs.uidObj.getUid());
5104                sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
5105                sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
5106                sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
5107                sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
5108                pw.println(sb.toString());
5109                totalTime += bs.mobileActive;
5110            }
5111            sb.setLength(0);
5112            sb.append(prefix);
5113            sb.append("    TOTAL TIME: ");
5114            formatTimeMs(sb, totalTime);
5115            sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
5116            sb.append(")");
5117            pw.println(sb.toString());
5118            pw.println();
5119        }
5120
5121        final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
5122            @Override
5123            public int compare(TimerEntry lhs, TimerEntry rhs) {
5124                long lhsTime = lhs.mTime;
5125                long rhsTime = rhs.mTime;
5126                if (lhsTime < rhsTime) {
5127                    return 1;
5128                }
5129                if (lhsTime > rhsTime) {
5130                    return -1;
5131                }
5132                return 0;
5133            }
5134        };
5135
5136        if (reqUid < 0) {
5137            final Map<String, ? extends BatteryStats.Timer> kernelWakelocks
5138                    = getKernelWakelockStats();
5139            if (kernelWakelocks.size() > 0) {
5140                final ArrayList<TimerEntry> ktimers = new ArrayList<>();
5141                for (Map.Entry<String, ? extends BatteryStats.Timer> ent
5142                        : kernelWakelocks.entrySet()) {
5143                    final BatteryStats.Timer timer = ent.getValue();
5144                    final long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
5145                    if (totalTimeMillis > 0) {
5146                        ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
5147                    }
5148                }
5149                if (ktimers.size() > 0) {
5150                    Collections.sort(ktimers, timerComparator);
5151                    pw.print(prefix); pw.println("  All kernel wake locks:");
5152                    for (int i=0; i<ktimers.size(); i++) {
5153                        final TimerEntry timer = ktimers.get(i);
5154                        String linePrefix = ": ";
5155                        sb.setLength(0);
5156                        sb.append(prefix);
5157                        sb.append("  Kernel Wake lock ");
5158                        sb.append(timer.mName);
5159                        linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null,
5160                                which, linePrefix);
5161                        if (!linePrefix.equals(": ")) {
5162                            sb.append(" realtime");
5163                            // Only print out wake locks that were held
5164                            pw.println(sb.toString());
5165                        }
5166                    }
5167                    pw.println();
5168                }
5169            }
5170
5171            if (timers.size() > 0) {
5172                Collections.sort(timers, timerComparator);
5173                pw.print(prefix); pw.println("  All partial wake locks:");
5174                for (int i=0; i<timers.size(); i++) {
5175                    TimerEntry timer = timers.get(i);
5176                    sb.setLength(0);
5177                    sb.append("  Wake lock ");
5178                    UserHandle.formatUid(sb, timer.mId);
5179                    sb.append(" ");
5180                    sb.append(timer.mName);
5181                    printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
5182                    sb.append(" realtime");
5183                    pw.println(sb.toString());
5184                }
5185                timers.clear();
5186                pw.println();
5187            }
5188
5189            final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
5190            if (wakeupReasons.size() > 0) {
5191                pw.print(prefix); pw.println("  All wakeup reasons:");
5192                final ArrayList<TimerEntry> reasons = new ArrayList<>();
5193                for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
5194                    final Timer timer = ent.getValue();
5195                    reasons.add(new TimerEntry(ent.getKey(), 0, timer,
5196                            timer.getCountLocked(which)));
5197                }
5198                Collections.sort(reasons, timerComparator);
5199                for (int i=0; i<reasons.size(); i++) {
5200                    TimerEntry timer = reasons.get(i);
5201                    String linePrefix = ": ";
5202                    sb.setLength(0);
5203                    sb.append(prefix);
5204                    sb.append("  Wakeup reason ");
5205                    sb.append(timer.mName);
5206                    printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
5207                    sb.append(" realtime");
5208                    pw.println(sb.toString());
5209                }
5210                pw.println();
5211            }
5212        }
5213
5214        final LongSparseArray<? extends Timer> mMemoryStats = getKernelMemoryStats();
5215        if (mMemoryStats.size() > 0) {
5216            pw.println("  Memory Stats");
5217            for (int i = 0; i < mMemoryStats.size(); i++) {
5218                sb.setLength(0);
5219                sb.append("  Bandwidth ");
5220                sb.append(mMemoryStats.keyAt(i));
5221                sb.append(" Time ");
5222                sb.append(mMemoryStats.valueAt(i).getTotalTimeLocked(rawRealtime, which));
5223                pw.println(sb.toString());
5224            }
5225            pw.println();
5226        }
5227
5228        final Map<String, ? extends Timer> rpmStats = getRpmStats();
5229        if (rpmStats.size() > 0) {
5230            pw.print(prefix); pw.println("  Resource Power Manager Stats");
5231            if (rpmStats.size() > 0) {
5232                for (Map.Entry<String, ? extends Timer> ent : rpmStats.entrySet()) {
5233                    final String timerName = ent.getKey();
5234                    final Timer timer = ent.getValue();
5235                    printTimer(pw, sb, timer, rawRealtime, which, prefix, timerName);
5236                }
5237            }
5238            pw.println();
5239        }
5240        if (SCREEN_OFF_RPM_STATS_ENABLED) {
5241            final Map<String, ? extends Timer> screenOffRpmStats = getScreenOffRpmStats();
5242            if (screenOffRpmStats.size() > 0) {
5243                pw.print(prefix);
5244                pw.println("  Resource Power Manager Stats for when screen was off");
5245                if (screenOffRpmStats.size() > 0) {
5246                    for (Map.Entry<String, ? extends Timer> ent : screenOffRpmStats.entrySet()) {
5247                        final String timerName = ent.getKey();
5248                        final Timer timer = ent.getValue();
5249                        printTimer(pw, sb, timer, rawRealtime, which, prefix, timerName);
5250                    }
5251                }
5252                pw.println();
5253            }
5254        }
5255
5256        final long[] cpuFreqs = getCpuFreqs();
5257        if (cpuFreqs != null) {
5258            sb.setLength(0);
5259            sb.append("  CPU freqs:");
5260            for (int i = 0; i < cpuFreqs.length; ++i) {
5261                sb.append(" " + cpuFreqs[i]);
5262            }
5263            pw.println(sb.toString());
5264            pw.println();
5265        }
5266
5267        for (int iu=0; iu<NU; iu++) {
5268            final int uid = uidStats.keyAt(iu);
5269            if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
5270                continue;
5271            }
5272
5273            final Uid u = uidStats.valueAt(iu);
5274
5275            pw.print(prefix);
5276            pw.print("  ");
5277            UserHandle.formatUid(pw, uid);
5278            pw.println(":");
5279            boolean uidActivity = false;
5280
5281            final long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
5282            final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
5283            final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
5284            final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
5285            final long btRxBytes = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
5286            final long btTxBytes = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
5287
5288            final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
5289            final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
5290            final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
5291            final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
5292
5293            final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
5294            final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
5295
5296            final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
5297            final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
5298            final int wifiScanCount = u.getWifiScanCount(which);
5299            final int wifiScanCountBg = u.getWifiScanBackgroundCount(which);
5300            // 'actualTime' are unpooled and always since reset (regardless of 'which')
5301            final long wifiScanActualTime = u.getWifiScanActualTime(rawRealtime);
5302            final long wifiScanActualTimeBg = u.getWifiScanBackgroundTime(rawRealtime);
5303            final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
5304
5305            final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
5306            final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
5307
5308            if (mobileRxBytes > 0 || mobileTxBytes > 0
5309                    || mobileRxPackets > 0 || mobileTxPackets > 0) {
5310                pw.print(prefix); pw.print("    Mobile network: ");
5311                        pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
5312                        pw.print(formatBytesLocked(mobileTxBytes));
5313                        pw.print(" sent (packets "); pw.print(mobileRxPackets);
5314                        pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
5315            }
5316            if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
5317                sb.setLength(0);
5318                sb.append(prefix); sb.append("    Mobile radio active: ");
5319                formatTimeMs(sb, uidMobileActiveTime / 1000);
5320                sb.append("(");
5321                sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
5322                sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
5323                long packets = mobileRxPackets + mobileTxPackets;
5324                if (packets == 0) {
5325                    packets = 1;
5326                }
5327                sb.append(" @ ");
5328                sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
5329                sb.append(" mspp");
5330                pw.println(sb.toString());
5331            }
5332
5333            if (mobileWakeup > 0) {
5334                sb.setLength(0);
5335                sb.append(prefix);
5336                sb.append("    Mobile radio AP wakeups: ");
5337                sb.append(mobileWakeup);
5338                pw.println(sb.toString());
5339            }
5340
5341            printControllerActivityIfInteresting(pw, sb, prefix + "  ",
5342                CELLULAR_CONTROLLER_NAME, u.getModemControllerActivity(), which);
5343
5344            if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
5345                pw.print(prefix); pw.print("    Wi-Fi network: ");
5346                        pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
5347                        pw.print(formatBytesLocked(wifiTxBytes));
5348                        pw.print(" sent (packets "); pw.print(wifiRxPackets);
5349                        pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
5350            }
5351
5352            if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
5353                    || wifiScanCountBg != 0 || wifiScanActualTime != 0 || wifiScanActualTimeBg != 0
5354                    || uidWifiRunningTime != 0) {
5355                sb.setLength(0);
5356                sb.append(prefix); sb.append("    Wifi Running: ");
5357                        formatTimeMs(sb, uidWifiRunningTime / 1000);
5358                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
5359                                whichBatteryRealtime)); sb.append(")\n");
5360                sb.append(prefix); sb.append("    Full Wifi Lock: ");
5361                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
5362                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
5363                                whichBatteryRealtime)); sb.append(")\n");
5364                sb.append(prefix); sb.append("    Wifi Scan (blamed): ");
5365                        formatTimeMs(sb, wifiScanTime / 1000);
5366                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
5367                                whichBatteryRealtime)); sb.append(") ");
5368                                sb.append(wifiScanCount);
5369                                sb.append("x\n");
5370                // actual and background times are unpooled and since reset (regardless of 'which')
5371                sb.append(prefix); sb.append("    Wifi Scan (actual): ");
5372                        formatTimeMs(sb, wifiScanActualTime / 1000);
5373                        sb.append("("); sb.append(formatRatioLocked(wifiScanActualTime,
5374                                computeBatteryRealtime(rawRealtime, STATS_SINCE_CHARGED)));
5375                                sb.append(") ");
5376                                sb.append(wifiScanCount);
5377                                sb.append("x\n");
5378                sb.append(prefix); sb.append("    Background Wifi Scan: ");
5379                        formatTimeMs(sb, wifiScanActualTimeBg / 1000);
5380                        sb.append("("); sb.append(formatRatioLocked(wifiScanActualTimeBg,
5381                                computeBatteryRealtime(rawRealtime, STATS_SINCE_CHARGED)));
5382                                sb.append(") ");
5383                                sb.append(wifiScanCountBg);
5384                                sb.append("x");
5385                pw.println(sb.toString());
5386            }
5387
5388            if (wifiWakeup > 0) {
5389                sb.setLength(0);
5390                sb.append(prefix);
5391                sb.append("    WiFi AP wakeups: ");
5392                sb.append(wifiWakeup);
5393                pw.println(sb.toString());
5394            }
5395
5396            printControllerActivityIfInteresting(pw, sb, prefix + "  ", WIFI_CONTROLLER_NAME,
5397                    u.getWifiControllerActivity(), which);
5398
5399            if (btRxBytes > 0 || btTxBytes > 0) {
5400                pw.print(prefix); pw.print("    Bluetooth network: ");
5401                pw.print(formatBytesLocked(btRxBytes)); pw.print(" received, ");
5402                pw.print(formatBytesLocked(btTxBytes));
5403                pw.println(" sent");
5404            }
5405
5406            final Timer bleTimer = u.getBluetoothScanTimer();
5407            if (bleTimer != null) {
5408                // Convert from microseconds to milliseconds with rounding
5409                final long totalTimeMs = (bleTimer.getTotalTimeLocked(rawRealtime, which) + 500)
5410                        / 1000;
5411                if (totalTimeMs != 0) {
5412                    final int count = bleTimer.getCountLocked(which);
5413                    final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
5414                    final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
5415                    // 'actualTime' are unpooled and always since reset (regardless of 'which')
5416                    final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
5417                    final long actualTimeMsBg = bleTimerBg != null ?
5418                            bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5419                    // Result counters
5420                    final int resultCount = u.getBluetoothScanResultCounter() != null ?
5421                            u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
5422                    final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
5423                            u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
5424                    // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
5425                    final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
5426                    final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
5427                            unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5428                    final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
5429                            unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
5430                    // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
5431                    final Timer unoptimizedScanTimerBg =
5432                            u.getBluetoothUnoptimizedScanBackgroundTimer();
5433                    final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
5434                            unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5435                    final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
5436                            unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
5437
5438                    sb.setLength(0);
5439                    if (actualTimeMs != totalTimeMs) {
5440                        sb.append(prefix);
5441                        sb.append("    Bluetooth Scan (total blamed realtime): ");
5442                        formatTimeMs(sb, totalTimeMs);
5443                        sb.append(" (");
5444                        sb.append(count);
5445                        sb.append(" times)");
5446                        if (bleTimer.isRunningLocked()) {
5447                            sb.append(" (currently running)");
5448                        }
5449                        sb.append("\n");
5450                    }
5451
5452                    sb.append(prefix);
5453                    sb.append("    Bluetooth Scan (total actual realtime): ");
5454                    formatTimeMs(sb, actualTimeMs); // since reset, ignores 'which'
5455                    sb.append(" (");
5456                    sb.append(count);
5457                    sb.append(" times)");
5458                    if (bleTimer.isRunningLocked()) {
5459                            sb.append(" (currently running)");
5460                    }
5461                    sb.append("\n");
5462                    if (actualTimeMsBg > 0 || countBg > 0) {
5463                        sb.append(prefix);
5464                        sb.append("    Bluetooth Scan (background realtime): ");
5465                        formatTimeMs(sb, actualTimeMsBg); // since reset, ignores 'which'
5466                        sb.append(" (");
5467                        sb.append(countBg);
5468                        sb.append(" times)");
5469                        if (bleTimerBg != null && bleTimerBg.isRunningLocked()) {
5470                            sb.append(" (currently running in background)");
5471                        }
5472                        sb.append("\n");
5473                    }
5474
5475                    sb.append(prefix);
5476                    sb.append("    Bluetooth Scan Results: ");
5477                    sb.append(resultCount);
5478                    sb.append(" (");
5479                    sb.append(resultCountBg);
5480                    sb.append(" in background)");
5481
5482                    if (unoptimizedScanTotalTime > 0 || unoptimizedScanTotalTimeBg > 0) {
5483                        sb.append("\n");
5484                        sb.append(prefix);
5485                        sb.append("    Unoptimized Bluetooth Scan (realtime): ");
5486                        formatTimeMs(sb, unoptimizedScanTotalTime); // since reset, ignores 'which'
5487                        sb.append(" (max ");
5488                        formatTimeMs(sb, unoptimizedScanMaxTime); // since reset, ignores 'which'
5489                        sb.append(")");
5490                        if (unoptimizedScanTimer != null
5491                                && unoptimizedScanTimer.isRunningLocked()) {
5492                            sb.append(" (currently running unoptimized)");
5493                        }
5494                        if (unoptimizedScanTimerBg != null && unoptimizedScanTotalTimeBg > 0) {
5495                            sb.append("\n");
5496                            sb.append(prefix);
5497                            sb.append("    Unoptimized Bluetooth Scan (background realtime): ");
5498                            formatTimeMs(sb, unoptimizedScanTotalTimeBg); // since reset
5499                            sb.append(" (max ");
5500                            formatTimeMs(sb, unoptimizedScanMaxTimeBg); // since reset
5501                            sb.append(")");
5502                            if (unoptimizedScanTimerBg.isRunningLocked()) {
5503                                sb.append(" (currently running unoptimized in background)");
5504                            }
5505                        }
5506                    }
5507                    pw.println(sb.toString());
5508                    uidActivity = true;
5509                }
5510            }
5511
5512
5513
5514            if (u.hasUserActivity()) {
5515                boolean hasData = false;
5516                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5517                    final int val = u.getUserActivityCount(i, which);
5518                    if (val != 0) {
5519                        if (!hasData) {
5520                            sb.setLength(0);
5521                            sb.append("    User activity: ");
5522                            hasData = true;
5523                        } else {
5524                            sb.append(", ");
5525                        }
5526                        sb.append(val);
5527                        sb.append(" ");
5528                        sb.append(Uid.USER_ACTIVITY_TYPES[i]);
5529                    }
5530                }
5531                if (hasData) {
5532                    pw.println(sb.toString());
5533                }
5534            }
5535
5536            final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
5537                    = u.getWakelockStats();
5538            long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
5539            long totalDrawWakelock = 0;
5540            int countWakelock = 0;
5541            for (int iw=wakelocks.size()-1; iw>=0; iw--) {
5542                final Uid.Wakelock wl = wakelocks.valueAt(iw);
5543                String linePrefix = ": ";
5544                sb.setLength(0);
5545                sb.append(prefix);
5546                sb.append("    Wake lock ");
5547                sb.append(wakelocks.keyAt(iw));
5548                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
5549                        "full", which, linePrefix);
5550                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
5551                linePrefix = printWakeLock(sb, pTimer, rawRealtime,
5552                        "partial", which, linePrefix);
5553                linePrefix = printWakeLock(sb, pTimer != null ? pTimer.getSubTimer() : null,
5554                        rawRealtime, "background partial", which, linePrefix);
5555                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
5556                        "window", which, linePrefix);
5557                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
5558                        "draw", which, linePrefix);
5559                sb.append(" realtime");
5560                pw.println(sb.toString());
5561                uidActivity = true;
5562                countWakelock++;
5563
5564                totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
5565                        rawRealtime, which);
5566                totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
5567                        rawRealtime, which);
5568                totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
5569                        rawRealtime, which);
5570                totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW),
5571                        rawRealtime, which);
5572            }
5573            if (countWakelock > 1) {
5574                // get unpooled partial wakelock quantities (unlike totalPartialWakelock, which is
5575                // pooled and therefore just a lower bound)
5576                long actualTotalPartialWakelock = 0;
5577                long actualBgPartialWakelock = 0;
5578                if (u.getAggregatedPartialWakelockTimer() != null) {
5579                    final Timer aggTimer = u.getAggregatedPartialWakelockTimer();
5580                    // Convert from microseconds to milliseconds with rounding
5581                    actualTotalPartialWakelock =
5582                            aggTimer.getTotalDurationMsLocked(rawRealtimeMs);
5583                    final Timer bgAggTimer = aggTimer.getSubTimer();
5584                    actualBgPartialWakelock = bgAggTimer != null ?
5585                            bgAggTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5586                }
5587
5588                if (actualTotalPartialWakelock != 0 || actualBgPartialWakelock != 0 ||
5589                        totalFullWakelock != 0 || totalPartialWakelock != 0 ||
5590                        totalWindowWakelock != 0) {
5591                    sb.setLength(0);
5592                    sb.append(prefix);
5593                    sb.append("    TOTAL wake: ");
5594                    boolean needComma = false;
5595                    if (totalFullWakelock != 0) {
5596                        needComma = true;
5597                        formatTimeMs(sb, totalFullWakelock);
5598                        sb.append("full");
5599                    }
5600                    if (totalPartialWakelock != 0) {
5601                        if (needComma) {
5602                            sb.append(", ");
5603                        }
5604                        needComma = true;
5605                        formatTimeMs(sb, totalPartialWakelock);
5606                        sb.append("blamed partial");
5607                    }
5608                    if (actualTotalPartialWakelock != 0) {
5609                        if (needComma) {
5610                            sb.append(", ");
5611                        }
5612                        needComma = true;
5613                        formatTimeMs(sb, actualTotalPartialWakelock);
5614                        sb.append("actual partial");
5615                    }
5616                    if (actualBgPartialWakelock != 0) {
5617                        if (needComma) {
5618                            sb.append(", ");
5619                        }
5620                        needComma = true;
5621                        formatTimeMs(sb, actualBgPartialWakelock);
5622                        sb.append("actual background partial");
5623                    }
5624                    if (totalWindowWakelock != 0) {
5625                        if (needComma) {
5626                            sb.append(", ");
5627                        }
5628                        needComma = true;
5629                        formatTimeMs(sb, totalWindowWakelock);
5630                        sb.append("window");
5631                    }
5632                    if (totalDrawWakelock != 0) {
5633                        if (needComma) {
5634                            sb.append(",");
5635                        }
5636                        needComma = true;
5637                        formatTimeMs(sb, totalDrawWakelock);
5638                        sb.append("draw");
5639                    }
5640                    sb.append(" realtime");
5641                    pw.println(sb.toString());
5642                }
5643            }
5644
5645            // Calculate multicast wakelock stats
5646            final Timer mcTimer = u.getMulticastWakelockStats();
5647            if (mcTimer != null) {
5648                final long multicastWakeLockTimeMicros = mcTimer.getTotalTimeLocked(rawRealtime, which);
5649                final int multicastWakeLockCount = mcTimer.getCountLocked(which);
5650
5651                if (multicastWakeLockTimeMicros > 0) {
5652                    sb.setLength(0);
5653                    sb.append(prefix);
5654                    sb.append("    WiFi Multicast Wakelock");
5655                    sb.append(" count = ");
5656                    sb.append(multicastWakeLockCount);
5657                    sb.append(" time = ");
5658                    formatTimeMsNoSpace(sb, (multicastWakeLockTimeMicros + 500) / 1000);
5659                    pw.println(sb.toString());
5660                }
5661            }
5662
5663            final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
5664            for (int isy=syncs.size()-1; isy>=0; isy--) {
5665                final Timer timer = syncs.valueAt(isy);
5666                // Convert from microseconds to milliseconds with rounding
5667                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
5668                final int count = timer.getCountLocked(which);
5669                final Timer bgTimer = timer.getSubTimer();
5670                final long bgTime = bgTimer != null ?
5671                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
5672                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
5673                sb.setLength(0);
5674                sb.append(prefix);
5675                sb.append("    Sync ");
5676                sb.append(syncs.keyAt(isy));
5677                sb.append(": ");
5678                if (totalTime != 0) {
5679                    formatTimeMs(sb, totalTime);
5680                    sb.append("realtime (");
5681                    sb.append(count);
5682                    sb.append(" times)");
5683                    if (bgTime > 0) {
5684                        sb.append(", ");
5685                        formatTimeMs(sb, bgTime);
5686                        sb.append("background (");
5687                        sb.append(bgCount);
5688                        sb.append(" times)");
5689                    }
5690                } else {
5691                    sb.append("(not used)");
5692                }
5693                pw.println(sb.toString());
5694                uidActivity = true;
5695            }
5696
5697            final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
5698            for (int ij=jobs.size()-1; ij>=0; ij--) {
5699                final Timer timer = jobs.valueAt(ij);
5700                // Convert from microseconds to milliseconds with rounding
5701                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
5702                final int count = timer.getCountLocked(which);
5703                final Timer bgTimer = timer.getSubTimer();
5704                final long bgTime = bgTimer != null ?
5705                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
5706                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
5707                sb.setLength(0);
5708                sb.append(prefix);
5709                sb.append("    Job ");
5710                sb.append(jobs.keyAt(ij));
5711                sb.append(": ");
5712                if (totalTime != 0) {
5713                    formatTimeMs(sb, totalTime);
5714                    sb.append("realtime (");
5715                    sb.append(count);
5716                    sb.append(" times)");
5717                    if (bgTime > 0) {
5718                        sb.append(", ");
5719                        formatTimeMs(sb, bgTime);
5720                        sb.append("background (");
5721                        sb.append(bgCount);
5722                        sb.append(" times)");
5723                    }
5724                } else {
5725                    sb.append("(not used)");
5726                }
5727                pw.println(sb.toString());
5728                uidActivity = true;
5729            }
5730
5731            final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
5732            for (int ic=completions.size()-1; ic>=0; ic--) {
5733                SparseIntArray types = completions.valueAt(ic);
5734                if (types != null) {
5735                    pw.print(prefix);
5736                    pw.print("    Job Completions ");
5737                    pw.print(completions.keyAt(ic));
5738                    pw.print(":");
5739                    for (int it=0; it<types.size(); it++) {
5740                        pw.print(" ");
5741                        pw.print(JobParameters.getReasonName(types.keyAt(it)));
5742                        pw.print("(");
5743                        pw.print(types.valueAt(it));
5744                        pw.print("x)");
5745                    }
5746                    pw.println();
5747                }
5748            }
5749
5750            u.getDeferredJobsLineLocked(sb, which);
5751            if (sb.length() > 0) {
5752                pw.print("    Jobs deferred on launch "); pw.println(sb.toString());
5753            }
5754
5755            uidActivity |= printTimer(pw, sb, u.getFlashlightTurnedOnTimer(), rawRealtime, which,
5756                    prefix, "Flashlight");
5757            uidActivity |= printTimer(pw, sb, u.getCameraTurnedOnTimer(), rawRealtime, which,
5758                    prefix, "Camera");
5759            uidActivity |= printTimer(pw, sb, u.getVideoTurnedOnTimer(), rawRealtime, which,
5760                    prefix, "Video");
5761            uidActivity |= printTimer(pw, sb, u.getAudioTurnedOnTimer(), rawRealtime, which,
5762                    prefix, "Audio");
5763
5764            final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
5765            final int NSE = sensors.size();
5766            for (int ise=0; ise<NSE; ise++) {
5767                final Uid.Sensor se = sensors.valueAt(ise);
5768                final int sensorNumber = sensors.keyAt(ise);
5769                sb.setLength(0);
5770                sb.append(prefix);
5771                sb.append("    Sensor ");
5772                int handle = se.getHandle();
5773                if (handle == Uid.Sensor.GPS) {
5774                    sb.append("GPS");
5775                } else {
5776                    sb.append(handle);
5777                }
5778                sb.append(": ");
5779
5780                final Timer timer = se.getSensorTime();
5781                if (timer != null) {
5782                    // Convert from microseconds to milliseconds with rounding
5783                    final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
5784                            / 1000;
5785                    final int count = timer.getCountLocked(which);
5786                    final Timer bgTimer = se.getSensorBackgroundTime();
5787                    final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
5788                    // 'actualTime' are unpooled and always since reset (regardless of 'which')
5789                    final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
5790                    final long bgActualTime = bgTimer != null ?
5791                            bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
5792
5793                    //timer.logState();
5794                    if (totalTime != 0) {
5795                        if (actualTime != totalTime) {
5796                            formatTimeMs(sb, totalTime);
5797                            sb.append("blamed realtime, ");
5798                        }
5799
5800                        formatTimeMs(sb, actualTime); // since reset, regardless of 'which'
5801                        sb.append("realtime (");
5802                        sb.append(count);
5803                        sb.append(" times)");
5804
5805                        if (bgActualTime != 0 || bgCount > 0) {
5806                            sb.append(", ");
5807                            formatTimeMs(sb, bgActualTime); // since reset, regardless of 'which'
5808                            sb.append("background (");
5809                            sb.append(bgCount);
5810                            sb.append(" times)");
5811                        }
5812                    } else {
5813                        sb.append("(not used)");
5814                    }
5815                } else {
5816                    sb.append("(not used)");
5817                }
5818
5819                pw.println(sb.toString());
5820                uidActivity = true;
5821            }
5822
5823            uidActivity |= printTimer(pw, sb, u.getVibratorOnTimer(), rawRealtime, which, prefix,
5824                    "Vibrator");
5825            uidActivity |= printTimer(pw, sb, u.getForegroundActivityTimer(), rawRealtime, which,
5826                    prefix, "Foreground activities");
5827            uidActivity |= printTimer(pw, sb, u.getForegroundServiceTimer(), rawRealtime, which,
5828                    prefix, "Foreground services");
5829
5830            long totalStateTime = 0;
5831            for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
5832                long time = u.getProcessStateTime(ips, rawRealtime, which);
5833                if (time > 0) {
5834                    totalStateTime += time;
5835                    sb.setLength(0);
5836                    sb.append(prefix);
5837                    sb.append("    ");
5838                    sb.append(Uid.PROCESS_STATE_NAMES[ips]);
5839                    sb.append(" for: ");
5840                    formatTimeMs(sb, (time + 500) / 1000);
5841                    pw.println(sb.toString());
5842                    uidActivity = true;
5843                }
5844            }
5845            if (totalStateTime > 0) {
5846                sb.setLength(0);
5847                sb.append(prefix);
5848                sb.append("    Total running: ");
5849                formatTimeMs(sb, (totalStateTime + 500) / 1000);
5850                pw.println(sb.toString());
5851            }
5852
5853            final long userCpuTimeUs = u.getUserCpuTimeUs(which);
5854            final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
5855            if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
5856                sb.setLength(0);
5857                sb.append(prefix);
5858                sb.append("    Total cpu time: u=");
5859                formatTimeMs(sb, userCpuTimeUs / 1000);
5860                sb.append("s=");
5861                formatTimeMs(sb, systemCpuTimeUs / 1000);
5862                pw.println(sb.toString());
5863            }
5864
5865            final long[] cpuFreqTimes = u.getCpuFreqTimes(which);
5866            if (cpuFreqTimes != null) {
5867                sb.setLength(0);
5868                sb.append("    Total cpu time per freq:");
5869                for (int i = 0; i < cpuFreqTimes.length; ++i) {
5870                    sb.append(" " + cpuFreqTimes[i]);
5871                }
5872                pw.println(sb.toString());
5873            }
5874            final long[] screenOffCpuFreqTimes = u.getScreenOffCpuFreqTimes(which);
5875            if (screenOffCpuFreqTimes != null) {
5876                sb.setLength(0);
5877                sb.append("    Total screen-off cpu time per freq:");
5878                for (int i = 0; i < screenOffCpuFreqTimes.length; ++i) {
5879                    sb.append(" " + screenOffCpuFreqTimes[i]);
5880                }
5881                pw.println(sb.toString());
5882            }
5883
5884            for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
5885                final long[] cpuTimes = u.getCpuFreqTimes(which, procState);
5886                if (cpuTimes != null) {
5887                    sb.setLength(0);
5888                    sb.append("    Cpu times per freq at state "
5889                            + Uid.PROCESS_STATE_NAMES[procState] + ":");
5890                    for (int i = 0; i < cpuTimes.length; ++i) {
5891                        sb.append(" " + cpuTimes[i]);
5892                    }
5893                    pw.println(sb.toString());
5894                }
5895
5896                final long[] screenOffCpuTimes = u.getScreenOffCpuFreqTimes(which, procState);
5897                if (screenOffCpuTimes != null) {
5898                    sb.setLength(0);
5899                    sb.append("   Screen-off cpu times per freq at state "
5900                            + Uid.PROCESS_STATE_NAMES[procState] + ":");
5901                    for (int i = 0; i < screenOffCpuTimes.length; ++i) {
5902                        sb.append(" " + screenOffCpuTimes[i]);
5903                    }
5904                    pw.println(sb.toString());
5905                }
5906            }
5907
5908            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
5909                    = u.getProcessStats();
5910            for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
5911                final Uid.Proc ps = processStats.valueAt(ipr);
5912                long userTime;
5913                long systemTime;
5914                long foregroundTime;
5915                int starts;
5916                int numExcessive;
5917
5918                userTime = ps.getUserTime(which);
5919                systemTime = ps.getSystemTime(which);
5920                foregroundTime = ps.getForegroundTime(which);
5921                starts = ps.getStarts(which);
5922                final int numCrashes = ps.getNumCrashes(which);
5923                final int numAnrs = ps.getNumAnrs(which);
5924                numExcessive = which == STATS_SINCE_CHARGED
5925                        ? ps.countExcessivePowers() : 0;
5926
5927                if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
5928                        || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
5929                    sb.setLength(0);
5930                    sb.append(prefix); sb.append("    Proc ");
5931                            sb.append(processStats.keyAt(ipr)); sb.append(":\n");
5932                    sb.append(prefix); sb.append("      CPU: ");
5933                            formatTimeMs(sb, userTime); sb.append("usr + ");
5934                            formatTimeMs(sb, systemTime); sb.append("krn ; ");
5935                            formatTimeMs(sb, foregroundTime); sb.append("fg");
5936                    if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
5937                        sb.append("\n"); sb.append(prefix); sb.append("      ");
5938                        boolean hasOne = false;
5939                        if (starts != 0) {
5940                            hasOne = true;
5941                            sb.append(starts); sb.append(" starts");
5942                        }
5943                        if (numCrashes != 0) {
5944                            if (hasOne) {
5945                                sb.append(", ");
5946                            }
5947                            hasOne = true;
5948                            sb.append(numCrashes); sb.append(" crashes");
5949                        }
5950                        if (numAnrs != 0) {
5951                            if (hasOne) {
5952                                sb.append(", ");
5953                            }
5954                            sb.append(numAnrs); sb.append(" anrs");
5955                        }
5956                    }
5957                    pw.println(sb.toString());
5958                    for (int e=0; e<numExcessive; e++) {
5959                        Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
5960                        if (ew != null) {
5961                            pw.print(prefix); pw.print("      * Killed for ");
5962                                    if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
5963                                        pw.print("cpu");
5964                                    } else {
5965                                        pw.print("unknown");
5966                                    }
5967                                    pw.print(" use: ");
5968                                    TimeUtils.formatDuration(ew.usedTime, pw);
5969                                    pw.print(" over ");
5970                                    TimeUtils.formatDuration(ew.overTime, pw);
5971                                    if (ew.overTime != 0) {
5972                                        pw.print(" (");
5973                                        pw.print((ew.usedTime*100)/ew.overTime);
5974                                        pw.println("%)");
5975                                    }
5976                        }
5977                    }
5978                    uidActivity = true;
5979                }
5980            }
5981
5982            final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
5983                    = u.getPackageStats();
5984            for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
5985                pw.print(prefix); pw.print("    Apk "); pw.print(packageStats.keyAt(ipkg));
5986                pw.println(":");
5987                boolean apkActivity = false;
5988                final Uid.Pkg ps = packageStats.valueAt(ipkg);
5989                final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
5990                for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
5991                    pw.print(prefix); pw.print("      Wakeup alarm ");
5992                            pw.print(alarms.keyAt(iwa)); pw.print(": ");
5993                            pw.print(alarms.valueAt(iwa).getCountLocked(which));
5994                            pw.println(" times");
5995                    apkActivity = true;
5996                }
5997                final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
5998                for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
5999                    final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
6000                    final long startTime = ss.getStartTime(batteryUptime, which);
6001                    final int starts = ss.getStarts(which);
6002                    final int launches = ss.getLaunches(which);
6003                    if (startTime != 0 || starts != 0 || launches != 0) {
6004                        sb.setLength(0);
6005                        sb.append(prefix); sb.append("      Service ");
6006                                sb.append(serviceStats.keyAt(isvc)); sb.append(":\n");
6007                        sb.append(prefix); sb.append("        Created for: ");
6008                                formatTimeMs(sb, startTime / 1000);
6009                                sb.append("uptime\n");
6010                        sb.append(prefix); sb.append("        Starts: ");
6011                                sb.append(starts);
6012                                sb.append(", launches: "); sb.append(launches);
6013                        pw.println(sb.toString());
6014                        apkActivity = true;
6015                    }
6016                }
6017                if (!apkActivity) {
6018                    pw.print(prefix); pw.println("      (nothing executed)");
6019                }
6020                uidActivity = true;
6021            }
6022            if (!uidActivity) {
6023                pw.print(prefix); pw.println("    (nothing executed)");
6024            }
6025        }
6026    }
6027
6028    static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag,
6029            BitDescription[] descriptions, boolean longNames) {
6030        int diff = oldval ^ newval;
6031        if (diff == 0) return;
6032        boolean didWake = false;
6033        for (int i=0; i<descriptions.length; i++) {
6034            BitDescription bd = descriptions[i];
6035            if ((diff&bd.mask) != 0) {
6036                pw.print(longNames ? " " : ",");
6037                if (bd.shift < 0) {
6038                    pw.print((newval&bd.mask) != 0 ? "+" : "-");
6039                    pw.print(longNames ? bd.name : bd.shortName);
6040                    if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
6041                        didWake = true;
6042                        pw.print("=");
6043                        if (longNames) {
6044                            UserHandle.formatUid(pw, wakelockTag.uid);
6045                            pw.print(":\"");
6046                            pw.print(wakelockTag.string);
6047                            pw.print("\"");
6048                        } else {
6049                            pw.print(wakelockTag.poolIdx);
6050                        }
6051                    }
6052                } else {
6053                    pw.print(longNames ? bd.name : bd.shortName);
6054                    pw.print("=");
6055                    int val = (newval&bd.mask)>>bd.shift;
6056                    if (bd.values != null && val >= 0 && val < bd.values.length) {
6057                        pw.print(longNames? bd.values[val] : bd.shortValues[val]);
6058                    } else {
6059                        pw.print(val);
6060                    }
6061                }
6062            }
6063        }
6064        if (!didWake && wakelockTag != null) {
6065            pw.print(longNames ? " wake_lock=" : ",w=");
6066            if (longNames) {
6067                UserHandle.formatUid(pw, wakelockTag.uid);
6068                pw.print(":\"");
6069                pw.print(wakelockTag.string);
6070                pw.print("\"");
6071            } else {
6072                pw.print(wakelockTag.poolIdx);
6073            }
6074        }
6075    }
6076
6077    public void prepareForDumpLocked() {
6078        // We don't need to require subclasses implement this.
6079    }
6080
6081    public static class HistoryPrinter {
6082        int oldState = 0;
6083        int oldState2 = 0;
6084        int oldLevel = -1;
6085        int oldStatus = -1;
6086        int oldHealth = -1;
6087        int oldPlug = -1;
6088        int oldTemp = -1;
6089        int oldVolt = -1;
6090        int oldChargeMAh = -1;
6091        long lastTime = -1;
6092
6093        void reset() {
6094            oldState = oldState2 = 0;
6095            oldLevel = -1;
6096            oldStatus = -1;
6097            oldHealth = -1;
6098            oldPlug = -1;
6099            oldTemp = -1;
6100            oldVolt = -1;
6101            oldChargeMAh = -1;
6102        }
6103
6104        public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
6105                boolean verbose) {
6106            if (!checkin) {
6107                pw.print("  ");
6108                TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
6109                pw.print(" (");
6110                pw.print(rec.numReadInts);
6111                pw.print(") ");
6112            } else {
6113                pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
6114                pw.print(HISTORY_DATA); pw.print(',');
6115                if (lastTime < 0) {
6116                    pw.print(rec.time - baseTime);
6117                } else {
6118                    pw.print(rec.time - lastTime);
6119                }
6120                lastTime = rec.time;
6121            }
6122            if (rec.cmd == HistoryItem.CMD_START) {
6123                if (checkin) {
6124                    pw.print(":");
6125                }
6126                pw.println("START");
6127                reset();
6128            } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
6129                    || rec.cmd == HistoryItem.CMD_RESET) {
6130                if (checkin) {
6131                    pw.print(":");
6132                }
6133                if (rec.cmd == HistoryItem.CMD_RESET) {
6134                    pw.print("RESET:");
6135                    reset();
6136                }
6137                pw.print("TIME:");
6138                if (checkin) {
6139                    pw.println(rec.currentTime);
6140                } else {
6141                    pw.print(" ");
6142                    pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6143                            rec.currentTime).toString());
6144                }
6145            } else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) {
6146                if (checkin) {
6147                    pw.print(":");
6148                }
6149                pw.println("SHUTDOWN");
6150            } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
6151                if (checkin) {
6152                    pw.print(":");
6153                }
6154                pw.println("*OVERFLOW*");
6155            } else {
6156                if (!checkin) {
6157                    if (rec.batteryLevel < 10) pw.print("00");
6158                    else if (rec.batteryLevel < 100) pw.print("0");
6159                    pw.print(rec.batteryLevel);
6160                    if (verbose) {
6161                        pw.print(" ");
6162                        if (rec.states < 0) ;
6163                        else if (rec.states < 0x10) pw.print("0000000");
6164                        else if (rec.states < 0x100) pw.print("000000");
6165                        else if (rec.states < 0x1000) pw.print("00000");
6166                        else if (rec.states < 0x10000) pw.print("0000");
6167                        else if (rec.states < 0x100000) pw.print("000");
6168                        else if (rec.states < 0x1000000) pw.print("00");
6169                        else if (rec.states < 0x10000000) pw.print("0");
6170                        pw.print(Integer.toHexString(rec.states));
6171                    }
6172                } else {
6173                    if (oldLevel != rec.batteryLevel) {
6174                        oldLevel = rec.batteryLevel;
6175                        pw.print(",Bl="); pw.print(rec.batteryLevel);
6176                    }
6177                }
6178                if (oldStatus != rec.batteryStatus) {
6179                    oldStatus = rec.batteryStatus;
6180                    pw.print(checkin ? ",Bs=" : " status=");
6181                    switch (oldStatus) {
6182                        case BatteryManager.BATTERY_STATUS_UNKNOWN:
6183                            pw.print(checkin ? "?" : "unknown");
6184                            break;
6185                        case BatteryManager.BATTERY_STATUS_CHARGING:
6186                            pw.print(checkin ? "c" : "charging");
6187                            break;
6188                        case BatteryManager.BATTERY_STATUS_DISCHARGING:
6189                            pw.print(checkin ? "d" : "discharging");
6190                            break;
6191                        case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
6192                            pw.print(checkin ? "n" : "not-charging");
6193                            break;
6194                        case BatteryManager.BATTERY_STATUS_FULL:
6195                            pw.print(checkin ? "f" : "full");
6196                            break;
6197                        default:
6198                            pw.print(oldStatus);
6199                            break;
6200                    }
6201                }
6202                if (oldHealth != rec.batteryHealth) {
6203                    oldHealth = rec.batteryHealth;
6204                    pw.print(checkin ? ",Bh=" : " health=");
6205                    switch (oldHealth) {
6206                        case BatteryManager.BATTERY_HEALTH_UNKNOWN:
6207                            pw.print(checkin ? "?" : "unknown");
6208                            break;
6209                        case BatteryManager.BATTERY_HEALTH_GOOD:
6210                            pw.print(checkin ? "g" : "good");
6211                            break;
6212                        case BatteryManager.BATTERY_HEALTH_OVERHEAT:
6213                            pw.print(checkin ? "h" : "overheat");
6214                            break;
6215                        case BatteryManager.BATTERY_HEALTH_DEAD:
6216                            pw.print(checkin ? "d" : "dead");
6217                            break;
6218                        case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
6219                            pw.print(checkin ? "v" : "over-voltage");
6220                            break;
6221                        case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
6222                            pw.print(checkin ? "f" : "failure");
6223                            break;
6224                        case BatteryManager.BATTERY_HEALTH_COLD:
6225                            pw.print(checkin ? "c" : "cold");
6226                            break;
6227                        default:
6228                            pw.print(oldHealth);
6229                            break;
6230                    }
6231                }
6232                if (oldPlug != rec.batteryPlugType) {
6233                    oldPlug = rec.batteryPlugType;
6234                    pw.print(checkin ? ",Bp=" : " plug=");
6235                    switch (oldPlug) {
6236                        case 0:
6237                            pw.print(checkin ? "n" : "none");
6238                            break;
6239                        case BatteryManager.BATTERY_PLUGGED_AC:
6240                            pw.print(checkin ? "a" : "ac");
6241                            break;
6242                        case BatteryManager.BATTERY_PLUGGED_USB:
6243                            pw.print(checkin ? "u" : "usb");
6244                            break;
6245                        case BatteryManager.BATTERY_PLUGGED_WIRELESS:
6246                            pw.print(checkin ? "w" : "wireless");
6247                            break;
6248                        default:
6249                            pw.print(oldPlug);
6250                            break;
6251                    }
6252                }
6253                if (oldTemp != rec.batteryTemperature) {
6254                    oldTemp = rec.batteryTemperature;
6255                    pw.print(checkin ? ",Bt=" : " temp=");
6256                    pw.print(oldTemp);
6257                }
6258                if (oldVolt != rec.batteryVoltage) {
6259                    oldVolt = rec.batteryVoltage;
6260                    pw.print(checkin ? ",Bv=" : " volt=");
6261                    pw.print(oldVolt);
6262                }
6263                final int chargeMAh = rec.batteryChargeUAh / 1000;
6264                if (oldChargeMAh != chargeMAh) {
6265                    oldChargeMAh = chargeMAh;
6266                    pw.print(checkin ? ",Bcc=" : " charge=");
6267                    pw.print(oldChargeMAh);
6268                }
6269                printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
6270                        HISTORY_STATE_DESCRIPTIONS, !checkin);
6271                printBitDescriptions(pw, oldState2, rec.states2, null,
6272                        HISTORY_STATE2_DESCRIPTIONS, !checkin);
6273                if (rec.wakeReasonTag != null) {
6274                    if (checkin) {
6275                        pw.print(",wr=");
6276                        pw.print(rec.wakeReasonTag.poolIdx);
6277                    } else {
6278                        pw.print(" wake_reason=");
6279                        pw.print(rec.wakeReasonTag.uid);
6280                        pw.print(":\"");
6281                        pw.print(rec.wakeReasonTag.string);
6282                        pw.print("\"");
6283                    }
6284                }
6285                if (rec.eventCode != HistoryItem.EVENT_NONE) {
6286                    pw.print(checkin ? "," : " ");
6287                    if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
6288                        pw.print("+");
6289                    } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
6290                        pw.print("-");
6291                    }
6292                    String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
6293                            : HISTORY_EVENT_NAMES;
6294                    int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
6295                            | HistoryItem.EVENT_FLAG_FINISH);
6296                    if (idx >= 0 && idx < eventNames.length) {
6297                        pw.print(eventNames[idx]);
6298                    } else {
6299                        pw.print(checkin ? "Ev" : "event");
6300                        pw.print(idx);
6301                    }
6302                    pw.print("=");
6303                    if (checkin) {
6304                        pw.print(rec.eventTag.poolIdx);
6305                    } else {
6306                        pw.append(HISTORY_EVENT_INT_FORMATTERS[idx]
6307                                .applyAsString(rec.eventTag.uid));
6308                        pw.print(":\"");
6309                        pw.print(rec.eventTag.string);
6310                        pw.print("\"");
6311                    }
6312                }
6313                pw.println();
6314                if (rec.stepDetails != null) {
6315                    if (!checkin) {
6316                        pw.print("                 Details: cpu=");
6317                        pw.print(rec.stepDetails.userTime);
6318                        pw.print("u+");
6319                        pw.print(rec.stepDetails.systemTime);
6320                        pw.print("s");
6321                        if (rec.stepDetails.appCpuUid1 >= 0) {
6322                            pw.print(" (");
6323                            printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid1,
6324                                    rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
6325                            if (rec.stepDetails.appCpuUid2 >= 0) {
6326                                pw.print(", ");
6327                                printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid2,
6328                                        rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
6329                            }
6330                            if (rec.stepDetails.appCpuUid3 >= 0) {
6331                                pw.print(", ");
6332                                printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid3,
6333                                        rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
6334                            }
6335                            pw.print(')');
6336                        }
6337                        pw.println();
6338                        pw.print("                          /proc/stat=");
6339                        pw.print(rec.stepDetails.statUserTime);
6340                        pw.print(" usr, ");
6341                        pw.print(rec.stepDetails.statSystemTime);
6342                        pw.print(" sys, ");
6343                        pw.print(rec.stepDetails.statIOWaitTime);
6344                        pw.print(" io, ");
6345                        pw.print(rec.stepDetails.statIrqTime);
6346                        pw.print(" irq, ");
6347                        pw.print(rec.stepDetails.statSoftIrqTime);
6348                        pw.print(" sirq, ");
6349                        pw.print(rec.stepDetails.statIdlTime);
6350                        pw.print(" idle");
6351                        int totalRun = rec.stepDetails.statUserTime + rec.stepDetails.statSystemTime
6352                                + rec.stepDetails.statIOWaitTime + rec.stepDetails.statIrqTime
6353                                + rec.stepDetails.statSoftIrqTime;
6354                        int total = totalRun + rec.stepDetails.statIdlTime;
6355                        if (total > 0) {
6356                            pw.print(" (");
6357                            float perc = ((float)totalRun) / ((float)total) * 100;
6358                            pw.print(String.format("%.1f%%", perc));
6359                            pw.print(" of ");
6360                            StringBuilder sb = new StringBuilder(64);
6361                            formatTimeMsNoSpace(sb, total*10);
6362                            pw.print(sb);
6363                            pw.print(")");
6364                        }
6365                        pw.print(", PlatformIdleStat ");
6366                        pw.print(rec.stepDetails.statPlatformIdleState);
6367                        pw.println();
6368
6369                        pw.print(", SubsystemPowerState ");
6370                        pw.print(rec.stepDetails.statSubsystemPowerState);
6371                        pw.println();
6372                    } else {
6373                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
6374                        pw.print(HISTORY_DATA); pw.print(",0,Dcpu=");
6375                        pw.print(rec.stepDetails.userTime);
6376                        pw.print(":");
6377                        pw.print(rec.stepDetails.systemTime);
6378                        if (rec.stepDetails.appCpuUid1 >= 0) {
6379                            printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid1,
6380                                    rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
6381                            if (rec.stepDetails.appCpuUid2 >= 0) {
6382                                printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid2,
6383                                        rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
6384                            }
6385                            if (rec.stepDetails.appCpuUid3 >= 0) {
6386                                printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid3,
6387                                        rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
6388                            }
6389                        }
6390                        pw.println();
6391                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
6392                        pw.print(HISTORY_DATA); pw.print(",0,Dpst=");
6393                        pw.print(rec.stepDetails.statUserTime);
6394                        pw.print(',');
6395                        pw.print(rec.stepDetails.statSystemTime);
6396                        pw.print(',');
6397                        pw.print(rec.stepDetails.statIOWaitTime);
6398                        pw.print(',');
6399                        pw.print(rec.stepDetails.statIrqTime);
6400                        pw.print(',');
6401                        pw.print(rec.stepDetails.statSoftIrqTime);
6402                        pw.print(',');
6403                        pw.print(rec.stepDetails.statIdlTime);
6404                        pw.print(',');
6405                        if (rec.stepDetails.statPlatformIdleState != null) {
6406                            pw.print(rec.stepDetails.statPlatformIdleState);
6407                            if (rec.stepDetails.statSubsystemPowerState != null) {
6408                                pw.print(',');
6409                            }
6410                        }
6411
6412                        if (rec.stepDetails.statSubsystemPowerState != null) {
6413                            pw.print(rec.stepDetails.statSubsystemPowerState);
6414                        }
6415                        pw.println();
6416                    }
6417                }
6418                oldState = rec.states;
6419                oldState2 = rec.states2;
6420            }
6421        }
6422
6423        private void printStepCpuUidDetails(PrintWriter pw, int uid, int utime, int stime) {
6424            UserHandle.formatUid(pw, uid);
6425            pw.print("=");
6426            pw.print(utime);
6427            pw.print("u+");
6428            pw.print(stime);
6429            pw.print("s");
6430        }
6431
6432        private void printStepCpuUidCheckinDetails(PrintWriter pw, int uid, int utime, int stime) {
6433            pw.print('/');
6434            pw.print(uid);
6435            pw.print(":");
6436            pw.print(utime);
6437            pw.print(":");
6438            pw.print(stime);
6439        }
6440    }
6441
6442    private void printSizeValue(PrintWriter pw, long size) {
6443        float result = size;
6444        String suffix = "";
6445        if (result >= 10*1024) {
6446            suffix = "KB";
6447            result = result / 1024;
6448        }
6449        if (result >= 10*1024) {
6450            suffix = "MB";
6451            result = result / 1024;
6452        }
6453        if (result >= 10*1024) {
6454            suffix = "GB";
6455            result = result / 1024;
6456        }
6457        if (result >= 10*1024) {
6458            suffix = "TB";
6459            result = result / 1024;
6460        }
6461        if (result >= 10*1024) {
6462            suffix = "PB";
6463            result = result / 1024;
6464        }
6465        pw.print((int)result);
6466        pw.print(suffix);
6467    }
6468
6469    private static boolean dumpTimeEstimate(PrintWriter pw, String label1, String label2,
6470            String label3, long estimatedTime) {
6471        if (estimatedTime < 0) {
6472            return false;
6473        }
6474        pw.print(label1);
6475        pw.print(label2);
6476        pw.print(label3);
6477        StringBuilder sb = new StringBuilder(64);
6478        formatTimeMs(sb, estimatedTime);
6479        pw.print(sb);
6480        pw.println();
6481        return true;
6482    }
6483
6484    private static boolean dumpDurationSteps(PrintWriter pw, String prefix, String header,
6485            LevelStepTracker steps, boolean checkin) {
6486        if (steps == null) {
6487            return false;
6488        }
6489        int count = steps.mNumStepDurations;
6490        if (count <= 0) {
6491            return false;
6492        }
6493        if (!checkin) {
6494            pw.println(header);
6495        }
6496        String[] lineArgs = new String[5];
6497        for (int i=0; i<count; i++) {
6498            long duration = steps.getDurationAt(i);
6499            int level = steps.getLevelAt(i);
6500            long initMode = steps.getInitModeAt(i);
6501            long modMode = steps.getModModeAt(i);
6502            if (checkin) {
6503                lineArgs[0] = Long.toString(duration);
6504                lineArgs[1] = Integer.toString(level);
6505                if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
6506                    switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
6507                        case Display.STATE_OFF: lineArgs[2] = "s-"; break;
6508                        case Display.STATE_ON: lineArgs[2] = "s+"; break;
6509                        case Display.STATE_DOZE: lineArgs[2] = "sd"; break;
6510                        case Display.STATE_DOZE_SUSPEND: lineArgs[2] = "sds"; break;
6511                        default: lineArgs[2] = "?"; break;
6512                    }
6513                } else {
6514                    lineArgs[2] = "";
6515                }
6516                if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
6517                    lineArgs[3] = (initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 ? "p+" : "p-";
6518                } else {
6519                    lineArgs[3] = "";
6520                }
6521                if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
6522                    lineArgs[4] = (initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0 ? "i+" : "i-";
6523                } else {
6524                    lineArgs[4] = "";
6525                }
6526                dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs);
6527            } else {
6528                pw.print(prefix);
6529                pw.print("#"); pw.print(i); pw.print(": ");
6530                TimeUtils.formatDuration(duration, pw);
6531                pw.print(" to "); pw.print(level);
6532                boolean haveModes = false;
6533                if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
6534                    pw.print(" (");
6535                    switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
6536                        case Display.STATE_OFF: pw.print("screen-off"); break;
6537                        case Display.STATE_ON: pw.print("screen-on"); break;
6538                        case Display.STATE_DOZE: pw.print("screen-doze"); break;
6539                        case Display.STATE_DOZE_SUSPEND: pw.print("screen-doze-suspend"); break;
6540                        default: pw.print("screen-?"); break;
6541                    }
6542                    haveModes = true;
6543                }
6544                if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
6545                    pw.print(haveModes ? ", " : " (");
6546                    pw.print((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0
6547                            ? "power-save-on" : "power-save-off");
6548                    haveModes = true;
6549                }
6550                if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
6551                    pw.print(haveModes ? ", " : " (");
6552                    pw.print((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0
6553                            ? "device-idle-on" : "device-idle-off");
6554                    haveModes = true;
6555                }
6556                if (haveModes) {
6557                    pw.print(")");
6558                }
6559                pw.println();
6560            }
6561        }
6562        return true;
6563    }
6564
6565    private static void dumpDurationSteps(ProtoOutputStream proto, long fieldId,
6566            LevelStepTracker steps) {
6567        if (steps == null) {
6568            return;
6569        }
6570        int count = steps.mNumStepDurations;
6571        for (int i = 0; i < count; ++i) {
6572            long token = proto.start(fieldId);
6573            proto.write(SystemProto.BatteryLevelStep.DURATION_MS, steps.getDurationAt(i));
6574            proto.write(SystemProto.BatteryLevelStep.LEVEL, steps.getLevelAt(i));
6575
6576            final long initMode = steps.getInitModeAt(i);
6577            final long modMode = steps.getModModeAt(i);
6578
6579            int ds = SystemProto.BatteryLevelStep.DS_MIXED;
6580            if ((modMode & STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
6581                switch ((int) (initMode & STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
6582                    case Display.STATE_OFF:
6583                        ds = SystemProto.BatteryLevelStep.DS_OFF;
6584                        break;
6585                    case Display.STATE_ON:
6586                        ds = SystemProto.BatteryLevelStep.DS_ON;
6587                        break;
6588                    case Display.STATE_DOZE:
6589                        ds = SystemProto.BatteryLevelStep.DS_DOZE;
6590                        break;
6591                    case Display.STATE_DOZE_SUSPEND:
6592                        ds = SystemProto.BatteryLevelStep.DS_DOZE_SUSPEND;
6593                        break;
6594                    default:
6595                        ds = SystemProto.BatteryLevelStep.DS_ERROR;
6596                        break;
6597                }
6598            }
6599            proto.write(SystemProto.BatteryLevelStep.DISPLAY_STATE, ds);
6600
6601            int psm = SystemProto.BatteryLevelStep.PSM_MIXED;
6602            if ((modMode & STEP_LEVEL_MODE_POWER_SAVE) == 0) {
6603                psm = (initMode & STEP_LEVEL_MODE_POWER_SAVE) != 0
6604                    ? SystemProto.BatteryLevelStep.PSM_ON : SystemProto.BatteryLevelStep.PSM_OFF;
6605            }
6606            proto.write(SystemProto.BatteryLevelStep.POWER_SAVE_MODE, psm);
6607
6608            int im = SystemProto.BatteryLevelStep.IM_MIXED;
6609            if ((modMode & STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
6610                im = (initMode & STEP_LEVEL_MODE_DEVICE_IDLE) != 0
6611                    ? SystemProto.BatteryLevelStep.IM_ON : SystemProto.BatteryLevelStep.IM_OFF;
6612            }
6613            proto.write(SystemProto.BatteryLevelStep.IDLE_MODE, im);
6614
6615            proto.end(token);
6616        }
6617    }
6618
6619    public static final int DUMP_CHARGED_ONLY = 1<<1;
6620    public static final int DUMP_DAILY_ONLY = 1<<2;
6621    public static final int DUMP_HISTORY_ONLY = 1<<3;
6622    public static final int DUMP_INCLUDE_HISTORY = 1<<4;
6623    public static final int DUMP_VERBOSE = 1<<5;
6624    public static final int DUMP_DEVICE_WIFI_ONLY = 1<<6;
6625
6626    private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
6627        final HistoryPrinter hprinter = new HistoryPrinter();
6628        final HistoryItem rec = new HistoryItem();
6629        long lastTime = -1;
6630        long baseTime = -1;
6631        boolean printed = false;
6632        HistoryEventTracker tracker = null;
6633        while (getNextHistoryLocked(rec)) {
6634            lastTime = rec.time;
6635            if (baseTime < 0) {
6636                baseTime = lastTime;
6637            }
6638            if (rec.time >= histStart) {
6639                if (histStart >= 0 && !printed) {
6640                    if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
6641                            || rec.cmd == HistoryItem.CMD_RESET
6642                            || rec.cmd == HistoryItem.CMD_START
6643                            || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
6644                        printed = true;
6645                        hprinter.printNextItem(pw, rec, baseTime, checkin,
6646                                (flags&DUMP_VERBOSE) != 0);
6647                        rec.cmd = HistoryItem.CMD_UPDATE;
6648                    } else if (rec.currentTime != 0) {
6649                        printed = true;
6650                        byte cmd = rec.cmd;
6651                        rec.cmd = HistoryItem.CMD_CURRENT_TIME;
6652                        hprinter.printNextItem(pw, rec, baseTime, checkin,
6653                                (flags&DUMP_VERBOSE) != 0);
6654                        rec.cmd = cmd;
6655                    }
6656                    if (tracker != null) {
6657                        if (rec.cmd != HistoryItem.CMD_UPDATE) {
6658                            hprinter.printNextItem(pw, rec, baseTime, checkin,
6659                                    (flags&DUMP_VERBOSE) != 0);
6660                            rec.cmd = HistoryItem.CMD_UPDATE;
6661                        }
6662                        int oldEventCode = rec.eventCode;
6663                        HistoryTag oldEventTag = rec.eventTag;
6664                        rec.eventTag = new HistoryTag();
6665                        for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
6666                            HashMap<String, SparseIntArray> active
6667                                    = tracker.getStateForEvent(i);
6668                            if (active == null) {
6669                                continue;
6670                            }
6671                            for (HashMap.Entry<String, SparseIntArray> ent
6672                                    : active.entrySet()) {
6673                                SparseIntArray uids = ent.getValue();
6674                                for (int j=0; j<uids.size(); j++) {
6675                                    rec.eventCode = i;
6676                                    rec.eventTag.string = ent.getKey();
6677                                    rec.eventTag.uid = uids.keyAt(j);
6678                                    rec.eventTag.poolIdx = uids.valueAt(j);
6679                                    hprinter.printNextItem(pw, rec, baseTime, checkin,
6680                                            (flags&DUMP_VERBOSE) != 0);
6681                                    rec.wakeReasonTag = null;
6682                                    rec.wakelockTag = null;
6683                                }
6684                            }
6685                        }
6686                        rec.eventCode = oldEventCode;
6687                        rec.eventTag = oldEventTag;
6688                        tracker = null;
6689                    }
6690                }
6691                hprinter.printNextItem(pw, rec, baseTime, checkin,
6692                        (flags&DUMP_VERBOSE) != 0);
6693            } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) {
6694                // This is an attempt to aggregate the previous state and generate
6695                // fake events to reflect that state at the point where we start
6696                // printing real events.  It doesn't really work right, so is turned off.
6697                if (tracker == null) {
6698                    tracker = new HistoryEventTracker();
6699                }
6700                tracker.updateState(rec.eventCode, rec.eventTag.string,
6701                        rec.eventTag.uid, rec.eventTag.poolIdx);
6702            }
6703        }
6704        if (histStart >= 0) {
6705            commitCurrentHistoryBatchLocked();
6706            pw.print(checkin ? "NEXT: " : "  NEXT: "); pw.println(lastTime+1);
6707        }
6708    }
6709
6710    private void dumpDailyLevelStepSummary(PrintWriter pw, String prefix, String label,
6711            LevelStepTracker steps, StringBuilder tmpSb, int[] tmpOutInt) {
6712        if (steps == null) {
6713            return;
6714        }
6715        long timeRemaining = steps.computeTimeEstimate(0, 0, tmpOutInt);
6716        if (timeRemaining >= 0) {
6717            pw.print(prefix); pw.print(label); pw.print(" total time: ");
6718            tmpSb.setLength(0);
6719            formatTimeMs(tmpSb, timeRemaining);
6720            pw.print(tmpSb);
6721            pw.print(" (from "); pw.print(tmpOutInt[0]);
6722            pw.println(" steps)");
6723        }
6724        for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
6725            long estimatedTime = steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
6726                    STEP_LEVEL_MODE_VALUES[i], tmpOutInt);
6727            if (estimatedTime > 0) {
6728                pw.print(prefix); pw.print(label); pw.print(" ");
6729                pw.print(STEP_LEVEL_MODE_LABELS[i]);
6730                pw.print(" time: ");
6731                tmpSb.setLength(0);
6732                formatTimeMs(tmpSb, estimatedTime);
6733                pw.print(tmpSb);
6734                pw.print(" (from "); pw.print(tmpOutInt[0]);
6735                pw.println(" steps)");
6736            }
6737        }
6738    }
6739
6740    private void dumpDailyPackageChanges(PrintWriter pw, String prefix,
6741            ArrayList<PackageChange> changes) {
6742        if (changes == null) {
6743            return;
6744        }
6745        pw.print(prefix); pw.println("Package changes:");
6746        for (int i=0; i<changes.size(); i++) {
6747            PackageChange pc = changes.get(i);
6748            if (pc.mUpdate) {
6749                pw.print(prefix); pw.print("  Update "); pw.print(pc.mPackageName);
6750                pw.print(" vers="); pw.println(pc.mVersionCode);
6751            } else {
6752                pw.print(prefix); pw.print("  Uninstall "); pw.println(pc.mPackageName);
6753            }
6754        }
6755    }
6756
6757    /**
6758     * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
6759     *
6760     * @param pw a Printer to receive the dump output.
6761     */
6762    @SuppressWarnings("unused")
6763    public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
6764        prepareForDumpLocked();
6765
6766        final boolean filtering = (flags
6767                & (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
6768
6769        if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
6770            final long historyTotalSize = getHistoryTotalSize();
6771            final long historyUsedSize = getHistoryUsedSize();
6772            if (startIteratingHistoryLocked()) {
6773                try {
6774                    pw.print("Battery History (");
6775                    pw.print((100*historyUsedSize)/historyTotalSize);
6776                    pw.print("% used, ");
6777                    printSizeValue(pw, historyUsedSize);
6778                    pw.print(" used of ");
6779                    printSizeValue(pw, historyTotalSize);
6780                    pw.print(", ");
6781                    pw.print(getHistoryStringPoolSize());
6782                    pw.print(" strings using ");
6783                    printSizeValue(pw, getHistoryStringPoolBytes());
6784                    pw.println("):");
6785                    dumpHistoryLocked(pw, flags, histStart, false);
6786                    pw.println();
6787                } finally {
6788                    finishIteratingHistoryLocked();
6789                }
6790            }
6791
6792            if (startIteratingOldHistoryLocked()) {
6793                try {
6794                    final HistoryItem rec = new HistoryItem();
6795                    pw.println("Old battery History:");
6796                    HistoryPrinter hprinter = new HistoryPrinter();
6797                    long baseTime = -1;
6798                    while (getNextOldHistoryLocked(rec)) {
6799                        if (baseTime < 0) {
6800                            baseTime = rec.time;
6801                        }
6802                        hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0);
6803                    }
6804                    pw.println();
6805                } finally {
6806                    finishIteratingOldHistoryLocked();
6807                }
6808            }
6809        }
6810
6811        if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
6812            return;
6813        }
6814
6815        if (!filtering) {
6816            SparseArray<? extends Uid> uidStats = getUidStats();
6817            final int NU = uidStats.size();
6818            boolean didPid = false;
6819            long nowRealtime = SystemClock.elapsedRealtime();
6820            for (int i=0; i<NU; i++) {
6821                Uid uid = uidStats.valueAt(i);
6822                SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
6823                if (pids != null) {
6824                    for (int j=0; j<pids.size(); j++) {
6825                        Uid.Pid pid = pids.valueAt(j);
6826                        if (!didPid) {
6827                            pw.println("Per-PID Stats:");
6828                            didPid = true;
6829                        }
6830                        long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
6831                                ? (nowRealtime - pid.mWakeStartMs) : 0);
6832                        pw.print("  PID "); pw.print(pids.keyAt(j));
6833                                pw.print(" wake time: ");
6834                                TimeUtils.formatDuration(time, pw);
6835                                pw.println("");
6836                    }
6837                }
6838            }
6839            if (didPid) {
6840                pw.println();
6841            }
6842        }
6843
6844        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
6845            if (dumpDurationSteps(pw, "  ", "Discharge step durations:",
6846                    getDischargeLevelStepTracker(), false)) {
6847                long timeRemaining = computeBatteryTimeRemaining(
6848                    SystemClock.elapsedRealtime() * 1000);
6849                if (timeRemaining >= 0) {
6850                    pw.print("  Estimated discharge time remaining: ");
6851                    TimeUtils.formatDuration(timeRemaining / 1000, pw);
6852                    pw.println();
6853                }
6854                final LevelStepTracker steps = getDischargeLevelStepTracker();
6855                for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
6856                    dumpTimeEstimate(pw, "  Estimated ", STEP_LEVEL_MODE_LABELS[i], " time: ",
6857                            steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
6858                                    STEP_LEVEL_MODE_VALUES[i], null));
6859                }
6860                pw.println();
6861            }
6862            if (dumpDurationSteps(pw, "  ", "Charge step durations:",
6863                    getChargeLevelStepTracker(), false)) {
6864                long timeRemaining = computeChargeTimeRemaining(
6865                    SystemClock.elapsedRealtime() * 1000);
6866                if (timeRemaining >= 0) {
6867                    pw.print("  Estimated charge time remaining: ");
6868                    TimeUtils.formatDuration(timeRemaining / 1000, pw);
6869                    pw.println();
6870                }
6871                pw.println();
6872            }
6873        }
6874        if (!filtering || (flags & DUMP_DAILY_ONLY) != 0) {
6875            pw.println("Daily stats:");
6876            pw.print("  Current start time: ");
6877            pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6878                    getCurrentDailyStartTime()).toString());
6879            pw.print("  Next min deadline: ");
6880            pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6881                    getNextMinDailyDeadline()).toString());
6882            pw.print("  Next max deadline: ");
6883            pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
6884                    getNextMaxDailyDeadline()).toString());
6885            StringBuilder sb = new StringBuilder(64);
6886            int[] outInt = new int[1];
6887            LevelStepTracker dsteps = getDailyDischargeLevelStepTracker();
6888            LevelStepTracker csteps = getDailyChargeLevelStepTracker();
6889            ArrayList<PackageChange> pkgc = getDailyPackageChanges();
6890            if (dsteps.mNumStepDurations > 0 || csteps.mNumStepDurations > 0 || pkgc != null) {
6891                if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
6892                    if (dumpDurationSteps(pw, "    ", "  Current daily discharge step durations:",
6893                            dsteps, false)) {
6894                        dumpDailyLevelStepSummary(pw, "      ", "Discharge", dsteps,
6895                                sb, outInt);
6896                    }
6897                    if (dumpDurationSteps(pw, "    ", "  Current daily charge step durations:",
6898                            csteps, false)) {
6899                        dumpDailyLevelStepSummary(pw, "      ", "Charge", csteps,
6900                                sb, outInt);
6901                    }
6902                    dumpDailyPackageChanges(pw, "    ", pkgc);
6903                } else {
6904                    pw.println("  Current daily steps:");
6905                    dumpDailyLevelStepSummary(pw, "    ", "Discharge", dsteps,
6906                            sb, outInt);
6907                    dumpDailyLevelStepSummary(pw, "    ", "Charge", csteps,
6908                            sb, outInt);
6909                }
6910            }
6911            DailyItem dit;
6912            int curIndex = 0;
6913            while ((dit=getDailyItemLocked(curIndex)) != null) {
6914                curIndex++;
6915                if ((flags&DUMP_DAILY_ONLY) != 0) {
6916                    pw.println();
6917                }
6918                pw.print("  Daily from ");
6919                pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mStartTime).toString());
6920                pw.print(" to ");
6921                pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mEndTime).toString());
6922                pw.println(":");
6923                if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
6924                    if (dumpDurationSteps(pw, "      ",
6925                            "    Discharge step durations:", dit.mDischargeSteps, false)) {
6926                        dumpDailyLevelStepSummary(pw, "        ", "Discharge", dit.mDischargeSteps,
6927                                sb, outInt);
6928                    }
6929                    if (dumpDurationSteps(pw, "      ",
6930                            "    Charge step durations:", dit.mChargeSteps, false)) {
6931                        dumpDailyLevelStepSummary(pw, "        ", "Charge", dit.mChargeSteps,
6932                                sb, outInt);
6933                    }
6934                    dumpDailyPackageChanges(pw, "    ", dit.mPackageChanges);
6935                } else {
6936                    dumpDailyLevelStepSummary(pw, "    ", "Discharge", dit.mDischargeSteps,
6937                            sb, outInt);
6938                    dumpDailyLevelStepSummary(pw, "    ", "Charge", dit.mChargeSteps,
6939                            sb, outInt);
6940                }
6941            }
6942            pw.println();
6943        }
6944        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
6945            pw.println("Statistics since last charge:");
6946            pw.println("  System starts: " + getStartCount()
6947                    + ", currently on battery: " + getIsOnBattery());
6948            dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
6949                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
6950            pw.println();
6951        }
6952    }
6953
6954    // This is called from BatteryStatsService.
6955    @SuppressWarnings("unused")
6956    public void dumpCheckinLocked(Context context, PrintWriter pw,
6957            List<ApplicationInfo> apps, int flags, long histStart) {
6958        prepareForDumpLocked();
6959
6960        dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
6961                CHECKIN_VERSION, getParcelVersion(), getStartPlatformVersion(),
6962                getEndPlatformVersion());
6963
6964        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
6965
6966        if ((flags & (DUMP_INCLUDE_HISTORY | DUMP_HISTORY_ONLY)) != 0) {
6967            if (startIteratingHistoryLocked()) {
6968                try {
6969                    for (int i=0; i<getHistoryStringPoolSize(); i++) {
6970                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
6971                        pw.print(HISTORY_STRING_POOL); pw.print(',');
6972                        pw.print(i);
6973                        pw.print(",");
6974                        pw.print(getHistoryTagPoolUid(i));
6975                        pw.print(",\"");
6976                        String str = getHistoryTagPoolString(i);
6977                        str = str.replace("\\", "\\\\");
6978                        str = str.replace("\"", "\\\"");
6979                        pw.print(str);
6980                        pw.print("\"");
6981                        pw.println();
6982                    }
6983                    dumpHistoryLocked(pw, flags, histStart, true);
6984                } finally {
6985                    finishIteratingHistoryLocked();
6986                }
6987            }
6988        }
6989
6990        if ((flags & DUMP_HISTORY_ONLY) != 0) {
6991            return;
6992        }
6993
6994        if (apps != null) {
6995            SparseArray<Pair<ArrayList<String>, MutableBoolean>> uids = new SparseArray<>();
6996            for (int i=0; i<apps.size(); i++) {
6997                ApplicationInfo ai = apps.get(i);
6998                Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(
6999                        UserHandle.getAppId(ai.uid));
7000                if (pkgs == null) {
7001                    pkgs = new Pair<>(new ArrayList<String>(), new MutableBoolean(false));
7002                    uids.put(UserHandle.getAppId(ai.uid), pkgs);
7003                }
7004                pkgs.first.add(ai.packageName);
7005            }
7006            SparseArray<? extends Uid> uidStats = getUidStats();
7007            final int NU = uidStats.size();
7008            String[] lineArgs = new String[2];
7009            for (int i=0; i<NU; i++) {
7010                int uid = UserHandle.getAppId(uidStats.keyAt(i));
7011                Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(uid);
7012                if (pkgs != null && !pkgs.second.value) {
7013                    pkgs.second.value = true;
7014                    for (int j=0; j<pkgs.first.size(); j++) {
7015                        lineArgs[0] = Integer.toString(uid);
7016                        lineArgs[1] = pkgs.first.get(j);
7017                        dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
7018                                (Object[])lineArgs);
7019                    }
7020                }
7021            }
7022        }
7023        if ((flags & DUMP_DAILY_ONLY) == 0) {
7024            dumpDurationSteps(pw, "", DISCHARGE_STEP_DATA, getDischargeLevelStepTracker(), true);
7025            String[] lineArgs = new String[1];
7026            long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime() * 1000);
7027            if (timeRemaining >= 0) {
7028                lineArgs[0] = Long.toString(timeRemaining);
7029                dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA,
7030                        (Object[])lineArgs);
7031            }
7032            dumpDurationSteps(pw, "", CHARGE_STEP_DATA, getChargeLevelStepTracker(), true);
7033            timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime() * 1000);
7034            if (timeRemaining >= 0) {
7035                lineArgs[0] = Long.toString(timeRemaining);
7036                dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA,
7037                        (Object[])lineArgs);
7038            }
7039            dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
7040                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
7041        }
7042    }
7043
7044    /** Dump #STATS_SINCE_CHARGED batterystats data to a proto. @hide */
7045    public void dumpProtoLocked(Context context, FileDescriptor fd, List<ApplicationInfo> apps,
7046            int flags) {
7047        final ProtoOutputStream proto = new ProtoOutputStream(fd);
7048        final long bToken = proto.start(BatteryStatsServiceDumpProto.BATTERYSTATS);
7049        prepareForDumpLocked();
7050
7051        proto.write(BatteryStatsProto.REPORT_VERSION, CHECKIN_VERSION);
7052        proto.write(BatteryStatsProto.PARCEL_VERSION, getParcelVersion());
7053        proto.write(BatteryStatsProto.START_PLATFORM_VERSION, getStartPlatformVersion());
7054        proto.write(BatteryStatsProto.END_PLATFORM_VERSION, getEndPlatformVersion());
7055
7056        // History intentionally not included in proto dump.
7057
7058        if ((flags & (DUMP_HISTORY_ONLY | DUMP_DAILY_ONLY)) == 0) {
7059            final BatteryStatsHelper helper = new BatteryStatsHelper(context, false,
7060                    (flags & DUMP_DEVICE_WIFI_ONLY) != 0);
7061            helper.create(this);
7062            helper.refreshStats(STATS_SINCE_CHARGED, UserHandle.USER_ALL);
7063
7064            dumpProtoAppsLocked(proto, helper, apps);
7065            dumpProtoSystemLocked(proto, helper);
7066        }
7067
7068        proto.end(bToken);
7069        proto.flush();
7070    }
7071
7072    private void dumpProtoAppsLocked(ProtoOutputStream proto, BatteryStatsHelper helper,
7073            List<ApplicationInfo> apps) {
7074        final int which = STATS_SINCE_CHARGED;
7075        final long rawUptimeUs = SystemClock.uptimeMillis() * 1000;
7076        final long rawRealtimeMs = SystemClock.elapsedRealtime();
7077        final long rawRealtimeUs = rawRealtimeMs * 1000;
7078        final long batteryUptimeUs = getBatteryUptime(rawUptimeUs);
7079
7080        SparseArray<ArrayList<String>> aidToPackages = new SparseArray<>();
7081        if (apps != null) {
7082            for (int i = 0; i < apps.size(); ++i) {
7083                ApplicationInfo ai = apps.get(i);
7084                int aid = UserHandle.getAppId(ai.uid);
7085                ArrayList<String> pkgs = aidToPackages.get(aid);
7086                if (pkgs == null) {
7087                    pkgs = new ArrayList<String>();
7088                    aidToPackages.put(aid, pkgs);
7089                }
7090                pkgs.add(ai.packageName);
7091            }
7092        }
7093
7094        SparseArray<BatterySipper> uidToSipper = new SparseArray<>();
7095        final List<BatterySipper> sippers = helper.getUsageList();
7096        if (sippers != null) {
7097            for (int i = 0; i < sippers.size(); ++i) {
7098                final BatterySipper bs = sippers.get(i);
7099                if (bs.drainType != BatterySipper.DrainType.APP) {
7100                    // Others are handled by dumpProtoSystemLocked()
7101                    continue;
7102                }
7103                uidToSipper.put(bs.uidObj.getUid(), bs);
7104            }
7105        }
7106
7107        SparseArray<? extends Uid> uidStats = getUidStats();
7108        final int n = uidStats.size();
7109        for (int iu = 0; iu < n; ++iu) {
7110            final long uTkn = proto.start(BatteryStatsProto.UIDS);
7111            final Uid u = uidStats.valueAt(iu);
7112
7113            final int uid = uidStats.keyAt(iu);
7114            proto.write(UidProto.UID, uid);
7115
7116            // Print packages and apk stats (UID_DATA & APK_DATA)
7117            ArrayList<String> pkgs = aidToPackages.get(UserHandle.getAppId(uid));
7118            if (pkgs == null) {
7119                pkgs = new ArrayList<String>();
7120            }
7121            final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats =
7122                    u.getPackageStats();
7123            for (int ipkg = packageStats.size() - 1; ipkg >= 0; --ipkg) {
7124                String pkg = packageStats.keyAt(ipkg);
7125                final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats =
7126                        packageStats.valueAt(ipkg).getServiceStats();
7127                if (serviceStats.size() == 0) {
7128                    // Due to the way ActivityManagerService logs wakeup alarms, some packages (for
7129                    // example, "android") may be included in the packageStats that aren't part of
7130                    // the UID. If they don't have any services, then they shouldn't be listed here.
7131                    // These packages won't be a part in the pkgs List.
7132                    continue;
7133                }
7134
7135                final long pToken = proto.start(UidProto.PACKAGES);
7136                proto.write(UidProto.Package.NAME, pkg);
7137                // Remove from the packages list since we're logging it here.
7138                pkgs.remove(pkg);
7139
7140                for (int isvc = serviceStats.size() - 1; isvc >= 0; --isvc) {
7141                    final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
7142
7143                    final long startTimeMs = roundUsToMs(ss.getStartTime(batteryUptimeUs, which));
7144                    final int starts = ss.getStarts(which);
7145                    final int launches = ss.getLaunches(which);
7146                    if (startTimeMs == 0 && starts == 0 && launches == 0) {
7147                        continue;
7148                    }
7149
7150                    long sToken = proto.start(UidProto.Package.SERVICES);
7151
7152                    proto.write(UidProto.Package.Service.NAME, serviceStats.keyAt(isvc));
7153                    proto.write(UidProto.Package.Service.START_DURATION_MS, startTimeMs);
7154                    proto.write(UidProto.Package.Service.START_COUNT, starts);
7155                    proto.write(UidProto.Package.Service.LAUNCH_COUNT, launches);
7156
7157                    proto.end(sToken);
7158                }
7159                proto.end(pToken);
7160            }
7161            // Print any remaining packages that weren't in the packageStats map. pkgs is pulled
7162            // from PackageManager data. Packages are only included in packageStats if there was
7163            // specific data tracked for them (services and wakeup alarms, etc.).
7164            for (String p : pkgs) {
7165                final long pToken = proto.start(UidProto.PACKAGES);
7166                proto.write(UidProto.Package.NAME, p);
7167                proto.end(pToken);
7168            }
7169
7170            // Total wakelock data (AGGREGATED_WAKELOCK_DATA)
7171            if (u.getAggregatedPartialWakelockTimer() != null) {
7172                final Timer timer = u.getAggregatedPartialWakelockTimer();
7173                // Times are since reset (regardless of 'which')
7174                final long totTimeMs = timer.getTotalDurationMsLocked(rawRealtimeMs);
7175                final Timer bgTimer = timer.getSubTimer();
7176                final long bgTimeMs = bgTimer != null
7177                        ? bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
7178                final long awToken = proto.start(UidProto.AGGREGATED_WAKELOCK);
7179                proto.write(UidProto.AggregatedWakelock.PARTIAL_DURATION_MS, totTimeMs);
7180                proto.write(UidProto.AggregatedWakelock.BACKGROUND_PARTIAL_DURATION_MS, bgTimeMs);
7181                proto.end(awToken);
7182            }
7183
7184            // Audio (AUDIO_DATA)
7185            dumpTimer(proto, UidProto.AUDIO, u.getAudioTurnedOnTimer(), rawRealtimeUs, which);
7186
7187            // Bluetooth Controller (BLUETOOTH_CONTROLLER_DATA)
7188            dumpControllerActivityProto(proto, UidProto.BLUETOOTH_CONTROLLER,
7189                    u.getBluetoothControllerActivity(), which);
7190
7191            // BLE scans (BLUETOOTH_MISC_DATA) (uses totalDurationMsLocked and MaxDurationMsLocked)
7192            final Timer bleTimer = u.getBluetoothScanTimer();
7193            if (bleTimer != null) {
7194                final long bmToken = proto.start(UidProto.BLUETOOTH_MISC);
7195
7196                dumpTimer(proto, UidProto.BluetoothMisc.APPORTIONED_BLE_SCAN, bleTimer,
7197                        rawRealtimeUs, which);
7198                dumpTimer(proto, UidProto.BluetoothMisc.BACKGROUND_BLE_SCAN,
7199                        u.getBluetoothScanBackgroundTimer(), rawRealtimeUs, which);
7200                // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
7201                dumpTimer(proto, UidProto.BluetoothMisc.UNOPTIMIZED_BLE_SCAN,
7202                        u.getBluetoothUnoptimizedScanTimer(), rawRealtimeUs, which);
7203                // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
7204                dumpTimer(proto, UidProto.BluetoothMisc.BACKGROUND_UNOPTIMIZED_BLE_SCAN,
7205                        u.getBluetoothUnoptimizedScanBackgroundTimer(), rawRealtimeUs, which);
7206                // Result counters
7207                proto.write(UidProto.BluetoothMisc.BLE_SCAN_RESULT_COUNT,
7208                        u.getBluetoothScanResultCounter() != null
7209                            ? u.getBluetoothScanResultCounter().getCountLocked(which) : 0);
7210                proto.write(UidProto.BluetoothMisc.BACKGROUND_BLE_SCAN_RESULT_COUNT,
7211                        u.getBluetoothScanResultBgCounter() != null
7212                            ? u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0);
7213
7214                proto.end(bmToken);
7215            }
7216
7217            // Camera (CAMERA_DATA)
7218            dumpTimer(proto, UidProto.CAMERA, u.getCameraTurnedOnTimer(), rawRealtimeUs, which);
7219
7220            // CPU stats (CPU_DATA & CPU_TIMES_AT_FREQ_DATA)
7221            final long cpuToken = proto.start(UidProto.CPU);
7222            proto.write(UidProto.Cpu.USER_DURATION_MS, roundUsToMs(u.getUserCpuTimeUs(which)));
7223            proto.write(UidProto.Cpu.SYSTEM_DURATION_MS, roundUsToMs(u.getSystemCpuTimeUs(which)));
7224
7225            final long[] cpuFreqs = getCpuFreqs();
7226            if (cpuFreqs != null) {
7227                final long[] cpuFreqTimeMs = u.getCpuFreqTimes(which);
7228                // If total cpuFreqTimes is null, then we don't need to check for
7229                // screenOffCpuFreqTimes.
7230                if (cpuFreqTimeMs != null && cpuFreqTimeMs.length == cpuFreqs.length) {
7231                    long[] screenOffCpuFreqTimeMs = u.getScreenOffCpuFreqTimes(which);
7232                    if (screenOffCpuFreqTimeMs == null) {
7233                        screenOffCpuFreqTimeMs = new long[cpuFreqTimeMs.length];
7234                    }
7235                    for (int ic = 0; ic < cpuFreqTimeMs.length; ++ic) {
7236                        long cToken = proto.start(UidProto.Cpu.BY_FREQUENCY);
7237                        proto.write(UidProto.Cpu.ByFrequency.FREQUENCY_INDEX, ic + 1);
7238                        proto.write(UidProto.Cpu.ByFrequency.TOTAL_DURATION_MS,
7239                                cpuFreqTimeMs[ic]);
7240                        proto.write(UidProto.Cpu.ByFrequency.SCREEN_OFF_DURATION_MS,
7241                                screenOffCpuFreqTimeMs[ic]);
7242                        proto.end(cToken);
7243                    }
7244                }
7245            }
7246
7247            for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
7248                final long[] timesMs = u.getCpuFreqTimes(which, procState);
7249                if (timesMs != null && timesMs.length == cpuFreqs.length) {
7250                    long[] screenOffTimesMs = u.getScreenOffCpuFreqTimes(which, procState);
7251                    if (screenOffTimesMs == null) {
7252                        screenOffTimesMs = new long[timesMs.length];
7253                    }
7254                    final long procToken = proto.start(UidProto.Cpu.BY_PROCESS_STATE);
7255                    proto.write(UidProto.Cpu.ByProcessState.PROCESS_STATE, procState);
7256                    for (int ic = 0; ic < timesMs.length; ++ic) {
7257                        long cToken = proto.start(UidProto.Cpu.ByProcessState.BY_FREQUENCY);
7258                        proto.write(UidProto.Cpu.ByFrequency.FREQUENCY_INDEX, ic + 1);
7259                        proto.write(UidProto.Cpu.ByFrequency.TOTAL_DURATION_MS,
7260                                timesMs[ic]);
7261                        proto.write(UidProto.Cpu.ByFrequency.SCREEN_OFF_DURATION_MS,
7262                                screenOffTimesMs[ic]);
7263                        proto.end(cToken);
7264                    }
7265                    proto.end(procToken);
7266                }
7267            }
7268            proto.end(cpuToken);
7269
7270            // Flashlight (FLASHLIGHT_DATA)
7271            dumpTimer(proto, UidProto.FLASHLIGHT, u.getFlashlightTurnedOnTimer(),
7272                    rawRealtimeUs, which);
7273
7274            // Foreground activity (FOREGROUND_ACTIVITY_DATA)
7275            dumpTimer(proto, UidProto.FOREGROUND_ACTIVITY, u.getForegroundActivityTimer(),
7276                    rawRealtimeUs, which);
7277
7278            // Foreground service (FOREGROUND_SERVICE_DATA)
7279            dumpTimer(proto, UidProto.FOREGROUND_SERVICE, u.getForegroundServiceTimer(),
7280                    rawRealtimeUs, which);
7281
7282            // Job completion (JOB_COMPLETION_DATA)
7283            final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
7284            final int[] reasons = new int[]{
7285                JobParameters.REASON_CANCELED,
7286                JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED,
7287                JobParameters.REASON_PREEMPT,
7288                JobParameters.REASON_TIMEOUT,
7289                JobParameters.REASON_DEVICE_IDLE,
7290            };
7291            for (int ic = 0; ic < completions.size(); ++ic) {
7292                SparseIntArray types = completions.valueAt(ic);
7293                if (types != null) {
7294                    final long jcToken = proto.start(UidProto.JOB_COMPLETION);
7295
7296                    proto.write(UidProto.JobCompletion.NAME, completions.keyAt(ic));
7297
7298                    for (int r : reasons) {
7299                        long rToken = proto.start(UidProto.JobCompletion.REASON_COUNT);
7300                        proto.write(UidProto.JobCompletion.ReasonCount.NAME, r);
7301                        proto.write(UidProto.JobCompletion.ReasonCount.COUNT, types.get(r, 0));
7302                        proto.end(rToken);
7303                    }
7304
7305                    proto.end(jcToken);
7306                }
7307            }
7308
7309            // Scheduled jobs (JOB_DATA)
7310            final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
7311            for (int ij = jobs.size() - 1; ij >= 0; --ij) {
7312                final Timer timer = jobs.valueAt(ij);
7313                final Timer bgTimer = timer.getSubTimer();
7314                final long jToken = proto.start(UidProto.JOBS);
7315
7316                proto.write(UidProto.Job.NAME, jobs.keyAt(ij));
7317                // Background uses totalDurationMsLocked, while total uses totalTimeLocked
7318                dumpTimer(proto, UidProto.Job.TOTAL, timer, rawRealtimeUs, which);
7319                dumpTimer(proto, UidProto.Job.BACKGROUND, bgTimer, rawRealtimeUs, which);
7320
7321                proto.end(jToken);
7322            }
7323
7324            // Modem Controller (MODEM_CONTROLLER_DATA)
7325            dumpControllerActivityProto(proto, UidProto.MODEM_CONTROLLER,
7326                    u.getModemControllerActivity(), which);
7327
7328            // Network stats (NETWORK_DATA)
7329            final long nToken = proto.start(UidProto.NETWORK);
7330            proto.write(UidProto.Network.MOBILE_BYTES_RX,
7331                    u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which));
7332            proto.write(UidProto.Network.MOBILE_BYTES_TX,
7333                    u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which));
7334            proto.write(UidProto.Network.WIFI_BYTES_RX,
7335                    u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
7336            proto.write(UidProto.Network.WIFI_BYTES_TX,
7337                    u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
7338            proto.write(UidProto.Network.BT_BYTES_RX,
7339                    u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which));
7340            proto.write(UidProto.Network.BT_BYTES_TX,
7341                    u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which));
7342            proto.write(UidProto.Network.MOBILE_PACKETS_RX,
7343                    u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which));
7344            proto.write(UidProto.Network.MOBILE_PACKETS_TX,
7345                    u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which));
7346            proto.write(UidProto.Network.WIFI_PACKETS_RX,
7347                    u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
7348            proto.write(UidProto.Network.WIFI_PACKETS_TX,
7349                    u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
7350            proto.write(UidProto.Network.MOBILE_ACTIVE_DURATION_MS,
7351                    roundUsToMs(u.getMobileRadioActiveTime(which)));
7352            proto.write(UidProto.Network.MOBILE_ACTIVE_COUNT,
7353                    u.getMobileRadioActiveCount(which));
7354            proto.write(UidProto.Network.MOBILE_WAKEUP_COUNT,
7355                    u.getMobileRadioApWakeupCount(which));
7356            proto.write(UidProto.Network.WIFI_WAKEUP_COUNT,
7357                    u.getWifiRadioApWakeupCount(which));
7358            proto.write(UidProto.Network.MOBILE_BYTES_BG_RX,
7359                    u.getNetworkActivityBytes(NETWORK_MOBILE_BG_RX_DATA, which));
7360            proto.write(UidProto.Network.MOBILE_BYTES_BG_TX,
7361                    u.getNetworkActivityBytes(NETWORK_MOBILE_BG_TX_DATA, which));
7362            proto.write(UidProto.Network.WIFI_BYTES_BG_RX,
7363                    u.getNetworkActivityBytes(NETWORK_WIFI_BG_RX_DATA, which));
7364            proto.write(UidProto.Network.WIFI_BYTES_BG_TX,
7365                    u.getNetworkActivityBytes(NETWORK_WIFI_BG_TX_DATA, which));
7366            proto.write(UidProto.Network.MOBILE_PACKETS_BG_RX,
7367                    u.getNetworkActivityPackets(NETWORK_MOBILE_BG_RX_DATA, which));
7368            proto.write(UidProto.Network.MOBILE_PACKETS_BG_TX,
7369                    u.getNetworkActivityPackets(NETWORK_MOBILE_BG_TX_DATA, which));
7370            proto.write(UidProto.Network.WIFI_PACKETS_BG_RX,
7371                    u.getNetworkActivityPackets(NETWORK_WIFI_BG_RX_DATA, which));
7372            proto.write(UidProto.Network.WIFI_PACKETS_BG_TX,
7373                    u.getNetworkActivityPackets(NETWORK_WIFI_BG_TX_DATA, which));
7374            proto.end(nToken);
7375
7376            // Power use item (POWER_USE_ITEM_DATA)
7377            BatterySipper bs = uidToSipper.get(uid);
7378            if (bs != null) {
7379                final long bsToken = proto.start(UidProto.POWER_USE_ITEM);
7380                proto.write(UidProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah);
7381                proto.write(UidProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide);
7382                proto.write(UidProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah);
7383                proto.write(UidProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH,
7384                        bs.proportionalSmearMah);
7385                proto.end(bsToken);
7386            }
7387
7388            // Processes (PROCESS_DATA)
7389            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats =
7390                    u.getProcessStats();
7391            for (int ipr = processStats.size() - 1; ipr >= 0; --ipr) {
7392                final Uid.Proc ps = processStats.valueAt(ipr);
7393                final long prToken = proto.start(UidProto.PROCESS);
7394
7395                proto.write(UidProto.Process.NAME, processStats.keyAt(ipr));
7396                proto.write(UidProto.Process.USER_DURATION_MS, ps.getUserTime(which));
7397                proto.write(UidProto.Process.SYSTEM_DURATION_MS, ps.getSystemTime(which));
7398                proto.write(UidProto.Process.FOREGROUND_DURATION_MS, ps.getForegroundTime(which));
7399                proto.write(UidProto.Process.START_COUNT, ps.getStarts(which));
7400                proto.write(UidProto.Process.ANR_COUNT, ps.getNumAnrs(which));
7401                proto.write(UidProto.Process.CRASH_COUNT, ps.getNumCrashes(which));
7402
7403                proto.end(prToken);
7404            }
7405
7406            // Sensors (SENSOR_DATA)
7407            final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
7408            for (int ise = 0; ise < sensors.size(); ++ise) {
7409                final Uid.Sensor se = sensors.valueAt(ise);
7410                final Timer timer = se.getSensorTime();
7411                if (timer == null) {
7412                    continue;
7413                }
7414                final Timer bgTimer = se.getSensorBackgroundTime();
7415                final int sensorNumber = sensors.keyAt(ise);
7416                final long seToken = proto.start(UidProto.SENSORS);
7417
7418                proto.write(UidProto.Sensor.ID, sensorNumber);
7419                // Background uses totalDurationMsLocked, while total uses totalTimeLocked
7420                dumpTimer(proto, UidProto.Sensor.APPORTIONED, timer, rawRealtimeUs, which);
7421                dumpTimer(proto, UidProto.Sensor.BACKGROUND, bgTimer, rawRealtimeUs, which);
7422
7423                proto.end(seToken);
7424            }
7425
7426            // State times (STATE_TIME_DATA)
7427            for (int ips = 0; ips < Uid.NUM_PROCESS_STATE; ++ips) {
7428                long durMs = roundUsToMs(u.getProcessStateTime(ips, rawRealtimeUs, which));
7429                if (durMs == 0) {
7430                    continue;
7431                }
7432                final long stToken = proto.start(UidProto.STATES);
7433                proto.write(UidProto.StateTime.STATE, ips);
7434                proto.write(UidProto.StateTime.DURATION_MS, durMs);
7435                proto.end(stToken);
7436            }
7437
7438            // Syncs (SYNC_DATA)
7439            final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
7440            for (int isy = syncs.size() - 1; isy >= 0; --isy) {
7441                final Timer timer = syncs.valueAt(isy);
7442                final Timer bgTimer = timer.getSubTimer();
7443                final long syToken = proto.start(UidProto.SYNCS);
7444
7445                proto.write(UidProto.Sync.NAME, syncs.keyAt(isy));
7446                // Background uses totalDurationMsLocked, while total uses totalTimeLocked
7447                dumpTimer(proto, UidProto.Sync.TOTAL, timer, rawRealtimeUs, which);
7448                dumpTimer(proto, UidProto.Sync.BACKGROUND, bgTimer, rawRealtimeUs, which);
7449
7450                proto.end(syToken);
7451            }
7452
7453            // User activity (USER_ACTIVITY_DATA)
7454            if (u.hasUserActivity()) {
7455                for (int i = 0; i < Uid.NUM_USER_ACTIVITY_TYPES; ++i) {
7456                    int val = u.getUserActivityCount(i, which);
7457                    if (val != 0) {
7458                        final long uaToken = proto.start(UidProto.USER_ACTIVITY);
7459                        proto.write(UidProto.UserActivity.NAME, i);
7460                        proto.write(UidProto.UserActivity.COUNT, val);
7461                        proto.end(uaToken);
7462                    }
7463                }
7464            }
7465
7466            // Vibrator (VIBRATOR_DATA)
7467            dumpTimer(proto, UidProto.VIBRATOR, u.getVibratorOnTimer(), rawRealtimeUs, which);
7468
7469            // Video (VIDEO_DATA)
7470            dumpTimer(proto, UidProto.VIDEO, u.getVideoTurnedOnTimer(), rawRealtimeUs, which);
7471
7472            // Wakelocks (WAKELOCK_DATA)
7473            final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
7474            for (int iw = wakelocks.size() - 1; iw >= 0; --iw) {
7475                final Uid.Wakelock wl = wakelocks.valueAt(iw);
7476                final long wToken = proto.start(UidProto.WAKELOCKS);
7477                proto.write(UidProto.Wakelock.NAME, wakelocks.keyAt(iw));
7478                dumpTimer(proto, UidProto.Wakelock.FULL, wl.getWakeTime(WAKE_TYPE_FULL),
7479                        rawRealtimeUs, which);
7480                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
7481                if (pTimer != null) {
7482                    dumpTimer(proto, UidProto.Wakelock.PARTIAL, pTimer, rawRealtimeUs, which);
7483                    dumpTimer(proto, UidProto.Wakelock.BACKGROUND_PARTIAL, pTimer.getSubTimer(),
7484                            rawRealtimeUs, which);
7485                }
7486                dumpTimer(proto, UidProto.Wakelock.WINDOW, wl.getWakeTime(WAKE_TYPE_WINDOW),
7487                        rawRealtimeUs, which);
7488                proto.end(wToken);
7489            }
7490
7491            // Wifi Multicast Wakelock (WIFI_MULTICAST_WAKELOCK_DATA)
7492            dumpTimer(proto, UidProto.WIFI_MULTICAST_WAKELOCK, u.getMulticastWakelockStats(),
7493                    rawRealtimeUs, which);
7494
7495            // Wakeup alarms (WAKEUP_ALARM_DATA)
7496            for (int ipkg = packageStats.size() - 1; ipkg >= 0; --ipkg) {
7497                final Uid.Pkg ps = packageStats.valueAt(ipkg);
7498                final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
7499                for (int iwa = alarms.size() - 1; iwa >= 0; --iwa) {
7500                    final long waToken = proto.start(UidProto.WAKEUP_ALARM);
7501                    proto.write(UidProto.WakeupAlarm.NAME, alarms.keyAt(iwa));
7502                    proto.write(UidProto.WakeupAlarm.COUNT,
7503                            alarms.valueAt(iwa).getCountLocked(which));
7504                    proto.end(waToken);
7505                }
7506            }
7507
7508            // Wifi Controller (WIFI_CONTROLLER_DATA)
7509            dumpControllerActivityProto(proto, UidProto.WIFI_CONTROLLER,
7510                    u.getWifiControllerActivity(), which);
7511
7512            // Wifi data (WIFI_DATA)
7513            final long wToken = proto.start(UidProto.WIFI);
7514            proto.write(UidProto.Wifi.FULL_WIFI_LOCK_DURATION_MS,
7515                    roundUsToMs(u.getFullWifiLockTime(rawRealtimeUs, which)));
7516            dumpTimer(proto, UidProto.Wifi.APPORTIONED_SCAN, u.getWifiScanTimer(),
7517                    rawRealtimeUs, which);
7518            proto.write(UidProto.Wifi.RUNNING_DURATION_MS,
7519                    roundUsToMs(u.getWifiRunningTime(rawRealtimeUs, which)));
7520            dumpTimer(proto, UidProto.Wifi.BACKGROUND_SCAN, u.getWifiScanBackgroundTimer(),
7521                    rawRealtimeUs, which);
7522            proto.end(wToken);
7523
7524            proto.end(uTkn);
7525        }
7526    }
7527
7528    private void dumpProtoSystemLocked(ProtoOutputStream proto, BatteryStatsHelper helper) {
7529        final long sToken = proto.start(BatteryStatsProto.SYSTEM);
7530        final long rawUptimeUs = SystemClock.uptimeMillis() * 1000;
7531        final long rawRealtimeMs = SystemClock.elapsedRealtime();
7532        final long rawRealtimeUs = rawRealtimeMs * 1000;
7533        final int which = STATS_SINCE_CHARGED;
7534
7535        // Battery data (BATTERY_DATA)
7536        final long bToken = proto.start(SystemProto.BATTERY);
7537        proto.write(SystemProto.Battery.START_CLOCK_TIME_MS, getStartClockTime());
7538        proto.write(SystemProto.Battery.START_COUNT, getStartCount());
7539        proto.write(SystemProto.Battery.TOTAL_REALTIME_MS,
7540                computeRealtime(rawRealtimeUs, which) / 1000);
7541        proto.write(SystemProto.Battery.TOTAL_UPTIME_MS,
7542                computeUptime(rawUptimeUs, which) / 1000);
7543        proto.write(SystemProto.Battery.BATTERY_REALTIME_MS,
7544                computeBatteryRealtime(rawRealtimeUs, which) / 1000);
7545        proto.write(SystemProto.Battery.BATTERY_UPTIME_MS,
7546                computeBatteryUptime(rawUptimeUs, which) / 1000);
7547        proto.write(SystemProto.Battery.SCREEN_OFF_REALTIME_MS,
7548                computeBatteryScreenOffRealtime(rawRealtimeUs, which) / 1000);
7549        proto.write(SystemProto.Battery.SCREEN_OFF_UPTIME_MS,
7550                computeBatteryScreenOffUptime(rawUptimeUs, which) / 1000);
7551        proto.write(SystemProto.Battery.SCREEN_DOZE_DURATION_MS,
7552                getScreenDozeTime(rawRealtimeUs, which) / 1000);
7553        proto.write(SystemProto.Battery.ESTIMATED_BATTERY_CAPACITY_MAH,
7554                getEstimatedBatteryCapacity());
7555        proto.write(SystemProto.Battery.MIN_LEARNED_BATTERY_CAPACITY_UAH,
7556                getMinLearnedBatteryCapacity());
7557        proto.write(SystemProto.Battery.MAX_LEARNED_BATTERY_CAPACITY_UAH,
7558                getMaxLearnedBatteryCapacity());
7559        proto.end(bToken);
7560
7561        // Battery discharge (BATTERY_DISCHARGE_DATA)
7562        final long bdToken = proto.start(SystemProto.BATTERY_DISCHARGE);
7563        proto.write(SystemProto.BatteryDischarge.LOWER_BOUND_SINCE_CHARGE,
7564                getLowDischargeAmountSinceCharge());
7565        proto.write(SystemProto.BatteryDischarge.UPPER_BOUND_SINCE_CHARGE,
7566                getHighDischargeAmountSinceCharge());
7567        proto.write(SystemProto.BatteryDischarge.SCREEN_ON_SINCE_CHARGE,
7568                getDischargeAmountScreenOnSinceCharge());
7569        proto.write(SystemProto.BatteryDischarge.SCREEN_OFF_SINCE_CHARGE,
7570                getDischargeAmountScreenOffSinceCharge());
7571        proto.write(SystemProto.BatteryDischarge.SCREEN_DOZE_SINCE_CHARGE,
7572                getDischargeAmountScreenDozeSinceCharge());
7573        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH,
7574                getUahDischarge(which) / 1000);
7575        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_SCREEN_OFF,
7576                getUahDischargeScreenOff(which) / 1000);
7577        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_SCREEN_DOZE,
7578                getUahDischargeScreenDoze(which) / 1000);
7579        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_LIGHT_DOZE,
7580                getUahDischargeLightDoze(which) / 1000);
7581        proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_DEEP_DOZE,
7582                getUahDischargeDeepDoze(which) / 1000);
7583        proto.end(bdToken);
7584
7585        // Time remaining
7586        long timeRemainingUs = computeChargeTimeRemaining(rawRealtimeUs);
7587        // These are part of a oneof, so we should only set one of them.
7588        if (timeRemainingUs >= 0) {
7589            // Charge time remaining (CHARGE_TIME_REMAIN_DATA)
7590            proto.write(SystemProto.CHARGE_TIME_REMAINING_MS, timeRemainingUs / 1000);
7591        } else {
7592            timeRemainingUs = computeBatteryTimeRemaining(rawRealtimeUs);
7593            // Discharge time remaining (DISCHARGE_TIME_REMAIN_DATA)
7594            if (timeRemainingUs >= 0) {
7595                proto.write(SystemProto.DISCHARGE_TIME_REMAINING_MS, timeRemainingUs / 1000);
7596            } else {
7597                proto.write(SystemProto.DISCHARGE_TIME_REMAINING_MS, -1);
7598            }
7599        }
7600
7601        // Charge step (CHARGE_STEP_DATA)
7602        dumpDurationSteps(proto, SystemProto.CHARGE_STEP, getChargeLevelStepTracker());
7603
7604        // Phone data connection (DATA_CONNECTION_TIME_DATA and DATA_CONNECTION_COUNT_DATA)
7605        for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; ++i) {
7606            // Map OTHER to TelephonyManager.NETWORK_TYPE_UNKNOWN and mark NONE as a boolean.
7607            boolean isNone = (i == DATA_CONNECTION_NONE);
7608            int telephonyNetworkType = i;
7609            if (i == DATA_CONNECTION_OTHER) {
7610                telephonyNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
7611            }
7612            final long pdcToken = proto.start(SystemProto.DATA_CONNECTION);
7613            if (isNone) {
7614                proto.write(SystemProto.DataConnection.IS_NONE, isNone);
7615            } else {
7616                proto.write(SystemProto.DataConnection.NAME, telephonyNetworkType);
7617            }
7618            dumpTimer(proto, SystemProto.DataConnection.TOTAL, getPhoneDataConnectionTimer(i),
7619                    rawRealtimeUs, which);
7620            proto.end(pdcToken);
7621        }
7622
7623        // Discharge step (DISCHARGE_STEP_DATA)
7624        dumpDurationSteps(proto, SystemProto.DISCHARGE_STEP, getDischargeLevelStepTracker());
7625
7626        // CPU frequencies (GLOBAL_CPU_FREQ_DATA)
7627        final long[] cpuFreqs = getCpuFreqs();
7628        if (cpuFreqs != null) {
7629            for (long i : cpuFreqs) {
7630                proto.write(SystemProto.CPU_FREQUENCY, i);
7631            }
7632        }
7633
7634        // Bluetooth controller (GLOBAL_BLUETOOTH_CONTROLLER_DATA)
7635        dumpControllerActivityProto(proto, SystemProto.GLOBAL_BLUETOOTH_CONTROLLER,
7636                getBluetoothControllerActivity(), which);
7637
7638        // Modem controller (GLOBAL_MODEM_CONTROLLER_DATA)
7639        dumpControllerActivityProto(proto, SystemProto.GLOBAL_MODEM_CONTROLLER,
7640                getModemControllerActivity(), which);
7641
7642        // Global network data (GLOBAL_NETWORK_DATA)
7643        final long gnToken = proto.start(SystemProto.GLOBAL_NETWORK);
7644        proto.write(SystemProto.GlobalNetwork.MOBILE_BYTES_RX,
7645                getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which));
7646        proto.write(SystemProto.GlobalNetwork.MOBILE_BYTES_TX,
7647                getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which));
7648        proto.write(SystemProto.GlobalNetwork.MOBILE_PACKETS_RX,
7649                getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which));
7650        proto.write(SystemProto.GlobalNetwork.MOBILE_PACKETS_TX,
7651                getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which));
7652        proto.write(SystemProto.GlobalNetwork.WIFI_BYTES_RX,
7653                getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
7654        proto.write(SystemProto.GlobalNetwork.WIFI_BYTES_TX,
7655                getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
7656        proto.write(SystemProto.GlobalNetwork.WIFI_PACKETS_RX,
7657                getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
7658        proto.write(SystemProto.GlobalNetwork.WIFI_PACKETS_TX,
7659                getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
7660        proto.write(SystemProto.GlobalNetwork.BT_BYTES_RX,
7661                getNetworkActivityBytes(NETWORK_BT_RX_DATA, which));
7662        proto.write(SystemProto.GlobalNetwork.BT_BYTES_TX,
7663                getNetworkActivityBytes(NETWORK_BT_TX_DATA, which));
7664        proto.end(gnToken);
7665
7666        // Wifi controller (GLOBAL_WIFI_CONTROLLER_DATA)
7667        dumpControllerActivityProto(proto, SystemProto.GLOBAL_WIFI_CONTROLLER,
7668                getWifiControllerActivity(), which);
7669
7670
7671        // Global wifi (GLOBAL_WIFI_DATA)
7672        final long gwToken = proto.start(SystemProto.GLOBAL_WIFI);
7673        proto.write(SystemProto.GlobalWifi.ON_DURATION_MS,
7674                getWifiOnTime(rawRealtimeUs, which) / 1000);
7675        proto.write(SystemProto.GlobalWifi.RUNNING_DURATION_MS,
7676                getGlobalWifiRunningTime(rawRealtimeUs, which) / 1000);
7677        proto.end(gwToken);
7678
7679        // Kernel wakelock (KERNEL_WAKELOCK_DATA)
7680        final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
7681        for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
7682            final long kwToken = proto.start(SystemProto.KERNEL_WAKELOCK);
7683            proto.write(SystemProto.KernelWakelock.NAME, ent.getKey());
7684            dumpTimer(proto, SystemProto.KernelWakelock.TOTAL, ent.getValue(),
7685                    rawRealtimeUs, which);
7686            proto.end(kwToken);
7687        }
7688
7689        // Misc (MISC_DATA)
7690        // Calculate wakelock times across all uids.
7691        long fullWakeLockTimeTotalUs = 0;
7692        long partialWakeLockTimeTotalUs = 0;
7693
7694        final SparseArray<? extends Uid> uidStats = getUidStats();
7695        for (int iu = 0; iu < uidStats.size(); iu++) {
7696            final Uid u = uidStats.valueAt(iu);
7697
7698            final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks =
7699                    u.getWakelockStats();
7700            for (int iw = wakelocks.size() - 1; iw >= 0; --iw) {
7701                final Uid.Wakelock wl = wakelocks.valueAt(iw);
7702
7703                final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
7704                if (fullWakeTimer != null) {
7705                    fullWakeLockTimeTotalUs += fullWakeTimer.getTotalTimeLocked(rawRealtimeUs,
7706                            which);
7707                }
7708
7709                final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
7710                if (partialWakeTimer != null) {
7711                    partialWakeLockTimeTotalUs += partialWakeTimer.getTotalTimeLocked(
7712                        rawRealtimeUs, which);
7713                }
7714            }
7715        }
7716        final long mToken = proto.start(SystemProto.MISC);
7717        proto.write(SystemProto.Misc.SCREEN_ON_DURATION_MS,
7718                getScreenOnTime(rawRealtimeUs, which) / 1000);
7719        proto.write(SystemProto.Misc.PHONE_ON_DURATION_MS,
7720                getPhoneOnTime(rawRealtimeUs, which) / 1000);
7721        proto.write(SystemProto.Misc.FULL_WAKELOCK_TOTAL_DURATION_MS,
7722                fullWakeLockTimeTotalUs / 1000);
7723        proto.write(SystemProto.Misc.PARTIAL_WAKELOCK_TOTAL_DURATION_MS,
7724                partialWakeLockTimeTotalUs / 1000);
7725        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_DURATION_MS,
7726                getMobileRadioActiveTime(rawRealtimeUs, which) / 1000);
7727        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_ADJUSTED_TIME_MS,
7728                getMobileRadioActiveAdjustedTime(which) / 1000);
7729        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_COUNT,
7730                getMobileRadioActiveCount(which));
7731        proto.write(SystemProto.Misc.MOBILE_RADIO_ACTIVE_UNKNOWN_DURATION_MS,
7732                getMobileRadioActiveUnknownTime(which) / 1000);
7733        proto.write(SystemProto.Misc.INTERACTIVE_DURATION_MS,
7734                getInteractiveTime(rawRealtimeUs, which) / 1000);
7735        proto.write(SystemProto.Misc.BATTERY_SAVER_MODE_ENABLED_DURATION_MS,
7736                getPowerSaveModeEnabledTime(rawRealtimeUs, which) / 1000);
7737        proto.write(SystemProto.Misc.NUM_CONNECTIVITY_CHANGES,
7738                getNumConnectivityChange(which));
7739        proto.write(SystemProto.Misc.DEEP_DOZE_ENABLED_DURATION_MS,
7740                getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP, rawRealtimeUs, which) / 1000);
7741        proto.write(SystemProto.Misc.DEEP_DOZE_COUNT,
7742                getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which));
7743        proto.write(SystemProto.Misc.DEEP_DOZE_IDLING_DURATION_MS,
7744                getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP, rawRealtimeUs, which) / 1000);
7745        proto.write(SystemProto.Misc.DEEP_DOZE_IDLING_COUNT,
7746                getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which));
7747        proto.write(SystemProto.Misc.LONGEST_DEEP_DOZE_DURATION_MS,
7748                getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
7749        proto.write(SystemProto.Misc.LIGHT_DOZE_ENABLED_DURATION_MS,
7750                getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT, rawRealtimeUs, which) / 1000);
7751        proto.write(SystemProto.Misc.LIGHT_DOZE_COUNT,
7752                getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which));
7753        proto.write(SystemProto.Misc.LIGHT_DOZE_IDLING_DURATION_MS,
7754                getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT, rawRealtimeUs, which) / 1000);
7755        proto.write(SystemProto.Misc.LIGHT_DOZE_IDLING_COUNT,
7756                getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which));
7757        proto.write(SystemProto.Misc.LONGEST_LIGHT_DOZE_DURATION_MS,
7758                getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
7759        proto.end(mToken);
7760
7761        // Wifi multicast wakelock total stats (WIFI_MULTICAST_WAKELOCK_TOTAL_DATA)
7762        final long multicastWakeLockTimeTotalUs =
7763                getWifiMulticastWakelockTime(rawRealtimeUs, which);
7764        final int multicastWakeLockCountTotal = getWifiMulticastWakelockCount(which);
7765        final long wmctToken = proto.start(SystemProto.WIFI_MULTICAST_WAKELOCK_TOTAL);
7766        proto.write(SystemProto.WifiMulticastWakelockTotal.DURATION_MS,
7767                multicastWakeLockTimeTotalUs / 1000);
7768        proto.write(SystemProto.WifiMulticastWakelockTotal.COUNT,
7769                multicastWakeLockCountTotal);
7770        proto.end(wmctToken);
7771
7772        // Power use item (POWER_USE_ITEM_DATA)
7773        final List<BatterySipper> sippers = helper.getUsageList();
7774        if (sippers != null) {
7775            for (int i = 0; i < sippers.size(); ++i) {
7776                final BatterySipper bs = sippers.get(i);
7777                int n = SystemProto.PowerUseItem.UNKNOWN_SIPPER;
7778                int uid = 0;
7779                switch (bs.drainType) {
7780                    case IDLE:
7781                        n = SystemProto.PowerUseItem.IDLE;
7782                        break;
7783                    case CELL:
7784                        n = SystemProto.PowerUseItem.CELL;
7785                        break;
7786                    case PHONE:
7787                        n = SystemProto.PowerUseItem.PHONE;
7788                        break;
7789                    case WIFI:
7790                        n = SystemProto.PowerUseItem.WIFI;
7791                        break;
7792                    case BLUETOOTH:
7793                        n = SystemProto.PowerUseItem.BLUETOOTH;
7794                        break;
7795                    case SCREEN:
7796                        n = SystemProto.PowerUseItem.SCREEN;
7797                        break;
7798                    case FLASHLIGHT:
7799                        n = SystemProto.PowerUseItem.FLASHLIGHT;
7800                        break;
7801                    case APP:
7802                        // dumpProtoAppsLocked will handle this.
7803                        continue;
7804                    case USER:
7805                        n = SystemProto.PowerUseItem.USER;
7806                        uid = UserHandle.getUid(bs.userId, 0);
7807                        break;
7808                    case UNACCOUNTED:
7809                        n = SystemProto.PowerUseItem.UNACCOUNTED;
7810                        break;
7811                    case OVERCOUNTED:
7812                        n = SystemProto.PowerUseItem.OVERCOUNTED;
7813                        break;
7814                    case CAMERA:
7815                        n = SystemProto.PowerUseItem.CAMERA;
7816                        break;
7817                    case MEMORY:
7818                        n = SystemProto.PowerUseItem.MEMORY;
7819                        break;
7820                }
7821                final long puiToken = proto.start(SystemProto.POWER_USE_ITEM);
7822                proto.write(SystemProto.PowerUseItem.NAME, n);
7823                proto.write(SystemProto.PowerUseItem.UID, uid);
7824                proto.write(SystemProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah);
7825                proto.write(SystemProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide);
7826                proto.write(SystemProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah);
7827                proto.write(SystemProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH,
7828                        bs.proportionalSmearMah);
7829                proto.end(puiToken);
7830            }
7831        }
7832
7833        // Power use summary (POWER_USE_SUMMARY_DATA)
7834        final long pusToken = proto.start(SystemProto.POWER_USE_SUMMARY);
7835        proto.write(SystemProto.PowerUseSummary.BATTERY_CAPACITY_MAH,
7836                helper.getPowerProfile().getBatteryCapacity());
7837        proto.write(SystemProto.PowerUseSummary.COMPUTED_POWER_MAH, helper.getComputedPower());
7838        proto.write(SystemProto.PowerUseSummary.MIN_DRAINED_POWER_MAH, helper.getMinDrainedPower());
7839        proto.write(SystemProto.PowerUseSummary.MAX_DRAINED_POWER_MAH, helper.getMaxDrainedPower());
7840        proto.end(pusToken);
7841
7842        // RPM stats (RESOURCE_POWER_MANAGER_DATA)
7843        final Map<String, ? extends Timer> rpmStats = getRpmStats();
7844        final Map<String, ? extends Timer> screenOffRpmStats = getScreenOffRpmStats();
7845        for (Map.Entry<String, ? extends Timer> ent : rpmStats.entrySet()) {
7846            final long rpmToken = proto.start(SystemProto.RESOURCE_POWER_MANAGER);
7847            proto.write(SystemProto.ResourcePowerManager.NAME, ent.getKey());
7848            dumpTimer(proto, SystemProto.ResourcePowerManager.TOTAL,
7849                    ent.getValue(), rawRealtimeUs, which);
7850            dumpTimer(proto, SystemProto.ResourcePowerManager.SCREEN_OFF,
7851                    screenOffRpmStats.get(ent.getKey()), rawRealtimeUs, which);
7852            proto.end(rpmToken);
7853        }
7854
7855        // Screen brightness (SCREEN_BRIGHTNESS_DATA)
7856        for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; ++i) {
7857            final long sbToken = proto.start(SystemProto.SCREEN_BRIGHTNESS);
7858            proto.write(SystemProto.ScreenBrightness.NAME, i);
7859            dumpTimer(proto, SystemProto.ScreenBrightness.TOTAL, getScreenBrightnessTimer(i),
7860                    rawRealtimeUs, which);
7861            proto.end(sbToken);
7862        }
7863
7864        // Signal scanning time (SIGNAL_SCANNING_TIME_DATA)
7865        dumpTimer(proto, SystemProto.SIGNAL_SCANNING, getPhoneSignalScanningTimer(), rawRealtimeUs,
7866                which);
7867
7868        // Phone signal strength (SIGNAL_STRENGTH_TIME_DATA and SIGNAL_STRENGTH_COUNT_DATA)
7869        for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; ++i) {
7870            final long pssToken = proto.start(SystemProto.PHONE_SIGNAL_STRENGTH);
7871            proto.write(SystemProto.PhoneSignalStrength.NAME, i);
7872            dumpTimer(proto, SystemProto.PhoneSignalStrength.TOTAL, getPhoneSignalStrengthTimer(i),
7873                    rawRealtimeUs, which);
7874            proto.end(pssToken);
7875        }
7876
7877        // Wakeup reasons (WAKEUP_REASON_DATA)
7878        final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
7879        for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
7880            final long wrToken = proto.start(SystemProto.WAKEUP_REASON);
7881            proto.write(SystemProto.WakeupReason.NAME, ent.getKey());
7882            dumpTimer(proto, SystemProto.WakeupReason.TOTAL, ent.getValue(), rawRealtimeUs, which);
7883            proto.end(wrToken);
7884        }
7885
7886        // Wifi signal strength (WIFI_SIGNAL_STRENGTH_TIME_DATA and WIFI_SIGNAL_STRENGTH_COUNT_DATA)
7887        for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; ++i) {
7888            final long wssToken = proto.start(SystemProto.WIFI_SIGNAL_STRENGTH);
7889            proto.write(SystemProto.WifiSignalStrength.NAME, i);
7890            dumpTimer(proto, SystemProto.WifiSignalStrength.TOTAL, getWifiSignalStrengthTimer(i),
7891                    rawRealtimeUs, which);
7892            proto.end(wssToken);
7893        }
7894
7895        // Wifi state (WIFI_STATE_TIME_DATA and WIFI_STATE_COUNT_DATA)
7896        for (int i = 0; i < NUM_WIFI_STATES; ++i) {
7897            final long wsToken = proto.start(SystemProto.WIFI_STATE);
7898            proto.write(SystemProto.WifiState.NAME, i);
7899            dumpTimer(proto, SystemProto.WifiState.TOTAL, getWifiStateTimer(i),
7900                    rawRealtimeUs, which);
7901            proto.end(wsToken);
7902        }
7903
7904        // Wifi supplicant state (WIFI_SUPPL_STATE_TIME_DATA and WIFI_SUPPL_STATE_COUNT_DATA)
7905        for (int i = 0; i < NUM_WIFI_SUPPL_STATES; ++i) {
7906            final long wssToken = proto.start(SystemProto.WIFI_SUPPLICANT_STATE);
7907            proto.write(SystemProto.WifiSupplicantState.NAME, i);
7908            dumpTimer(proto, SystemProto.WifiSupplicantState.TOTAL, getWifiSupplStateTimer(i),
7909                    rawRealtimeUs, which);
7910            proto.end(wssToken);
7911        }
7912
7913        proto.end(sToken);
7914    }
7915}
7916