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