• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.os;
18 
19 import java.io.PrintWriter;
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.Comparator;
23 import java.util.Formatter;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 
28 import android.content.Context;
29 import android.content.pm.ApplicationInfo;
30 import android.telephony.SignalStrength;
31 import android.text.format.DateFormat;
32 import android.util.ArrayMap;
33 import android.util.Printer;
34 import android.util.SparseArray;
35 import android.util.SparseIntArray;
36 import android.util.TimeUtils;
37 import android.view.Display;
38 import com.android.internal.os.BatterySipper;
39 import com.android.internal.os.BatteryStatsHelper;
40 
41 /**
42  * A class providing access to battery usage statistics, including information on
43  * wakelocks, processes, packages, and services.  All times are represented in microseconds
44  * except where indicated otherwise.
45  * @hide
46  */
47 public abstract class BatteryStats implements Parcelable {
48 
49     private static final boolean LOCAL_LOGV = false;
50 
51     /** @hide */
52     public static final String SERVICE_NAME = "batterystats";
53 
54     /**
55      * A constant indicating a partial wake lock timer.
56      */
57     public static final int WAKE_TYPE_PARTIAL = 0;
58 
59     /**
60      * A constant indicating a full wake lock timer.
61      */
62     public static final int WAKE_TYPE_FULL = 1;
63 
64     /**
65      * A constant indicating a window wake lock timer.
66      */
67     public static final int WAKE_TYPE_WINDOW = 2;
68 
69     /**
70      * A constant indicating a sensor timer.
71      */
72     public static final int SENSOR = 3;
73 
74     /**
75      * A constant indicating a a wifi running timer
76      */
77     public static final int WIFI_RUNNING = 4;
78 
79     /**
80      * A constant indicating a full wifi lock timer
81      */
82     public static final int FULL_WIFI_LOCK = 5;
83 
84     /**
85      * A constant indicating a wifi scan
86      */
87     public static final int WIFI_SCAN = 6;
88 
89     /**
90      * A constant indicating a wifi multicast timer
91      */
92     public static final int WIFI_MULTICAST_ENABLED = 7;
93 
94     /**
95      * A constant indicating a video turn on timer
96      */
97     public static final int VIDEO_TURNED_ON = 8;
98 
99     /**
100      * A constant indicating a vibrator on timer
101      */
102     public static final int VIBRATOR_ON = 9;
103 
104     /**
105      * A constant indicating a foreground activity timer
106      */
107     public static final int FOREGROUND_ACTIVITY = 10;
108 
109     /**
110      * A constant indicating a wifi batched scan is active
111      */
112     public static final int WIFI_BATCHED_SCAN = 11;
113 
114     /**
115      * A constant indicating a process state timer
116      */
117     public static final int PROCESS_STATE = 12;
118 
119     /**
120      * A constant indicating a sync timer
121      */
122     public static final int SYNC = 13;
123 
124     /**
125      * A constant indicating a job timer
126      */
127     public static final int JOB = 14;
128 
129     /**
130      * A constant indicating an audio turn on timer
131      */
132     public static final int AUDIO_TURNED_ON = 15;
133 
134     /**
135      * A constant indicating a flashlight turn on timer
136      */
137     public static final int FLASHLIGHT_TURNED_ON = 16;
138 
139     /**
140      * A constant indicating a camera turn on timer
141      */
142     public static final int CAMERA_TURNED_ON = 17;
143 
144     /**
145      * A constant indicating a draw wake lock timer.
146      */
147     public static final int WAKE_TYPE_DRAW = 18;
148 
149     /**
150      * Include all of the data in the stats, including previously saved data.
151      */
152     public static final int STATS_SINCE_CHARGED = 0;
153 
154     /**
155      * Include only the current run in the stats.
156      */
157     public static final int STATS_CURRENT = 1;
158 
159     /**
160      * Include only the run since the last time the device was unplugged in the stats.
161      */
162     public static final int STATS_SINCE_UNPLUGGED = 2;
163 
164     // NOTE: Update this list if you add/change any stats above.
165     // These characters are supposed to represent "total", "last", "current",
166     // and "unplugged". They were shortened for efficiency sake.
167     private static final String[] STAT_NAMES = { "l", "c", "u" };
168 
169     /**
170      * Current version of checkin data format.
171      */
172     static final String CHECKIN_VERSION = "15";
173 
174     /**
175      * Old version, we hit 9 and ran out of room, need to remove.
176      */
177     private static final int BATTERY_STATS_CHECKIN_VERSION = 9;
178 
179     private static final long BYTES_PER_KB = 1024;
180     private static final long BYTES_PER_MB = 1048576; // 1024^2
181     private static final long BYTES_PER_GB = 1073741824; //1024^3
182 
183     private static final String VERSION_DATA = "vers";
184     private static final String UID_DATA = "uid";
185     private static final String APK_DATA = "apk";
186     private static final String PROCESS_DATA = "pr";
187     private static final String CPU_DATA = "cpu";
188     private static final String SENSOR_DATA = "sr";
189     private static final String VIBRATOR_DATA = "vib";
190     private static final String FOREGROUND_DATA = "fg";
191     private static final String STATE_TIME_DATA = "st";
192     private static final String WAKELOCK_DATA = "wl";
193     private static final String SYNC_DATA = "sy";
194     private static final String JOB_DATA = "jb";
195     private static final String KERNEL_WAKELOCK_DATA = "kwl";
196     private static final String WAKEUP_REASON_DATA = "wr";
197     private static final String NETWORK_DATA = "nt";
198     private static final String USER_ACTIVITY_DATA = "ua";
199     private static final String BATTERY_DATA = "bt";
200     private static final String BATTERY_DISCHARGE_DATA = "dc";
201     private static final String BATTERY_LEVEL_DATA = "lv";
202     private static final String GLOBAL_WIFI_DATA = "gwfl";
203     private static final String WIFI_DATA = "wfl";
204     private static final String GLOBAL_BLUETOOTH_DATA = "gble";
205     private static final String MISC_DATA = "m";
206     private static final String GLOBAL_NETWORK_DATA = "gn";
207     private static final String HISTORY_STRING_POOL = "hsp";
208     private static final String HISTORY_DATA = "h";
209     private static final String SCREEN_BRIGHTNESS_DATA = "br";
210     private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
211     private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
212     private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
213     private static final String DATA_CONNECTION_TIME_DATA = "dct";
214     private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
215     private static final String WIFI_STATE_TIME_DATA = "wst";
216     private static final String WIFI_STATE_COUNT_DATA = "wsc";
217     private static final String WIFI_SUPPL_STATE_TIME_DATA = "wsst";
218     private static final String WIFI_SUPPL_STATE_COUNT_DATA = "wssc";
219     private static final String WIFI_SIGNAL_STRENGTH_TIME_DATA = "wsgt";
220     private static final String WIFI_SIGNAL_STRENGTH_COUNT_DATA = "wsgc";
221     private static final String POWER_USE_SUMMARY_DATA = "pws";
222     private static final String POWER_USE_ITEM_DATA = "pwi";
223     private static final String DISCHARGE_STEP_DATA = "dsd";
224     private static final String CHARGE_STEP_DATA = "csd";
225     private static final String DISCHARGE_TIME_REMAIN_DATA = "dtr";
226     private static final String CHARGE_TIME_REMAIN_DATA = "ctr";
227     private static final String FLASHLIGHT_DATA = "fla";
228     private static final String CAMERA_DATA = "cam";
229     private static final String VIDEO_DATA = "vid";
230     private static final String AUDIO_DATA = "aud";
231 
232     private final StringBuilder mFormatBuilder = new StringBuilder(32);
233     private final Formatter mFormatter = new Formatter(mFormatBuilder);
234 
235     /**
236      * State for keeping track of counting information.
237      */
238     public static abstract class Counter {
239 
240         /**
241          * Returns the count associated with this Counter for the
242          * selected type of statistics.
243          *
244          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
245          */
getCountLocked(int which)246         public abstract int getCountLocked(int which);
247 
248         /**
249          * Temporary for debugging.
250          */
logState(Printer pw, String prefix)251         public abstract void logState(Printer pw, String prefix);
252     }
253 
254     /**
255      * State for keeping track of long counting information.
256      */
257     public static abstract class LongCounter {
258 
259         /**
260          * Returns the count associated with this Counter for the
261          * selected type of statistics.
262          *
263          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
264          */
getCountLocked(int which)265         public abstract long getCountLocked(int which);
266 
267         /**
268          * Temporary for debugging.
269          */
logState(Printer pw, String prefix)270         public abstract void logState(Printer pw, String prefix);
271     }
272 
273     /**
274      * State for keeping track of timing information.
275      */
276     public static abstract class Timer {
277 
278         /**
279          * Returns the count associated with this Timer for the
280          * selected type of statistics.
281          *
282          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
283          */
getCountLocked(int which)284         public abstract int getCountLocked(int which);
285 
286         /**
287          * Returns the total time in microseconds associated with this Timer for the
288          * selected type of statistics.
289          *
290          * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
291          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
292          * @return a time in microseconds
293          */
getTotalTimeLocked(long elapsedRealtimeUs, int which)294         public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which);
295 
296         /**
297          * Returns the total time in microseconds associated with this Timer since the
298          * 'mark' was last set.
299          *
300          * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
301          * @return a time in microseconds
302          */
getTimeSinceMarkLocked(long elapsedRealtimeUs)303         public abstract long getTimeSinceMarkLocked(long elapsedRealtimeUs);
304 
305         /**
306          * Temporary for debugging.
307          */
logState(Printer pw, String prefix)308         public abstract void logState(Printer pw, String prefix);
309     }
310 
311     /**
312      * The statistics associated with a particular uid.
313      */
314     public static abstract class Uid {
315 
316         /**
317          * Returns a mapping containing wakelock statistics.
318          *
319          * @return a Map from Strings to Uid.Wakelock objects.
320          */
getWakelockStats()321         public abstract ArrayMap<String, ? extends Wakelock> getWakelockStats();
322 
323         /**
324          * Returns a mapping containing sync statistics.
325          *
326          * @return a Map from Strings to Timer objects.
327          */
getSyncStats()328         public abstract ArrayMap<String, ? extends Timer> getSyncStats();
329 
330         /**
331          * Returns a mapping containing scheduled job statistics.
332          *
333          * @return a Map from Strings to Timer objects.
334          */
getJobStats()335         public abstract ArrayMap<String, ? extends Timer> getJobStats();
336 
337         /**
338          * The statistics associated with a particular wake lock.
339          */
340         public static abstract class Wakelock {
getWakeTime(int type)341             public abstract Timer getWakeTime(int type);
342         }
343 
344         /**
345          * Returns a mapping containing sensor statistics.
346          *
347          * @return a Map from Integer sensor ids to Uid.Sensor objects.
348          */
getSensorStats()349         public abstract SparseArray<? extends Sensor> getSensorStats();
350 
351         /**
352          * Returns a mapping containing active process data.
353          */
getPidStats()354         public abstract SparseArray<? extends Pid> getPidStats();
355 
356         /**
357          * Returns a mapping containing process statistics.
358          *
359          * @return a Map from Strings to Uid.Proc objects.
360          */
getProcessStats()361         public abstract ArrayMap<String, ? extends Proc> getProcessStats();
362 
363         /**
364          * Returns a mapping containing package statistics.
365          *
366          * @return a Map from Strings to Uid.Pkg objects.
367          */
getPackageStats()368         public abstract ArrayMap<String, ? extends Pkg> getPackageStats();
369 
370         /**
371          * Returns the time in milliseconds that this app kept the WiFi controller in the
372          * specified state <code>type</code>.
373          * @param type one of {@link #CONTROLLER_IDLE_TIME}, {@link #CONTROLLER_RX_TIME}, or
374          *             {@link #CONTROLLER_TX_TIME}.
375          * @param which one of {@link #STATS_CURRENT}, {@link #STATS_SINCE_CHARGED}, or
376          *              {@link #STATS_SINCE_UNPLUGGED}.
377          */
getWifiControllerActivity(int type, int which)378         public abstract long getWifiControllerActivity(int type, int which);
379 
380         /**
381          * {@hide}
382          */
getUid()383         public abstract int getUid();
384 
noteWifiRunningLocked(long elapsedRealtime)385         public abstract void noteWifiRunningLocked(long elapsedRealtime);
noteWifiStoppedLocked(long elapsedRealtime)386         public abstract void noteWifiStoppedLocked(long elapsedRealtime);
noteFullWifiLockAcquiredLocked(long elapsedRealtime)387         public abstract void noteFullWifiLockAcquiredLocked(long elapsedRealtime);
noteFullWifiLockReleasedLocked(long elapsedRealtime)388         public abstract void noteFullWifiLockReleasedLocked(long elapsedRealtime);
noteWifiScanStartedLocked(long elapsedRealtime)389         public abstract void noteWifiScanStartedLocked(long elapsedRealtime);
noteWifiScanStoppedLocked(long elapsedRealtime)390         public abstract void noteWifiScanStoppedLocked(long elapsedRealtime);
noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime)391         public abstract void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime);
noteWifiBatchedScanStoppedLocked(long elapsedRealtime)392         public abstract void noteWifiBatchedScanStoppedLocked(long elapsedRealtime);
noteWifiMulticastEnabledLocked(long elapsedRealtime)393         public abstract void noteWifiMulticastEnabledLocked(long elapsedRealtime);
noteWifiMulticastDisabledLocked(long elapsedRealtime)394         public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime);
noteActivityResumedLocked(long elapsedRealtime)395         public abstract void noteActivityResumedLocked(long elapsedRealtime);
noteActivityPausedLocked(long elapsedRealtime)396         public abstract void noteActivityPausedLocked(long elapsedRealtime);
getWifiRunningTime(long elapsedRealtimeUs, int which)397         public abstract long getWifiRunningTime(long elapsedRealtimeUs, int which);
getFullWifiLockTime(long elapsedRealtimeUs, int which)398         public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which);
getWifiScanTime(long elapsedRealtimeUs, int which)399         public abstract long getWifiScanTime(long elapsedRealtimeUs, int which);
getWifiScanCount(int which)400         public abstract int getWifiScanCount(int which);
getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)401         public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which);
getWifiBatchedScanCount(int csphBin, int which)402         public abstract int getWifiBatchedScanCount(int csphBin, int which);
getWifiMulticastTime(long elapsedRealtimeUs, int which)403         public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which);
getAudioTurnedOnTimer()404         public abstract Timer getAudioTurnedOnTimer();
getVideoTurnedOnTimer()405         public abstract Timer getVideoTurnedOnTimer();
getFlashlightTurnedOnTimer()406         public abstract Timer getFlashlightTurnedOnTimer();
getCameraTurnedOnTimer()407         public abstract Timer getCameraTurnedOnTimer();
getForegroundActivityTimer()408         public abstract Timer getForegroundActivityTimer();
409 
410         // Time this uid has any processes in foreground state.
411         public static final int PROCESS_STATE_FOREGROUND = 0;
412         // Time this uid has any process in active state (not cached).
413         public static final int PROCESS_STATE_ACTIVE = 1;
414         // Time this uid has any processes running at all.
415         public static final int PROCESS_STATE_RUNNING = 2;
416         // Total number of process states we track.
417         public static final int NUM_PROCESS_STATE = 3;
418 
419         static final String[] PROCESS_STATE_NAMES = {
420             "Foreground", "Active", "Running"
421         };
422 
getProcessStateTime(int state, long elapsedRealtimeUs, int which)423         public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which);
424 
getVibratorOnTimer()425         public abstract Timer getVibratorOnTimer();
426 
427         public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5;
428 
429         /**
430          * Note that these must match the constants in android.os.PowerManager.
431          * Also, if the user activity types change, the BatteryStatsImpl.VERSION must
432          * also be bumped.
433          */
434         static final String[] USER_ACTIVITY_TYPES = {
435             "other", "button", "touch"
436         };
437 
438         public static final int NUM_USER_ACTIVITY_TYPES = 3;
439 
noteUserActivityLocked(int type)440         public abstract void noteUserActivityLocked(int type);
hasUserActivity()441         public abstract boolean hasUserActivity();
getUserActivityCount(int type, int which)442         public abstract int getUserActivityCount(int type, int which);
443 
hasNetworkActivity()444         public abstract boolean hasNetworkActivity();
getNetworkActivityBytes(int type, int which)445         public abstract long getNetworkActivityBytes(int type, int which);
getNetworkActivityPackets(int type, int which)446         public abstract long getNetworkActivityPackets(int type, int which);
getMobileRadioActiveTime(int which)447         public abstract long getMobileRadioActiveTime(int which);
getMobileRadioActiveCount(int which)448         public abstract int getMobileRadioActiveCount(int which);
449 
450         /**
451          * Get the total cpu time (in microseconds) this UID had processes executing in userspace.
452          */
getUserCpuTimeUs(int which)453         public abstract long getUserCpuTimeUs(int which);
454 
455         /**
456          * Get the total cpu time (in microseconds) this UID had processes executing kernel syscalls.
457          */
getSystemCpuTimeUs(int which)458         public abstract long getSystemCpuTimeUs(int which);
459 
460         /**
461          * Get the total cpu power consumed (in milli-ampere-microseconds).
462          */
getCpuPowerMaUs(int which)463         public abstract long getCpuPowerMaUs(int which);
464 
465         /**
466          * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed for a
467          * given CPU cluster.
468          * @param cluster the index of the CPU cluster.
469          * @param step the index of the CPU speed. This is not the actual speed of the CPU.
470          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
471          * @see PowerProfile.getNumCpuClusters()
472          * @see PowerProfile.getNumSpeedStepsInCpuCluster(int)
473          */
getTimeAtCpuSpeed(int cluster, int step, int which)474         public abstract long getTimeAtCpuSpeed(int cluster, int step, int which);
475 
476         public static abstract class Sensor {
477             /*
478              * FIXME: it's not correct to use this magic value because it
479              * could clash with a sensor handle (which are defined by
480              * the sensor HAL, and therefore out of our control
481              */
482             // Magic sensor number for the GPS.
483             public static final int GPS = -10000;
484 
getHandle()485             public abstract int getHandle();
486 
getSensorTime()487             public abstract Timer getSensorTime();
488         }
489 
490         public class Pid {
491             public int mWakeNesting;
492             public long mWakeSumMs;
493             public long mWakeStartMs;
494         }
495 
496         /**
497          * The statistics associated with a particular process.
498          */
499         public static abstract class Proc {
500 
501             public static class ExcessivePower {
502                 public static final int TYPE_WAKE = 1;
503                 public static final int TYPE_CPU = 2;
504 
505                 public int type;
506                 public long overTime;
507                 public long usedTime;
508             }
509 
510             /**
511              * Returns true if this process is still active in the battery stats.
512              */
isActive()513             public abstract boolean isActive();
514 
515             /**
516              * Returns the total time (in milliseconds) spent executing in user code.
517              *
518              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
519              */
getUserTime(int which)520             public abstract long getUserTime(int which);
521 
522             /**
523              * Returns the total time (in milliseconds) spent executing in system code.
524              *
525              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
526              */
getSystemTime(int which)527             public abstract long getSystemTime(int which);
528 
529             /**
530              * Returns the number of times the process has been started.
531              *
532              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
533              */
getStarts(int which)534             public abstract int getStarts(int which);
535 
536             /**
537              * Returns the number of times the process has crashed.
538              *
539              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
540              */
getNumCrashes(int which)541             public abstract int getNumCrashes(int which);
542 
543             /**
544              * Returns the number of times the process has ANRed.
545              *
546              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
547              */
getNumAnrs(int which)548             public abstract int getNumAnrs(int which);
549 
550             /**
551              * Returns the cpu time (milliseconds) spent while the process was in the foreground.
552              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
553              * @return foreground cpu time in microseconds
554              */
getForegroundTime(int which)555             public abstract long getForegroundTime(int which);
556 
countExcessivePowers()557             public abstract int countExcessivePowers();
558 
getExcessivePower(int i)559             public abstract ExcessivePower getExcessivePower(int i);
560         }
561 
562         /**
563          * The statistics associated with a particular package.
564          */
565         public static abstract class Pkg {
566 
567             /**
568              * Returns information about all wakeup alarms that have been triggered for this
569              * package.  The mapping keys are tag names for the alarms, the counter contains
570              * the number of times the alarm was triggered while on battery.
571              */
getWakeupAlarmStats()572             public abstract ArrayMap<String, ? extends Counter> getWakeupAlarmStats();
573 
574             /**
575              * Returns a mapping containing service statistics.
576              */
getServiceStats()577             public abstract ArrayMap<String, ? extends Serv> getServiceStats();
578 
579             /**
580              * The statistics associated with a particular service.
581              */
582             public abstract class Serv {
583 
584                 /**
585                  * Returns the amount of time spent started.
586                  *
587                  * @param batteryUptime elapsed uptime on battery in microseconds.
588                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
589                  * @return
590                  */
getStartTime(long batteryUptime, int which)591                 public abstract long getStartTime(long batteryUptime, int which);
592 
593                 /**
594                  * Returns the total number of times startService() has been called.
595                  *
596                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
597                  */
getStarts(int which)598                 public abstract int getStarts(int which);
599 
600                 /**
601                  * Returns the total number times the service has been launched.
602                  *
603                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
604                  */
getLaunches(int which)605                 public abstract int getLaunches(int which);
606             }
607         }
608     }
609 
610     public static final class LevelStepTracker {
611         public long mLastStepTime = -1;
612         public int mNumStepDurations;
613         public final long[] mStepDurations;
614 
LevelStepTracker(int maxLevelSteps)615         public LevelStepTracker(int maxLevelSteps) {
616             mStepDurations = new long[maxLevelSteps];
617         }
618 
LevelStepTracker(int numSteps, long[] steps)619         public LevelStepTracker(int numSteps, long[] steps) {
620             mNumStepDurations = numSteps;
621             mStepDurations = new long[numSteps];
622             System.arraycopy(steps, 0, mStepDurations, 0, numSteps);
623         }
624 
getDurationAt(int index)625         public long getDurationAt(int index) {
626             return mStepDurations[index] & STEP_LEVEL_TIME_MASK;
627         }
628 
getLevelAt(int index)629         public int getLevelAt(int index) {
630             return (int)((mStepDurations[index] & STEP_LEVEL_LEVEL_MASK)
631                     >> STEP_LEVEL_LEVEL_SHIFT);
632         }
633 
getInitModeAt(int index)634         public int getInitModeAt(int index) {
635             return (int)((mStepDurations[index] & STEP_LEVEL_INITIAL_MODE_MASK)
636                     >> STEP_LEVEL_INITIAL_MODE_SHIFT);
637         }
638 
getModModeAt(int index)639         public int getModModeAt(int index) {
640             return (int)((mStepDurations[index] & STEP_LEVEL_MODIFIED_MODE_MASK)
641                     >> STEP_LEVEL_MODIFIED_MODE_SHIFT);
642         }
643 
appendHex(long val, int topOffset, StringBuilder out)644         private void appendHex(long val, int topOffset, StringBuilder out) {
645             boolean hasData = false;
646             while (topOffset >= 0) {
647                 int digit = (int)( (val>>topOffset) & 0xf );
648                 topOffset -= 4;
649                 if (!hasData && digit == 0) {
650                     continue;
651                 }
652                 hasData = true;
653                 if (digit >= 0 && digit <= 9) {
654                     out.append((char)('0' + digit));
655                 } else {
656                     out.append((char)('a' + digit - 10));
657                 }
658             }
659         }
660 
encodeEntryAt(int index, StringBuilder out)661         public void encodeEntryAt(int index, StringBuilder out) {
662             long item = mStepDurations[index];
663             long duration = item & STEP_LEVEL_TIME_MASK;
664             int level = (int)((item & STEP_LEVEL_LEVEL_MASK)
665                     >> STEP_LEVEL_LEVEL_SHIFT);
666             int initMode = (int)((item & STEP_LEVEL_INITIAL_MODE_MASK)
667                     >> STEP_LEVEL_INITIAL_MODE_SHIFT);
668             int modMode = (int)((item & STEP_LEVEL_MODIFIED_MODE_MASK)
669                     >> STEP_LEVEL_MODIFIED_MODE_SHIFT);
670             switch ((initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
671                 case Display.STATE_OFF: out.append('f'); break;
672                 case Display.STATE_ON: out.append('o'); break;
673                 case Display.STATE_DOZE: out.append('d'); break;
674                 case Display.STATE_DOZE_SUSPEND: out.append('z'); break;
675             }
676             if ((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) {
677                 out.append('p');
678             }
679             if ((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) {
680                 out.append('i');
681             }
682             switch ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
683                 case Display.STATE_OFF: out.append('F'); break;
684                 case Display.STATE_ON: out.append('O'); break;
685                 case Display.STATE_DOZE: out.append('D'); break;
686                 case Display.STATE_DOZE_SUSPEND: out.append('Z'); break;
687             }
688             if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) {
689                 out.append('P');
690             }
691             if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) {
692                 out.append('I');
693             }
694             out.append('-');
695             appendHex(level, 4, out);
696             out.append('-');
697             appendHex(duration, STEP_LEVEL_LEVEL_SHIFT-4, out);
698         }
699 
decodeEntryAt(int index, String value)700         public void decodeEntryAt(int index, String value) {
701             final int N = value.length();
702             int i = 0;
703             char c;
704             long out = 0;
705             while (i < N && (c=value.charAt(i)) != '-') {
706                 i++;
707                 switch (c) {
708                     case 'f': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
709                         break;
710                     case 'o': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
711                         break;
712                     case 'd': out |= (((long)Display.STATE_DOZE-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
713                         break;
714                     case 'z': out |= (((long)Display.STATE_DOZE_SUSPEND-1)
715                             << STEP_LEVEL_INITIAL_MODE_SHIFT);
716                         break;
717                     case 'p': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE)
718                             << STEP_LEVEL_INITIAL_MODE_SHIFT);
719                         break;
720                     case 'i': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE)
721                             << STEP_LEVEL_INITIAL_MODE_SHIFT);
722                         break;
723                     case 'F': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
724                         break;
725                     case 'O': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
726                         break;
727                     case 'D': out |= (((long)Display.STATE_DOZE-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
728                         break;
729                     case 'Z': out |= (((long)Display.STATE_DOZE_SUSPEND-1)
730                             << STEP_LEVEL_MODIFIED_MODE_SHIFT);
731                         break;
732                     case 'P': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE)
733                             << STEP_LEVEL_MODIFIED_MODE_SHIFT);
734                         break;
735                     case 'I': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE)
736                             << STEP_LEVEL_MODIFIED_MODE_SHIFT);
737                         break;
738                 }
739             }
740             i++;
741             long level = 0;
742             while (i < N && (c=value.charAt(i)) != '-') {
743                 i++;
744                 level <<= 4;
745                 if (c >= '0' && c <= '9') {
746                     level += c - '0';
747                 } else if (c >= 'a' && c <= 'f') {
748                     level += c - 'a' + 10;
749                 } else if (c >= 'A' && c <= 'F') {
750                     level += c - 'A' + 10;
751                 }
752             }
753             i++;
754             out |= (level << STEP_LEVEL_LEVEL_SHIFT) & STEP_LEVEL_LEVEL_MASK;
755             long duration = 0;
756             while (i < N && (c=value.charAt(i)) != '-') {
757                 i++;
758                 duration <<= 4;
759                 if (c >= '0' && c <= '9') {
760                     duration += c - '0';
761                 } else if (c >= 'a' && c <= 'f') {
762                     duration += c - 'a' + 10;
763                 } else if (c >= 'A' && c <= 'F') {
764                     duration += c - 'A' + 10;
765                 }
766             }
767             mStepDurations[index] = out | (duration & STEP_LEVEL_TIME_MASK);
768         }
769 
init()770         public void init() {
771             mLastStepTime = -1;
772             mNumStepDurations = 0;
773         }
774 
clearTime()775         public void clearTime() {
776             mLastStepTime = -1;
777         }
778 
computeTimePerLevel()779         public long computeTimePerLevel() {
780             final long[] steps = mStepDurations;
781             final int numSteps = mNumStepDurations;
782 
783             // For now we'll do a simple average across all steps.
784             if (numSteps <= 0) {
785                 return -1;
786             }
787             long total = 0;
788             for (int i=0; i<numSteps; i++) {
789                 total += steps[i] & STEP_LEVEL_TIME_MASK;
790             }
791             return total / numSteps;
792             /*
793             long[] buckets = new long[numSteps];
794             int numBuckets = 0;
795             int numToAverage = 4;
796             int i = 0;
797             while (i < numSteps) {
798                 long totalTime = 0;
799                 int num = 0;
800                 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
801                     totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
802                     num++;
803                 }
804                 buckets[numBuckets] = totalTime / num;
805                 numBuckets++;
806                 numToAverage *= 2;
807                 i += num;
808             }
809             if (numBuckets < 1) {
810                 return -1;
811             }
812             long averageTime = buckets[numBuckets-1];
813             for (i=numBuckets-2; i>=0; i--) {
814                 averageTime = (averageTime + buckets[i]) / 2;
815             }
816             return averageTime;
817             */
818         }
819 
computeTimeEstimate(long modesOfInterest, long modeValues, int[] outNumOfInterest)820         public long computeTimeEstimate(long modesOfInterest, long modeValues,
821                 int[] outNumOfInterest) {
822             final long[] steps = mStepDurations;
823             final int count = mNumStepDurations;
824             if (count <= 0) {
825                 return -1;
826             }
827             long total = 0;
828             int numOfInterest = 0;
829             for (int i=0; i<count; i++) {
830                 long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK)
831                         >> STEP_LEVEL_INITIAL_MODE_SHIFT;
832                 long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK)
833                         >> STEP_LEVEL_MODIFIED_MODE_SHIFT;
834                 // If the modes of interest didn't change during this step period...
835                 if ((modMode&modesOfInterest) == 0) {
836                     // And the mode values during this period match those we are measuring...
837                     if ((initMode&modesOfInterest) == modeValues) {
838                         // Then this can be used to estimate the total time!
839                         numOfInterest++;
840                         total += steps[i] & STEP_LEVEL_TIME_MASK;
841                     }
842                 }
843             }
844             if (numOfInterest <= 0) {
845                 return -1;
846             }
847 
848             if (outNumOfInterest != null) {
849                 outNumOfInterest[0] = numOfInterest;
850             }
851 
852             // The estimated time is the average time we spend in each level, multipled
853             // by 100 -- the total number of battery levels
854             return (total / numOfInterest) * 100;
855         }
856 
addLevelSteps(int numStepLevels, long modeBits, long elapsedRealtime)857         public void addLevelSteps(int numStepLevels, long modeBits, long elapsedRealtime) {
858             int stepCount = mNumStepDurations;
859             final long lastStepTime = mLastStepTime;
860             if (lastStepTime >= 0 && numStepLevels > 0) {
861                 final long[] steps = mStepDurations;
862                 long duration = elapsedRealtime - lastStepTime;
863                 for (int i=0; i<numStepLevels; i++) {
864                     System.arraycopy(steps, 0, steps, 1, steps.length-1);
865                     long thisDuration = duration / (numStepLevels-i);
866                     duration -= thisDuration;
867                     if (thisDuration > STEP_LEVEL_TIME_MASK) {
868                         thisDuration = STEP_LEVEL_TIME_MASK;
869                     }
870                     steps[0] = thisDuration | modeBits;
871                 }
872                 stepCount += numStepLevels;
873                 if (stepCount > steps.length) {
874                     stepCount = steps.length;
875                 }
876             }
877             mNumStepDurations = stepCount;
878             mLastStepTime = elapsedRealtime;
879         }
880 
readFromParcel(Parcel in)881         public void readFromParcel(Parcel in) {
882             final int N = in.readInt();
883             if (N > mStepDurations.length) {
884                 throw new ParcelFormatException("more step durations than available: " + N);
885             }
886             mNumStepDurations = N;
887             for (int i=0; i<N; i++) {
888                 mStepDurations[i] = in.readLong();
889             }
890         }
891 
writeToParcel(Parcel out)892         public void writeToParcel(Parcel out) {
893             final int N = mNumStepDurations;
894             out.writeInt(N);
895             for (int i=0; i<N; i++) {
896                 out.writeLong(mStepDurations[i]);
897             }
898         }
899     }
900 
901     public static final class PackageChange {
902         public String mPackageName;
903         public boolean mUpdate;
904         public int mVersionCode;
905     }
906 
907     public static final class DailyItem {
908         public long mStartTime;
909         public long mEndTime;
910         public LevelStepTracker mDischargeSteps;
911         public LevelStepTracker mChargeSteps;
912         public ArrayList<PackageChange> mPackageChanges;
913     }
914 
getDailyItemLocked(int daysAgo)915     public abstract DailyItem getDailyItemLocked(int daysAgo);
916 
getCurrentDailyStartTime()917     public abstract long getCurrentDailyStartTime();
918 
getNextMinDailyDeadline()919     public abstract long getNextMinDailyDeadline();
920 
getNextMaxDailyDeadline()921     public abstract long getNextMaxDailyDeadline();
922 
923     public final static class HistoryTag {
924         public String string;
925         public int uid;
926 
927         public int poolIdx;
928 
setTo(HistoryTag o)929         public void setTo(HistoryTag o) {
930             string = o.string;
931             uid = o.uid;
932             poolIdx = o.poolIdx;
933         }
934 
setTo(String _string, int _uid)935         public void setTo(String _string, int _uid) {
936             string = _string;
937             uid = _uid;
938             poolIdx = -1;
939         }
940 
writeToParcel(Parcel dest, int flags)941         public void writeToParcel(Parcel dest, int flags) {
942             dest.writeString(string);
943             dest.writeInt(uid);
944         }
945 
readFromParcel(Parcel src)946         public void readFromParcel(Parcel src) {
947             string = src.readString();
948             uid = src.readInt();
949             poolIdx = -1;
950         }
951 
952         @Override
equals(Object o)953         public boolean equals(Object o) {
954             if (this == o) return true;
955             if (o == null || getClass() != o.getClass()) return false;
956 
957             HistoryTag that = (HistoryTag) o;
958 
959             if (uid != that.uid) return false;
960             if (!string.equals(that.string)) return false;
961 
962             return true;
963         }
964 
965         @Override
hashCode()966         public int hashCode() {
967             int result = string.hashCode();
968             result = 31 * result + uid;
969             return result;
970         }
971     }
972 
973     /**
974      * Optional detailed information that can go into a history step.  This is typically
975      * generated each time the battery level changes.
976      */
977     public final static class HistoryStepDetails {
978         // Time (in 1/100 second) spent in user space and the kernel since the last step.
979         public int userTime;
980         public int systemTime;
981 
982         // Top three apps using CPU in the last step, with times in 1/100 second.
983         public int appCpuUid1;
984         public int appCpuUTime1;
985         public int appCpuSTime1;
986         public int appCpuUid2;
987         public int appCpuUTime2;
988         public int appCpuSTime2;
989         public int appCpuUid3;
990         public int appCpuUTime3;
991         public int appCpuSTime3;
992 
993         // Information from /proc/stat
994         public int statUserTime;
995         public int statSystemTime;
996         public int statIOWaitTime;
997         public int statIrqTime;
998         public int statSoftIrqTime;
999         public int statIdlTime;
1000 
HistoryStepDetails()1001         public HistoryStepDetails() {
1002             clear();
1003         }
1004 
clear()1005         public void clear() {
1006             userTime = systemTime = 0;
1007             appCpuUid1 = appCpuUid2 = appCpuUid3 = -1;
1008             appCpuUTime1 = appCpuSTime1 = appCpuUTime2 = appCpuSTime2
1009                     = appCpuUTime3 = appCpuSTime3 = 0;
1010         }
1011 
writeToParcel(Parcel out)1012         public void writeToParcel(Parcel out) {
1013             out.writeInt(userTime);
1014             out.writeInt(systemTime);
1015             out.writeInt(appCpuUid1);
1016             out.writeInt(appCpuUTime1);
1017             out.writeInt(appCpuSTime1);
1018             out.writeInt(appCpuUid2);
1019             out.writeInt(appCpuUTime2);
1020             out.writeInt(appCpuSTime2);
1021             out.writeInt(appCpuUid3);
1022             out.writeInt(appCpuUTime3);
1023             out.writeInt(appCpuSTime3);
1024             out.writeInt(statUserTime);
1025             out.writeInt(statSystemTime);
1026             out.writeInt(statIOWaitTime);
1027             out.writeInt(statIrqTime);
1028             out.writeInt(statSoftIrqTime);
1029             out.writeInt(statIdlTime);
1030         }
1031 
readFromParcel(Parcel in)1032         public void readFromParcel(Parcel in) {
1033             userTime = in.readInt();
1034             systemTime = in.readInt();
1035             appCpuUid1 = in.readInt();
1036             appCpuUTime1 = in.readInt();
1037             appCpuSTime1 = in.readInt();
1038             appCpuUid2 = in.readInt();
1039             appCpuUTime2 = in.readInt();
1040             appCpuSTime2 = in.readInt();
1041             appCpuUid3 = in.readInt();
1042             appCpuUTime3 = in.readInt();
1043             appCpuSTime3 = in.readInt();
1044             statUserTime = in.readInt();
1045             statSystemTime = in.readInt();
1046             statIOWaitTime = in.readInt();
1047             statIrqTime = in.readInt();
1048             statSoftIrqTime = in.readInt();
1049             statIdlTime = in.readInt();
1050         }
1051     }
1052 
1053     public final static class HistoryItem implements Parcelable {
1054         public HistoryItem next;
1055 
1056         // The time of this event in milliseconds, as per SystemClock.elapsedRealtime().
1057         public long time;
1058 
1059         public static final byte CMD_UPDATE = 0;        // These can be written as deltas
1060         public static final byte CMD_NULL = -1;
1061         public static final byte CMD_START = 4;
1062         public static final byte CMD_CURRENT_TIME = 5;
1063         public static final byte CMD_OVERFLOW = 6;
1064         public static final byte CMD_RESET = 7;
1065         public static final byte CMD_SHUTDOWN = 8;
1066 
1067         public byte cmd = CMD_NULL;
1068 
1069         /**
1070          * Return whether the command code is a delta data update.
1071          */
isDeltaData()1072         public boolean isDeltaData() {
1073             return cmd == CMD_UPDATE;
1074         }
1075 
1076         public byte batteryLevel;
1077         public byte batteryStatus;
1078         public byte batteryHealth;
1079         public byte batteryPlugType;
1080 
1081         public short batteryTemperature;
1082         public char batteryVoltage;
1083 
1084         // Constants from SCREEN_BRIGHTNESS_*
1085         public static final int STATE_BRIGHTNESS_SHIFT = 0;
1086         public static final int STATE_BRIGHTNESS_MASK = 0x7;
1087         // Constants from SIGNAL_STRENGTH_*
1088         public static final int STATE_PHONE_SIGNAL_STRENGTH_SHIFT = 3;
1089         public static final int STATE_PHONE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_PHONE_SIGNAL_STRENGTH_SHIFT;
1090         // Constants from ServiceState.STATE_*
1091         public static final int STATE_PHONE_STATE_SHIFT = 6;
1092         public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT;
1093         // Constants from DATA_CONNECTION_*
1094         public static final int STATE_DATA_CONNECTION_SHIFT = 9;
1095         public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT;
1096 
1097         // These states always appear directly in the first int token
1098         // of a delta change; they should be ones that change relatively
1099         // frequently.
1100         public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
1101         public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
1102         public static final int STATE_GPS_ON_FLAG = 1<<29;
1103         public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
1104         public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
1105         public static final int STATE_WIFI_RADIO_ACTIVE_FLAG = 1<<26;
1106         public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
1107         // These are on the lower bits used for the command; if they change
1108         // we need to write another int of data.
1109         public static final int STATE_SENSOR_ON_FLAG = 1<<23;
1110         public static final int STATE_AUDIO_ON_FLAG = 1<<22;
1111         public static final int STATE_PHONE_SCANNING_FLAG = 1<<21;
1112         public static final int STATE_SCREEN_ON_FLAG = 1<<20;       // consider moving to states2
1113         public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; // consider moving to states2
1114         // empty slot
1115         // empty slot
1116         public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<16;
1117 
1118         public static final int MOST_INTERESTING_STATES =
1119             STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG;
1120 
1121         public static final int SETTLE_TO_ZERO_STATES = 0xffff0000 & ~MOST_INTERESTING_STATES;
1122 
1123         public int states;
1124 
1125         // Constants from WIFI_SUPPL_STATE_*
1126         public static final int STATE2_WIFI_SUPPL_STATE_SHIFT = 0;
1127         public static final int STATE2_WIFI_SUPPL_STATE_MASK = 0xf;
1128         // Values for NUM_WIFI_SIGNAL_STRENGTH_BINS
1129         public static final int STATE2_WIFI_SIGNAL_STRENGTH_SHIFT = 4;
1130         public static final int STATE2_WIFI_SIGNAL_STRENGTH_MASK =
1131                 0x7 << STATE2_WIFI_SIGNAL_STRENGTH_SHIFT;
1132 
1133         public static final int STATE2_POWER_SAVE_FLAG = 1<<31;
1134         public static final int STATE2_VIDEO_ON_FLAG = 1<<30;
1135         public static final int STATE2_WIFI_RUNNING_FLAG = 1<<29;
1136         public static final int STATE2_WIFI_ON_FLAG = 1<<28;
1137         public static final int STATE2_FLASHLIGHT_FLAG = 1<<27;
1138         public static final int STATE2_DEVICE_IDLE_FLAG = 1<<26;
1139         public static final int STATE2_CHARGING_FLAG = 1<<25;
1140         public static final int STATE2_PHONE_IN_CALL_FLAG = 1<<24;
1141         public static final int STATE2_BLUETOOTH_ON_FLAG = 1<<23;
1142         public static final int STATE2_CAMERA_FLAG = 1<<22;
1143 
1144         public static final int MOST_INTERESTING_STATES2 =
1145             STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_FLAG
1146             | STATE2_CHARGING_FLAG | STATE2_PHONE_IN_CALL_FLAG | STATE2_BLUETOOTH_ON_FLAG;
1147 
1148         public static final int SETTLE_TO_ZERO_STATES2 = 0xffff0000 & ~MOST_INTERESTING_STATES2;
1149 
1150         public int states2;
1151 
1152         // The wake lock that was acquired at this point.
1153         public HistoryTag wakelockTag;
1154 
1155         // Kernel wakeup reason at this point.
1156         public HistoryTag wakeReasonTag;
1157 
1158         // Non-null when there is more detailed information at this step.
1159         public HistoryStepDetails stepDetails;
1160 
1161         public static final int EVENT_FLAG_START = 0x8000;
1162         public static final int EVENT_FLAG_FINISH = 0x4000;
1163 
1164         // No event in this item.
1165         public static final int EVENT_NONE = 0x0000;
1166         // Event is about a process that is running.
1167         public static final int EVENT_PROC = 0x0001;
1168         // Event is about an application package that is in the foreground.
1169         public static final int EVENT_FOREGROUND = 0x0002;
1170         // Event is about an application package that is at the top of the screen.
1171         public static final int EVENT_TOP = 0x0003;
1172         // Event is about active sync operations.
1173         public static final int EVENT_SYNC = 0x0004;
1174         // Events for all additional wake locks aquired/release within a wake block.
1175         // These are not generated by default.
1176         public static final int EVENT_WAKE_LOCK = 0x0005;
1177         // Event is about an application executing a scheduled job.
1178         public static final int EVENT_JOB = 0x0006;
1179         // Events for users running.
1180         public static final int EVENT_USER_RUNNING = 0x0007;
1181         // Events for foreground user.
1182         public static final int EVENT_USER_FOREGROUND = 0x0008;
1183         // Event for connectivity changed.
1184         public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009;
1185         // Event for becoming active taking us out of idle mode.
1186         public static final int EVENT_ACTIVE = 0x000a;
1187         // Event for a package being installed.
1188         public static final int EVENT_PACKAGE_INSTALLED = 0x000b;
1189         // Event for a package being uninstalled.
1190         public static final int EVENT_PACKAGE_UNINSTALLED = 0x000c;
1191         // Event for a package being uninstalled.
1192         public static final int EVENT_ALARM = 0x000d;
1193         // Record that we have decided we need to collect new stats data.
1194         public static final int EVENT_COLLECT_EXTERNAL_STATS = 0x000e;
1195         // Event for a package becoming inactive due to being unused for a period of time.
1196         public static final int EVENT_PACKAGE_INACTIVE = 0x000f;
1197         // Event for a package becoming active due to an interaction.
1198         public static final int EVENT_PACKAGE_ACTIVE = 0x0010;
1199         // Event for a package being on the temporary whitelist.
1200         public static final int EVENT_TEMP_WHITELIST = 0x0011;
1201         // Event for the screen waking up.
1202         public static final int EVENT_SCREEN_WAKE_UP = 0x0012;
1203 
1204         // Number of event types.
1205         public static final int EVENT_COUNT = 0x0013;
1206         // Mask to extract out only the type part of the event.
1207         public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
1208 
1209         public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
1210         public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
1211         public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START;
1212         public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
1213         public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
1214         public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
1215         public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
1216         public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
1217         public static final int EVENT_WAKE_LOCK_START = EVENT_WAKE_LOCK | EVENT_FLAG_START;
1218         public static final int EVENT_WAKE_LOCK_FINISH = EVENT_WAKE_LOCK | EVENT_FLAG_FINISH;
1219         public static final int EVENT_JOB_START = EVENT_JOB | EVENT_FLAG_START;
1220         public static final int EVENT_JOB_FINISH = EVENT_JOB | EVENT_FLAG_FINISH;
1221         public static final int EVENT_USER_RUNNING_START = EVENT_USER_RUNNING | EVENT_FLAG_START;
1222         public static final int EVENT_USER_RUNNING_FINISH = EVENT_USER_RUNNING | EVENT_FLAG_FINISH;
1223         public static final int EVENT_USER_FOREGROUND_START =
1224                 EVENT_USER_FOREGROUND | EVENT_FLAG_START;
1225         public static final int EVENT_USER_FOREGROUND_FINISH =
1226                 EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
1227         public static final int EVENT_ALARM_START = EVENT_ALARM | EVENT_FLAG_START;
1228         public static final int EVENT_ALARM_FINISH = EVENT_ALARM | EVENT_FLAG_FINISH;
1229         public static final int EVENT_TEMP_WHITELIST_START =
1230                 EVENT_TEMP_WHITELIST | EVENT_FLAG_START;
1231         public static final int EVENT_TEMP_WHITELIST_FINISH =
1232                 EVENT_TEMP_WHITELIST | EVENT_FLAG_FINISH;
1233 
1234         // For CMD_EVENT.
1235         public int eventCode;
1236         public HistoryTag eventTag;
1237 
1238         // Only set for CMD_CURRENT_TIME or CMD_RESET, as per System.currentTimeMillis().
1239         public long currentTime;
1240 
1241         // Meta-data when reading.
1242         public int numReadInts;
1243 
1244         // Pre-allocated objects.
1245         public final HistoryTag localWakelockTag = new HistoryTag();
1246         public final HistoryTag localWakeReasonTag = new HistoryTag();
1247         public final HistoryTag localEventTag = new HistoryTag();
1248 
HistoryItem()1249         public HistoryItem() {
1250         }
1251 
HistoryItem(long time, Parcel src)1252         public HistoryItem(long time, Parcel src) {
1253             this.time = time;
1254             numReadInts = 2;
1255             readFromParcel(src);
1256         }
1257 
describeContents()1258         public int describeContents() {
1259             return 0;
1260         }
1261 
writeToParcel(Parcel dest, int flags)1262         public void writeToParcel(Parcel dest, int flags) {
1263             dest.writeLong(time);
1264             int bat = (((int)cmd)&0xff)
1265                     | ((((int)batteryLevel)<<8)&0xff00)
1266                     | ((((int)batteryStatus)<<16)&0xf0000)
1267                     | ((((int)batteryHealth)<<20)&0xf00000)
1268                     | ((((int)batteryPlugType)<<24)&0xf000000)
1269                     | (wakelockTag != null ? 0x10000000 : 0)
1270                     | (wakeReasonTag != null ? 0x20000000 : 0)
1271                     | (eventCode != EVENT_NONE ? 0x40000000 : 0);
1272             dest.writeInt(bat);
1273             bat = (((int)batteryTemperature)&0xffff)
1274                     | ((((int)batteryVoltage)<<16)&0xffff0000);
1275             dest.writeInt(bat);
1276             dest.writeInt(states);
1277             dest.writeInt(states2);
1278             if (wakelockTag != null) {
1279                 wakelockTag.writeToParcel(dest, flags);
1280             }
1281             if (wakeReasonTag != null) {
1282                 wakeReasonTag.writeToParcel(dest, flags);
1283             }
1284             if (eventCode != EVENT_NONE) {
1285                 dest.writeInt(eventCode);
1286                 eventTag.writeToParcel(dest, flags);
1287             }
1288             if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
1289                 dest.writeLong(currentTime);
1290             }
1291         }
1292 
readFromParcel(Parcel src)1293         public void readFromParcel(Parcel src) {
1294             int start = src.dataPosition();
1295             int bat = src.readInt();
1296             cmd = (byte)(bat&0xff);
1297             batteryLevel = (byte)((bat>>8)&0xff);
1298             batteryStatus = (byte)((bat>>16)&0xf);
1299             batteryHealth = (byte)((bat>>20)&0xf);
1300             batteryPlugType = (byte)((bat>>24)&0xf);
1301             int bat2 = src.readInt();
1302             batteryTemperature = (short)(bat2&0xffff);
1303             batteryVoltage = (char)((bat2>>16)&0xffff);
1304             states = src.readInt();
1305             states2 = src.readInt();
1306             if ((bat&0x10000000) != 0) {
1307                 wakelockTag = localWakelockTag;
1308                 wakelockTag.readFromParcel(src);
1309             } else {
1310                 wakelockTag = null;
1311             }
1312             if ((bat&0x20000000) != 0) {
1313                 wakeReasonTag = localWakeReasonTag;
1314                 wakeReasonTag.readFromParcel(src);
1315             } else {
1316                 wakeReasonTag = null;
1317             }
1318             if ((bat&0x40000000) != 0) {
1319                 eventCode = src.readInt();
1320                 eventTag = localEventTag;
1321                 eventTag.readFromParcel(src);
1322             } else {
1323                 eventCode = EVENT_NONE;
1324                 eventTag = null;
1325             }
1326             if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
1327                 currentTime = src.readLong();
1328             } else {
1329                 currentTime = 0;
1330             }
1331             numReadInts += (src.dataPosition()-start)/4;
1332         }
1333 
clear()1334         public void clear() {
1335             time = 0;
1336             cmd = CMD_NULL;
1337             batteryLevel = 0;
1338             batteryStatus = 0;
1339             batteryHealth = 0;
1340             batteryPlugType = 0;
1341             batteryTemperature = 0;
1342             batteryVoltage = 0;
1343             states = 0;
1344             states2 = 0;
1345             wakelockTag = null;
1346             wakeReasonTag = null;
1347             eventCode = EVENT_NONE;
1348             eventTag = null;
1349         }
1350 
setTo(HistoryItem o)1351         public void setTo(HistoryItem o) {
1352             time = o.time;
1353             cmd = o.cmd;
1354             setToCommon(o);
1355         }
1356 
setTo(long time, byte cmd, HistoryItem o)1357         public void setTo(long time, byte cmd, HistoryItem o) {
1358             this.time = time;
1359             this.cmd = cmd;
1360             setToCommon(o);
1361         }
1362 
setToCommon(HistoryItem o)1363         private void setToCommon(HistoryItem o) {
1364             batteryLevel = o.batteryLevel;
1365             batteryStatus = o.batteryStatus;
1366             batteryHealth = o.batteryHealth;
1367             batteryPlugType = o.batteryPlugType;
1368             batteryTemperature = o.batteryTemperature;
1369             batteryVoltage = o.batteryVoltage;
1370             states = o.states;
1371             states2 = o.states2;
1372             if (o.wakelockTag != null) {
1373                 wakelockTag = localWakelockTag;
1374                 wakelockTag.setTo(o.wakelockTag);
1375             } else {
1376                 wakelockTag = null;
1377             }
1378             if (o.wakeReasonTag != null) {
1379                 wakeReasonTag = localWakeReasonTag;
1380                 wakeReasonTag.setTo(o.wakeReasonTag);
1381             } else {
1382                 wakeReasonTag = null;
1383             }
1384             eventCode = o.eventCode;
1385             if (o.eventTag != null) {
1386                 eventTag = localEventTag;
1387                 eventTag.setTo(o.eventTag);
1388             } else {
1389                 eventTag = null;
1390             }
1391             currentTime = o.currentTime;
1392         }
1393 
sameNonEvent(HistoryItem o)1394         public boolean sameNonEvent(HistoryItem o) {
1395             return batteryLevel == o.batteryLevel
1396                     && batteryStatus == o.batteryStatus
1397                     && batteryHealth == o.batteryHealth
1398                     && batteryPlugType == o.batteryPlugType
1399                     && batteryTemperature == o.batteryTemperature
1400                     && batteryVoltage == o.batteryVoltage
1401                     && states == o.states
1402                     && states2 == o.states2
1403                     && currentTime == o.currentTime;
1404         }
1405 
same(HistoryItem o)1406         public boolean same(HistoryItem o) {
1407             if (!sameNonEvent(o) || eventCode != o.eventCode) {
1408                 return false;
1409             }
1410             if (wakelockTag != o.wakelockTag) {
1411                 if (wakelockTag == null || o.wakelockTag == null) {
1412                     return false;
1413                 }
1414                 if (!wakelockTag.equals(o.wakelockTag)) {
1415                     return false;
1416                 }
1417             }
1418             if (wakeReasonTag != o.wakeReasonTag) {
1419                 if (wakeReasonTag == null || o.wakeReasonTag == null) {
1420                     return false;
1421                 }
1422                 if (!wakeReasonTag.equals(o.wakeReasonTag)) {
1423                     return false;
1424                 }
1425             }
1426             if (eventTag != o.eventTag) {
1427                 if (eventTag == null || o.eventTag == null) {
1428                     return false;
1429                 }
1430                 if (!eventTag.equals(o.eventTag)) {
1431                     return false;
1432                 }
1433             }
1434             return true;
1435         }
1436     }
1437 
1438     public final static class HistoryEventTracker {
1439         private final HashMap<String, SparseIntArray>[] mActiveEvents
1440                 = (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
1441 
updateState(int code, String name, int uid, int poolIdx)1442         public boolean updateState(int code, String name, int uid, int poolIdx) {
1443             if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
1444                 int idx = code&HistoryItem.EVENT_TYPE_MASK;
1445                 HashMap<String, SparseIntArray> active = mActiveEvents[idx];
1446                 if (active == null) {
1447                     active = new HashMap<>();
1448                     mActiveEvents[idx] = active;
1449                 }
1450                 SparseIntArray uids = active.get(name);
1451                 if (uids == null) {
1452                     uids = new SparseIntArray();
1453                     active.put(name, uids);
1454                 }
1455                 if (uids.indexOfKey(uid) >= 0) {
1456                     // Already set, nothing to do!
1457                     return false;
1458                 }
1459                 uids.put(uid, poolIdx);
1460             } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
1461                 int idx = code&HistoryItem.EVENT_TYPE_MASK;
1462                 HashMap<String, SparseIntArray> active = mActiveEvents[idx];
1463                 if (active == null) {
1464                     // not currently active, nothing to do.
1465                     return false;
1466                 }
1467                 SparseIntArray uids = active.get(name);
1468                 if (uids == null) {
1469                     // not currently active, nothing to do.
1470                     return false;
1471                 }
1472                 idx = uids.indexOfKey(uid);
1473                 if (idx < 0) {
1474                     // not currently active, nothing to do.
1475                     return false;
1476                 }
1477                 uids.removeAt(idx);
1478                 if (uids.size() <= 0) {
1479                     active.remove(name);
1480                 }
1481             }
1482             return true;
1483         }
1484 
removeEvents(int code)1485         public void removeEvents(int code) {
1486             int idx = code&HistoryItem.EVENT_TYPE_MASK;
1487             mActiveEvents[idx] = null;
1488         }
1489 
getStateForEvent(int code)1490         public HashMap<String, SparseIntArray> getStateForEvent(int code) {
1491             return mActiveEvents[code];
1492         }
1493     }
1494 
1495     public static final class BitDescription {
1496         public final int mask;
1497         public final int shift;
1498         public final String name;
1499         public final String shortName;
1500         public final String[] values;
1501         public final String[] shortValues;
1502 
BitDescription(int mask, String name, String shortName)1503         public BitDescription(int mask, String name, String shortName) {
1504             this.mask = mask;
1505             this.shift = -1;
1506             this.name = name;
1507             this.shortName = shortName;
1508             this.values = null;
1509             this.shortValues = null;
1510         }
1511 
BitDescription(int mask, int shift, String name, String shortName, String[] values, String[] shortValues)1512         public BitDescription(int mask, int shift, String name, String shortName,
1513                 String[] values, String[] shortValues) {
1514             this.mask = mask;
1515             this.shift = shift;
1516             this.name = name;
1517             this.shortName = shortName;
1518             this.values = values;
1519             this.shortValues = shortValues;
1520         }
1521     }
1522 
1523     /**
1524      * Don't allow any more batching in to the current history event.  This
1525      * is called when printing partial histories, so to ensure that the next
1526      * history event will go in to a new batch after what was printed in the
1527      * last partial history.
1528      */
commitCurrentHistoryBatchLocked()1529     public abstract void commitCurrentHistoryBatchLocked();
1530 
getHistoryTotalSize()1531     public abstract int getHistoryTotalSize();
1532 
getHistoryUsedSize()1533     public abstract int getHistoryUsedSize();
1534 
startIteratingHistoryLocked()1535     public abstract boolean startIteratingHistoryLocked();
1536 
getHistoryStringPoolSize()1537     public abstract int getHistoryStringPoolSize();
1538 
getHistoryStringPoolBytes()1539     public abstract int getHistoryStringPoolBytes();
1540 
getHistoryTagPoolString(int index)1541     public abstract String getHistoryTagPoolString(int index);
1542 
getHistoryTagPoolUid(int index)1543     public abstract int getHistoryTagPoolUid(int index);
1544 
getNextHistoryLocked(HistoryItem out)1545     public abstract boolean getNextHistoryLocked(HistoryItem out);
1546 
finishIteratingHistoryLocked()1547     public abstract void finishIteratingHistoryLocked();
1548 
startIteratingOldHistoryLocked()1549     public abstract boolean startIteratingOldHistoryLocked();
1550 
getNextOldHistoryLocked(HistoryItem out)1551     public abstract boolean getNextOldHistoryLocked(HistoryItem out);
1552 
finishIteratingOldHistoryLocked()1553     public abstract void finishIteratingOldHistoryLocked();
1554 
1555     /**
1556      * Return the base time offset for the battery history.
1557      */
getHistoryBaseTime()1558     public abstract long getHistoryBaseTime();
1559 
1560     /**
1561      * Returns the number of times the device has been started.
1562      */
getStartCount()1563     public abstract int getStartCount();
1564 
1565     /**
1566      * Returns the time in microseconds that the screen has been on while the device was
1567      * running on battery.
1568      *
1569      * {@hide}
1570      */
getScreenOnTime(long elapsedRealtimeUs, int which)1571     public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
1572 
1573     /**
1574      * Returns the number of times the screen was turned on.
1575      *
1576      * {@hide}
1577      */
getScreenOnCount(int which)1578     public abstract int getScreenOnCount(int which);
1579 
getInteractiveTime(long elapsedRealtimeUs, int which)1580     public abstract long getInteractiveTime(long elapsedRealtimeUs, int which);
1581 
1582     public static final int SCREEN_BRIGHTNESS_DARK = 0;
1583     public static final int SCREEN_BRIGHTNESS_DIM = 1;
1584     public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
1585     public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
1586     public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
1587 
1588     static final String[] SCREEN_BRIGHTNESS_NAMES = {
1589         "dark", "dim", "medium", "light", "bright"
1590     };
1591 
1592     static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
1593         "0", "1", "2", "3", "4"
1594     };
1595 
1596     public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
1597 
1598     /**
1599      * Returns the time in microseconds that the screen has been on with
1600      * the given brightness
1601      *
1602      * {@hide}
1603      */
getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)1604     public abstract long getScreenBrightnessTime(int brightnessBin,
1605             long elapsedRealtimeUs, int which);
1606 
1607     /**
1608      * Returns the time in microseconds that power save mode has been enabled while the device was
1609      * running on battery.
1610      *
1611      * {@hide}
1612      */
getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)1613     public abstract long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which);
1614 
1615     /**
1616      * Returns the number of times that power save mode was enabled.
1617      *
1618      * {@hide}
1619      */
getPowerSaveModeEnabledCount(int which)1620     public abstract int getPowerSaveModeEnabledCount(int which);
1621 
1622     /**
1623      * Returns the time in microseconds that device has been in idle mode while
1624      * running on battery.
1625      *
1626      * {@hide}
1627      */
getDeviceIdleModeEnabledTime(long elapsedRealtimeUs, int which)1628     public abstract long getDeviceIdleModeEnabledTime(long elapsedRealtimeUs, int which);
1629 
1630     /**
1631      * Returns the number of times that the devie has gone in to idle mode.
1632      *
1633      * {@hide}
1634      */
getDeviceIdleModeEnabledCount(int which)1635     public abstract int getDeviceIdleModeEnabledCount(int which);
1636 
1637     /**
1638      * Returns the time in microseconds that device has been in idling while on
1639      * battery.  This is broader than {@link #getDeviceIdleModeEnabledTime} -- it
1640      * counts all of the time that we consider the device to be idle, whether or not
1641      * it is currently in the actual device idle mode.
1642      *
1643      * {@hide}
1644      */
getDeviceIdlingTime(long elapsedRealtimeUs, int which)1645     public abstract long getDeviceIdlingTime(long elapsedRealtimeUs, int which);
1646 
1647     /**
1648      * Returns the number of times that the devie has started idling.
1649      *
1650      * {@hide}
1651      */
getDeviceIdlingCount(int which)1652     public abstract int getDeviceIdlingCount(int which);
1653 
1654     /**
1655      * Returns the number of times that connectivity state changed.
1656      *
1657      * {@hide}
1658      */
getNumConnectivityChange(int which)1659     public abstract int getNumConnectivityChange(int which);
1660 
1661     /**
1662      * Returns the time in microseconds that the phone has been on while the device was
1663      * running on battery.
1664      *
1665      * {@hide}
1666      */
getPhoneOnTime(long elapsedRealtimeUs, int which)1667     public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
1668 
1669     /**
1670      * Returns the number of times a phone call was activated.
1671      *
1672      * {@hide}
1673      */
getPhoneOnCount(int which)1674     public abstract int getPhoneOnCount(int which);
1675 
1676     /**
1677      * Returns the time in microseconds that the phone has been running with
1678      * the given signal strength.
1679      *
1680      * {@hide}
1681      */
getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)1682     public abstract long getPhoneSignalStrengthTime(int strengthBin,
1683             long elapsedRealtimeUs, int which);
1684 
1685     /**
1686      * Returns the time in microseconds that the phone has been trying to
1687      * acquire a signal.
1688      *
1689      * {@hide}
1690      */
getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)1691     public abstract long getPhoneSignalScanningTime(
1692             long elapsedRealtimeUs, int which);
1693 
1694     /**
1695      * Returns the number of times the phone has entered the given signal strength.
1696      *
1697      * {@hide}
1698      */
getPhoneSignalStrengthCount(int strengthBin, int which)1699     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
1700 
1701     /**
1702      * Returns the time in microseconds that the mobile network has been active
1703      * (in a high power state).
1704      *
1705      * {@hide}
1706      */
getMobileRadioActiveTime(long elapsedRealtimeUs, int which)1707     public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which);
1708 
1709     /**
1710      * Returns the number of times that the mobile network has transitioned to the
1711      * active state.
1712      *
1713      * {@hide}
1714      */
getMobileRadioActiveCount(int which)1715     public abstract int getMobileRadioActiveCount(int which);
1716 
1717     /**
1718      * Returns the time in microseconds that is the difference between the mobile radio
1719      * time we saw based on the elapsed timestamp when going down vs. the given time stamp
1720      * from the radio.
1721      *
1722      * {@hide}
1723      */
getMobileRadioActiveAdjustedTime(int which)1724     public abstract long getMobileRadioActiveAdjustedTime(int which);
1725 
1726     /**
1727      * Returns the time in microseconds that the mobile network has been active
1728      * (in a high power state) but not being able to blame on an app.
1729      *
1730      * {@hide}
1731      */
getMobileRadioActiveUnknownTime(int which)1732     public abstract long getMobileRadioActiveUnknownTime(int which);
1733 
1734     /**
1735      * Return count of number of times radio was up that could not be blamed on apps.
1736      *
1737      * {@hide}
1738      */
getMobileRadioActiveUnknownCount(int which)1739     public abstract int getMobileRadioActiveUnknownCount(int which);
1740 
1741     public static final int DATA_CONNECTION_NONE = 0;
1742     public static final int DATA_CONNECTION_GPRS = 1;
1743     public static final int DATA_CONNECTION_EDGE = 2;
1744     public static final int DATA_CONNECTION_UMTS = 3;
1745     public static final int DATA_CONNECTION_CDMA = 4;
1746     public static final int DATA_CONNECTION_EVDO_0 = 5;
1747     public static final int DATA_CONNECTION_EVDO_A = 6;
1748     public static final int DATA_CONNECTION_1xRTT = 7;
1749     public static final int DATA_CONNECTION_HSDPA = 8;
1750     public static final int DATA_CONNECTION_HSUPA = 9;
1751     public static final int DATA_CONNECTION_HSPA = 10;
1752     public static final int DATA_CONNECTION_IDEN = 11;
1753     public static final int DATA_CONNECTION_EVDO_B = 12;
1754     public static final int DATA_CONNECTION_LTE = 13;
1755     public static final int DATA_CONNECTION_EHRPD = 14;
1756     public static final int DATA_CONNECTION_HSPAP = 15;
1757     public static final int DATA_CONNECTION_OTHER = 16;
1758 
1759     static final String[] DATA_CONNECTION_NAMES = {
1760         "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
1761         "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
1762         "ehrpd", "hspap", "other"
1763     };
1764 
1765     public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
1766 
1767     /**
1768      * Returns the time in microseconds that the phone has been running with
1769      * the given data connection.
1770      *
1771      * {@hide}
1772      */
getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)1773     public abstract long getPhoneDataConnectionTime(int dataType,
1774             long elapsedRealtimeUs, int which);
1775 
1776     /**
1777      * Returns the number of times the phone has entered the given data
1778      * connection type.
1779      *
1780      * {@hide}
1781      */
getPhoneDataConnectionCount(int dataType, int which)1782     public abstract int getPhoneDataConnectionCount(int dataType, int which);
1783 
1784     public static final int WIFI_SUPPL_STATE_INVALID = 0;
1785     public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1;
1786     public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2;
1787     public static final int WIFI_SUPPL_STATE_INACTIVE = 3;
1788     public static final int WIFI_SUPPL_STATE_SCANNING = 4;
1789     public static final int WIFI_SUPPL_STATE_AUTHENTICATING = 5;
1790     public static final int WIFI_SUPPL_STATE_ASSOCIATING = 6;
1791     public static final int WIFI_SUPPL_STATE_ASSOCIATED = 7;
1792     public static final int WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE = 8;
1793     public static final int WIFI_SUPPL_STATE_GROUP_HANDSHAKE = 9;
1794     public static final int WIFI_SUPPL_STATE_COMPLETED = 10;
1795     public static final int WIFI_SUPPL_STATE_DORMANT = 11;
1796     public static final int WIFI_SUPPL_STATE_UNINITIALIZED = 12;
1797 
1798     public static final int NUM_WIFI_SUPPL_STATES = WIFI_SUPPL_STATE_UNINITIALIZED+1;
1799 
1800     static final String[] WIFI_SUPPL_STATE_NAMES = {
1801         "invalid", "disconn", "disabled", "inactive", "scanning",
1802         "authenticating", "associating", "associated", "4-way-handshake",
1803         "group-handshake", "completed", "dormant", "uninit"
1804     };
1805 
1806     static final String[] WIFI_SUPPL_STATE_SHORT_NAMES = {
1807         "inv", "dsc", "dis", "inact", "scan",
1808         "auth", "ascing", "asced", "4-way",
1809         "group", "compl", "dorm", "uninit"
1810     };
1811 
1812     public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
1813             = new BitDescription[] {
1814         new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
1815         new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
1816         new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
1817         new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
1818         new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
1819         new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
1820         new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
1821         new BitDescription(HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG, "wifi_radio", "Wr"),
1822         new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
1823         new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
1824         new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
1825         new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
1826         new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
1827         new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
1828                 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
1829                 DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
1830         new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
1831                 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
1832                 new String[] {"in", "out", "emergency", "off"},
1833                 new String[] {"in", "out", "em", "off"}),
1834         new BitDescription(HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK,
1835                 HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT, "phone_signal_strength", "Pss",
1836                 SignalStrength.SIGNAL_STRENGTH_NAMES,
1837                 new String[] { "0", "1", "2", "3", "4" }),
1838         new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
1839                 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
1840                 SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
1841     };
1842 
1843     public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
1844             = new BitDescription[] {
1845         new BitDescription(HistoryItem.STATE2_POWER_SAVE_FLAG, "power_save", "ps"),
1846         new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
1847         new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Ww"),
1848         new BitDescription(HistoryItem.STATE2_WIFI_ON_FLAG, "wifi", "W"),
1849         new BitDescription(HistoryItem.STATE2_FLASHLIGHT_FLAG, "flashlight", "fl"),
1850         new BitDescription(HistoryItem.STATE2_DEVICE_IDLE_FLAG, "device_idle", "di"),
1851         new BitDescription(HistoryItem.STATE2_CHARGING_FLAG, "charging", "ch"),
1852         new BitDescription(HistoryItem.STATE2_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
1853         new BitDescription(HistoryItem.STATE2_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
1854         new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
1855                 HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT, "wifi_signal_strength", "Wss",
1856                 new String[] { "0", "1", "2", "3", "4" },
1857                 new String[] { "0", "1", "2", "3", "4" }),
1858         new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK,
1859                 HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp",
1860                 WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES),
1861         new BitDescription(HistoryItem.STATE2_CAMERA_FLAG, "camera", "ca"),
1862     };
1863 
1864     public static final String[] HISTORY_EVENT_NAMES = new String[] {
1865             "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
1866             "active", "pkginst", "pkgunin", "alarm", "stats", "inactive", "active", "tmpwhitelist",
1867             "screenwake",
1868     };
1869 
1870     public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
1871             "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
1872             "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa", "Etw",
1873             "Esw",
1874     };
1875 
1876     /**
1877      * Returns the time in microseconds that wifi has been on while the device was
1878      * running on battery.
1879      *
1880      * {@hide}
1881      */
getWifiOnTime(long elapsedRealtimeUs, int which)1882     public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
1883 
1884     /**
1885      * Returns the time in microseconds that wifi has been on and the driver has
1886      * been in the running state while the device was running on battery.
1887      *
1888      * {@hide}
1889      */
getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)1890     public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
1891 
1892     public static final int WIFI_STATE_OFF = 0;
1893     public static final int WIFI_STATE_OFF_SCANNING = 1;
1894     public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
1895     public static final int WIFI_STATE_ON_DISCONNECTED = 3;
1896     public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
1897     public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
1898     public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
1899     public static final int WIFI_STATE_SOFT_AP = 7;
1900 
1901     static final String[] WIFI_STATE_NAMES = {
1902         "off", "scanning", "no_net", "disconn",
1903         "sta", "p2p", "sta_p2p", "soft_ap"
1904     };
1905 
1906     public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1;
1907 
1908     /**
1909      * Returns the time in microseconds that WiFi has been running in the given state.
1910      *
1911      * {@hide}
1912      */
getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)1913     public abstract long getWifiStateTime(int wifiState,
1914             long elapsedRealtimeUs, int which);
1915 
1916     /**
1917      * Returns the number of times that WiFi has entered the given state.
1918      *
1919      * {@hide}
1920      */
getWifiStateCount(int wifiState, int which)1921     public abstract int getWifiStateCount(int wifiState, int which);
1922 
1923     /**
1924      * Returns the time in microseconds that the wifi supplicant has been
1925      * in a given state.
1926      *
1927      * {@hide}
1928      */
getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)1929     public abstract long getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which);
1930 
1931     /**
1932      * Returns the number of times that the wifi supplicant has transitioned
1933      * to a given state.
1934      *
1935      * {@hide}
1936      */
getWifiSupplStateCount(int state, int which)1937     public abstract int getWifiSupplStateCount(int state, int which);
1938 
1939     public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5;
1940 
1941     /**
1942      * Returns the time in microseconds that WIFI has been running with
1943      * the given signal strength.
1944      *
1945      * {@hide}
1946      */
getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)1947     public abstract long getWifiSignalStrengthTime(int strengthBin,
1948             long elapsedRealtimeUs, int which);
1949 
1950     /**
1951      * Returns the number of times WIFI has entered the given signal strength.
1952      *
1953      * {@hide}
1954      */
getWifiSignalStrengthCount(int strengthBin, int which)1955     public abstract int getWifiSignalStrengthCount(int strengthBin, int which);
1956 
1957     /**
1958      * Returns the time in microseconds that the flashlight has been on while the device was
1959      * running on battery.
1960      *
1961      * {@hide}
1962      */
getFlashlightOnTime(long elapsedRealtimeUs, int which)1963     public abstract long getFlashlightOnTime(long elapsedRealtimeUs, int which);
1964 
1965     /**
1966      * Returns the number of times that the flashlight has been turned on while the device was
1967      * running on battery.
1968      *
1969      * {@hide}
1970      */
getFlashlightOnCount(int which)1971     public abstract long getFlashlightOnCount(int which);
1972 
1973     /**
1974      * Returns the time in microseconds that the camera has been on while the device was
1975      * running on battery.
1976      *
1977      * {@hide}
1978      */
getCameraOnTime(long elapsedRealtimeUs, int which)1979     public abstract long getCameraOnTime(long elapsedRealtimeUs, int which);
1980 
1981 
1982     public static final int NETWORK_MOBILE_RX_DATA = 0;
1983     public static final int NETWORK_MOBILE_TX_DATA = 1;
1984     public static final int NETWORK_WIFI_RX_DATA = 2;
1985     public static final int NETWORK_WIFI_TX_DATA = 3;
1986     public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1;
1987 
getNetworkActivityBytes(int type, int which)1988     public abstract long getNetworkActivityBytes(int type, int which);
getNetworkActivityPackets(int type, int which)1989     public abstract long getNetworkActivityPackets(int type, int which);
1990 
1991     public static final int CONTROLLER_IDLE_TIME = 0;
1992     public static final int CONTROLLER_RX_TIME = 1;
1993     public static final int CONTROLLER_TX_TIME = 2;
1994     public static final int CONTROLLER_POWER_DRAIN = 3;
1995     public static final int NUM_CONTROLLER_ACTIVITY_TYPES = CONTROLLER_POWER_DRAIN + 1;
1996 
1997     /**
1998      * Returns true if the BatteryStats object has detailed bluetooth power reports.
1999      * When true, calling {@link #getBluetoothControllerActivity(int, int)} will yield the
2000      * actual power data.
2001      */
hasBluetoothActivityReporting()2002     public abstract boolean hasBluetoothActivityReporting();
2003 
2004     /**
2005      * For {@link #CONTROLLER_IDLE_TIME}, {@link #CONTROLLER_RX_TIME}, and
2006      * {@link #CONTROLLER_TX_TIME}, returns the time spent (in milliseconds) in the
2007      * respective state.
2008      * For {@link #CONTROLLER_POWER_DRAIN}, returns the power used by the controller in
2009      * milli-ampere-milliseconds (mAms).
2010      */
getBluetoothControllerActivity(int type, int which)2011     public abstract long getBluetoothControllerActivity(int type, int which);
2012 
2013     /**
2014      * Returns true if the BatteryStats object has detailed WiFi power reports.
2015      * When true, calling {@link #getWifiControllerActivity(int, int)} will yield the
2016      * actual power data.
2017      */
hasWifiActivityReporting()2018     public abstract boolean hasWifiActivityReporting();
2019 
2020     /**
2021      * For {@link #CONTROLLER_IDLE_TIME}, {@link #CONTROLLER_RX_TIME}, and
2022      * {@link #CONTROLLER_TX_TIME}, returns the time spent (in milliseconds) in the
2023      * respective state.
2024      * For {@link #CONTROLLER_POWER_DRAIN}, returns the power used by the controller in
2025      * milli-ampere-milliseconds (mAms).
2026      */
getWifiControllerActivity(int type, int which)2027     public abstract long getWifiControllerActivity(int type, int which);
2028 
2029     /**
2030      * Return the wall clock time when battery stats data collection started.
2031      */
getStartClockTime()2032     public abstract long getStartClockTime();
2033 
2034     /**
2035      * Return platform version tag that we were running in when the battery stats started.
2036      */
getStartPlatformVersion()2037     public abstract String getStartPlatformVersion();
2038 
2039     /**
2040      * Return platform version tag that we were running in when the battery stats ended.
2041      */
getEndPlatformVersion()2042     public abstract String getEndPlatformVersion();
2043 
2044     /**
2045      * Return the internal version code of the parcelled format.
2046      */
getParcelVersion()2047     public abstract int getParcelVersion();
2048 
2049     /**
2050      * Return whether we are currently running on battery.
2051      */
getIsOnBattery()2052     public abstract boolean getIsOnBattery();
2053 
2054     /**
2055      * Returns a SparseArray containing the statistics for each uid.
2056      */
getUidStats()2057     public abstract SparseArray<? extends Uid> getUidStats();
2058 
2059     /**
2060      * Returns the current battery uptime in microseconds.
2061      *
2062      * @param curTime the amount of elapsed realtime in microseconds.
2063      */
getBatteryUptime(long curTime)2064     public abstract long getBatteryUptime(long curTime);
2065 
2066     /**
2067      * Returns the current battery realtime in microseconds.
2068      *
2069      * @param curTime the amount of elapsed realtime in microseconds.
2070      */
getBatteryRealtime(long curTime)2071     public abstract long getBatteryRealtime(long curTime);
2072 
2073     /**
2074      * Returns the battery percentage level at the last time the device was unplugged from power, or
2075      * the last time it booted on battery power.
2076      */
getDischargeStartLevel()2077     public abstract int getDischargeStartLevel();
2078 
2079     /**
2080      * Returns the current battery percentage level if we are in a discharge cycle, otherwise
2081      * returns the level at the last plug event.
2082      */
getDischargeCurrentLevel()2083     public abstract int getDischargeCurrentLevel();
2084 
2085     /**
2086      * Get the amount the battery has discharged since the stats were
2087      * last reset after charging, as a lower-end approximation.
2088      */
getLowDischargeAmountSinceCharge()2089     public abstract int getLowDischargeAmountSinceCharge();
2090 
2091     /**
2092      * Get the amount the battery has discharged since the stats were
2093      * last reset after charging, as an upper-end approximation.
2094      */
getHighDischargeAmountSinceCharge()2095     public abstract int getHighDischargeAmountSinceCharge();
2096 
2097     /**
2098      * Retrieve the discharge amount over the selected discharge period <var>which</var>.
2099      */
getDischargeAmount(int which)2100     public abstract int getDischargeAmount(int which);
2101 
2102     /**
2103      * Get the amount the battery has discharged while the screen was on,
2104      * since the last time power was unplugged.
2105      */
getDischargeAmountScreenOn()2106     public abstract int getDischargeAmountScreenOn();
2107 
2108     /**
2109      * Get the amount the battery has discharged while the screen was on,
2110      * since the last time the device was charged.
2111      */
getDischargeAmountScreenOnSinceCharge()2112     public abstract int getDischargeAmountScreenOnSinceCharge();
2113 
2114     /**
2115      * Get the amount the battery has discharged while the screen was off,
2116      * since the last time power was unplugged.
2117      */
getDischargeAmountScreenOff()2118     public abstract int getDischargeAmountScreenOff();
2119 
2120     /**
2121      * Get the amount the battery has discharged while the screen was off,
2122      * since the last time the device was charged.
2123      */
getDischargeAmountScreenOffSinceCharge()2124     public abstract int getDischargeAmountScreenOffSinceCharge();
2125 
2126     /**
2127      * Returns the total, last, or current battery uptime in microseconds.
2128      *
2129      * @param curTime the elapsed realtime in microseconds.
2130      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2131      */
computeBatteryUptime(long curTime, int which)2132     public abstract long computeBatteryUptime(long curTime, int which);
2133 
2134     /**
2135      * Returns the total, last, or current battery realtime in microseconds.
2136      *
2137      * @param curTime the current elapsed realtime in microseconds.
2138      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2139      */
computeBatteryRealtime(long curTime, int which)2140     public abstract long computeBatteryRealtime(long curTime, int which);
2141 
2142     /**
2143      * Returns the total, last, or current battery screen off uptime in microseconds.
2144      *
2145      * @param curTime the elapsed realtime in microseconds.
2146      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2147      */
computeBatteryScreenOffUptime(long curTime, int which)2148     public abstract long computeBatteryScreenOffUptime(long curTime, int which);
2149 
2150     /**
2151      * Returns the total, last, or current battery screen off realtime in microseconds.
2152      *
2153      * @param curTime the current elapsed realtime in microseconds.
2154      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2155      */
computeBatteryScreenOffRealtime(long curTime, int which)2156     public abstract long computeBatteryScreenOffRealtime(long curTime, int which);
2157 
2158     /**
2159      * Returns the total, last, or current uptime in microseconds.
2160      *
2161      * @param curTime the current elapsed realtime in microseconds.
2162      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2163      */
computeUptime(long curTime, int which)2164     public abstract long computeUptime(long curTime, int which);
2165 
2166     /**
2167      * Returns the total, last, or current realtime in microseconds.
2168      *
2169      * @param curTime the current elapsed realtime in microseconds.
2170      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2171      */
computeRealtime(long curTime, int which)2172     public abstract long computeRealtime(long curTime, int which);
2173 
2174     /**
2175      * Compute an approximation for how much run time (in microseconds) is remaining on
2176      * the battery.  Returns -1 if no time can be computed: either there is not
2177      * enough current data to make a decision, or the battery is currently
2178      * charging.
2179      *
2180      * @param curTime The current elepsed realtime in microseconds.
2181      */
computeBatteryTimeRemaining(long curTime)2182     public abstract long computeBatteryTimeRemaining(long curTime);
2183 
2184     // The part of a step duration that is the actual time.
2185     public static final long STEP_LEVEL_TIME_MASK = 0x000000ffffffffffL;
2186 
2187     // Bits in a step duration that are the new battery level we are at.
2188     public static final long STEP_LEVEL_LEVEL_MASK = 0x0000ff0000000000L;
2189     public static final int STEP_LEVEL_LEVEL_SHIFT = 40;
2190 
2191     // Bits in a step duration that are the initial mode we were in at that step.
2192     public static final long STEP_LEVEL_INITIAL_MODE_MASK = 0x00ff000000000000L;
2193     public static final int STEP_LEVEL_INITIAL_MODE_SHIFT = 48;
2194 
2195     // Bits in a step duration that indicate which modes changed during that step.
2196     public static final long STEP_LEVEL_MODIFIED_MODE_MASK = 0xff00000000000000L;
2197     public static final int STEP_LEVEL_MODIFIED_MODE_SHIFT = 56;
2198 
2199     // Step duration mode: the screen is on, off, dozed, etc; value is Display.STATE_* - 1.
2200     public static final int STEP_LEVEL_MODE_SCREEN_STATE = 0x03;
2201 
2202     // Step duration mode: power save is on.
2203     public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04;
2204 
2205     // Step duration mode: device is currently in idle mode.
2206     public static final int STEP_LEVEL_MODE_DEVICE_IDLE = 0x08;
2207 
2208     public static final int[] STEP_LEVEL_MODES_OF_INTEREST = new int[] {
2209             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2210             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE,
2211             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
2212             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2213             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2214             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2215             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2216             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2217             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE,
2218             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
2219     };
2220     public static final int[] STEP_LEVEL_MODE_VALUES = new int[] {
2221             (Display.STATE_OFF-1),
2222             (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE,
2223             (Display.STATE_OFF-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
2224             (Display.STATE_ON-1),
2225             (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE,
2226             (Display.STATE_DOZE-1),
2227             (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE,
2228             (Display.STATE_DOZE_SUSPEND-1),
2229             (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE,
2230             (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
2231     };
2232     public static final String[] STEP_LEVEL_MODE_LABELS = new String[] {
2233             "screen off",
2234             "screen off power save",
2235             "screen off device idle",
2236             "screen on",
2237             "screen on power save",
2238             "screen doze",
2239             "screen doze power save",
2240             "screen doze-suspend",
2241             "screen doze-suspend power save",
2242             "screen doze-suspend device idle",
2243     };
2244 
2245     /**
2246      * Return the array of discharge step durations.
2247      */
getDischargeLevelStepTracker()2248     public abstract LevelStepTracker getDischargeLevelStepTracker();
2249 
2250     /**
2251      * Return the array of daily discharge step durations.
2252      */
getDailyDischargeLevelStepTracker()2253     public abstract LevelStepTracker getDailyDischargeLevelStepTracker();
2254 
2255     /**
2256      * Compute an approximation for how much time (in microseconds) remains until the battery
2257      * is fully charged.  Returns -1 if no time can be computed: either there is not
2258      * enough current data to make a decision, or the battery is currently
2259      * discharging.
2260      *
2261      * @param curTime The current elepsed realtime in microseconds.
2262      */
computeChargeTimeRemaining(long curTime)2263     public abstract long computeChargeTimeRemaining(long curTime);
2264 
2265     /**
2266      * Return the array of charge step durations.
2267      */
getChargeLevelStepTracker()2268     public abstract LevelStepTracker getChargeLevelStepTracker();
2269 
2270     /**
2271      * Return the array of daily charge step durations.
2272      */
getDailyChargeLevelStepTracker()2273     public abstract LevelStepTracker getDailyChargeLevelStepTracker();
2274 
getDailyPackageChanges()2275     public abstract ArrayList<PackageChange> getDailyPackageChanges();
2276 
getWakeupReasonStats()2277     public abstract Map<String, ? extends Timer> getWakeupReasonStats();
2278 
getKernelWakelockStats()2279     public abstract Map<String, ? extends Timer> getKernelWakelockStats();
2280 
writeToParcelWithoutUids(Parcel out, int flags)2281     public abstract void writeToParcelWithoutUids(Parcel out, int flags);
2282 
formatTimeRaw(StringBuilder out, long seconds)2283     private final static void formatTimeRaw(StringBuilder out, long seconds) {
2284         long days = seconds / (60 * 60 * 24);
2285         if (days != 0) {
2286             out.append(days);
2287             out.append("d ");
2288         }
2289         long used = days * 60 * 60 * 24;
2290 
2291         long hours = (seconds - used) / (60 * 60);
2292         if (hours != 0 || used != 0) {
2293             out.append(hours);
2294             out.append("h ");
2295         }
2296         used += hours * 60 * 60;
2297 
2298         long mins = (seconds-used) / 60;
2299         if (mins != 0 || used != 0) {
2300             out.append(mins);
2301             out.append("m ");
2302         }
2303         used += mins * 60;
2304 
2305         if (seconds != 0 || used != 0) {
2306             out.append(seconds-used);
2307             out.append("s ");
2308         }
2309     }
2310 
formatTimeMs(StringBuilder sb, long time)2311     public final static void formatTimeMs(StringBuilder sb, long time) {
2312         long sec = time / 1000;
2313         formatTimeRaw(sb, sec);
2314         sb.append(time - (sec * 1000));
2315         sb.append("ms ");
2316     }
2317 
formatTimeMsNoSpace(StringBuilder sb, long time)2318     public final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
2319         long sec = time / 1000;
2320         formatTimeRaw(sb, sec);
2321         sb.append(time - (sec * 1000));
2322         sb.append("ms");
2323     }
2324 
formatRatioLocked(long num, long den)2325     public final String formatRatioLocked(long num, long den) {
2326         if (den == 0L) {
2327             return "--%";
2328         }
2329         float perc = ((float)num) / ((float)den) * 100;
2330         mFormatBuilder.setLength(0);
2331         mFormatter.format("%.1f%%", perc);
2332         return mFormatBuilder.toString();
2333     }
2334 
formatBytesLocked(long bytes)2335     final String formatBytesLocked(long bytes) {
2336         mFormatBuilder.setLength(0);
2337 
2338         if (bytes < BYTES_PER_KB) {
2339             return bytes + "B";
2340         } else if (bytes < BYTES_PER_MB) {
2341             mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
2342             return mFormatBuilder.toString();
2343         } else if (bytes < BYTES_PER_GB){
2344             mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
2345             return mFormatBuilder.toString();
2346         } else {
2347             mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
2348             return mFormatBuilder.toString();
2349         }
2350     }
2351 
computeWakeLock(Timer timer, long elapsedRealtimeUs, int which)2352     private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) {
2353         if (timer != null) {
2354             // Convert from microseconds to milliseconds with rounding
2355             long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
2356             long totalTimeMillis = (totalTimeMicros + 500) / 1000;
2357             return totalTimeMillis;
2358         }
2359         return 0;
2360     }
2361 
2362     /**
2363      *
2364      * @param sb a StringBuilder object.
2365      * @param timer a Timer object contining the wakelock times.
2366      * @param elapsedRealtimeUs the current on-battery time in microseconds.
2367      * @param name the name of the wakelock.
2368      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2369      * @param linePrefix a String to be prepended to each line of output.
2370      * @return the line prefix
2371      */
printWakeLock(StringBuilder sb, Timer timer, long elapsedRealtimeUs, String name, int which, String linePrefix)2372     private static final String printWakeLock(StringBuilder sb, Timer timer,
2373             long elapsedRealtimeUs, String name, int which, String linePrefix) {
2374 
2375         if (timer != null) {
2376             long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which);
2377 
2378             int count = timer.getCountLocked(which);
2379             if (totalTimeMillis != 0) {
2380                 sb.append(linePrefix);
2381                 formatTimeMs(sb, totalTimeMillis);
2382                 if (name != null) {
2383                     sb.append(name);
2384                     sb.append(' ');
2385                 }
2386                 sb.append('(');
2387                 sb.append(count);
2388                 sb.append(" times)");
2389                 return ", ";
2390             }
2391         }
2392         return linePrefix;
2393     }
2394 
2395     /**
2396      *
2397      * @param pw a PrintWriter object to print to.
2398      * @param sb a StringBuilder object.
2399      * @param timer a Timer object contining the wakelock times.
2400      * @param rawRealtime the current on-battery time in microseconds.
2401      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2402      * @param prefix a String to be prepended to each line of output.
2403      * @param type the name of the timer.
2404      */
printTimer(PrintWriter pw, StringBuilder sb, Timer timer, long rawRealtime, int which, String prefix, String type)2405     private static final boolean printTimer(PrintWriter pw, StringBuilder sb, Timer timer,
2406             long rawRealtime, int which, String prefix, String type) {
2407         if (timer != null) {
2408             // Convert from microseconds to milliseconds with rounding
2409             final long totalTime = (timer.getTotalTimeLocked(
2410                     rawRealtime, which) + 500) / 1000;
2411             final int count = timer.getCountLocked(which);
2412             if (totalTime != 0) {
2413                 sb.setLength(0);
2414                 sb.append(prefix);
2415                 sb.append("    ");
2416                 sb.append(type);
2417                 sb.append(": ");
2418                 formatTimeMs(sb, totalTime);
2419                 sb.append("realtime (");
2420                 sb.append(count);
2421                 sb.append(" times)");
2422                 pw.println(sb.toString());
2423                 return true;
2424             }
2425         }
2426         return false;
2427     }
2428 
2429     /**
2430      * Checkin version of wakelock printer. Prints simple comma-separated list.
2431      *
2432      * @param sb a StringBuilder object.
2433      * @param timer a Timer object contining the wakelock times.
2434      * @param elapsedRealtimeUs the current time in microseconds.
2435      * @param name the name of the wakelock.
2436      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2437      * @param linePrefix a String to be prepended to each line of output.
2438      * @return the line prefix
2439      */
printWakeLockCheckin(StringBuilder sb, Timer timer, long elapsedRealtimeUs, String name, int which, String linePrefix)2440     private static final String printWakeLockCheckin(StringBuilder sb, Timer timer,
2441             long elapsedRealtimeUs, String name, int which, String linePrefix) {
2442         long totalTimeMicros = 0;
2443         int count = 0;
2444         if (timer != null) {
2445             totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
2446             count = timer.getCountLocked(which);
2447         }
2448         sb.append(linePrefix);
2449         sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
2450         sb.append(',');
2451         sb.append(name != null ? name + "," : "");
2452         sb.append(count);
2453         return ",";
2454     }
2455 
2456     /**
2457      * Dump a comma-separated line of values for terse checkin mode.
2458      *
2459      * @param pw the PageWriter to dump log to
2460      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
2461      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
2462      * @param args type-dependent data arguments
2463      */
dumpLine(PrintWriter pw, int uid, String category, String type, Object... args )2464     private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
2465            Object... args ) {
2466         pw.print(BATTERY_STATS_CHECKIN_VERSION);
2467         pw.print(',');
2468         pw.print(uid);
2469         pw.print(',');
2470         pw.print(category);
2471         pw.print(',');
2472         pw.print(type);
2473 
2474         for (Object arg : args) {
2475             pw.print(',');
2476             pw.print(arg);
2477         }
2478         pw.println();
2479     }
2480 
2481     /**
2482      * Dump a given timer stat for terse checkin mode.
2483      *
2484      * @param pw the PageWriter to dump log to
2485      * @param uid the UID to log
2486      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
2487      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
2488      * @param timer a {@link Timer} to dump stats for
2489      * @param rawRealtime the current elapsed realtime of the system in microseconds
2490      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
2491      */
dumpTimer(PrintWriter pw, int uid, String category, String type, Timer timer, long rawRealtime, int which)2492     private static final void dumpTimer(PrintWriter pw, int uid, String category, String type,
2493                                         Timer timer, long rawRealtime, int which) {
2494         if (timer != null) {
2495             // Convert from microseconds to milliseconds with rounding
2496             final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
2497                     / 1000;
2498             final int count = timer.getCountLocked(which);
2499             if (totalTime != 0) {
2500                 dumpLine(pw, uid, category, type, totalTime, count);
2501             }
2502         }
2503     }
2504 
2505     /**
2506      * Temporary for settings.
2507      */
dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid)2508     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
2509         dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
2510     }
2511 
2512     /**
2513      * Checkin server version of dump to produce more compact, computer-readable log.
2514      *
2515      * NOTE: all times are expressed in 'ms'.
2516      */
dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid, boolean wifiOnly)2517     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
2518             boolean wifiOnly) {
2519         final long rawUptime = SystemClock.uptimeMillis() * 1000;
2520         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
2521         final long batteryUptime = getBatteryUptime(rawUptime);
2522         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
2523         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
2524         final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
2525         final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
2526                 which);
2527         final long totalRealtime = computeRealtime(rawRealtime, which);
2528         final long totalUptime = computeUptime(rawUptime, which);
2529         final long screenOnTime = getScreenOnTime(rawRealtime, which);
2530         final long interactiveTime = getInteractiveTime(rawRealtime, which);
2531         final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
2532         final long deviceIdleModeEnabledTime = getDeviceIdleModeEnabledTime(rawRealtime, which);
2533         final long deviceIdlingTime = getDeviceIdlingTime(rawRealtime, which);
2534         final int connChanges = getNumConnectivityChange(which);
2535         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
2536 
2537         final StringBuilder sb = new StringBuilder(128);
2538 
2539         final SparseArray<? extends Uid> uidStats = getUidStats();
2540         final int NU = uidStats.size();
2541 
2542         final String category = STAT_NAMES[which];
2543 
2544         // Dump "battery" stat
2545         dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
2546                 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
2547                 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
2548                 totalRealtime / 1000, totalUptime / 1000,
2549                 getStartClockTime(),
2550                 whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000);
2551 
2552         // Calculate wakelock times across all uids.
2553         long fullWakeLockTimeTotal = 0;
2554         long partialWakeLockTimeTotal = 0;
2555 
2556         for (int iu = 0; iu < NU; iu++) {
2557             final Uid u = uidStats.valueAt(iu);
2558 
2559             final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
2560                     = u.getWakelockStats();
2561             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
2562                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
2563 
2564                 final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
2565                 if (fullWakeTimer != null) {
2566                     fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
2567                             which);
2568                 }
2569 
2570                 final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
2571                 if (partialWakeTimer != null) {
2572                     partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
2573                         rawRealtime, which);
2574                 }
2575             }
2576         }
2577 
2578         // Dump network stats
2579         final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
2580         final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
2581         final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
2582         final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
2583         final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
2584         final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
2585         final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
2586         final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
2587         dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
2588                 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
2589                 mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets);
2590 
2591         // Dump Wifi controller stats
2592         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
2593         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
2594         final long wifiIdleTimeMs = getWifiControllerActivity(CONTROLLER_IDLE_TIME, which);
2595         final long wifiRxTimeMs = getWifiControllerActivity(CONTROLLER_RX_TIME, which);
2596         final long wifiTxTimeMs = getWifiControllerActivity(CONTROLLER_TX_TIME, which);
2597         final long wifiPowerMaMs = getWifiControllerActivity(CONTROLLER_POWER_DRAIN, which);
2598         dumpLine(pw, 0 /* uid */, category, GLOBAL_WIFI_DATA,
2599                 wifiOnTime / 1000, wifiRunningTime / 1000,
2600                 wifiIdleTimeMs, wifiRxTimeMs, wifiTxTimeMs, wifiPowerMaMs / (1000*60*60));
2601 
2602         // Dump Bluetooth controller stats
2603         final long btIdleTimeMs = getBluetoothControllerActivity(CONTROLLER_IDLE_TIME, which);
2604         final long btRxTimeMs = getBluetoothControllerActivity(CONTROLLER_RX_TIME, which);
2605         final long btTxTimeMs = getBluetoothControllerActivity(CONTROLLER_TX_TIME, which);
2606         final long btPowerMaMs = getBluetoothControllerActivity(CONTROLLER_POWER_DRAIN, which);
2607         dumpLine(pw, 0 /* uid */, category, GLOBAL_BLUETOOTH_DATA,
2608                 btIdleTimeMs, btRxTimeMs, btTxTimeMs, btPowerMaMs / (1000*60*60));
2609 
2610         // Dump misc stats
2611         dumpLine(pw, 0 /* uid */, category, MISC_DATA,
2612                 screenOnTime / 1000, phoneOnTime / 1000,
2613                 fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000,
2614                 getMobileRadioActiveTime(rawRealtime, which) / 1000,
2615                 getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000,
2616                 powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeEnabledTime / 1000,
2617                 getDeviceIdleModeEnabledCount(which), deviceIdlingTime / 1000,
2618                 getDeviceIdlingCount(which),
2619                 getMobileRadioActiveCount(which),
2620                 getMobileRadioActiveUnknownTime(which) / 1000);
2621 
2622         // Dump screen brightness stats
2623         Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
2624         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
2625             args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
2626         }
2627         dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
2628 
2629         // Dump signal strength stats
2630         args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
2631         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
2632             args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
2633         }
2634         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
2635         dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
2636                 getPhoneSignalScanningTime(rawRealtime, which) / 1000);
2637         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
2638             args[i] = getPhoneSignalStrengthCount(i, which);
2639         }
2640         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
2641 
2642         // Dump network type stats
2643         args = new Object[NUM_DATA_CONNECTION_TYPES];
2644         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
2645             args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
2646         }
2647         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
2648         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
2649             args[i] = getPhoneDataConnectionCount(i, which);
2650         }
2651         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
2652 
2653         // Dump wifi state stats
2654         args = new Object[NUM_WIFI_STATES];
2655         for (int i=0; i<NUM_WIFI_STATES; i++) {
2656             args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
2657         }
2658         dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args);
2659         for (int i=0; i<NUM_WIFI_STATES; i++) {
2660             args[i] = getWifiStateCount(i, which);
2661         }
2662         dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args);
2663 
2664         // Dump wifi suppl state stats
2665         args = new Object[NUM_WIFI_SUPPL_STATES];
2666         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
2667             args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
2668         }
2669         dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_TIME_DATA, args);
2670         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
2671             args[i] = getWifiSupplStateCount(i, which);
2672         }
2673         dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_COUNT_DATA, args);
2674 
2675         // Dump wifi signal strength stats
2676         args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
2677         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
2678             args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
2679         }
2680         dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
2681         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
2682             args[i] = getWifiSignalStrengthCount(i, which);
2683         }
2684         dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
2685 
2686         if (which == STATS_SINCE_UNPLUGGED) {
2687             dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
2688                     getDischargeCurrentLevel());
2689         }
2690 
2691         if (which == STATS_SINCE_UNPLUGGED) {
2692             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
2693                     getDischargeStartLevel()-getDischargeCurrentLevel(),
2694                     getDischargeStartLevel()-getDischargeCurrentLevel(),
2695                     getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
2696         } else {
2697             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
2698                     getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
2699                     getDischargeAmountScreenOnSinceCharge(),
2700                     getDischargeAmountScreenOffSinceCharge());
2701         }
2702 
2703         if (reqUid < 0) {
2704             final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
2705             if (kernelWakelocks.size() > 0) {
2706                 for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
2707                     sb.setLength(0);
2708                     printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
2709                     dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
2710                             sb.toString());
2711                 }
2712             }
2713             final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
2714             if (wakeupReasons.size() > 0) {
2715                 for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
2716                     // Not doing the regular wake lock formatting to remain compatible
2717                     // with the old checkin format.
2718                     long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which);
2719                     int count = ent.getValue().getCountLocked(which);
2720                     dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA,
2721                             "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count);
2722                 }
2723             }
2724         }
2725 
2726         final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
2727         helper.create(this);
2728         helper.refreshStats(which, UserHandle.USER_ALL);
2729         final List<BatterySipper> sippers = helper.getUsageList();
2730         if (sippers != null && sippers.size() > 0) {
2731             dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
2732                     BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
2733                     BatteryStatsHelper.makemAh(helper.getComputedPower()),
2734                     BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
2735                     BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
2736             for (int i=0; i<sippers.size(); i++) {
2737                 final BatterySipper bs = sippers.get(i);
2738                 int uid = 0;
2739                 String label;
2740                 switch (bs.drainType) {
2741                     case IDLE:
2742                         label="idle";
2743                         break;
2744                     case CELL:
2745                         label="cell";
2746                         break;
2747                     case PHONE:
2748                         label="phone";
2749                         break;
2750                     case WIFI:
2751                         label="wifi";
2752                         break;
2753                     case BLUETOOTH:
2754                         label="blue";
2755                         break;
2756                     case SCREEN:
2757                         label="scrn";
2758                         break;
2759                     case FLASHLIGHT:
2760                         label="flashlight";
2761                         break;
2762                     case APP:
2763                         uid = bs.uidObj.getUid();
2764                         label = "uid";
2765                         break;
2766                     case USER:
2767                         uid = UserHandle.getUid(bs.userId, 0);
2768                         label = "user";
2769                         break;
2770                     case UNACCOUNTED:
2771                         label = "unacc";
2772                         break;
2773                     case OVERCOUNTED:
2774                         label = "over";
2775                         break;
2776                     case CAMERA:
2777                         label = "camera";
2778                         break;
2779                     default:
2780                         label = "???";
2781                 }
2782                 dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
2783                         BatteryStatsHelper.makemAh(bs.totalPowerMah));
2784             }
2785         }
2786 
2787         for (int iu = 0; iu < NU; iu++) {
2788             final int uid = uidStats.keyAt(iu);
2789             if (reqUid >= 0 && uid != reqUid) {
2790                 continue;
2791             }
2792             final Uid u = uidStats.valueAt(iu);
2793 
2794             // Dump Network stats per uid, if any
2795             final long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
2796             final long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
2797             final long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
2798             final long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
2799             final long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
2800             final long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
2801             final long mobileActiveTime = u.getMobileRadioActiveTime(which);
2802             final int mobileActiveCount = u.getMobileRadioActiveCount(which);
2803             final long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
2804             final long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
2805             if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
2806                     || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
2807                     || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0) {
2808                 dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
2809                         wifiBytesRx, wifiBytesTx,
2810                         mobilePacketsRx, mobilePacketsTx,
2811                         wifiPacketsRx, wifiPacketsTx,
2812                         mobileActiveTime, mobileActiveCount);
2813             }
2814 
2815             final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
2816             final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
2817             final int wifiScanCount = u.getWifiScanCount(which);
2818             final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
2819             final long uidWifiIdleTimeMs = u.getWifiControllerActivity(CONTROLLER_IDLE_TIME, which);
2820             final long uidWifiRxTimeMs = u.getWifiControllerActivity(CONTROLLER_RX_TIME, which);
2821             final long uidWifiTxTimeMs = u.getWifiControllerActivity(CONTROLLER_TX_TIME, which);
2822             if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
2823                     || uidWifiRunningTime != 0 || uidWifiIdleTimeMs != 0 || uidWifiRxTimeMs != 0
2824                     || uidWifiTxTimeMs != 0) {
2825                 dumpLine(pw, uid, category, WIFI_DATA,
2826                         fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime, wifiScanCount,
2827                         uidWifiIdleTimeMs, uidWifiRxTimeMs, uidWifiTxTimeMs);
2828             }
2829 
2830             if (u.hasUserActivity()) {
2831                 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
2832                 boolean hasData = false;
2833                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
2834                     int val = u.getUserActivityCount(i, which);
2835                     args[i] = val;
2836                     if (val != 0) hasData = true;
2837                 }
2838                 if (hasData) {
2839                     dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args);
2840                 }
2841             }
2842 
2843             final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
2844             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
2845                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
2846                 String linePrefix = "";
2847                 sb.setLength(0);
2848                 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
2849                         rawRealtime, "f", which, linePrefix);
2850                 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
2851                         rawRealtime, "p", which, linePrefix);
2852                 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
2853                         rawRealtime, "w", which, linePrefix);
2854 
2855                 // Only log if we had at lease one wakelock...
2856                 if (sb.length() > 0) {
2857                     String name = wakelocks.keyAt(iw);
2858                     if (name.indexOf(',') >= 0) {
2859                         name = name.replace(',', '_');
2860                     }
2861                     dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
2862                 }
2863             }
2864 
2865             final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
2866             for (int isy=syncs.size()-1; isy>=0; isy--) {
2867                 final Timer timer = syncs.valueAt(isy);
2868                 // Convert from microseconds to milliseconds with rounding
2869                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2870                 final int count = timer.getCountLocked(which);
2871                 if (totalTime != 0) {
2872                     dumpLine(pw, uid, category, SYNC_DATA, syncs.keyAt(isy), totalTime, count);
2873                 }
2874             }
2875 
2876             final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
2877             for (int ij=jobs.size()-1; ij>=0; ij--) {
2878                 final Timer timer = jobs.valueAt(ij);
2879                 // Convert from microseconds to milliseconds with rounding
2880                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2881                 final int count = timer.getCountLocked(which);
2882                 if (totalTime != 0) {
2883                     dumpLine(pw, uid, category, JOB_DATA, jobs.keyAt(ij), totalTime, count);
2884                 }
2885             }
2886 
2887             dumpTimer(pw, uid, category, FLASHLIGHT_DATA, u.getFlashlightTurnedOnTimer(),
2888                     rawRealtime, which);
2889             dumpTimer(pw, uid, category, CAMERA_DATA, u.getCameraTurnedOnTimer(),
2890                     rawRealtime, which);
2891             dumpTimer(pw, uid, category, VIDEO_DATA, u.getVideoTurnedOnTimer(),
2892                     rawRealtime, which);
2893             dumpTimer(pw, uid, category, AUDIO_DATA, u.getAudioTurnedOnTimer(),
2894                     rawRealtime, which);
2895 
2896             final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
2897             final int NSE = sensors.size();
2898             for (int ise=0; ise<NSE; ise++) {
2899                 final Uid.Sensor se = sensors.valueAt(ise);
2900                 final int sensorNumber = sensors.keyAt(ise);
2901                 final Timer timer = se.getSensorTime();
2902                 if (timer != null) {
2903                     // Convert from microseconds to milliseconds with rounding
2904                     final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
2905                             / 1000;
2906                     final int count = timer.getCountLocked(which);
2907                     if (totalTime != 0) {
2908                         dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
2909                     }
2910                 }
2911             }
2912 
2913             dumpTimer(pw, uid, category, VIBRATOR_DATA, u.getVibratorOnTimer(),
2914                     rawRealtime, which);
2915 
2916             dumpTimer(pw, uid, category, FOREGROUND_DATA, u.getForegroundActivityTimer(),
2917                     rawRealtime, which);
2918 
2919             final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
2920             long totalStateTime = 0;
2921             for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
2922                 totalStateTime += u.getProcessStateTime(ips, rawRealtime, which);
2923                 stateTimes[ips] = (totalStateTime + 500) / 1000;
2924             }
2925             if (totalStateTime > 0) {
2926                 dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
2927             }
2928 
2929             final long userCpuTimeUs = u.getUserCpuTimeUs(which);
2930             final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
2931             final long powerCpuMaUs = u.getCpuPowerMaUs(which);
2932             if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
2933                 dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000,
2934                         powerCpuMaUs / 1000);
2935             }
2936 
2937             final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
2938                     = u.getProcessStats();
2939             for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
2940                 final Uid.Proc ps = processStats.valueAt(ipr);
2941 
2942                 final long userMillis = ps.getUserTime(which);
2943                 final long systemMillis = ps.getSystemTime(which);
2944                 final long foregroundMillis = ps.getForegroundTime(which);
2945                 final int starts = ps.getStarts(which);
2946                 final int numCrashes = ps.getNumCrashes(which);
2947                 final int numAnrs = ps.getNumAnrs(which);
2948 
2949                 if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
2950                         || starts != 0 || numAnrs != 0 || numCrashes != 0) {
2951                     dumpLine(pw, uid, category, PROCESS_DATA, processStats.keyAt(ipr), userMillis,
2952                             systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
2953                 }
2954             }
2955 
2956             final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
2957                     = u.getPackageStats();
2958             for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
2959                 final Uid.Pkg ps = packageStats.valueAt(ipkg);
2960                 int wakeups = 0;
2961                 final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
2962                 for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
2963                     wakeups += alarms.valueAt(iwa).getCountLocked(which);
2964                 }
2965                 final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
2966                 for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
2967                     final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
2968                     final long startTime = ss.getStartTime(batteryUptime, which);
2969                     final int starts = ss.getStarts(which);
2970                     final int launches = ss.getLaunches(which);
2971                     if (startTime != 0 || starts != 0 || launches != 0) {
2972                         dumpLine(pw, uid, category, APK_DATA,
2973                                 wakeups, // wakeup alarms
2974                                 packageStats.keyAt(ipkg), // Apk
2975                                 serviceStats.keyAt(isvc), // service
2976                                 startTime / 1000, // time spent started, in ms
2977                                 starts,
2978                                 launches);
2979                     }
2980                 }
2981             }
2982         }
2983     }
2984 
2985     static final class TimerEntry {
2986         final String mName;
2987         final int mId;
2988         final BatteryStats.Timer mTimer;
2989         final long mTime;
TimerEntry(String name, int id, BatteryStats.Timer timer, long time)2990         TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
2991             mName = name;
2992             mId = id;
2993             mTimer = timer;
2994             mTime = time;
2995         }
2996     }
2997 
printmAh(PrintWriter printer, double power)2998     private void printmAh(PrintWriter printer, double power) {
2999         printer.print(BatteryStatsHelper.makemAh(power));
3000     }
3001 
printmAh(StringBuilder sb, double power)3002     private void printmAh(StringBuilder sb, double power) {
3003         sb.append(BatteryStatsHelper.makemAh(power));
3004     }
3005 
3006     /**
3007      * Temporary for settings.
3008      */
dumpLocked(Context context, PrintWriter pw, String prefix, int which, int reqUid)3009     public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which,
3010             int reqUid) {
3011         dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
3012     }
3013 
3014     @SuppressWarnings("unused")
dumpLocked(Context context, PrintWriter pw, String prefix, final int which, int reqUid, boolean wifiOnly)3015     public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
3016             int reqUid, boolean wifiOnly) {
3017         final long rawUptime = SystemClock.uptimeMillis() * 1000;
3018         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
3019         final long batteryUptime = getBatteryUptime(rawUptime);
3020 
3021         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
3022         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
3023         final long totalRealtime = computeRealtime(rawRealtime, which);
3024         final long totalUptime = computeUptime(rawUptime, which);
3025         final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
3026         final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
3027                 which);
3028         final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
3029         final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
3030 
3031         final StringBuilder sb = new StringBuilder(128);
3032 
3033         final SparseArray<? extends Uid> uidStats = getUidStats();
3034         final int NU = uidStats.size();
3035 
3036         sb.setLength(0);
3037         sb.append(prefix);
3038                 sb.append("  Time on battery: ");
3039                 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
3040                 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
3041                 sb.append(") realtime, ");
3042                 formatTimeMs(sb, whichBatteryUptime / 1000);
3043                 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
3044                 sb.append(") uptime");
3045         pw.println(sb.toString());
3046         sb.setLength(0);
3047         sb.append(prefix);
3048                 sb.append("  Time on battery screen off: ");
3049                 formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("(");
3050                 sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime));
3051                 sb.append(") realtime, ");
3052                 formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
3053                 sb.append("(");
3054                 sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime));
3055                 sb.append(") uptime");
3056         pw.println(sb.toString());
3057         sb.setLength(0);
3058         sb.append(prefix);
3059                 sb.append("  Total run time: ");
3060                 formatTimeMs(sb, totalRealtime / 1000);
3061                 sb.append("realtime, ");
3062                 formatTimeMs(sb, totalUptime / 1000);
3063                 sb.append("uptime");
3064         pw.println(sb.toString());
3065         if (batteryTimeRemaining >= 0) {
3066             sb.setLength(0);
3067             sb.append(prefix);
3068                     sb.append("  Battery time remaining: ");
3069                     formatTimeMs(sb, batteryTimeRemaining / 1000);
3070             pw.println(sb.toString());
3071         }
3072         if (chargeTimeRemaining >= 0) {
3073             sb.setLength(0);
3074             sb.append(prefix);
3075                     sb.append("  Charge time remaining: ");
3076                     formatTimeMs(sb, chargeTimeRemaining / 1000);
3077             pw.println(sb.toString());
3078         }
3079         pw.print("  Start clock time: ");
3080         pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
3081 
3082         final long screenOnTime = getScreenOnTime(rawRealtime, which);
3083         final long interactiveTime = getInteractiveTime(rawRealtime, which);
3084         final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
3085         final long deviceIdleModeEnabledTime = getDeviceIdleModeEnabledTime(rawRealtime, which);
3086         final long deviceIdlingTime = getDeviceIdlingTime(rawRealtime, which);
3087         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
3088         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
3089         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
3090         sb.setLength(0);
3091         sb.append(prefix);
3092                 sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
3093                 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
3094                 sb.append(") "); sb.append(getScreenOnCount(which));
3095                 sb.append("x, Interactive: "); formatTimeMs(sb, interactiveTime / 1000);
3096                 sb.append("("); sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime));
3097                 sb.append(")");
3098         pw.println(sb.toString());
3099         sb.setLength(0);
3100         sb.append(prefix);
3101         sb.append("  Screen brightnesses:");
3102         boolean didOne = false;
3103         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3104             final long time = getScreenBrightnessTime(i, rawRealtime, which);
3105             if (time == 0) {
3106                 continue;
3107             }
3108             sb.append("\n    ");
3109             sb.append(prefix);
3110             didOne = true;
3111             sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
3112             sb.append(" ");
3113             formatTimeMs(sb, time/1000);
3114             sb.append("(");
3115             sb.append(formatRatioLocked(time, screenOnTime));
3116             sb.append(")");
3117         }
3118         if (!didOne) sb.append(" (no activity)");
3119         pw.println(sb.toString());
3120         if (powerSaveModeEnabledTime != 0) {
3121             sb.setLength(0);
3122             sb.append(prefix);
3123                     sb.append("  Power save mode enabled: ");
3124                     formatTimeMs(sb, powerSaveModeEnabledTime / 1000);
3125                     sb.append("(");
3126                     sb.append(formatRatioLocked(powerSaveModeEnabledTime, whichBatteryRealtime));
3127                     sb.append(")");
3128             pw.println(sb.toString());
3129         }
3130         if (deviceIdlingTime != 0) {
3131             sb.setLength(0);
3132             sb.append(prefix);
3133                     sb.append("  Device idling: ");
3134                     formatTimeMs(sb, deviceIdlingTime / 1000);
3135                     sb.append("(");
3136                     sb.append(formatRatioLocked(deviceIdlingTime, whichBatteryRealtime));
3137                     sb.append(") "); sb.append(getDeviceIdlingCount(which));
3138                     sb.append("x");
3139             pw.println(sb.toString());
3140         }
3141         if (deviceIdleModeEnabledTime != 0) {
3142             sb.setLength(0);
3143             sb.append(prefix);
3144                     sb.append("  Idle mode time: ");
3145                     formatTimeMs(sb, deviceIdleModeEnabledTime / 1000);
3146                     sb.append("(");
3147                     sb.append(formatRatioLocked(deviceIdleModeEnabledTime, whichBatteryRealtime));
3148                     sb.append(") "); sb.append(getDeviceIdleModeEnabledCount(which));
3149                     sb.append("x");
3150             pw.println(sb.toString());
3151         }
3152         if (phoneOnTime != 0) {
3153             sb.setLength(0);
3154             sb.append(prefix);
3155                     sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
3156                     sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
3157                     sb.append(") "); sb.append(getPhoneOnCount(which)); sb.append("x");
3158         }
3159         final int connChanges = getNumConnectivityChange(which);
3160         if (connChanges != 0) {
3161             pw.print(prefix);
3162             pw.print("  Connectivity changes: "); pw.println(connChanges);
3163         }
3164 
3165         // Calculate wakelock times across all uids.
3166         long fullWakeLockTimeTotalMicros = 0;
3167         long partialWakeLockTimeTotalMicros = 0;
3168 
3169         final ArrayList<TimerEntry> timers = new ArrayList<>();
3170 
3171         for (int iu = 0; iu < NU; iu++) {
3172             final Uid u = uidStats.valueAt(iu);
3173 
3174             final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
3175                     = u.getWakelockStats();
3176             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
3177                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
3178 
3179                 final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
3180                 if (fullWakeTimer != null) {
3181                     fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
3182                             rawRealtime, which);
3183                 }
3184 
3185                 final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
3186                 if (partialWakeTimer != null) {
3187                     final long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
3188                             rawRealtime, which);
3189                     if (totalTimeMicros > 0) {
3190                         if (reqUid < 0) {
3191                             // Only show the ordered list of all wake
3192                             // locks if the caller is not asking for data
3193                             // about a specific uid.
3194                             timers.add(new TimerEntry(wakelocks.keyAt(iw), u.getUid(),
3195                                     partialWakeTimer, totalTimeMicros));
3196                         }
3197                         partialWakeLockTimeTotalMicros += totalTimeMicros;
3198                     }
3199                 }
3200             }
3201         }
3202 
3203         final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
3204         final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
3205         final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
3206         final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
3207         final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
3208         final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
3209         final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
3210         final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
3211 
3212         if (fullWakeLockTimeTotalMicros != 0) {
3213             sb.setLength(0);
3214             sb.append(prefix);
3215                     sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
3216                             (fullWakeLockTimeTotalMicros + 500) / 1000);
3217             pw.println(sb.toString());
3218         }
3219 
3220         if (partialWakeLockTimeTotalMicros != 0) {
3221             sb.setLength(0);
3222             sb.append(prefix);
3223                     sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
3224                             (partialWakeLockTimeTotalMicros + 500) / 1000);
3225             pw.println(sb.toString());
3226         }
3227 
3228         pw.print(prefix);
3229                 pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
3230                 pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
3231                 pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
3232                 pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
3233         sb.setLength(0);
3234         sb.append(prefix);
3235         sb.append("  Phone signal levels:");
3236         didOne = false;
3237         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
3238             final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
3239             if (time == 0) {
3240                 continue;
3241             }
3242             sb.append("\n    ");
3243             sb.append(prefix);
3244             didOne = true;
3245             sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
3246             sb.append(" ");
3247             formatTimeMs(sb, time/1000);
3248             sb.append("(");
3249             sb.append(formatRatioLocked(time, whichBatteryRealtime));
3250             sb.append(") ");
3251             sb.append(getPhoneSignalStrengthCount(i, which));
3252             sb.append("x");
3253         }
3254         if (!didOne) sb.append(" (no activity)");
3255         pw.println(sb.toString());
3256 
3257         sb.setLength(0);
3258         sb.append(prefix);
3259         sb.append("  Signal scanning time: ");
3260         formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
3261         pw.println(sb.toString());
3262 
3263         sb.setLength(0);
3264         sb.append(prefix);
3265         sb.append("  Radio types:");
3266         didOne = false;
3267         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3268             final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
3269             if (time == 0) {
3270                 continue;
3271             }
3272             sb.append("\n    ");
3273             sb.append(prefix);
3274             didOne = true;
3275             sb.append(DATA_CONNECTION_NAMES[i]);
3276             sb.append(" ");
3277             formatTimeMs(sb, time/1000);
3278             sb.append("(");
3279             sb.append(formatRatioLocked(time, whichBatteryRealtime));
3280             sb.append(") ");
3281             sb.append(getPhoneDataConnectionCount(i, which));
3282             sb.append("x");
3283         }
3284         if (!didOne) sb.append(" (no activity)");
3285         pw.println(sb.toString());
3286 
3287         sb.setLength(0);
3288         sb.append(prefix);
3289         sb.append("  Mobile radio active time: ");
3290         final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
3291         formatTimeMs(sb, mobileActiveTime / 1000);
3292         sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
3293         sb.append(") "); sb.append(getMobileRadioActiveCount(which));
3294         sb.append("x");
3295         pw.println(sb.toString());
3296 
3297         final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
3298         if (mobileActiveUnknownTime != 0) {
3299             sb.setLength(0);
3300             sb.append(prefix);
3301             sb.append("  Mobile radio active unknown time: ");
3302             formatTimeMs(sb, mobileActiveUnknownTime / 1000);
3303             sb.append("(");
3304             sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
3305             sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which));
3306             sb.append("x");
3307             pw.println(sb.toString());
3308         }
3309 
3310         final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which);
3311         if (mobileActiveAdjustedTime != 0) {
3312             sb.setLength(0);
3313             sb.append(prefix);
3314             sb.append("  Mobile radio active adjusted time: ");
3315             formatTimeMs(sb, mobileActiveAdjustedTime / 1000);
3316             sb.append("(");
3317             sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime));
3318             sb.append(")");
3319             pw.println(sb.toString());
3320         }
3321 
3322         pw.print(prefix);
3323                 pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
3324                 pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
3325                 pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
3326                 pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
3327         sb.setLength(0);
3328         sb.append(prefix);
3329                 sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
3330                 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
3331                 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
3332                 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
3333                 sb.append(")");
3334         pw.println(sb.toString());
3335 
3336         sb.setLength(0);
3337         sb.append(prefix);
3338         sb.append("  Wifi states:");
3339         didOne = false;
3340         for (int i=0; i<NUM_WIFI_STATES; i++) {
3341             final long time = getWifiStateTime(i, rawRealtime, which);
3342             if (time == 0) {
3343                 continue;
3344             }
3345             sb.append("\n    ");
3346             didOne = true;
3347             sb.append(WIFI_STATE_NAMES[i]);
3348             sb.append(" ");
3349             formatTimeMs(sb, time/1000);
3350             sb.append("(");
3351             sb.append(formatRatioLocked(time, whichBatteryRealtime));
3352             sb.append(") ");
3353             sb.append(getWifiStateCount(i, which));
3354             sb.append("x");
3355         }
3356         if (!didOne) sb.append(" (no activity)");
3357         pw.println(sb.toString());
3358 
3359         sb.setLength(0);
3360         sb.append(prefix);
3361         sb.append("  Wifi supplicant states:");
3362         didOne = false;
3363         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
3364             final long time = getWifiSupplStateTime(i, rawRealtime, which);
3365             if (time == 0) {
3366                 continue;
3367             }
3368             sb.append("\n    ");
3369             didOne = true;
3370             sb.append(WIFI_SUPPL_STATE_NAMES[i]);
3371             sb.append(" ");
3372             formatTimeMs(sb, time/1000);
3373             sb.append("(");
3374             sb.append(formatRatioLocked(time, whichBatteryRealtime));
3375             sb.append(") ");
3376             sb.append(getWifiSupplStateCount(i, which));
3377             sb.append("x");
3378         }
3379         if (!didOne) sb.append(" (no activity)");
3380         pw.println(sb.toString());
3381 
3382         sb.setLength(0);
3383         sb.append(prefix);
3384         sb.append("  Wifi signal levels:");
3385         didOne = false;
3386         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
3387             final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
3388             if (time == 0) {
3389                 continue;
3390             }
3391             sb.append("\n    ");
3392             sb.append(prefix);
3393             didOne = true;
3394             sb.append("level(");
3395             sb.append(i);
3396             sb.append(") ");
3397             formatTimeMs(sb, time/1000);
3398             sb.append("(");
3399             sb.append(formatRatioLocked(time, whichBatteryRealtime));
3400             sb.append(") ");
3401             sb.append(getWifiSignalStrengthCount(i, which));
3402             sb.append("x");
3403         }
3404         if (!didOne) sb.append(" (no activity)");
3405         pw.println(sb.toString());
3406 
3407         final long wifiIdleTimeMs = getWifiControllerActivity(CONTROLLER_IDLE_TIME, which);
3408         final long wifiRxTimeMs = getWifiControllerActivity(CONTROLLER_RX_TIME, which);
3409         final long wifiTxTimeMs = getWifiControllerActivity(CONTROLLER_TX_TIME, which);
3410         final long wifiPowerDrainMaMs = getWifiControllerActivity(CONTROLLER_POWER_DRAIN, which);
3411         final long wifiTotalTimeMs = wifiIdleTimeMs + wifiRxTimeMs + wifiTxTimeMs;
3412 
3413         sb.setLength(0);
3414         sb.append(prefix);
3415         sb.append("  WiFi Idle time: "); formatTimeMs(sb, wifiIdleTimeMs);
3416         sb.append("(");
3417         sb.append(formatRatioLocked(wifiIdleTimeMs, wifiTotalTimeMs));
3418         sb.append(")");
3419         pw.println(sb.toString());
3420 
3421         sb.setLength(0);
3422         sb.append(prefix);
3423         sb.append("  WiFi Rx time:   "); formatTimeMs(sb, wifiRxTimeMs);
3424         sb.append("(");
3425         sb.append(formatRatioLocked(wifiRxTimeMs, wifiTotalTimeMs));
3426         sb.append(")");
3427         pw.println(sb.toString());
3428 
3429         sb.setLength(0);
3430         sb.append(prefix);
3431         sb.append("  WiFi Tx time:   "); formatTimeMs(sb, wifiTxTimeMs);
3432         sb.append("(");
3433         sb.append(formatRatioLocked(wifiTxTimeMs, wifiTotalTimeMs));
3434         sb.append(")");
3435         pw.println(sb.toString());
3436 
3437         sb.setLength(0);
3438         sb.append(prefix);
3439         sb.append("  WiFi Power drain: ").append(
3440                 BatteryStatsHelper.makemAh(wifiPowerDrainMaMs / (double) (1000*60*60)));
3441         sb.append("mAh");
3442         pw.println(sb.toString());
3443 
3444         final long bluetoothIdleTimeMs =
3445                 getBluetoothControllerActivity(CONTROLLER_IDLE_TIME, which);
3446         final long bluetoothRxTimeMs = getBluetoothControllerActivity(CONTROLLER_RX_TIME, which);
3447         final long bluetoothTxTimeMs = getBluetoothControllerActivity(CONTROLLER_TX_TIME, which);
3448         final long bluetoothTotalTimeMs = bluetoothIdleTimeMs + bluetoothRxTimeMs +
3449                 bluetoothTxTimeMs;
3450 
3451         sb.setLength(0);
3452         sb.append(prefix);
3453         sb.append("  Bluetooth Idle time: "); formatTimeMs(sb, bluetoothIdleTimeMs);
3454         sb.append("(");
3455         sb.append(formatRatioLocked(bluetoothIdleTimeMs, bluetoothTotalTimeMs));
3456         sb.append(")");
3457         pw.println(sb.toString());
3458 
3459         sb.setLength(0);
3460         sb.append(prefix);
3461         sb.append("  Bluetooth Rx time:   "); formatTimeMs(sb, bluetoothRxTimeMs);
3462         sb.append("(");
3463         sb.append(formatRatioLocked(bluetoothRxTimeMs, bluetoothTotalTimeMs));
3464         sb.append(")");
3465         pw.println(sb.toString());
3466 
3467         sb.setLength(0);
3468         sb.append(prefix);
3469         sb.append("  Bluetooth Tx time:   "); formatTimeMs(sb, bluetoothTxTimeMs);
3470         sb.append("(");
3471         sb.append(formatRatioLocked(bluetoothTxTimeMs, bluetoothTotalTimeMs));
3472         sb.append(")");
3473         pw.println(sb.toString());
3474 
3475         sb.setLength(0);
3476         sb.append(prefix);
3477         sb.append("  Bluetooth Power drain: ").append(BatteryStatsHelper.makemAh(
3478                 getBluetoothControllerActivity(CONTROLLER_POWER_DRAIN, which) /
3479                         (double)(1000*60*60)));
3480         sb.append("mAh");
3481         pw.println(sb.toString());
3482 
3483         pw.println();
3484 
3485         if (which == STATS_SINCE_UNPLUGGED) {
3486             if (getIsOnBattery()) {
3487                 pw.print(prefix); pw.println("  Device is currently unplugged");
3488                 pw.print(prefix); pw.print("    Discharge cycle start level: ");
3489                         pw.println(getDischargeStartLevel());
3490                 pw.print(prefix); pw.print("    Discharge cycle current level: ");
3491                         pw.println(getDischargeCurrentLevel());
3492             } else {
3493                 pw.print(prefix); pw.println("  Device is currently plugged into power");
3494                 pw.print(prefix); pw.print("    Last discharge cycle start level: ");
3495                         pw.println(getDischargeStartLevel());
3496                 pw.print(prefix); pw.print("    Last discharge cycle end level: ");
3497                         pw.println(getDischargeCurrentLevel());
3498             }
3499             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
3500                     pw.println(getDischargeAmountScreenOn());
3501             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
3502                     pw.println(getDischargeAmountScreenOff());
3503             pw.println(" ");
3504         } else {
3505             pw.print(prefix); pw.println("  Device battery use since last full charge");
3506             pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
3507                     pw.println(getLowDischargeAmountSinceCharge());
3508             pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
3509                     pw.println(getHighDischargeAmountSinceCharge());
3510             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
3511                     pw.println(getDischargeAmountScreenOnSinceCharge());
3512             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
3513                     pw.println(getDischargeAmountScreenOffSinceCharge());
3514             pw.println();
3515         }
3516 
3517         final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
3518         helper.create(this);
3519         helper.refreshStats(which, UserHandle.USER_ALL);
3520         List<BatterySipper> sippers = helper.getUsageList();
3521         if (sippers != null && sippers.size() > 0) {
3522             pw.print(prefix); pw.println("  Estimated power use (mAh):");
3523             pw.print(prefix); pw.print("    Capacity: ");
3524                     printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
3525                     pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
3526                     pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower());
3527                     if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
3528                         pw.print("-"); printmAh(pw, helper.getMaxDrainedPower());
3529                     }
3530                     pw.println();
3531             for (int i=0; i<sippers.size(); i++) {
3532                 final BatterySipper bs = sippers.get(i);
3533                 pw.print(prefix);
3534                 switch (bs.drainType) {
3535                     case IDLE:
3536                         pw.print("    Idle: ");
3537                         break;
3538                     case CELL:
3539                         pw.print("    Cell standby: ");
3540                         break;
3541                     case PHONE:
3542                         pw.print("    Phone calls: ");
3543                         break;
3544                     case WIFI:
3545                         pw.print("    Wifi: ");
3546                         break;
3547                     case BLUETOOTH:
3548                         pw.print("    Bluetooth: ");
3549                         break;
3550                     case SCREEN:
3551                         pw.print("    Screen: ");
3552                         break;
3553                     case FLASHLIGHT:
3554                         pw.print("    Flashlight: ");
3555                         break;
3556                     case APP:
3557                         pw.print("    Uid ");
3558                         UserHandle.formatUid(pw, bs.uidObj.getUid());
3559                         pw.print(": ");
3560                         break;
3561                     case USER:
3562                         pw.print("    User "); pw.print(bs.userId);
3563                         pw.print(": ");
3564                         break;
3565                     case UNACCOUNTED:
3566                         pw.print("    Unaccounted: ");
3567                         break;
3568                     case OVERCOUNTED:
3569                         pw.print("    Over-counted: ");
3570                         break;
3571                     case CAMERA:
3572                         pw.print("    Camera: ");
3573                         break;
3574                     default:
3575                         pw.print("    ???: ");
3576                         break;
3577                 }
3578                 printmAh(pw, bs.totalPowerMah);
3579 
3580                 if (bs.usagePowerMah != bs.totalPowerMah) {
3581                     // If the usage (generic power) isn't the whole amount, we list out
3582                     // what components are involved in the calculation.
3583 
3584                     pw.print(" (");
3585                     if (bs.usagePowerMah != 0) {
3586                         pw.print(" usage=");
3587                         printmAh(pw, bs.usagePowerMah);
3588                     }
3589                     if (bs.cpuPowerMah != 0) {
3590                         pw.print(" cpu=");
3591                         printmAh(pw, bs.cpuPowerMah);
3592                     }
3593                     if (bs.wakeLockPowerMah != 0) {
3594                         pw.print(" wake=");
3595                         printmAh(pw, bs.wakeLockPowerMah);
3596                     }
3597                     if (bs.mobileRadioPowerMah != 0) {
3598                         pw.print(" radio=");
3599                         printmAh(pw, bs.mobileRadioPowerMah);
3600                     }
3601                     if (bs.wifiPowerMah != 0) {
3602                         pw.print(" wifi=");
3603                         printmAh(pw, bs.wifiPowerMah);
3604                     }
3605                     if (bs.gpsPowerMah != 0) {
3606                         pw.print(" gps=");
3607                         printmAh(pw, bs.gpsPowerMah);
3608                     }
3609                     if (bs.sensorPowerMah != 0) {
3610                         pw.print(" sensor=");
3611                         printmAh(pw, bs.sensorPowerMah);
3612                     }
3613                     if (bs.cameraPowerMah != 0) {
3614                         pw.print(" camera=");
3615                         printmAh(pw, bs.cameraPowerMah);
3616                     }
3617                     if (bs.flashlightPowerMah != 0) {
3618                         pw.print(" flash=");
3619                         printmAh(pw, bs.flashlightPowerMah);
3620                     }
3621                     pw.print(" )");
3622                 }
3623                 pw.println();
3624             }
3625             pw.println();
3626         }
3627 
3628         sippers = helper.getMobilemsppList();
3629         if (sippers != null && sippers.size() > 0) {
3630             pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
3631             long totalTime = 0;
3632             for (int i=0; i<sippers.size(); i++) {
3633                 final BatterySipper bs = sippers.get(i);
3634                 sb.setLength(0);
3635                 sb.append(prefix); sb.append("    Uid ");
3636                 UserHandle.formatUid(sb, bs.uidObj.getUid());
3637                 sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
3638                 sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
3639                 sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
3640                 sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
3641                 pw.println(sb.toString());
3642                 totalTime += bs.mobileActive;
3643             }
3644             sb.setLength(0);
3645             sb.append(prefix);
3646             sb.append("    TOTAL TIME: ");
3647             formatTimeMs(sb, totalTime);
3648             sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
3649             sb.append(")");
3650             pw.println(sb.toString());
3651             pw.println();
3652         }
3653 
3654         final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
3655             @Override
3656             public int compare(TimerEntry lhs, TimerEntry rhs) {
3657                 long lhsTime = lhs.mTime;
3658                 long rhsTime = rhs.mTime;
3659                 if (lhsTime < rhsTime) {
3660                     return 1;
3661                 }
3662                 if (lhsTime > rhsTime) {
3663                     return -1;
3664                 }
3665                 return 0;
3666             }
3667         };
3668 
3669         if (reqUid < 0) {
3670             final Map<String, ? extends BatteryStats.Timer> kernelWakelocks
3671                     = getKernelWakelockStats();
3672             if (kernelWakelocks.size() > 0) {
3673                 final ArrayList<TimerEntry> ktimers = new ArrayList<>();
3674                 for (Map.Entry<String, ? extends BatteryStats.Timer> ent
3675                         : kernelWakelocks.entrySet()) {
3676                     final BatteryStats.Timer timer = ent.getValue();
3677                     final long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
3678                     if (totalTimeMillis > 0) {
3679                         ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
3680                     }
3681                 }
3682                 if (ktimers.size() > 0) {
3683                     Collections.sort(ktimers, timerComparator);
3684                     pw.print(prefix); pw.println("  All kernel wake locks:");
3685                     for (int i=0; i<ktimers.size(); i++) {
3686                         final TimerEntry timer = ktimers.get(i);
3687                         String linePrefix = ": ";
3688                         sb.setLength(0);
3689                         sb.append(prefix);
3690                         sb.append("  Kernel Wake lock ");
3691                         sb.append(timer.mName);
3692                         linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null,
3693                                 which, linePrefix);
3694                         if (!linePrefix.equals(": ")) {
3695                             sb.append(" realtime");
3696                             // Only print out wake locks that were held
3697                             pw.println(sb.toString());
3698                         }
3699                     }
3700                     pw.println();
3701                 }
3702             }
3703 
3704             if (timers.size() > 0) {
3705                 Collections.sort(timers, timerComparator);
3706                 pw.print(prefix); pw.println("  All partial wake locks:");
3707                 for (int i=0; i<timers.size(); i++) {
3708                     TimerEntry timer = timers.get(i);
3709                     sb.setLength(0);
3710                     sb.append("  Wake lock ");
3711                     UserHandle.formatUid(sb, timer.mId);
3712                     sb.append(" ");
3713                     sb.append(timer.mName);
3714                     printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
3715                     sb.append(" realtime");
3716                     pw.println(sb.toString());
3717                 }
3718                 timers.clear();
3719                 pw.println();
3720             }
3721 
3722             final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
3723             if (wakeupReasons.size() > 0) {
3724                 pw.print(prefix); pw.println("  All wakeup reasons:");
3725                 final ArrayList<TimerEntry> reasons = new ArrayList<>();
3726                 for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
3727                     final Timer timer = ent.getValue();
3728                     reasons.add(new TimerEntry(ent.getKey(), 0, timer,
3729                             timer.getCountLocked(which)));
3730                 }
3731                 Collections.sort(reasons, timerComparator);
3732                 for (int i=0; i<reasons.size(); i++) {
3733                     TimerEntry timer = reasons.get(i);
3734                     String linePrefix = ": ";
3735                     sb.setLength(0);
3736                     sb.append(prefix);
3737                     sb.append("  Wakeup reason ");
3738                     sb.append(timer.mName);
3739                     printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
3740                     sb.append(" realtime");
3741                     pw.println(sb.toString());
3742                 }
3743                 pw.println();
3744             }
3745         }
3746 
3747         for (int iu=0; iu<NU; iu++) {
3748             final int uid = uidStats.keyAt(iu);
3749             if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
3750                 continue;
3751             }
3752 
3753             final Uid u = uidStats.valueAt(iu);
3754 
3755             pw.print(prefix);
3756             pw.print("  ");
3757             UserHandle.formatUid(pw, uid);
3758             pw.println(":");
3759             boolean uidActivity = false;
3760 
3761             final long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
3762             final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
3763             final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
3764             final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
3765             final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
3766             final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
3767             final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
3768             final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
3769             final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
3770             final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
3771             final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
3772             final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
3773             final int wifiScanCount = u.getWifiScanCount(which);
3774             final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
3775 
3776             if (mobileRxBytes > 0 || mobileTxBytes > 0
3777                     || mobileRxPackets > 0 || mobileTxPackets > 0) {
3778                 pw.print(prefix); pw.print("    Mobile network: ");
3779                         pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
3780                         pw.print(formatBytesLocked(mobileTxBytes));
3781                         pw.print(" sent (packets "); pw.print(mobileRxPackets);
3782                         pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
3783             }
3784             if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
3785                 sb.setLength(0);
3786                 sb.append(prefix); sb.append("    Mobile radio active: ");
3787                 formatTimeMs(sb, uidMobileActiveTime / 1000);
3788                 sb.append("(");
3789                 sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
3790                 sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
3791                 long packets = mobileRxPackets + mobileTxPackets;
3792                 if (packets == 0) {
3793                     packets = 1;
3794                 }
3795                 sb.append(" @ ");
3796                 sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
3797                 sb.append(" mspp");
3798                 pw.println(sb.toString());
3799             }
3800 
3801             if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
3802                 pw.print(prefix); pw.print("    Wi-Fi network: ");
3803                         pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
3804                         pw.print(formatBytesLocked(wifiTxBytes));
3805                         pw.print(" sent (packets "); pw.print(wifiRxPackets);
3806                         pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
3807             }
3808 
3809             if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0
3810                     || uidWifiRunningTime != 0) {
3811                 sb.setLength(0);
3812                 sb.append(prefix); sb.append("    Wifi Running: ");
3813                         formatTimeMs(sb, uidWifiRunningTime / 1000);
3814                         sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
3815                                 whichBatteryRealtime)); sb.append(")\n");
3816                 sb.append(prefix); sb.append("    Full Wifi Lock: ");
3817                         formatTimeMs(sb, fullWifiLockOnTime / 1000);
3818                         sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
3819                                 whichBatteryRealtime)); sb.append(")\n");
3820                 sb.append(prefix); sb.append("    Wifi Scan: ");
3821                         formatTimeMs(sb, wifiScanTime / 1000);
3822                         sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
3823                                 whichBatteryRealtime)); sb.append(") ");
3824                                 sb.append(wifiScanCount);
3825                                 sb.append("x");
3826                 pw.println(sb.toString());
3827             }
3828 
3829             final long uidWifiIdleTimeMs = u.getWifiControllerActivity(CONTROLLER_IDLE_TIME, which);
3830             final long uidWifiRxTimeMs = u.getWifiControllerActivity(CONTROLLER_RX_TIME, which);
3831             final long uidWifiTxTimeMs = u.getWifiControllerActivity(CONTROLLER_TX_TIME, which);
3832             final long uidWifiTotalTimeMs = uidWifiIdleTimeMs + uidWifiRxTimeMs + uidWifiTxTimeMs;
3833             if (uidWifiTotalTimeMs > 0) {
3834                 sb.setLength(0);
3835                 sb.append(prefix).append("    WiFi Idle time: ");
3836                 formatTimeMs(sb, uidWifiIdleTimeMs);
3837                 sb.append("(").append(formatRatioLocked(uidWifiIdleTimeMs, uidWifiTotalTimeMs))
3838                         .append(")\n");
3839 
3840                 sb.append(prefix).append("    WiFi Rx time:   "); formatTimeMs(sb, uidWifiRxTimeMs);
3841                 sb.append("(").append(formatRatioLocked(uidWifiRxTimeMs, uidWifiTotalTimeMs))
3842                         .append(")\n");
3843 
3844                 sb.append(prefix).append("    WiFi Tx time:   "); formatTimeMs(sb, uidWifiTxTimeMs);
3845                 sb.append("(").append(formatRatioLocked(uidWifiTxTimeMs, uidWifiTotalTimeMs))
3846                         .append(")");
3847                 pw.println(sb.toString());
3848             }
3849 
3850             if (u.hasUserActivity()) {
3851                 boolean hasData = false;
3852                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3853                     final int val = u.getUserActivityCount(i, which);
3854                     if (val != 0) {
3855                         if (!hasData) {
3856                             sb.setLength(0);
3857                             sb.append("    User activity: ");
3858                             hasData = true;
3859                         } else {
3860                             sb.append(", ");
3861                         }
3862                         sb.append(val);
3863                         sb.append(" ");
3864                         sb.append(Uid.USER_ACTIVITY_TYPES[i]);
3865                     }
3866                 }
3867                 if (hasData) {
3868                     pw.println(sb.toString());
3869                 }
3870             }
3871 
3872             final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
3873                     = u.getWakelockStats();
3874             long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
3875             long totalDrawWakelock = 0;
3876             int countWakelock = 0;
3877             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
3878                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
3879                 String linePrefix = ": ";
3880                 sb.setLength(0);
3881                 sb.append(prefix);
3882                 sb.append("    Wake lock ");
3883                 sb.append(wakelocks.keyAt(iw));
3884                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
3885                         "full", which, linePrefix);
3886                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
3887                         "partial", which, linePrefix);
3888                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
3889                         "window", which, linePrefix);
3890                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
3891                         "draw", which, linePrefix);
3892                 sb.append(" realtime");
3893                 pw.println(sb.toString());
3894                 uidActivity = true;
3895                 countWakelock++;
3896 
3897                 totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
3898                         rawRealtime, which);
3899                 totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
3900                         rawRealtime, which);
3901                 totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
3902                         rawRealtime, which);
3903                 totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW),
3904                         rawRealtime, which);
3905             }
3906             if (countWakelock > 1) {
3907                 if (totalFullWakelock != 0 || totalPartialWakelock != 0
3908                         || totalWindowWakelock != 0) {
3909                     sb.setLength(0);
3910                     sb.append(prefix);
3911                     sb.append("    TOTAL wake: ");
3912                     boolean needComma = false;
3913                     if (totalFullWakelock != 0) {
3914                         needComma = true;
3915                         formatTimeMs(sb, totalFullWakelock);
3916                         sb.append("full");
3917                     }
3918                     if (totalPartialWakelock != 0) {
3919                         if (needComma) {
3920                             sb.append(", ");
3921                         }
3922                         needComma = true;
3923                         formatTimeMs(sb, totalPartialWakelock);
3924                         sb.append("partial");
3925                     }
3926                     if (totalWindowWakelock != 0) {
3927                         if (needComma) {
3928                             sb.append(", ");
3929                         }
3930                         needComma = true;
3931                         formatTimeMs(sb, totalWindowWakelock);
3932                         sb.append("window");
3933                     }
3934                     if (totalDrawWakelock != 0) {
3935                         if (needComma) {
3936                             sb.append(",");
3937                         }
3938                         needComma = true;
3939                         formatTimeMs(sb, totalDrawWakelock);
3940                         sb.append("draw");
3941                     }
3942                     sb.append(" realtime");
3943                     pw.println(sb.toString());
3944                 }
3945             }
3946 
3947             final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
3948             for (int isy=syncs.size()-1; isy>=0; isy--) {
3949                 final Timer timer = syncs.valueAt(isy);
3950                 // Convert from microseconds to milliseconds with rounding
3951                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
3952                 final int count = timer.getCountLocked(which);
3953                 sb.setLength(0);
3954                 sb.append(prefix);
3955                 sb.append("    Sync ");
3956                 sb.append(syncs.keyAt(isy));
3957                 sb.append(": ");
3958                 if (totalTime != 0) {
3959                     formatTimeMs(sb, totalTime);
3960                     sb.append("realtime (");
3961                     sb.append(count);
3962                     sb.append(" times)");
3963                 } else {
3964                     sb.append("(not used)");
3965                 }
3966                 pw.println(sb.toString());
3967                 uidActivity = true;
3968             }
3969 
3970             final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
3971             for (int ij=jobs.size()-1; ij>=0; ij--) {
3972                 final Timer timer = jobs.valueAt(ij);
3973                 // Convert from microseconds to milliseconds with rounding
3974                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
3975                 final int count = timer.getCountLocked(which);
3976                 sb.setLength(0);
3977                 sb.append(prefix);
3978                 sb.append("    Job ");
3979                 sb.append(jobs.keyAt(ij));
3980                 sb.append(": ");
3981                 if (totalTime != 0) {
3982                     formatTimeMs(sb, totalTime);
3983                     sb.append("realtime (");
3984                     sb.append(count);
3985                     sb.append(" times)");
3986                 } else {
3987                     sb.append("(not used)");
3988                 }
3989                 pw.println(sb.toString());
3990                 uidActivity = true;
3991             }
3992 
3993             uidActivity |= printTimer(pw, sb, u.getFlashlightTurnedOnTimer(), rawRealtime, which,
3994                     prefix, "Flashlight");
3995             uidActivity |= printTimer(pw, sb, u.getCameraTurnedOnTimer(), rawRealtime, which,
3996                     prefix, "Camera");
3997             uidActivity |= printTimer(pw, sb, u.getVideoTurnedOnTimer(), rawRealtime, which,
3998                     prefix, "Video");
3999             uidActivity |= printTimer(pw, sb, u.getAudioTurnedOnTimer(), rawRealtime, which,
4000                     prefix, "Audio");
4001 
4002             final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
4003             final int NSE = sensors.size();
4004             for (int ise=0; ise<NSE; ise++) {
4005                 final Uid.Sensor se = sensors.valueAt(ise);
4006                 final int sensorNumber = sensors.keyAt(ise);
4007                 sb.setLength(0);
4008                 sb.append(prefix);
4009                 sb.append("    Sensor ");
4010                 int handle = se.getHandle();
4011                 if (handle == Uid.Sensor.GPS) {
4012                     sb.append("GPS");
4013                 } else {
4014                     sb.append(handle);
4015                 }
4016                 sb.append(": ");
4017 
4018                 final Timer timer = se.getSensorTime();
4019                 if (timer != null) {
4020                     // Convert from microseconds to milliseconds with rounding
4021                     final long totalTime = (timer.getTotalTimeLocked(
4022                             rawRealtime, which) + 500) / 1000;
4023                     final int count = timer.getCountLocked(which);
4024                     //timer.logState();
4025                     if (totalTime != 0) {
4026                         formatTimeMs(sb, totalTime);
4027                         sb.append("realtime (");
4028                         sb.append(count);
4029                         sb.append(" times)");
4030                     } else {
4031                         sb.append("(not used)");
4032                     }
4033                 } else {
4034                     sb.append("(not used)");
4035                 }
4036 
4037                 pw.println(sb.toString());
4038                 uidActivity = true;
4039             }
4040 
4041             uidActivity |= printTimer(pw, sb, u.getVibratorOnTimer(), rawRealtime, which, prefix,
4042                     "Vibrator");
4043             uidActivity |= printTimer(pw, sb, u.getForegroundActivityTimer(), rawRealtime, which,
4044                     prefix, "Foreground activities");
4045 
4046             long totalStateTime = 0;
4047             for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
4048                 long time = u.getProcessStateTime(ips, rawRealtime, which);
4049                 if (time > 0) {
4050                     totalStateTime += time;
4051                     sb.setLength(0);
4052                     sb.append(prefix);
4053                     sb.append("    ");
4054                     sb.append(Uid.PROCESS_STATE_NAMES[ips]);
4055                     sb.append(" for: ");
4056                     formatTimeMs(sb, (totalStateTime + 500) / 1000);
4057                     pw.println(sb.toString());
4058                     uidActivity = true;
4059                 }
4060             }
4061 
4062             final long userCpuTimeUs = u.getUserCpuTimeUs(which);
4063             final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
4064             final long powerCpuMaUs = u.getCpuPowerMaUs(which);
4065             if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
4066                 sb.setLength(0);
4067                 sb.append(prefix);
4068                 sb.append("    Total cpu time: u=");
4069                 formatTimeMs(sb, userCpuTimeUs / 1000);
4070                 sb.append("s=");
4071                 formatTimeMs(sb, systemCpuTimeUs / 1000);
4072                 sb.append("p=");
4073                 printmAh(sb, powerCpuMaUs / (1000.0 * 1000.0 * 60.0 * 60.0));
4074                 sb.append("mAh");
4075                 pw.println(sb.toString());
4076             }
4077 
4078             final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
4079                     = u.getProcessStats();
4080             for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
4081                 final Uid.Proc ps = processStats.valueAt(ipr);
4082                 long userTime;
4083                 long systemTime;
4084                 long foregroundTime;
4085                 int starts;
4086                 int numExcessive;
4087 
4088                 userTime = ps.getUserTime(which);
4089                 systemTime = ps.getSystemTime(which);
4090                 foregroundTime = ps.getForegroundTime(which);
4091                 starts = ps.getStarts(which);
4092                 final int numCrashes = ps.getNumCrashes(which);
4093                 final int numAnrs = ps.getNumAnrs(which);
4094                 numExcessive = which == STATS_SINCE_CHARGED
4095                         ? ps.countExcessivePowers() : 0;
4096 
4097                 if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
4098                         || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
4099                     sb.setLength(0);
4100                     sb.append(prefix); sb.append("    Proc ");
4101                             sb.append(processStats.keyAt(ipr)); sb.append(":\n");
4102                     sb.append(prefix); sb.append("      CPU: ");
4103                             formatTimeMs(sb, userTime); sb.append("usr + ");
4104                             formatTimeMs(sb, systemTime); sb.append("krn ; ");
4105                             formatTimeMs(sb, foregroundTime); sb.append("fg");
4106                     if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
4107                         sb.append("\n"); sb.append(prefix); sb.append("      ");
4108                         boolean hasOne = false;
4109                         if (starts != 0) {
4110                             hasOne = true;
4111                             sb.append(starts); sb.append(" starts");
4112                         }
4113                         if (numCrashes != 0) {
4114                             if (hasOne) {
4115                                 sb.append(", ");
4116                             }
4117                             hasOne = true;
4118                             sb.append(numCrashes); sb.append(" crashes");
4119                         }
4120                         if (numAnrs != 0) {
4121                             if (hasOne) {
4122                                 sb.append(", ");
4123                             }
4124                             sb.append(numAnrs); sb.append(" anrs");
4125                         }
4126                     }
4127                     pw.println(sb.toString());
4128                     for (int e=0; e<numExcessive; e++) {
4129                         Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
4130                         if (ew != null) {
4131                             pw.print(prefix); pw.print("      * Killed for ");
4132                                     if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
4133                                         pw.print("wake lock");
4134                                     } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
4135                                         pw.print("cpu");
4136                                     } else {
4137                                         pw.print("unknown");
4138                                     }
4139                                     pw.print(" use: ");
4140                                     TimeUtils.formatDuration(ew.usedTime, pw);
4141                                     pw.print(" over ");
4142                                     TimeUtils.formatDuration(ew.overTime, pw);
4143                                     if (ew.overTime != 0) {
4144                                         pw.print(" (");
4145                                         pw.print((ew.usedTime*100)/ew.overTime);
4146                                         pw.println("%)");
4147                                     }
4148                         }
4149                     }
4150                     uidActivity = true;
4151                 }
4152             }
4153 
4154             final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
4155                     = u.getPackageStats();
4156             for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
4157                 pw.print(prefix); pw.print("    Apk "); pw.print(packageStats.keyAt(ipkg));
4158                 pw.println(":");
4159                 boolean apkActivity = false;
4160                 final Uid.Pkg ps = packageStats.valueAt(ipkg);
4161                 final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
4162                 for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
4163                     pw.print(prefix); pw.print("      Wakeup alarm ");
4164                             pw.print(alarms.keyAt(iwa)); pw.print(": ");
4165                             pw.print(alarms.valueAt(iwa).getCountLocked(which));
4166                             pw.println(" times");
4167                     apkActivity = true;
4168                 }
4169                 final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
4170                 for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
4171                     final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
4172                     final long startTime = ss.getStartTime(batteryUptime, which);
4173                     final int starts = ss.getStarts(which);
4174                     final int launches = ss.getLaunches(which);
4175                     if (startTime != 0 || starts != 0 || launches != 0) {
4176                         sb.setLength(0);
4177                         sb.append(prefix); sb.append("      Service ");
4178                                 sb.append(serviceStats.keyAt(isvc)); sb.append(":\n");
4179                         sb.append(prefix); sb.append("        Created for: ");
4180                                 formatTimeMs(sb, startTime / 1000);
4181                                 sb.append("uptime\n");
4182                         sb.append(prefix); sb.append("        Starts: ");
4183                                 sb.append(starts);
4184                                 sb.append(", launches: "); sb.append(launches);
4185                         pw.println(sb.toString());
4186                         apkActivity = true;
4187                     }
4188                 }
4189                 if (!apkActivity) {
4190                     pw.print(prefix); pw.println("      (nothing executed)");
4191                 }
4192                 uidActivity = true;
4193             }
4194             if (!uidActivity) {
4195                 pw.print(prefix); pw.println("    (nothing executed)");
4196             }
4197         }
4198     }
4199 
printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag, BitDescription[] descriptions, boolean longNames)4200     static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag,
4201             BitDescription[] descriptions, boolean longNames) {
4202         int diff = oldval ^ newval;
4203         if (diff == 0) return;
4204         boolean didWake = false;
4205         for (int i=0; i<descriptions.length; i++) {
4206             BitDescription bd = descriptions[i];
4207             if ((diff&bd.mask) != 0) {
4208                 pw.print(longNames ? " " : ",");
4209                 if (bd.shift < 0) {
4210                     pw.print((newval&bd.mask) != 0 ? "+" : "-");
4211                     pw.print(longNames ? bd.name : bd.shortName);
4212                     if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
4213                         didWake = true;
4214                         pw.print("=");
4215                         if (longNames) {
4216                             UserHandle.formatUid(pw, wakelockTag.uid);
4217                             pw.print(":\"");
4218                             pw.print(wakelockTag.string);
4219                             pw.print("\"");
4220                         } else {
4221                             pw.print(wakelockTag.poolIdx);
4222                         }
4223                     }
4224                 } else {
4225                     pw.print(longNames ? bd.name : bd.shortName);
4226                     pw.print("=");
4227                     int val = (newval&bd.mask)>>bd.shift;
4228                     if (bd.values != null && val >= 0 && val < bd.values.length) {
4229                         pw.print(longNames? bd.values[val] : bd.shortValues[val]);
4230                     } else {
4231                         pw.print(val);
4232                     }
4233                 }
4234             }
4235         }
4236         if (!didWake && wakelockTag != null) {
4237             pw.print(longNames ? " wake_lock=" : ",w=");
4238             if (longNames) {
4239                 UserHandle.formatUid(pw, wakelockTag.uid);
4240                 pw.print(":\"");
4241                 pw.print(wakelockTag.string);
4242                 pw.print("\"");
4243             } else {
4244                 pw.print(wakelockTag.poolIdx);
4245             }
4246         }
4247     }
4248 
prepareForDumpLocked()4249     public void prepareForDumpLocked() {
4250     }
4251 
4252     public static class HistoryPrinter {
4253         int oldState = 0;
4254         int oldState2 = 0;
4255         int oldLevel = -1;
4256         int oldStatus = -1;
4257         int oldHealth = -1;
4258         int oldPlug = -1;
4259         int oldTemp = -1;
4260         int oldVolt = -1;
4261         long lastTime = -1;
4262 
reset()4263         void reset() {
4264             oldState = oldState2 = 0;
4265             oldLevel = -1;
4266             oldStatus = -1;
4267             oldHealth = -1;
4268             oldPlug = -1;
4269             oldTemp = -1;
4270             oldVolt = -1;
4271         }
4272 
printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin, boolean verbose)4273         public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
4274                 boolean verbose) {
4275             if (!checkin) {
4276                 pw.print("  ");
4277                 TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
4278                 pw.print(" (");
4279                 pw.print(rec.numReadInts);
4280                 pw.print(") ");
4281             } else {
4282                 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
4283                 pw.print(HISTORY_DATA); pw.print(',');
4284                 if (lastTime < 0) {
4285                     pw.print(rec.time - baseTime);
4286                 } else {
4287                     pw.print(rec.time - lastTime);
4288                 }
4289                 lastTime = rec.time;
4290             }
4291             if (rec.cmd == HistoryItem.CMD_START) {
4292                 if (checkin) {
4293                     pw.print(":");
4294                 }
4295                 pw.println("START");
4296                 reset();
4297             } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
4298                     || rec.cmd == HistoryItem.CMD_RESET) {
4299                 if (checkin) {
4300                     pw.print(":");
4301                 }
4302                 if (rec.cmd == HistoryItem.CMD_RESET) {
4303                     pw.print("RESET:");
4304                     reset();
4305                 }
4306                 pw.print("TIME:");
4307                 if (checkin) {
4308                     pw.println(rec.currentTime);
4309                 } else {
4310                     pw.print(" ");
4311                     pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
4312                             rec.currentTime).toString());
4313                 }
4314             } else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) {
4315                 if (checkin) {
4316                     pw.print(":");
4317                 }
4318                 pw.println("SHUTDOWN");
4319             } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
4320                 if (checkin) {
4321                     pw.print(":");
4322                 }
4323                 pw.println("*OVERFLOW*");
4324             } else {
4325                 if (!checkin) {
4326                     if (rec.batteryLevel < 10) pw.print("00");
4327                     else if (rec.batteryLevel < 100) pw.print("0");
4328                     pw.print(rec.batteryLevel);
4329                     if (verbose) {
4330                         pw.print(" ");
4331                         if (rec.states < 0) ;
4332                         else if (rec.states < 0x10) pw.print("0000000");
4333                         else if (rec.states < 0x100) pw.print("000000");
4334                         else if (rec.states < 0x1000) pw.print("00000");
4335                         else if (rec.states < 0x10000) pw.print("0000");
4336                         else if (rec.states < 0x100000) pw.print("000");
4337                         else if (rec.states < 0x1000000) pw.print("00");
4338                         else if (rec.states < 0x10000000) pw.print("0");
4339                         pw.print(Integer.toHexString(rec.states));
4340                     }
4341                 } else {
4342                     if (oldLevel != rec.batteryLevel) {
4343                         oldLevel = rec.batteryLevel;
4344                         pw.print(",Bl="); pw.print(rec.batteryLevel);
4345                     }
4346                 }
4347                 if (oldStatus != rec.batteryStatus) {
4348                     oldStatus = rec.batteryStatus;
4349                     pw.print(checkin ? ",Bs=" : " status=");
4350                     switch (oldStatus) {
4351                         case BatteryManager.BATTERY_STATUS_UNKNOWN:
4352                             pw.print(checkin ? "?" : "unknown");
4353                             break;
4354                         case BatteryManager.BATTERY_STATUS_CHARGING:
4355                             pw.print(checkin ? "c" : "charging");
4356                             break;
4357                         case BatteryManager.BATTERY_STATUS_DISCHARGING:
4358                             pw.print(checkin ? "d" : "discharging");
4359                             break;
4360                         case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
4361                             pw.print(checkin ? "n" : "not-charging");
4362                             break;
4363                         case BatteryManager.BATTERY_STATUS_FULL:
4364                             pw.print(checkin ? "f" : "full");
4365                             break;
4366                         default:
4367                             pw.print(oldStatus);
4368                             break;
4369                     }
4370                 }
4371                 if (oldHealth != rec.batteryHealth) {
4372                     oldHealth = rec.batteryHealth;
4373                     pw.print(checkin ? ",Bh=" : " health=");
4374                     switch (oldHealth) {
4375                         case BatteryManager.BATTERY_HEALTH_UNKNOWN:
4376                             pw.print(checkin ? "?" : "unknown");
4377                             break;
4378                         case BatteryManager.BATTERY_HEALTH_GOOD:
4379                             pw.print(checkin ? "g" : "good");
4380                             break;
4381                         case BatteryManager.BATTERY_HEALTH_OVERHEAT:
4382                             pw.print(checkin ? "h" : "overheat");
4383                             break;
4384                         case BatteryManager.BATTERY_HEALTH_DEAD:
4385                             pw.print(checkin ? "d" : "dead");
4386                             break;
4387                         case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
4388                             pw.print(checkin ? "v" : "over-voltage");
4389                             break;
4390                         case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
4391                             pw.print(checkin ? "f" : "failure");
4392                             break;
4393                         case BatteryManager.BATTERY_HEALTH_COLD:
4394                             pw.print(checkin ? "c" : "cold");
4395                             break;
4396                         default:
4397                             pw.print(oldHealth);
4398                             break;
4399                     }
4400                 }
4401                 if (oldPlug != rec.batteryPlugType) {
4402                     oldPlug = rec.batteryPlugType;
4403                     pw.print(checkin ? ",Bp=" : " plug=");
4404                     switch (oldPlug) {
4405                         case 0:
4406                             pw.print(checkin ? "n" : "none");
4407                             break;
4408                         case BatteryManager.BATTERY_PLUGGED_AC:
4409                             pw.print(checkin ? "a" : "ac");
4410                             break;
4411                         case BatteryManager.BATTERY_PLUGGED_USB:
4412                             pw.print(checkin ? "u" : "usb");
4413                             break;
4414                         case BatteryManager.BATTERY_PLUGGED_WIRELESS:
4415                             pw.print(checkin ? "w" : "wireless");
4416                             break;
4417                         default:
4418                             pw.print(oldPlug);
4419                             break;
4420                     }
4421                 }
4422                 if (oldTemp != rec.batteryTemperature) {
4423                     oldTemp = rec.batteryTemperature;
4424                     pw.print(checkin ? ",Bt=" : " temp=");
4425                     pw.print(oldTemp);
4426                 }
4427                 if (oldVolt != rec.batteryVoltage) {
4428                     oldVolt = rec.batteryVoltage;
4429                     pw.print(checkin ? ",Bv=" : " volt=");
4430                     pw.print(oldVolt);
4431                 }
4432                 printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
4433                         HISTORY_STATE_DESCRIPTIONS, !checkin);
4434                 printBitDescriptions(pw, oldState2, rec.states2, null,
4435                         HISTORY_STATE2_DESCRIPTIONS, !checkin);
4436                 if (rec.wakeReasonTag != null) {
4437                     if (checkin) {
4438                         pw.print(",wr=");
4439                         pw.print(rec.wakeReasonTag.poolIdx);
4440                     } else {
4441                         pw.print(" wake_reason=");
4442                         pw.print(rec.wakeReasonTag.uid);
4443                         pw.print(":\"");
4444                         pw.print(rec.wakeReasonTag.string);
4445                         pw.print("\"");
4446                     }
4447                 }
4448                 if (rec.eventCode != HistoryItem.EVENT_NONE) {
4449                     pw.print(checkin ? "," : " ");
4450                     if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
4451                         pw.print("+");
4452                     } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
4453                         pw.print("-");
4454                     }
4455                     String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
4456                             : HISTORY_EVENT_NAMES;
4457                     int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
4458                             | HistoryItem.EVENT_FLAG_FINISH);
4459                     if (idx >= 0 && idx < eventNames.length) {
4460                         pw.print(eventNames[idx]);
4461                     } else {
4462                         pw.print(checkin ? "Ev" : "event");
4463                         pw.print(idx);
4464                     }
4465                     pw.print("=");
4466                     if (checkin) {
4467                         pw.print(rec.eventTag.poolIdx);
4468                     } else {
4469                         UserHandle.formatUid(pw, rec.eventTag.uid);
4470                         pw.print(":\"");
4471                         pw.print(rec.eventTag.string);
4472                         pw.print("\"");
4473                     }
4474                 }
4475                 pw.println();
4476                 if (rec.stepDetails != null) {
4477                     if (!checkin) {
4478                         pw.print("                 Details: cpu=");
4479                         pw.print(rec.stepDetails.userTime);
4480                         pw.print("u+");
4481                         pw.print(rec.stepDetails.systemTime);
4482                         pw.print("s");
4483                         if (rec.stepDetails.appCpuUid1 >= 0) {
4484                             pw.print(" (");
4485                             printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid1,
4486                                     rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
4487                             if (rec.stepDetails.appCpuUid2 >= 0) {
4488                                 pw.print(", ");
4489                                 printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid2,
4490                                         rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
4491                             }
4492                             if (rec.stepDetails.appCpuUid3 >= 0) {
4493                                 pw.print(", ");
4494                                 printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid3,
4495                                         rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
4496                             }
4497                             pw.print(')');
4498                         }
4499                         pw.println();
4500                         pw.print("                          /proc/stat=");
4501                         pw.print(rec.stepDetails.statUserTime);
4502                         pw.print(" usr, ");
4503                         pw.print(rec.stepDetails.statSystemTime);
4504                         pw.print(" sys, ");
4505                         pw.print(rec.stepDetails.statIOWaitTime);
4506                         pw.print(" io, ");
4507                         pw.print(rec.stepDetails.statIrqTime);
4508                         pw.print(" irq, ");
4509                         pw.print(rec.stepDetails.statSoftIrqTime);
4510                         pw.print(" sirq, ");
4511                         pw.print(rec.stepDetails.statIdlTime);
4512                         pw.print(" idle");
4513                         int totalRun = rec.stepDetails.statUserTime + rec.stepDetails.statSystemTime
4514                                 + rec.stepDetails.statIOWaitTime + rec.stepDetails.statIrqTime
4515                                 + rec.stepDetails.statSoftIrqTime;
4516                         int total = totalRun + rec.stepDetails.statIdlTime;
4517                         if (total > 0) {
4518                             pw.print(" (");
4519                             float perc = ((float)totalRun) / ((float)total) * 100;
4520                             pw.print(String.format("%.1f%%", perc));
4521                             pw.print(" of ");
4522                             StringBuilder sb = new StringBuilder(64);
4523                             formatTimeMsNoSpace(sb, total*10);
4524                             pw.print(sb);
4525                             pw.print(")");
4526                         }
4527                         pw.println();
4528                     } else {
4529                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
4530                         pw.print(HISTORY_DATA); pw.print(",0,Dcpu=");
4531                         pw.print(rec.stepDetails.userTime);
4532                         pw.print(":");
4533                         pw.print(rec.stepDetails.systemTime);
4534                         if (rec.stepDetails.appCpuUid1 >= 0) {
4535                             printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid1,
4536                                     rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
4537                             if (rec.stepDetails.appCpuUid2 >= 0) {
4538                                 printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid2,
4539                                         rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
4540                             }
4541                             if (rec.stepDetails.appCpuUid3 >= 0) {
4542                                 printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid3,
4543                                         rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
4544                             }
4545                         }
4546                         pw.println();
4547                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
4548                         pw.print(HISTORY_DATA); pw.print(",0,Dpst=");
4549                         pw.print(rec.stepDetails.statUserTime);
4550                         pw.print(',');
4551                         pw.print(rec.stepDetails.statSystemTime);
4552                         pw.print(',');
4553                         pw.print(rec.stepDetails.statIOWaitTime);
4554                         pw.print(',');
4555                         pw.print(rec.stepDetails.statIrqTime);
4556                         pw.print(',');
4557                         pw.print(rec.stepDetails.statSoftIrqTime);
4558                         pw.print(',');
4559                         pw.print(rec.stepDetails.statIdlTime);
4560                         pw.println();
4561                     }
4562                 }
4563                 oldState = rec.states;
4564                 oldState2 = rec.states2;
4565             }
4566         }
4567 
printStepCpuUidDetails(PrintWriter pw, int uid, int utime, int stime)4568         private void printStepCpuUidDetails(PrintWriter pw, int uid, int utime, int stime) {
4569             UserHandle.formatUid(pw, uid);
4570             pw.print("=");
4571             pw.print(utime);
4572             pw.print("u+");
4573             pw.print(stime);
4574             pw.print("s");
4575         }
4576 
printStepCpuUidCheckinDetails(PrintWriter pw, int uid, int utime, int stime)4577         private void printStepCpuUidCheckinDetails(PrintWriter pw, int uid, int utime, int stime) {
4578             pw.print('/');
4579             pw.print(uid);
4580             pw.print(":");
4581             pw.print(utime);
4582             pw.print(":");
4583             pw.print(stime);
4584         }
4585     }
4586 
printSizeValue(PrintWriter pw, long size)4587     private void printSizeValue(PrintWriter pw, long size) {
4588         float result = size;
4589         String suffix = "";
4590         if (result >= 10*1024) {
4591             suffix = "KB";
4592             result = result / 1024;
4593         }
4594         if (result >= 10*1024) {
4595             suffix = "MB";
4596             result = result / 1024;
4597         }
4598         if (result >= 10*1024) {
4599             suffix = "GB";
4600             result = result / 1024;
4601         }
4602         if (result >= 10*1024) {
4603             suffix = "TB";
4604             result = result / 1024;
4605         }
4606         if (result >= 10*1024) {
4607             suffix = "PB";
4608             result = result / 1024;
4609         }
4610         pw.print((int)result);
4611         pw.print(suffix);
4612     }
4613 
dumpTimeEstimate(PrintWriter pw, String label1, String label2, String label3, long estimatedTime)4614     private static boolean dumpTimeEstimate(PrintWriter pw, String label1, String label2,
4615             String label3, long estimatedTime) {
4616         if (estimatedTime < 0) {
4617             return false;
4618         }
4619         pw.print(label1);
4620         pw.print(label2);
4621         pw.print(label3);
4622         StringBuilder sb = new StringBuilder(64);
4623         formatTimeMs(sb, estimatedTime);
4624         pw.print(sb);
4625         pw.println();
4626         return true;
4627     }
4628 
dumpDurationSteps(PrintWriter pw, String prefix, String header, LevelStepTracker steps, boolean checkin)4629     private static boolean dumpDurationSteps(PrintWriter pw, String prefix, String header,
4630             LevelStepTracker steps, boolean checkin) {
4631         if (steps == null) {
4632             return false;
4633         }
4634         int count = steps.mNumStepDurations;
4635         if (count <= 0) {
4636             return false;
4637         }
4638         if (!checkin) {
4639             pw.println(header);
4640         }
4641         String[] lineArgs = new String[5];
4642         for (int i=0; i<count; i++) {
4643             long duration = steps.getDurationAt(i);
4644             int level = steps.getLevelAt(i);
4645             long initMode = steps.getInitModeAt(i);
4646             long modMode = steps.getModModeAt(i);
4647             if (checkin) {
4648                 lineArgs[0] = Long.toString(duration);
4649                 lineArgs[1] = Integer.toString(level);
4650                 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
4651                     switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
4652                         case Display.STATE_OFF: lineArgs[2] = "s-"; break;
4653                         case Display.STATE_ON: lineArgs[2] = "s+"; break;
4654                         case Display.STATE_DOZE: lineArgs[2] = "sd"; break;
4655                         case Display.STATE_DOZE_SUSPEND: lineArgs[2] = "sds"; break;
4656                         default: lineArgs[2] = "?"; break;
4657                     }
4658                 } else {
4659                     lineArgs[2] = "";
4660                 }
4661                 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
4662                     lineArgs[3] = (initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 ? "p+" : "p-";
4663                 } else {
4664                     lineArgs[3] = "";
4665                 }
4666                 if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
4667                     lineArgs[4] = (initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0 ? "i+" : "i-";
4668                 } else {
4669                     lineArgs[4] = "";
4670                 }
4671                 dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs);
4672             } else {
4673                 pw.print(prefix);
4674                 pw.print("#"); pw.print(i); pw.print(": ");
4675                 TimeUtils.formatDuration(duration, pw);
4676                 pw.print(" to "); pw.print(level);
4677                 boolean haveModes = false;
4678                 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
4679                     pw.print(" (");
4680                     switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
4681                         case Display.STATE_OFF: pw.print("screen-off"); break;
4682                         case Display.STATE_ON: pw.print("screen-on"); break;
4683                         case Display.STATE_DOZE: pw.print("screen-doze"); break;
4684                         case Display.STATE_DOZE_SUSPEND: pw.print("screen-doze-suspend"); break;
4685                         default: pw.print("screen-?"); break;
4686                     }
4687                     haveModes = true;
4688                 }
4689                 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
4690                     pw.print(haveModes ? ", " : " (");
4691                     pw.print((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0
4692                             ? "power-save-on" : "power-save-off");
4693                     haveModes = true;
4694                 }
4695                 if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) {
4696                     pw.print(haveModes ? ", " : " (");
4697                     pw.print((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0
4698                             ? "device-idle-on" : "device-idle-off");
4699                     haveModes = true;
4700                 }
4701                 if (haveModes) {
4702                     pw.print(")");
4703                 }
4704                 pw.println();
4705             }
4706         }
4707         return true;
4708     }
4709 
4710     public static final int DUMP_CHARGED_ONLY = 1<<1;
4711     public static final int DUMP_DAILY_ONLY = 1<<2;
4712     public static final int DUMP_HISTORY_ONLY = 1<<3;
4713     public static final int DUMP_INCLUDE_HISTORY = 1<<4;
4714     public static final int DUMP_VERBOSE = 1<<5;
4715     public static final int DUMP_DEVICE_WIFI_ONLY = 1<<6;
4716 
dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin)4717     private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
4718         final HistoryPrinter hprinter = new HistoryPrinter();
4719         final HistoryItem rec = new HistoryItem();
4720         long lastTime = -1;
4721         long baseTime = -1;
4722         boolean printed = false;
4723         HistoryEventTracker tracker = null;
4724         while (getNextHistoryLocked(rec)) {
4725             lastTime = rec.time;
4726             if (baseTime < 0) {
4727                 baseTime = lastTime;
4728             }
4729             if (rec.time >= histStart) {
4730                 if (histStart >= 0 && !printed) {
4731                     if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
4732                             || rec.cmd == HistoryItem.CMD_RESET
4733                             || rec.cmd == HistoryItem.CMD_START
4734                             || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
4735                         printed = true;
4736                         hprinter.printNextItem(pw, rec, baseTime, checkin,
4737                                 (flags&DUMP_VERBOSE) != 0);
4738                         rec.cmd = HistoryItem.CMD_UPDATE;
4739                     } else if (rec.currentTime != 0) {
4740                         printed = true;
4741                         byte cmd = rec.cmd;
4742                         rec.cmd = HistoryItem.CMD_CURRENT_TIME;
4743                         hprinter.printNextItem(pw, rec, baseTime, checkin,
4744                                 (flags&DUMP_VERBOSE) != 0);
4745                         rec.cmd = cmd;
4746                     }
4747                     if (tracker != null) {
4748                         if (rec.cmd != HistoryItem.CMD_UPDATE) {
4749                             hprinter.printNextItem(pw, rec, baseTime, checkin,
4750                                     (flags&DUMP_VERBOSE) != 0);
4751                             rec.cmd = HistoryItem.CMD_UPDATE;
4752                         }
4753                         int oldEventCode = rec.eventCode;
4754                         HistoryTag oldEventTag = rec.eventTag;
4755                         rec.eventTag = new HistoryTag();
4756                         for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
4757                             HashMap<String, SparseIntArray> active
4758                                     = tracker.getStateForEvent(i);
4759                             if (active == null) {
4760                                 continue;
4761                             }
4762                             for (HashMap.Entry<String, SparseIntArray> ent
4763                                     : active.entrySet()) {
4764                                 SparseIntArray uids = ent.getValue();
4765                                 for (int j=0; j<uids.size(); j++) {
4766                                     rec.eventCode = i;
4767                                     rec.eventTag.string = ent.getKey();
4768                                     rec.eventTag.uid = uids.keyAt(j);
4769                                     rec.eventTag.poolIdx = uids.valueAt(j);
4770                                     hprinter.printNextItem(pw, rec, baseTime, checkin,
4771                                             (flags&DUMP_VERBOSE) != 0);
4772                                     rec.wakeReasonTag = null;
4773                                     rec.wakelockTag = null;
4774                                 }
4775                             }
4776                         }
4777                         rec.eventCode = oldEventCode;
4778                         rec.eventTag = oldEventTag;
4779                         tracker = null;
4780                     }
4781                 }
4782                 hprinter.printNextItem(pw, rec, baseTime, checkin,
4783                         (flags&DUMP_VERBOSE) != 0);
4784             } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) {
4785                 // This is an attempt to aggregate the previous state and generate
4786                 // fake events to reflect that state at the point where we start
4787                 // printing real events.  It doesn't really work right, so is turned off.
4788                 if (tracker == null) {
4789                     tracker = new HistoryEventTracker();
4790                 }
4791                 tracker.updateState(rec.eventCode, rec.eventTag.string,
4792                         rec.eventTag.uid, rec.eventTag.poolIdx);
4793             }
4794         }
4795         if (histStart >= 0) {
4796             commitCurrentHistoryBatchLocked();
4797             pw.print(checkin ? "NEXT: " : "  NEXT: "); pw.println(lastTime+1);
4798         }
4799     }
4800 
dumpDailyLevelStepSummary(PrintWriter pw, String prefix, String label, LevelStepTracker steps, StringBuilder tmpSb, int[] tmpOutInt)4801     private void dumpDailyLevelStepSummary(PrintWriter pw, String prefix, String label,
4802             LevelStepTracker steps, StringBuilder tmpSb, int[] tmpOutInt) {
4803         if (steps == null) {
4804             return;
4805         }
4806         long timeRemaining = steps.computeTimeEstimate(0, 0, tmpOutInt);
4807         if (timeRemaining >= 0) {
4808             pw.print(prefix); pw.print(label); pw.print(" total time: ");
4809             tmpSb.setLength(0);
4810             formatTimeMs(tmpSb, timeRemaining);
4811             pw.print(tmpSb);
4812             pw.print(" (from "); pw.print(tmpOutInt[0]);
4813             pw.println(" steps)");
4814         }
4815         for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
4816             long estimatedTime = steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
4817                     STEP_LEVEL_MODE_VALUES[i], tmpOutInt);
4818             if (estimatedTime > 0) {
4819                 pw.print(prefix); pw.print(label); pw.print(" ");
4820                 pw.print(STEP_LEVEL_MODE_LABELS[i]);
4821                 pw.print(" time: ");
4822                 tmpSb.setLength(0);
4823                 formatTimeMs(tmpSb, estimatedTime);
4824                 pw.print(tmpSb);
4825                 pw.print(" (from "); pw.print(tmpOutInt[0]);
4826                 pw.println(" steps)");
4827             }
4828         }
4829     }
4830 
dumpDailyPackageChanges(PrintWriter pw, String prefix, ArrayList<PackageChange> changes)4831     private void dumpDailyPackageChanges(PrintWriter pw, String prefix,
4832             ArrayList<PackageChange> changes) {
4833         if (changes == null) {
4834             return;
4835         }
4836         pw.print(prefix); pw.println("Package changes:");
4837         for (int i=0; i<changes.size(); i++) {
4838             PackageChange pc = changes.get(i);
4839             if (pc.mUpdate) {
4840                 pw.print(prefix); pw.print("  Update "); pw.print(pc.mPackageName);
4841                 pw.print(" vers="); pw.println(pc.mVersionCode);
4842             } else {
4843                 pw.print(prefix); pw.print("  Uninstall "); pw.println(pc.mPackageName);
4844             }
4845         }
4846     }
4847 
4848     /**
4849      * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
4850      *
4851      * @param pw a Printer to receive the dump output.
4852      */
4853     @SuppressWarnings("unused")
dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart)4854     public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
4855         prepareForDumpLocked();
4856 
4857         final boolean filtering = (flags
4858                 & (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
4859 
4860         if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
4861             final long historyTotalSize = getHistoryTotalSize();
4862             final long historyUsedSize = getHistoryUsedSize();
4863             if (startIteratingHistoryLocked()) {
4864                 try {
4865                     pw.print("Battery History (");
4866                     pw.print((100*historyUsedSize)/historyTotalSize);
4867                     pw.print("% used, ");
4868                     printSizeValue(pw, historyUsedSize);
4869                     pw.print(" used of ");
4870                     printSizeValue(pw, historyTotalSize);
4871                     pw.print(", ");
4872                     pw.print(getHistoryStringPoolSize());
4873                     pw.print(" strings using ");
4874                     printSizeValue(pw, getHistoryStringPoolBytes());
4875                     pw.println("):");
4876                     dumpHistoryLocked(pw, flags, histStart, false);
4877                     pw.println();
4878                 } finally {
4879                     finishIteratingHistoryLocked();
4880                 }
4881             }
4882 
4883             if (startIteratingOldHistoryLocked()) {
4884                 try {
4885                     final HistoryItem rec = new HistoryItem();
4886                     pw.println("Old battery History:");
4887                     HistoryPrinter hprinter = new HistoryPrinter();
4888                     long baseTime = -1;
4889                     while (getNextOldHistoryLocked(rec)) {
4890                         if (baseTime < 0) {
4891                             baseTime = rec.time;
4892                         }
4893                         hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0);
4894                     }
4895                     pw.println();
4896                 } finally {
4897                     finishIteratingOldHistoryLocked();
4898                 }
4899             }
4900         }
4901 
4902         if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
4903             return;
4904         }
4905 
4906         if (!filtering) {
4907             SparseArray<? extends Uid> uidStats = getUidStats();
4908             final int NU = uidStats.size();
4909             boolean didPid = false;
4910             long nowRealtime = SystemClock.elapsedRealtime();
4911             for (int i=0; i<NU; i++) {
4912                 Uid uid = uidStats.valueAt(i);
4913                 SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
4914                 if (pids != null) {
4915                     for (int j=0; j<pids.size(); j++) {
4916                         Uid.Pid pid = pids.valueAt(j);
4917                         if (!didPid) {
4918                             pw.println("Per-PID Stats:");
4919                             didPid = true;
4920                         }
4921                         long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
4922                                 ? (nowRealtime - pid.mWakeStartMs) : 0);
4923                         pw.print("  PID "); pw.print(pids.keyAt(j));
4924                                 pw.print(" wake time: ");
4925                                 TimeUtils.formatDuration(time, pw);
4926                                 pw.println("");
4927                     }
4928                 }
4929             }
4930             if (didPid) {
4931                 pw.println();
4932             }
4933         }
4934 
4935         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
4936             if (dumpDurationSteps(pw, "  ", "Discharge step durations:",
4937                     getDischargeLevelStepTracker(), false)) {
4938                 long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
4939                 if (timeRemaining >= 0) {
4940                     pw.print("  Estimated discharge time remaining: ");
4941                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
4942                     pw.println();
4943                 }
4944                 final LevelStepTracker steps = getDischargeLevelStepTracker();
4945                 for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) {
4946                     dumpTimeEstimate(pw, "  Estimated ", STEP_LEVEL_MODE_LABELS[i], " time: ",
4947                             steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i],
4948                                     STEP_LEVEL_MODE_VALUES[i], null));
4949                 }
4950                 pw.println();
4951             }
4952             if (dumpDurationSteps(pw, "  ", "Charge step durations:",
4953                     getChargeLevelStepTracker(), false)) {
4954                 long timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
4955                 if (timeRemaining >= 0) {
4956                     pw.print("  Estimated charge time remaining: ");
4957                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
4958                     pw.println();
4959                 }
4960                 pw.println();
4961             }
4962         }
4963         if (!filtering || (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0) {
4964             pw.println("Daily stats:");
4965             pw.print("  Current start time: ");
4966             pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
4967                     getCurrentDailyStartTime()).toString());
4968             pw.print("  Next min deadline: ");
4969             pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
4970                     getNextMinDailyDeadline()).toString());
4971             pw.print("  Next max deadline: ");
4972             pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
4973                     getNextMaxDailyDeadline()).toString());
4974             StringBuilder sb = new StringBuilder(64);
4975             int[] outInt = new int[1];
4976             LevelStepTracker dsteps = getDailyDischargeLevelStepTracker();
4977             LevelStepTracker csteps = getDailyChargeLevelStepTracker();
4978             ArrayList<PackageChange> pkgc = getDailyPackageChanges();
4979             if (dsteps.mNumStepDurations > 0 || csteps.mNumStepDurations > 0 || pkgc != null) {
4980                 if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
4981                     if (dumpDurationSteps(pw, "    ", "  Current daily discharge step durations:",
4982                             dsteps, false)) {
4983                         dumpDailyLevelStepSummary(pw, "      ", "Discharge", dsteps,
4984                                 sb, outInt);
4985                     }
4986                     if (dumpDurationSteps(pw, "    ", "  Current daily charge step durations:",
4987                             csteps, false)) {
4988                         dumpDailyLevelStepSummary(pw, "      ", "Charge", csteps,
4989                                 sb, outInt);
4990                     }
4991                     dumpDailyPackageChanges(pw, "    ", pkgc);
4992                 } else {
4993                     pw.println("  Current daily steps:");
4994                     dumpDailyLevelStepSummary(pw, "    ", "Discharge", dsteps,
4995                             sb, outInt);
4996                     dumpDailyLevelStepSummary(pw, "    ", "Charge", csteps,
4997                             sb, outInt);
4998                 }
4999             }
5000             DailyItem dit;
5001             int curIndex = 0;
5002             while ((dit=getDailyItemLocked(curIndex)) != null) {
5003                 curIndex++;
5004                 if ((flags&DUMP_DAILY_ONLY) != 0) {
5005                     pw.println();
5006                 }
5007                 pw.print("  Daily from ");
5008                 pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mStartTime).toString());
5009                 pw.print(" to ");
5010                 pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mEndTime).toString());
5011                 pw.println(":");
5012                 if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
5013                     if (dumpDurationSteps(pw, "      ",
5014                             "    Discharge step durations:", dit.mDischargeSteps, false)) {
5015                         dumpDailyLevelStepSummary(pw, "        ", "Discharge", dit.mDischargeSteps,
5016                                 sb, outInt);
5017                     }
5018                     if (dumpDurationSteps(pw, "      ",
5019                             "    Charge step durations:", dit.mChargeSteps, false)) {
5020                         dumpDailyLevelStepSummary(pw, "        ", "Charge", dit.mChargeSteps,
5021                                 sb, outInt);
5022                     }
5023                     dumpDailyPackageChanges(pw, "    ", dit.mPackageChanges);
5024                 } else {
5025                     dumpDailyLevelStepSummary(pw, "    ", "Discharge", dit.mDischargeSteps,
5026                             sb, outInt);
5027                     dumpDailyLevelStepSummary(pw, "    ", "Charge", dit.mChargeSteps,
5028                             sb, outInt);
5029                 }
5030             }
5031             pw.println();
5032         }
5033         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
5034             pw.println("Statistics since last charge:");
5035             pw.println("  System starts: " + getStartCount()
5036                     + ", currently on battery: " + getIsOnBattery());
5037             dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
5038                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
5039             pw.println();
5040         }
5041     }
5042 
5043     @SuppressWarnings("unused")
dumpCheckinLocked(Context context, PrintWriter pw, List<ApplicationInfo> apps, int flags, long histStart)5044     public void dumpCheckinLocked(Context context, PrintWriter pw,
5045             List<ApplicationInfo> apps, int flags, long histStart) {
5046         prepareForDumpLocked();
5047 
5048         dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
5049                 CHECKIN_VERSION, getParcelVersion(), getStartPlatformVersion(),
5050                 getEndPlatformVersion());
5051 
5052         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
5053 
5054         final boolean filtering = (flags &
5055                 (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
5056 
5057         if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) {
5058             if (startIteratingHistoryLocked()) {
5059                 try {
5060                     for (int i=0; i<getHistoryStringPoolSize(); i++) {
5061                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
5062                         pw.print(HISTORY_STRING_POOL); pw.print(',');
5063                         pw.print(i);
5064                         pw.print(",");
5065                         pw.print(getHistoryTagPoolUid(i));
5066                         pw.print(",\"");
5067                         String str = getHistoryTagPoolString(i);
5068                         str = str.replace("\\", "\\\\");
5069                         str = str.replace("\"", "\\\"");
5070                         pw.print(str);
5071                         pw.print("\"");
5072                         pw.println();
5073                     }
5074                     dumpHistoryLocked(pw, flags, histStart, true);
5075                 } finally {
5076                     finishIteratingHistoryLocked();
5077                 }
5078             }
5079         }
5080 
5081         if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
5082             return;
5083         }
5084 
5085         if (apps != null) {
5086             SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
5087             for (int i=0; i<apps.size(); i++) {
5088                 ApplicationInfo ai = apps.get(i);
5089                 ArrayList<String> pkgs = uids.get(ai.uid);
5090                 if (pkgs == null) {
5091                     pkgs = new ArrayList<String>();
5092                     uids.put(ai.uid, pkgs);
5093                 }
5094                 pkgs.add(ai.packageName);
5095             }
5096             SparseArray<? extends Uid> uidStats = getUidStats();
5097             final int NU = uidStats.size();
5098             String[] lineArgs = new String[2];
5099             for (int i=0; i<NU; i++) {
5100                 int uid = uidStats.keyAt(i);
5101                 ArrayList<String> pkgs = uids.get(uid);
5102                 if (pkgs != null) {
5103                     for (int j=0; j<pkgs.size(); j++) {
5104                         lineArgs[0] = Integer.toString(uid);
5105                         lineArgs[1] = pkgs.get(j);
5106                         dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
5107                                 (Object[])lineArgs);
5108                     }
5109                 }
5110             }
5111         }
5112         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
5113             dumpDurationSteps(pw, "", DISCHARGE_STEP_DATA, getDischargeLevelStepTracker(), true);
5114             String[] lineArgs = new String[1];
5115             long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
5116             if (timeRemaining >= 0) {
5117                 lineArgs[0] = Long.toString(timeRemaining);
5118                 dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA,
5119                         (Object[])lineArgs);
5120             }
5121             dumpDurationSteps(pw, "", CHARGE_STEP_DATA, getChargeLevelStepTracker(), true);
5122             timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
5123             if (timeRemaining >= 0) {
5124                 lineArgs[0] = Long.toString(timeRemaining);
5125                 dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA,
5126                         (Object[])lineArgs);
5127             }
5128             dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
5129                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
5130         }
5131     }
5132 }
5133