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