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