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.
467          * @param step the index of the CPU speed. This is not the actual speed of the CPU.
468          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
469          * @see BatteryStats#getCpuSpeedSteps()
470          */
getTimeAtCpuSpeed(int step, int which)471         public abstract long getTimeAtCpuSpeed(int step, int which);
472 
473         public static abstract class Sensor {
474             /*
475              * FIXME: it's not correct to use this magic value because it
476              * could clash with a sensor handle (which are defined by
477              * the sensor HAL, and therefore out of our control
478              */
479             // Magic sensor number for the GPS.
480             public static final int GPS = -10000;
481 
getHandle()482             public abstract int getHandle();
483 
getSensorTime()484             public abstract Timer getSensorTime();
485         }
486 
487         public class Pid {
488             public int mWakeNesting;
489             public long mWakeSumMs;
490             public long mWakeStartMs;
491         }
492 
493         /**
494          * The statistics associated with a particular process.
495          */
496         public static abstract class Proc {
497 
498             public static class ExcessivePower {
499                 public static final int TYPE_WAKE = 1;
500                 public static final int TYPE_CPU = 2;
501 
502                 public int type;
503                 public long overTime;
504                 public long usedTime;
505             }
506 
507             /**
508              * Returns true if this process is still active in the battery stats.
509              */
isActive()510             public abstract boolean isActive();
511 
512             /**
513              * Returns the total time (in milliseconds) spent executing in user code.
514              *
515              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
516              */
getUserTime(int which)517             public abstract long getUserTime(int which);
518 
519             /**
520              * Returns the total time (in milliseconds) spent executing in system code.
521              *
522              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
523              */
getSystemTime(int which)524             public abstract long getSystemTime(int which);
525 
526             /**
527              * Returns the number of times the process has been started.
528              *
529              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
530              */
getStarts(int which)531             public abstract int getStarts(int which);
532 
533             /**
534              * Returns the number of times the process has crashed.
535              *
536              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
537              */
getNumCrashes(int which)538             public abstract int getNumCrashes(int which);
539 
540             /**
541              * Returns the number of times the process has ANRed.
542              *
543              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
544              */
getNumAnrs(int which)545             public abstract int getNumAnrs(int which);
546 
547             /**
548              * Returns the cpu time (milliseconds) spent while the process was in the foreground.
549              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
550              * @return foreground cpu time in microseconds
551              */
getForegroundTime(int which)552             public abstract long getForegroundTime(int which);
553 
countExcessivePowers()554             public abstract int countExcessivePowers();
555 
getExcessivePower(int i)556             public abstract ExcessivePower getExcessivePower(int i);
557         }
558 
559         /**
560          * The statistics associated with a particular package.
561          */
562         public static abstract class Pkg {
563 
564             /**
565              * Returns information about all wakeup alarms that have been triggered for this
566              * package.  The mapping keys are tag names for the alarms, the counter contains
567              * the number of times the alarm was triggered while on battery.
568              */
getWakeupAlarmStats()569             public abstract ArrayMap<String, ? extends Counter> getWakeupAlarmStats();
570 
571             /**
572              * Returns a mapping containing service statistics.
573              */
getServiceStats()574             public abstract ArrayMap<String, ? extends Serv> getServiceStats();
575 
576             /**
577              * The statistics associated with a particular service.
578              */
579             public abstract class Serv {
580 
581                 /**
582                  * Returns the amount of time spent started.
583                  *
584                  * @param batteryUptime elapsed uptime on battery in microseconds.
585                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
586                  * @return
587                  */
getStartTime(long batteryUptime, int which)588                 public abstract long getStartTime(long batteryUptime, int which);
589 
590                 /**
591                  * Returns the total number of times startService() has been called.
592                  *
593                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
594                  */
getStarts(int which)595                 public abstract int getStarts(int which);
596 
597                 /**
598                  * Returns the total number times the service has been launched.
599                  *
600                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
601                  */
getLaunches(int which)602                 public abstract int getLaunches(int which);
603             }
604         }
605     }
606 
607     public static final class LevelStepTracker {
608         public long mLastStepTime = -1;
609         public int mNumStepDurations;
610         public final long[] mStepDurations;
611 
LevelStepTracker(int maxLevelSteps)612         public LevelStepTracker(int maxLevelSteps) {
613             mStepDurations = new long[maxLevelSteps];
614         }
615 
LevelStepTracker(int numSteps, long[] steps)616         public LevelStepTracker(int numSteps, long[] steps) {
617             mNumStepDurations = numSteps;
618             mStepDurations = new long[numSteps];
619             System.arraycopy(steps, 0, mStepDurations, 0, numSteps);
620         }
621 
getDurationAt(int index)622         public long getDurationAt(int index) {
623             return mStepDurations[index] & STEP_LEVEL_TIME_MASK;
624         }
625 
getLevelAt(int index)626         public int getLevelAt(int index) {
627             return (int)((mStepDurations[index] & STEP_LEVEL_LEVEL_MASK)
628                     >> STEP_LEVEL_LEVEL_SHIFT);
629         }
630 
getInitModeAt(int index)631         public int getInitModeAt(int index) {
632             return (int)((mStepDurations[index] & STEP_LEVEL_INITIAL_MODE_MASK)
633                     >> STEP_LEVEL_INITIAL_MODE_SHIFT);
634         }
635 
getModModeAt(int index)636         public int getModModeAt(int index) {
637             return (int)((mStepDurations[index] & STEP_LEVEL_MODIFIED_MODE_MASK)
638                     >> STEP_LEVEL_MODIFIED_MODE_SHIFT);
639         }
640 
appendHex(long val, int topOffset, StringBuilder out)641         private void appendHex(long val, int topOffset, StringBuilder out) {
642             boolean hasData = false;
643             while (topOffset >= 0) {
644                 int digit = (int)( (val>>topOffset) & 0xf );
645                 topOffset -= 4;
646                 if (!hasData && digit == 0) {
647                     continue;
648                 }
649                 hasData = true;
650                 if (digit >= 0 && digit <= 9) {
651                     out.append((char)('0' + digit));
652                 } else {
653                     out.append((char)('a' + digit - 10));
654                 }
655             }
656         }
657 
encodeEntryAt(int index, StringBuilder out)658         public void encodeEntryAt(int index, StringBuilder out) {
659             long item = mStepDurations[index];
660             long duration = item & STEP_LEVEL_TIME_MASK;
661             int level = (int)((item & STEP_LEVEL_LEVEL_MASK)
662                     >> STEP_LEVEL_LEVEL_SHIFT);
663             int initMode = (int)((item & STEP_LEVEL_INITIAL_MODE_MASK)
664                     >> STEP_LEVEL_INITIAL_MODE_SHIFT);
665             int modMode = (int)((item & STEP_LEVEL_MODIFIED_MODE_MASK)
666                     >> STEP_LEVEL_MODIFIED_MODE_SHIFT);
667             switch ((initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
668                 case Display.STATE_OFF: out.append('f'); break;
669                 case Display.STATE_ON: out.append('o'); break;
670                 case Display.STATE_DOZE: out.append('d'); break;
671                 case Display.STATE_DOZE_SUSPEND: out.append('z'); break;
672             }
673             if ((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) {
674                 out.append('p');
675             }
676             if ((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) {
677                 out.append('i');
678             }
679             switch ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
680                 case Display.STATE_OFF: out.append('F'); break;
681                 case Display.STATE_ON: out.append('O'); break;
682                 case Display.STATE_DOZE: out.append('D'); break;
683                 case Display.STATE_DOZE_SUSPEND: out.append('Z'); break;
684             }
685             if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) {
686                 out.append('P');
687             }
688             if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) {
689                 out.append('I');
690             }
691             out.append('-');
692             appendHex(level, 4, out);
693             out.append('-');
694             appendHex(duration, STEP_LEVEL_LEVEL_SHIFT-4, out);
695         }
696 
decodeEntryAt(int index, String value)697         public void decodeEntryAt(int index, String value) {
698             final int N = value.length();
699             int i = 0;
700             char c;
701             long out = 0;
702             while (i < N && (c=value.charAt(i)) != '-') {
703                 i++;
704                 switch (c) {
705                     case 'f': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
706                         break;
707                     case 'o': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
708                         break;
709                     case 'd': out |= (((long)Display.STATE_DOZE-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT);
710                         break;
711                     case 'z': out |= (((long)Display.STATE_DOZE_SUSPEND-1)
712                             << STEP_LEVEL_INITIAL_MODE_SHIFT);
713                         break;
714                     case 'p': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE)
715                             << STEP_LEVEL_INITIAL_MODE_SHIFT);
716                         break;
717                     case 'i': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE)
718                             << STEP_LEVEL_INITIAL_MODE_SHIFT);
719                         break;
720                     case 'F': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
721                         break;
722                     case 'O': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
723                         break;
724                     case 'D': out |= (((long)Display.STATE_DOZE-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT);
725                         break;
726                     case 'Z': out |= (((long)Display.STATE_DOZE_SUSPEND-1)
727                             << STEP_LEVEL_MODIFIED_MODE_SHIFT);
728                         break;
729                     case 'P': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE)
730                             << STEP_LEVEL_MODIFIED_MODE_SHIFT);
731                         break;
732                     case 'I': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE)
733                             << STEP_LEVEL_MODIFIED_MODE_SHIFT);
734                         break;
735                 }
736             }
737             i++;
738             long level = 0;
739             while (i < N && (c=value.charAt(i)) != '-') {
740                 i++;
741                 level <<= 4;
742                 if (c >= '0' && c <= '9') {
743                     level += c - '0';
744                 } else if (c >= 'a' && c <= 'f') {
745                     level += c - 'a' + 10;
746                 } else if (c >= 'A' && c <= 'F') {
747                     level += c - 'A' + 10;
748                 }
749             }
750             i++;
751             out |= (level << STEP_LEVEL_LEVEL_SHIFT) & STEP_LEVEL_LEVEL_MASK;
752             long duration = 0;
753             while (i < N && (c=value.charAt(i)) != '-') {
754                 i++;
755                 duration <<= 4;
756                 if (c >= '0' && c <= '9') {
757                     duration += c - '0';
758                 } else if (c >= 'a' && c <= 'f') {
759                     duration += c - 'a' + 10;
760                 } else if (c >= 'A' && c <= 'F') {
761                     duration += c - 'A' + 10;
762                 }
763             }
764             mStepDurations[index] = out | (duration & STEP_LEVEL_TIME_MASK);
765         }
766 
init()767         public void init() {
768             mLastStepTime = -1;
769             mNumStepDurations = 0;
770         }
771 
clearTime()772         public void clearTime() {
773             mLastStepTime = -1;
774         }
775 
computeTimePerLevel()776         public long computeTimePerLevel() {
777             final long[] steps = mStepDurations;
778             final int numSteps = mNumStepDurations;
779 
780             // For now we'll do a simple average across all steps.
781             if (numSteps <= 0) {
782                 return -1;
783             }
784             long total = 0;
785             for (int i=0; i<numSteps; i++) {
786                 total += steps[i] & STEP_LEVEL_TIME_MASK;
787             }
788             return total / numSteps;
789             /*
790             long[] buckets = new long[numSteps];
791             int numBuckets = 0;
792             int numToAverage = 4;
793             int i = 0;
794             while (i < numSteps) {
795                 long totalTime = 0;
796                 int num = 0;
797                 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
798                     totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
799                     num++;
800                 }
801                 buckets[numBuckets] = totalTime / num;
802                 numBuckets++;
803                 numToAverage *= 2;
804                 i += num;
805             }
806             if (numBuckets < 1) {
807                 return -1;
808             }
809             long averageTime = buckets[numBuckets-1];
810             for (i=numBuckets-2; i>=0; i--) {
811                 averageTime = (averageTime + buckets[i]) / 2;
812             }
813             return averageTime;
814             */
815         }
816 
computeTimeEstimate(long modesOfInterest, long modeValues, int[] outNumOfInterest)817         public long computeTimeEstimate(long modesOfInterest, long modeValues,
818                 int[] outNumOfInterest) {
819             final long[] steps = mStepDurations;
820             final int count = mNumStepDurations;
821             if (count <= 0) {
822                 return -1;
823             }
824             long total = 0;
825             int numOfInterest = 0;
826             for (int i=0; i<count; i++) {
827                 long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK)
828                         >> STEP_LEVEL_INITIAL_MODE_SHIFT;
829                 long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK)
830                         >> STEP_LEVEL_MODIFIED_MODE_SHIFT;
831                 // If the modes of interest didn't change during this step period...
832                 if ((modMode&modesOfInterest) == 0) {
833                     // And the mode values during this period match those we are measuring...
834                     if ((initMode&modesOfInterest) == modeValues) {
835                         // Then this can be used to estimate the total time!
836                         numOfInterest++;
837                         total += steps[i] & STEP_LEVEL_TIME_MASK;
838                     }
839                 }
840             }
841             if (numOfInterest <= 0) {
842                 return -1;
843             }
844 
845             if (outNumOfInterest != null) {
846                 outNumOfInterest[0] = numOfInterest;
847             }
848 
849             // The estimated time is the average time we spend in each level, multipled
850             // by 100 -- the total number of battery levels
851             return (total / numOfInterest) * 100;
852         }
853 
addLevelSteps(int numStepLevels, long modeBits, long elapsedRealtime)854         public void addLevelSteps(int numStepLevels, long modeBits, long elapsedRealtime) {
855             int stepCount = mNumStepDurations;
856             final long lastStepTime = mLastStepTime;
857             if (lastStepTime >= 0 && numStepLevels > 0) {
858                 final long[] steps = mStepDurations;
859                 long duration = elapsedRealtime - lastStepTime;
860                 for (int i=0; i<numStepLevels; i++) {
861                     System.arraycopy(steps, 0, steps, 1, steps.length-1);
862                     long thisDuration = duration / (numStepLevels-i);
863                     duration -= thisDuration;
864                     if (thisDuration > STEP_LEVEL_TIME_MASK) {
865                         thisDuration = STEP_LEVEL_TIME_MASK;
866                     }
867                     steps[0] = thisDuration | modeBits;
868                 }
869                 stepCount += numStepLevels;
870                 if (stepCount > steps.length) {
871                     stepCount = steps.length;
872                 }
873             }
874             mNumStepDurations = stepCount;
875             mLastStepTime = elapsedRealtime;
876         }
877 
readFromParcel(Parcel in)878         public void readFromParcel(Parcel in) {
879             final int N = in.readInt();
880             if (N > mStepDurations.length) {
881                 throw new ParcelFormatException("more step durations than available: " + N);
882             }
883             mNumStepDurations = N;
884             for (int i=0; i<N; i++) {
885                 mStepDurations[i] = in.readLong();
886             }
887         }
888 
writeToParcel(Parcel out)889         public void writeToParcel(Parcel out) {
890             final int N = mNumStepDurations;
891             out.writeInt(N);
892             for (int i=0; i<N; i++) {
893                 out.writeLong(mStepDurations[i]);
894             }
895         }
896     }
897 
898     public static final class PackageChange {
899         public String mPackageName;
900         public boolean mUpdate;
901         public int mVersionCode;
902     }
903 
904     public static final class DailyItem {
905         public long mStartTime;
906         public long mEndTime;
907         public LevelStepTracker mDischargeSteps;
908         public LevelStepTracker mChargeSteps;
909         public ArrayList<PackageChange> mPackageChanges;
910     }
911 
getDailyItemLocked(int daysAgo)912     public abstract DailyItem getDailyItemLocked(int daysAgo);
913 
getCurrentDailyStartTime()914     public abstract long getCurrentDailyStartTime();
915 
getNextMinDailyDeadline()916     public abstract long getNextMinDailyDeadline();
917 
getNextMaxDailyDeadline()918     public abstract long getNextMaxDailyDeadline();
919 
920     public final static class HistoryTag {
921         public String string;
922         public int uid;
923 
924         public int poolIdx;
925 
setTo(HistoryTag o)926         public void setTo(HistoryTag o) {
927             string = o.string;
928             uid = o.uid;
929             poolIdx = o.poolIdx;
930         }
931 
setTo(String _string, int _uid)932         public void setTo(String _string, int _uid) {
933             string = _string;
934             uid = _uid;
935             poolIdx = -1;
936         }
937 
writeToParcel(Parcel dest, int flags)938         public void writeToParcel(Parcel dest, int flags) {
939             dest.writeString(string);
940             dest.writeInt(uid);
941         }
942 
readFromParcel(Parcel src)943         public void readFromParcel(Parcel src) {
944             string = src.readString();
945             uid = src.readInt();
946             poolIdx = -1;
947         }
948 
949         @Override
equals(Object o)950         public boolean equals(Object o) {
951             if (this == o) return true;
952             if (o == null || getClass() != o.getClass()) return false;
953 
954             HistoryTag that = (HistoryTag) o;
955 
956             if (uid != that.uid) return false;
957             if (!string.equals(that.string)) return false;
958 
959             return true;
960         }
961 
962         @Override
hashCode()963         public int hashCode() {
964             int result = string.hashCode();
965             result = 31 * result + uid;
966             return result;
967         }
968     }
969 
970     /**
971      * Optional detailed information that can go into a history step.  This is typically
972      * generated each time the battery level changes.
973      */
974     public final static class HistoryStepDetails {
975         // Time (in 1/100 second) spent in user space and the kernel since the last step.
976         public int userTime;
977         public int systemTime;
978 
979         // Top three apps using CPU in the last step, with times in 1/100 second.
980         public int appCpuUid1;
981         public int appCpuUTime1;
982         public int appCpuSTime1;
983         public int appCpuUid2;
984         public int appCpuUTime2;
985         public int appCpuSTime2;
986         public int appCpuUid3;
987         public int appCpuUTime3;
988         public int appCpuSTime3;
989 
990         // Information from /proc/stat
991         public int statUserTime;
992         public int statSystemTime;
993         public int statIOWaitTime;
994         public int statIrqTime;
995         public int statSoftIrqTime;
996         public int statIdlTime;
997 
HistoryStepDetails()998         public HistoryStepDetails() {
999             clear();
1000         }
1001 
clear()1002         public void clear() {
1003             userTime = systemTime = 0;
1004             appCpuUid1 = appCpuUid2 = appCpuUid3 = -1;
1005             appCpuUTime1 = appCpuSTime1 = appCpuUTime2 = appCpuSTime2
1006                     = appCpuUTime3 = appCpuSTime3 = 0;
1007         }
1008 
writeToParcel(Parcel out)1009         public void writeToParcel(Parcel out) {
1010             out.writeInt(userTime);
1011             out.writeInt(systemTime);
1012             out.writeInt(appCpuUid1);
1013             out.writeInt(appCpuUTime1);
1014             out.writeInt(appCpuSTime1);
1015             out.writeInt(appCpuUid2);
1016             out.writeInt(appCpuUTime2);
1017             out.writeInt(appCpuSTime2);
1018             out.writeInt(appCpuUid3);
1019             out.writeInt(appCpuUTime3);
1020             out.writeInt(appCpuSTime3);
1021             out.writeInt(statUserTime);
1022             out.writeInt(statSystemTime);
1023             out.writeInt(statIOWaitTime);
1024             out.writeInt(statIrqTime);
1025             out.writeInt(statSoftIrqTime);
1026             out.writeInt(statIdlTime);
1027         }
1028 
readFromParcel(Parcel in)1029         public void readFromParcel(Parcel in) {
1030             userTime = in.readInt();
1031             systemTime = in.readInt();
1032             appCpuUid1 = in.readInt();
1033             appCpuUTime1 = in.readInt();
1034             appCpuSTime1 = in.readInt();
1035             appCpuUid2 = in.readInt();
1036             appCpuUTime2 = in.readInt();
1037             appCpuSTime2 = in.readInt();
1038             appCpuUid3 = in.readInt();
1039             appCpuUTime3 = in.readInt();
1040             appCpuSTime3 = in.readInt();
1041             statUserTime = in.readInt();
1042             statSystemTime = in.readInt();
1043             statIOWaitTime = in.readInt();
1044             statIrqTime = in.readInt();
1045             statSoftIrqTime = in.readInt();
1046             statIdlTime = in.readInt();
1047         }
1048     }
1049 
1050     public final static class HistoryItem implements Parcelable {
1051         public HistoryItem next;
1052 
1053         // The time of this event in milliseconds, as per SystemClock.elapsedRealtime().
1054         public long time;
1055 
1056         public static final byte CMD_UPDATE = 0;        // These can be written as deltas
1057         public static final byte CMD_NULL = -1;
1058         public static final byte CMD_START = 4;
1059         public static final byte CMD_CURRENT_TIME = 5;
1060         public static final byte CMD_OVERFLOW = 6;
1061         public static final byte CMD_RESET = 7;
1062         public static final byte CMD_SHUTDOWN = 8;
1063 
1064         public byte cmd = CMD_NULL;
1065 
1066         /**
1067          * Return whether the command code is a delta data update.
1068          */
isDeltaData()1069         public boolean isDeltaData() {
1070             return cmd == CMD_UPDATE;
1071         }
1072 
1073         public byte batteryLevel;
1074         public byte batteryStatus;
1075         public byte batteryHealth;
1076         public byte batteryPlugType;
1077 
1078         public short batteryTemperature;
1079         public char batteryVoltage;
1080 
1081         // Constants from SCREEN_BRIGHTNESS_*
1082         public static final int STATE_BRIGHTNESS_SHIFT = 0;
1083         public static final int STATE_BRIGHTNESS_MASK = 0x7;
1084         // Constants from SIGNAL_STRENGTH_*
1085         public static final int STATE_PHONE_SIGNAL_STRENGTH_SHIFT = 3;
1086         public static final int STATE_PHONE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_PHONE_SIGNAL_STRENGTH_SHIFT;
1087         // Constants from ServiceState.STATE_*
1088         public static final int STATE_PHONE_STATE_SHIFT = 6;
1089         public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT;
1090         // Constants from DATA_CONNECTION_*
1091         public static final int STATE_DATA_CONNECTION_SHIFT = 9;
1092         public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT;
1093 
1094         // These states always appear directly in the first int token
1095         // of a delta change; they should be ones that change relatively
1096         // frequently.
1097         public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
1098         public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
1099         public static final int STATE_GPS_ON_FLAG = 1<<29;
1100         public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
1101         public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
1102         public static final int STATE_WIFI_RADIO_ACTIVE_FLAG = 1<<26;
1103         public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
1104         // These are on the lower bits used for the command; if they change
1105         // we need to write another int of data.
1106         public static final int STATE_SENSOR_ON_FLAG = 1<<23;
1107         public static final int STATE_AUDIO_ON_FLAG = 1<<22;
1108         public static final int STATE_PHONE_SCANNING_FLAG = 1<<21;
1109         public static final int STATE_SCREEN_ON_FLAG = 1<<20;       // consider moving to states2
1110         public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; // consider moving to states2
1111         // empty slot
1112         // empty slot
1113         public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<16;
1114 
1115         public static final int MOST_INTERESTING_STATES =
1116             STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG;
1117 
1118         public static final int SETTLE_TO_ZERO_STATES = 0xffff0000 & ~MOST_INTERESTING_STATES;
1119 
1120         public int states;
1121 
1122         // Constants from WIFI_SUPPL_STATE_*
1123         public static final int STATE2_WIFI_SUPPL_STATE_SHIFT = 0;
1124         public static final int STATE2_WIFI_SUPPL_STATE_MASK = 0xf;
1125         // Values for NUM_WIFI_SIGNAL_STRENGTH_BINS
1126         public static final int STATE2_WIFI_SIGNAL_STRENGTH_SHIFT = 4;
1127         public static final int STATE2_WIFI_SIGNAL_STRENGTH_MASK =
1128                 0x7 << STATE2_WIFI_SIGNAL_STRENGTH_SHIFT;
1129 
1130         public static final int STATE2_POWER_SAVE_FLAG = 1<<31;
1131         public static final int STATE2_VIDEO_ON_FLAG = 1<<30;
1132         public static final int STATE2_WIFI_RUNNING_FLAG = 1<<29;
1133         public static final int STATE2_WIFI_ON_FLAG = 1<<28;
1134         public static final int STATE2_FLASHLIGHT_FLAG = 1<<27;
1135         public static final int STATE2_DEVICE_IDLE_FLAG = 1<<26;
1136         public static final int STATE2_CHARGING_FLAG = 1<<25;
1137         public static final int STATE2_PHONE_IN_CALL_FLAG = 1<<24;
1138         public static final int STATE2_BLUETOOTH_ON_FLAG = 1<<23;
1139         public static final int STATE2_CAMERA_FLAG = 1<<22;
1140 
1141         public static final int MOST_INTERESTING_STATES2 =
1142             STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_FLAG
1143             | STATE2_CHARGING_FLAG | STATE2_PHONE_IN_CALL_FLAG | STATE2_BLUETOOTH_ON_FLAG;
1144 
1145         public static final int SETTLE_TO_ZERO_STATES2 = 0xffff0000 & ~MOST_INTERESTING_STATES2;
1146 
1147         public int states2;
1148 
1149         // The wake lock that was acquired at this point.
1150         public HistoryTag wakelockTag;
1151 
1152         // Kernel wakeup reason at this point.
1153         public HistoryTag wakeReasonTag;
1154 
1155         // Non-null when there is more detailed information at this step.
1156         public HistoryStepDetails stepDetails;
1157 
1158         public static final int EVENT_FLAG_START = 0x8000;
1159         public static final int EVENT_FLAG_FINISH = 0x4000;
1160 
1161         // No event in this item.
1162         public static final int EVENT_NONE = 0x0000;
1163         // Event is about a process that is running.
1164         public static final int EVENT_PROC = 0x0001;
1165         // Event is about an application package that is in the foreground.
1166         public static final int EVENT_FOREGROUND = 0x0002;
1167         // Event is about an application package that is at the top of the screen.
1168         public static final int EVENT_TOP = 0x0003;
1169         // Event is about active sync operations.
1170         public static final int EVENT_SYNC = 0x0004;
1171         // Events for all additional wake locks aquired/release within a wake block.
1172         // These are not generated by default.
1173         public static final int EVENT_WAKE_LOCK = 0x0005;
1174         // Event is about an application executing a scheduled job.
1175         public static final int EVENT_JOB = 0x0006;
1176         // Events for users running.
1177         public static final int EVENT_USER_RUNNING = 0x0007;
1178         // Events for foreground user.
1179         public static final int EVENT_USER_FOREGROUND = 0x0008;
1180         // Event for connectivity changed.
1181         public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009;
1182         // Event for becoming active taking us out of idle mode.
1183         public static final int EVENT_ACTIVE = 0x000a;
1184         // Event for a package being installed.
1185         public static final int EVENT_PACKAGE_INSTALLED = 0x000b;
1186         // Event for a package being uninstalled.
1187         public static final int EVENT_PACKAGE_UNINSTALLED = 0x000c;
1188         // Event for a package being uninstalled.
1189         public static final int EVENT_ALARM = 0x000d;
1190         // Record that we have decided we need to collect new stats data.
1191         public static final int EVENT_COLLECT_EXTERNAL_STATS = 0x000e;
1192         // Event for a package becoming inactive due to being unused for a period of time.
1193         public static final int EVENT_PACKAGE_INACTIVE = 0x000f;
1194         // Event for a package becoming active due to an interaction.
1195         public static final int EVENT_PACKAGE_ACTIVE = 0x0010;
1196         // Event for a package being on the temporary whitelist.
1197         public static final int EVENT_TEMP_WHITELIST = 0x0011;
1198         // Event for the screen waking up.
1199         public static final int EVENT_SCREEN_WAKE_UP = 0x0012;
1200 
1201         // Number of event types.
1202         public static final int EVENT_COUNT = 0x0013;
1203         // Mask to extract out only the type part of the event.
1204         public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
1205 
1206         public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
1207         public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
1208         public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START;
1209         public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
1210         public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
1211         public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
1212         public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
1213         public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
1214         public static final int EVENT_WAKE_LOCK_START = EVENT_WAKE_LOCK | EVENT_FLAG_START;
1215         public static final int EVENT_WAKE_LOCK_FINISH = EVENT_WAKE_LOCK | EVENT_FLAG_FINISH;
1216         public static final int EVENT_JOB_START = EVENT_JOB | EVENT_FLAG_START;
1217         public static final int EVENT_JOB_FINISH = EVENT_JOB | EVENT_FLAG_FINISH;
1218         public static final int EVENT_USER_RUNNING_START = EVENT_USER_RUNNING | EVENT_FLAG_START;
1219         public static final int EVENT_USER_RUNNING_FINISH = EVENT_USER_RUNNING | EVENT_FLAG_FINISH;
1220         public static final int EVENT_USER_FOREGROUND_START =
1221                 EVENT_USER_FOREGROUND | EVENT_FLAG_START;
1222         public static final int EVENT_USER_FOREGROUND_FINISH =
1223                 EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
1224         public static final int EVENT_ALARM_START = EVENT_ALARM | EVENT_FLAG_START;
1225         public static final int EVENT_ALARM_FINISH = EVENT_ALARM | EVENT_FLAG_FINISH;
1226         public static final int EVENT_TEMP_WHITELIST_START =
1227                 EVENT_TEMP_WHITELIST | EVENT_FLAG_START;
1228         public static final int EVENT_TEMP_WHITELIST_FINISH =
1229                 EVENT_TEMP_WHITELIST | EVENT_FLAG_FINISH;
1230 
1231         // For CMD_EVENT.
1232         public int eventCode;
1233         public HistoryTag eventTag;
1234 
1235         // Only set for CMD_CURRENT_TIME or CMD_RESET, as per System.currentTimeMillis().
1236         public long currentTime;
1237 
1238         // Meta-data when reading.
1239         public int numReadInts;
1240 
1241         // Pre-allocated objects.
1242         public final HistoryTag localWakelockTag = new HistoryTag();
1243         public final HistoryTag localWakeReasonTag = new HistoryTag();
1244         public final HistoryTag localEventTag = new HistoryTag();
1245 
HistoryItem()1246         public HistoryItem() {
1247         }
1248 
HistoryItem(long time, Parcel src)1249         public HistoryItem(long time, Parcel src) {
1250             this.time = time;
1251             numReadInts = 2;
1252             readFromParcel(src);
1253         }
1254 
describeContents()1255         public int describeContents() {
1256             return 0;
1257         }
1258 
writeToParcel(Parcel dest, int flags)1259         public void writeToParcel(Parcel dest, int flags) {
1260             dest.writeLong(time);
1261             int bat = (((int)cmd)&0xff)
1262                     | ((((int)batteryLevel)<<8)&0xff00)
1263                     | ((((int)batteryStatus)<<16)&0xf0000)
1264                     | ((((int)batteryHealth)<<20)&0xf00000)
1265                     | ((((int)batteryPlugType)<<24)&0xf000000)
1266                     | (wakelockTag != null ? 0x10000000 : 0)
1267                     | (wakeReasonTag != null ? 0x20000000 : 0)
1268                     | (eventCode != EVENT_NONE ? 0x40000000 : 0);
1269             dest.writeInt(bat);
1270             bat = (((int)batteryTemperature)&0xffff)
1271                     | ((((int)batteryVoltage)<<16)&0xffff0000);
1272             dest.writeInt(bat);
1273             dest.writeInt(states);
1274             dest.writeInt(states2);
1275             if (wakelockTag != null) {
1276                 wakelockTag.writeToParcel(dest, flags);
1277             }
1278             if (wakeReasonTag != null) {
1279                 wakeReasonTag.writeToParcel(dest, flags);
1280             }
1281             if (eventCode != EVENT_NONE) {
1282                 dest.writeInt(eventCode);
1283                 eventTag.writeToParcel(dest, flags);
1284             }
1285             if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
1286                 dest.writeLong(currentTime);
1287             }
1288         }
1289 
readFromParcel(Parcel src)1290         public void readFromParcel(Parcel src) {
1291             int start = src.dataPosition();
1292             int bat = src.readInt();
1293             cmd = (byte)(bat&0xff);
1294             batteryLevel = (byte)((bat>>8)&0xff);
1295             batteryStatus = (byte)((bat>>16)&0xf);
1296             batteryHealth = (byte)((bat>>20)&0xf);
1297             batteryPlugType = (byte)((bat>>24)&0xf);
1298             int bat2 = src.readInt();
1299             batteryTemperature = (short)(bat2&0xffff);
1300             batteryVoltage = (char)((bat2>>16)&0xffff);
1301             states = src.readInt();
1302             states2 = src.readInt();
1303             if ((bat&0x10000000) != 0) {
1304                 wakelockTag = localWakelockTag;
1305                 wakelockTag.readFromParcel(src);
1306             } else {
1307                 wakelockTag = null;
1308             }
1309             if ((bat&0x20000000) != 0) {
1310                 wakeReasonTag = localWakeReasonTag;
1311                 wakeReasonTag.readFromParcel(src);
1312             } else {
1313                 wakeReasonTag = null;
1314             }
1315             if ((bat&0x40000000) != 0) {
1316                 eventCode = src.readInt();
1317                 eventTag = localEventTag;
1318                 eventTag.readFromParcel(src);
1319             } else {
1320                 eventCode = EVENT_NONE;
1321                 eventTag = null;
1322             }
1323             if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
1324                 currentTime = src.readLong();
1325             } else {
1326                 currentTime = 0;
1327             }
1328             numReadInts += (src.dataPosition()-start)/4;
1329         }
1330 
clear()1331         public void clear() {
1332             time = 0;
1333             cmd = CMD_NULL;
1334             batteryLevel = 0;
1335             batteryStatus = 0;
1336             batteryHealth = 0;
1337             batteryPlugType = 0;
1338             batteryTemperature = 0;
1339             batteryVoltage = 0;
1340             states = 0;
1341             states2 = 0;
1342             wakelockTag = null;
1343             wakeReasonTag = null;
1344             eventCode = EVENT_NONE;
1345             eventTag = null;
1346         }
1347 
setTo(HistoryItem o)1348         public void setTo(HistoryItem o) {
1349             time = o.time;
1350             cmd = o.cmd;
1351             setToCommon(o);
1352         }
1353 
setTo(long time, byte cmd, HistoryItem o)1354         public void setTo(long time, byte cmd, HistoryItem o) {
1355             this.time = time;
1356             this.cmd = cmd;
1357             setToCommon(o);
1358         }
1359 
setToCommon(HistoryItem o)1360         private void setToCommon(HistoryItem o) {
1361             batteryLevel = o.batteryLevel;
1362             batteryStatus = o.batteryStatus;
1363             batteryHealth = o.batteryHealth;
1364             batteryPlugType = o.batteryPlugType;
1365             batteryTemperature = o.batteryTemperature;
1366             batteryVoltage = o.batteryVoltage;
1367             states = o.states;
1368             states2 = o.states2;
1369             if (o.wakelockTag != null) {
1370                 wakelockTag = localWakelockTag;
1371                 wakelockTag.setTo(o.wakelockTag);
1372             } else {
1373                 wakelockTag = null;
1374             }
1375             if (o.wakeReasonTag != null) {
1376                 wakeReasonTag = localWakeReasonTag;
1377                 wakeReasonTag.setTo(o.wakeReasonTag);
1378             } else {
1379                 wakeReasonTag = null;
1380             }
1381             eventCode = o.eventCode;
1382             if (o.eventTag != null) {
1383                 eventTag = localEventTag;
1384                 eventTag.setTo(o.eventTag);
1385             } else {
1386                 eventTag = null;
1387             }
1388             currentTime = o.currentTime;
1389         }
1390 
sameNonEvent(HistoryItem o)1391         public boolean sameNonEvent(HistoryItem o) {
1392             return batteryLevel == o.batteryLevel
1393                     && batteryStatus == o.batteryStatus
1394                     && batteryHealth == o.batteryHealth
1395                     && batteryPlugType == o.batteryPlugType
1396                     && batteryTemperature == o.batteryTemperature
1397                     && batteryVoltage == o.batteryVoltage
1398                     && states == o.states
1399                     && states2 == o.states2
1400                     && currentTime == o.currentTime;
1401         }
1402 
same(HistoryItem o)1403         public boolean same(HistoryItem o) {
1404             if (!sameNonEvent(o) || eventCode != o.eventCode) {
1405                 return false;
1406             }
1407             if (wakelockTag != o.wakelockTag) {
1408                 if (wakelockTag == null || o.wakelockTag == null) {
1409                     return false;
1410                 }
1411                 if (!wakelockTag.equals(o.wakelockTag)) {
1412                     return false;
1413                 }
1414             }
1415             if (wakeReasonTag != o.wakeReasonTag) {
1416                 if (wakeReasonTag == null || o.wakeReasonTag == null) {
1417                     return false;
1418                 }
1419                 if (!wakeReasonTag.equals(o.wakeReasonTag)) {
1420                     return false;
1421                 }
1422             }
1423             if (eventTag != o.eventTag) {
1424                 if (eventTag == null || o.eventTag == null) {
1425                     return false;
1426                 }
1427                 if (!eventTag.equals(o.eventTag)) {
1428                     return false;
1429                 }
1430             }
1431             return true;
1432         }
1433     }
1434 
1435     public final static class HistoryEventTracker {
1436         private final HashMap<String, SparseIntArray>[] mActiveEvents
1437                 = (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
1438 
updateState(int code, String name, int uid, int poolIdx)1439         public boolean updateState(int code, String name, int uid, int poolIdx) {
1440             if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
1441                 int idx = code&HistoryItem.EVENT_TYPE_MASK;
1442                 HashMap<String, SparseIntArray> active = mActiveEvents[idx];
1443                 if (active == null) {
1444                     active = new HashMap<>();
1445                     mActiveEvents[idx] = active;
1446                 }
1447                 SparseIntArray uids = active.get(name);
1448                 if (uids == null) {
1449                     uids = new SparseIntArray();
1450                     active.put(name, uids);
1451                 }
1452                 if (uids.indexOfKey(uid) >= 0) {
1453                     // Already set, nothing to do!
1454                     return false;
1455                 }
1456                 uids.put(uid, poolIdx);
1457             } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
1458                 int idx = code&HistoryItem.EVENT_TYPE_MASK;
1459                 HashMap<String, SparseIntArray> active = mActiveEvents[idx];
1460                 if (active == null) {
1461                     // not currently active, nothing to do.
1462                     return false;
1463                 }
1464                 SparseIntArray uids = active.get(name);
1465                 if (uids == null) {
1466                     // not currently active, nothing to do.
1467                     return false;
1468                 }
1469                 idx = uids.indexOfKey(uid);
1470                 if (idx < 0) {
1471                     // not currently active, nothing to do.
1472                     return false;
1473                 }
1474                 uids.removeAt(idx);
1475                 if (uids.size() <= 0) {
1476                     active.remove(name);
1477                 }
1478             }
1479             return true;
1480         }
1481 
removeEvents(int code)1482         public void removeEvents(int code) {
1483             int idx = code&HistoryItem.EVENT_TYPE_MASK;
1484             mActiveEvents[idx] = null;
1485         }
1486 
getStateForEvent(int code)1487         public HashMap<String, SparseIntArray> getStateForEvent(int code) {
1488             return mActiveEvents[code];
1489         }
1490     }
1491 
1492     public static final class BitDescription {
1493         public final int mask;
1494         public final int shift;
1495         public final String name;
1496         public final String shortName;
1497         public final String[] values;
1498         public final String[] shortValues;
1499 
BitDescription(int mask, String name, String shortName)1500         public BitDescription(int mask, String name, String shortName) {
1501             this.mask = mask;
1502             this.shift = -1;
1503             this.name = name;
1504             this.shortName = shortName;
1505             this.values = null;
1506             this.shortValues = null;
1507         }
1508 
BitDescription(int mask, int shift, String name, String shortName, String[] values, String[] shortValues)1509         public BitDescription(int mask, int shift, String name, String shortName,
1510                 String[] values, String[] shortValues) {
1511             this.mask = mask;
1512             this.shift = shift;
1513             this.name = name;
1514             this.shortName = shortName;
1515             this.values = values;
1516             this.shortValues = shortValues;
1517         }
1518     }
1519 
1520     /**
1521      * Don't allow any more batching in to the current history event.  This
1522      * is called when printing partial histories, so to ensure that the next
1523      * history event will go in to a new batch after what was printed in the
1524      * last partial history.
1525      */
commitCurrentHistoryBatchLocked()1526     public abstract void commitCurrentHistoryBatchLocked();
1527 
getHistoryTotalSize()1528     public abstract int getHistoryTotalSize();
1529 
getHistoryUsedSize()1530     public abstract int getHistoryUsedSize();
1531 
startIteratingHistoryLocked()1532     public abstract boolean startIteratingHistoryLocked();
1533 
getHistoryStringPoolSize()1534     public abstract int getHistoryStringPoolSize();
1535 
getHistoryStringPoolBytes()1536     public abstract int getHistoryStringPoolBytes();
1537 
getHistoryTagPoolString(int index)1538     public abstract String getHistoryTagPoolString(int index);
1539 
getHistoryTagPoolUid(int index)1540     public abstract int getHistoryTagPoolUid(int index);
1541 
getNextHistoryLocked(HistoryItem out)1542     public abstract boolean getNextHistoryLocked(HistoryItem out);
1543 
finishIteratingHistoryLocked()1544     public abstract void finishIteratingHistoryLocked();
1545 
startIteratingOldHistoryLocked()1546     public abstract boolean startIteratingOldHistoryLocked();
1547 
getNextOldHistoryLocked(HistoryItem out)1548     public abstract boolean getNextOldHistoryLocked(HistoryItem out);
1549 
finishIteratingOldHistoryLocked()1550     public abstract void finishIteratingOldHistoryLocked();
1551 
1552     /**
1553      * Return the base time offset for the battery history.
1554      */
getHistoryBaseTime()1555     public abstract long getHistoryBaseTime();
1556 
1557     /**
1558      * Returns the number of times the device has been started.
1559      */
getStartCount()1560     public abstract int getStartCount();
1561 
1562     /**
1563      * Returns the time in microseconds that the screen has been on while the device was
1564      * running on battery.
1565      *
1566      * {@hide}
1567      */
getScreenOnTime(long elapsedRealtimeUs, int which)1568     public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
1569 
1570     /**
1571      * Returns the number of times the screen was turned on.
1572      *
1573      * {@hide}
1574      */
getScreenOnCount(int which)1575     public abstract int getScreenOnCount(int which);
1576 
getInteractiveTime(long elapsedRealtimeUs, int which)1577     public abstract long getInteractiveTime(long elapsedRealtimeUs, int which);
1578 
1579     public static final int SCREEN_BRIGHTNESS_DARK = 0;
1580     public static final int SCREEN_BRIGHTNESS_DIM = 1;
1581     public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
1582     public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
1583     public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
1584 
1585     static final String[] SCREEN_BRIGHTNESS_NAMES = {
1586         "dark", "dim", "medium", "light", "bright"
1587     };
1588 
1589     static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
1590         "0", "1", "2", "3", "4"
1591     };
1592 
1593     public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
1594 
1595     /**
1596      * Returns the time in microseconds that the screen has been on with
1597      * the given brightness
1598      *
1599      * {@hide}
1600      */
getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)1601     public abstract long getScreenBrightnessTime(int brightnessBin,
1602             long elapsedRealtimeUs, int which);
1603 
1604     /**
1605      * Returns the time in microseconds that power save mode has been enabled while the device was
1606      * running on battery.
1607      *
1608      * {@hide}
1609      */
getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)1610     public abstract long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which);
1611 
1612     /**
1613      * Returns the number of times that power save mode was enabled.
1614      *
1615      * {@hide}
1616      */
getPowerSaveModeEnabledCount(int which)1617     public abstract int getPowerSaveModeEnabledCount(int which);
1618 
1619     /**
1620      * Returns the time in microseconds that device has been in idle mode while
1621      * running on battery.
1622      *
1623      * {@hide}
1624      */
getDeviceIdleModeEnabledTime(long elapsedRealtimeUs, int which)1625     public abstract long getDeviceIdleModeEnabledTime(long elapsedRealtimeUs, int which);
1626 
1627     /**
1628      * Returns the number of times that the devie has gone in to idle mode.
1629      *
1630      * {@hide}
1631      */
getDeviceIdleModeEnabledCount(int which)1632     public abstract int getDeviceIdleModeEnabledCount(int which);
1633 
1634     /**
1635      * Returns the time in microseconds that device has been in idling while on
1636      * battery.  This is broader than {@link #getDeviceIdleModeEnabledTime} -- it
1637      * counts all of the time that we consider the device to be idle, whether or not
1638      * it is currently in the actual device idle mode.
1639      *
1640      * {@hide}
1641      */
getDeviceIdlingTime(long elapsedRealtimeUs, int which)1642     public abstract long getDeviceIdlingTime(long elapsedRealtimeUs, int which);
1643 
1644     /**
1645      * Returns the number of times that the devie has started idling.
1646      *
1647      * {@hide}
1648      */
getDeviceIdlingCount(int which)1649     public abstract int getDeviceIdlingCount(int which);
1650 
1651     /**
1652      * Returns the number of times that connectivity state changed.
1653      *
1654      * {@hide}
1655      */
getNumConnectivityChange(int which)1656     public abstract int getNumConnectivityChange(int which);
1657 
1658     /**
1659      * Returns the time in microseconds that the phone has been on while the device was
1660      * running on battery.
1661      *
1662      * {@hide}
1663      */
getPhoneOnTime(long elapsedRealtimeUs, int which)1664     public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
1665 
1666     /**
1667      * Returns the number of times a phone call was activated.
1668      *
1669      * {@hide}
1670      */
getPhoneOnCount(int which)1671     public abstract int getPhoneOnCount(int which);
1672 
1673     /**
1674      * Returns the time in microseconds that the phone has been running with
1675      * the given signal strength.
1676      *
1677      * {@hide}
1678      */
getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)1679     public abstract long getPhoneSignalStrengthTime(int strengthBin,
1680             long elapsedRealtimeUs, int which);
1681 
1682     /**
1683      * Returns the time in microseconds that the phone has been trying to
1684      * acquire a signal.
1685      *
1686      * {@hide}
1687      */
getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)1688     public abstract long getPhoneSignalScanningTime(
1689             long elapsedRealtimeUs, int which);
1690 
1691     /**
1692      * Returns the number of times the phone has entered the given signal strength.
1693      *
1694      * {@hide}
1695      */
getPhoneSignalStrengthCount(int strengthBin, int which)1696     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
1697 
1698     /**
1699      * Returns the time in microseconds that the mobile network has been active
1700      * (in a high power state).
1701      *
1702      * {@hide}
1703      */
getMobileRadioActiveTime(long elapsedRealtimeUs, int which)1704     public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which);
1705 
1706     /**
1707      * Returns the number of times that the mobile network has transitioned to the
1708      * active state.
1709      *
1710      * {@hide}
1711      */
getMobileRadioActiveCount(int which)1712     public abstract int getMobileRadioActiveCount(int which);
1713 
1714     /**
1715      * Returns the time in microseconds that is the difference between the mobile radio
1716      * time we saw based on the elapsed timestamp when going down vs. the given time stamp
1717      * from the radio.
1718      *
1719      * {@hide}
1720      */
getMobileRadioActiveAdjustedTime(int which)1721     public abstract long getMobileRadioActiveAdjustedTime(int which);
1722 
1723     /**
1724      * Returns the time in microseconds that the mobile network has been active
1725      * (in a high power state) but not being able to blame on an app.
1726      *
1727      * {@hide}
1728      */
getMobileRadioActiveUnknownTime(int which)1729     public abstract long getMobileRadioActiveUnknownTime(int which);
1730 
1731     /**
1732      * Return count of number of times radio was up that could not be blamed on apps.
1733      *
1734      * {@hide}
1735      */
getMobileRadioActiveUnknownCount(int which)1736     public abstract int getMobileRadioActiveUnknownCount(int which);
1737 
1738     public static final int DATA_CONNECTION_NONE = 0;
1739     public static final int DATA_CONNECTION_GPRS = 1;
1740     public static final int DATA_CONNECTION_EDGE = 2;
1741     public static final int DATA_CONNECTION_UMTS = 3;
1742     public static final int DATA_CONNECTION_CDMA = 4;
1743     public static final int DATA_CONNECTION_EVDO_0 = 5;
1744     public static final int DATA_CONNECTION_EVDO_A = 6;
1745     public static final int DATA_CONNECTION_1xRTT = 7;
1746     public static final int DATA_CONNECTION_HSDPA = 8;
1747     public static final int DATA_CONNECTION_HSUPA = 9;
1748     public static final int DATA_CONNECTION_HSPA = 10;
1749     public static final int DATA_CONNECTION_IDEN = 11;
1750     public static final int DATA_CONNECTION_EVDO_B = 12;
1751     public static final int DATA_CONNECTION_LTE = 13;
1752     public static final int DATA_CONNECTION_EHRPD = 14;
1753     public static final int DATA_CONNECTION_HSPAP = 15;
1754     public static final int DATA_CONNECTION_OTHER = 16;
1755 
1756     static final String[] DATA_CONNECTION_NAMES = {
1757         "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
1758         "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
1759         "ehrpd", "hspap", "other"
1760     };
1761 
1762     public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
1763 
1764     /**
1765      * Returns the time in microseconds that the phone has been running with
1766      * the given data connection.
1767      *
1768      * {@hide}
1769      */
getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)1770     public abstract long getPhoneDataConnectionTime(int dataType,
1771             long elapsedRealtimeUs, int which);
1772 
1773     /**
1774      * Returns the number of times the phone has entered the given data
1775      * connection type.
1776      *
1777      * {@hide}
1778      */
getPhoneDataConnectionCount(int dataType, int which)1779     public abstract int getPhoneDataConnectionCount(int dataType, int which);
1780 
1781     public static final int WIFI_SUPPL_STATE_INVALID = 0;
1782     public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1;
1783     public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2;
1784     public static final int WIFI_SUPPL_STATE_INACTIVE = 3;
1785     public static final int WIFI_SUPPL_STATE_SCANNING = 4;
1786     public static final int WIFI_SUPPL_STATE_AUTHENTICATING = 5;
1787     public static final int WIFI_SUPPL_STATE_ASSOCIATING = 6;
1788     public static final int WIFI_SUPPL_STATE_ASSOCIATED = 7;
1789     public static final int WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE = 8;
1790     public static final int WIFI_SUPPL_STATE_GROUP_HANDSHAKE = 9;
1791     public static final int WIFI_SUPPL_STATE_COMPLETED = 10;
1792     public static final int WIFI_SUPPL_STATE_DORMANT = 11;
1793     public static final int WIFI_SUPPL_STATE_UNINITIALIZED = 12;
1794 
1795     public static final int NUM_WIFI_SUPPL_STATES = WIFI_SUPPL_STATE_UNINITIALIZED+1;
1796 
1797     static final String[] WIFI_SUPPL_STATE_NAMES = {
1798         "invalid", "disconn", "disabled", "inactive", "scanning",
1799         "authenticating", "associating", "associated", "4-way-handshake",
1800         "group-handshake", "completed", "dormant", "uninit"
1801     };
1802 
1803     static final String[] WIFI_SUPPL_STATE_SHORT_NAMES = {
1804         "inv", "dsc", "dis", "inact", "scan",
1805         "auth", "ascing", "asced", "4-way",
1806         "group", "compl", "dorm", "uninit"
1807     };
1808 
1809     public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
1810             = new BitDescription[] {
1811         new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
1812         new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
1813         new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
1814         new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
1815         new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
1816         new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
1817         new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
1818         new BitDescription(HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG, "wifi_radio", "Wr"),
1819         new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
1820         new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
1821         new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
1822         new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
1823         new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
1824         new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
1825                 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
1826                 DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
1827         new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
1828                 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
1829                 new String[] {"in", "out", "emergency", "off"},
1830                 new String[] {"in", "out", "em", "off"}),
1831         new BitDescription(HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK,
1832                 HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT, "phone_signal_strength", "Pss",
1833                 SignalStrength.SIGNAL_STRENGTH_NAMES,
1834                 new String[] { "0", "1", "2", "3", "4" }),
1835         new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
1836                 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
1837                 SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
1838     };
1839 
1840     public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
1841             = new BitDescription[] {
1842         new BitDescription(HistoryItem.STATE2_POWER_SAVE_FLAG, "power_save", "ps"),
1843         new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
1844         new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Ww"),
1845         new BitDescription(HistoryItem.STATE2_WIFI_ON_FLAG, "wifi", "W"),
1846         new BitDescription(HistoryItem.STATE2_FLASHLIGHT_FLAG, "flashlight", "fl"),
1847         new BitDescription(HistoryItem.STATE2_DEVICE_IDLE_FLAG, "device_idle", "di"),
1848         new BitDescription(HistoryItem.STATE2_CHARGING_FLAG, "charging", "ch"),
1849         new BitDescription(HistoryItem.STATE2_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
1850         new BitDescription(HistoryItem.STATE2_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
1851         new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
1852                 HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT, "wifi_signal_strength", "Wss",
1853                 new String[] { "0", "1", "2", "3", "4" },
1854                 new String[] { "0", "1", "2", "3", "4" }),
1855         new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK,
1856                 HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp",
1857                 WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES),
1858         new BitDescription(HistoryItem.STATE2_CAMERA_FLAG, "camera", "ca"),
1859     };
1860 
1861     public static final String[] HISTORY_EVENT_NAMES = new String[] {
1862             "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
1863             "active", "pkginst", "pkgunin", "alarm", "stats", "inactive", "active", "tmpwhitelist",
1864             "screenwake",
1865     };
1866 
1867     public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
1868             "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
1869             "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa", "Etw",
1870             "Esw",
1871     };
1872 
1873     /**
1874      * Returns the time in microseconds that wifi has been on while the device was
1875      * running on battery.
1876      *
1877      * {@hide}
1878      */
getWifiOnTime(long elapsedRealtimeUs, int which)1879     public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
1880 
1881     /**
1882      * Returns the time in microseconds that wifi has been on and the driver has
1883      * been in the running state while the device was running on battery.
1884      *
1885      * {@hide}
1886      */
getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)1887     public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
1888 
1889     public static final int WIFI_STATE_OFF = 0;
1890     public static final int WIFI_STATE_OFF_SCANNING = 1;
1891     public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
1892     public static final int WIFI_STATE_ON_DISCONNECTED = 3;
1893     public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
1894     public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
1895     public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
1896     public static final int WIFI_STATE_SOFT_AP = 7;
1897 
1898     static final String[] WIFI_STATE_NAMES = {
1899         "off", "scanning", "no_net", "disconn",
1900         "sta", "p2p", "sta_p2p", "soft_ap"
1901     };
1902 
1903     public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1;
1904 
1905     /**
1906      * Returns the time in microseconds that WiFi has been running in the given state.
1907      *
1908      * {@hide}
1909      */
getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)1910     public abstract long getWifiStateTime(int wifiState,
1911             long elapsedRealtimeUs, int which);
1912 
1913     /**
1914      * Returns the number of times that WiFi has entered the given state.
1915      *
1916      * {@hide}
1917      */
getWifiStateCount(int wifiState, int which)1918     public abstract int getWifiStateCount(int wifiState, int which);
1919 
1920     /**
1921      * Returns the time in microseconds that the wifi supplicant has been
1922      * in a given state.
1923      *
1924      * {@hide}
1925      */
getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)1926     public abstract long getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which);
1927 
1928     /**
1929      * Returns the number of times that the wifi supplicant has transitioned
1930      * to a given state.
1931      *
1932      * {@hide}
1933      */
getWifiSupplStateCount(int state, int which)1934     public abstract int getWifiSupplStateCount(int state, int which);
1935 
1936     public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5;
1937 
1938     /**
1939      * Returns the time in microseconds that WIFI has been running with
1940      * the given signal strength.
1941      *
1942      * {@hide}
1943      */
getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)1944     public abstract long getWifiSignalStrengthTime(int strengthBin,
1945             long elapsedRealtimeUs, int which);
1946 
1947     /**
1948      * Returns the number of times WIFI has entered the given signal strength.
1949      *
1950      * {@hide}
1951      */
getWifiSignalStrengthCount(int strengthBin, int which)1952     public abstract int getWifiSignalStrengthCount(int strengthBin, int which);
1953 
1954     /**
1955      * Returns the time in microseconds that the flashlight has been on while the device was
1956      * running on battery.
1957      *
1958      * {@hide}
1959      */
getFlashlightOnTime(long elapsedRealtimeUs, int which)1960     public abstract long getFlashlightOnTime(long elapsedRealtimeUs, int which);
1961 
1962     /**
1963      * Returns the number of times that the flashlight has been turned on while the device was
1964      * running on battery.
1965      *
1966      * {@hide}
1967      */
getFlashlightOnCount(int which)1968     public abstract long getFlashlightOnCount(int which);
1969 
1970     /**
1971      * Returns the time in microseconds that the camera has been on while the device was
1972      * running on battery.
1973      *
1974      * {@hide}
1975      */
getCameraOnTime(long elapsedRealtimeUs, int which)1976     public abstract long getCameraOnTime(long elapsedRealtimeUs, int which);
1977 
1978 
1979     public static final int NETWORK_MOBILE_RX_DATA = 0;
1980     public static final int NETWORK_MOBILE_TX_DATA = 1;
1981     public static final int NETWORK_WIFI_RX_DATA = 2;
1982     public static final int NETWORK_WIFI_TX_DATA = 3;
1983     public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1;
1984 
getNetworkActivityBytes(int type, int which)1985     public abstract long getNetworkActivityBytes(int type, int which);
getNetworkActivityPackets(int type, int which)1986     public abstract long getNetworkActivityPackets(int type, int which);
1987 
1988     public static final int CONTROLLER_IDLE_TIME = 0;
1989     public static final int CONTROLLER_RX_TIME = 1;
1990     public static final int CONTROLLER_TX_TIME = 2;
1991     public static final int CONTROLLER_POWER_DRAIN = 3;
1992     public static final int NUM_CONTROLLER_ACTIVITY_TYPES = CONTROLLER_POWER_DRAIN + 1;
1993 
1994     /**
1995      * Returns true if the BatteryStats object has detailed bluetooth power reports.
1996      * When true, calling {@link #getBluetoothControllerActivity(int, int)} will yield the
1997      * actual power data.
1998      */
hasBluetoothActivityReporting()1999     public abstract boolean hasBluetoothActivityReporting();
2000 
2001     /**
2002      * For {@link #CONTROLLER_IDLE_TIME}, {@link #CONTROLLER_RX_TIME}, and
2003      * {@link #CONTROLLER_TX_TIME}, returns the time spent (in milliseconds) in the
2004      * respective state.
2005      * For {@link #CONTROLLER_POWER_DRAIN}, returns the power used by the controller in
2006      * milli-ampere-milliseconds (mAms).
2007      */
getBluetoothControllerActivity(int type, int which)2008     public abstract long getBluetoothControllerActivity(int type, int which);
2009 
2010     /**
2011      * Returns true if the BatteryStats object has detailed WiFi power reports.
2012      * When true, calling {@link #getWifiControllerActivity(int, int)} will yield the
2013      * actual power data.
2014      */
hasWifiActivityReporting()2015     public abstract boolean hasWifiActivityReporting();
2016 
2017     /**
2018      * For {@link #CONTROLLER_IDLE_TIME}, {@link #CONTROLLER_RX_TIME}, and
2019      * {@link #CONTROLLER_TX_TIME}, returns the time spent (in milliseconds) in the
2020      * respective state.
2021      * For {@link #CONTROLLER_POWER_DRAIN}, returns the power used by the controller in
2022      * milli-ampere-milliseconds (mAms).
2023      */
getWifiControllerActivity(int type, int which)2024     public abstract long getWifiControllerActivity(int type, int which);
2025 
2026     /**
2027      * Return the wall clock time when battery stats data collection started.
2028      */
getStartClockTime()2029     public abstract long getStartClockTime();
2030 
2031     /**
2032      * Return platform version tag that we were running in when the battery stats started.
2033      */
getStartPlatformVersion()2034     public abstract String getStartPlatformVersion();
2035 
2036     /**
2037      * Return platform version tag that we were running in when the battery stats ended.
2038      */
getEndPlatformVersion()2039     public abstract String getEndPlatformVersion();
2040 
2041     /**
2042      * Return the internal version code of the parcelled format.
2043      */
getParcelVersion()2044     public abstract int getParcelVersion();
2045 
2046     /**
2047      * Return whether we are currently running on battery.
2048      */
getIsOnBattery()2049     public abstract boolean getIsOnBattery();
2050 
2051     /**
2052      * Returns a SparseArray containing the statistics for each uid.
2053      */
getUidStats()2054     public abstract SparseArray<? extends Uid> getUidStats();
2055 
2056     /**
2057      * Returns the current battery uptime in microseconds.
2058      *
2059      * @param curTime the amount of elapsed realtime in microseconds.
2060      */
getBatteryUptime(long curTime)2061     public abstract long getBatteryUptime(long curTime);
2062 
2063     /**
2064      * Returns the current battery realtime in microseconds.
2065      *
2066      * @param curTime the amount of elapsed realtime in microseconds.
2067      */
getBatteryRealtime(long curTime)2068     public abstract long getBatteryRealtime(long curTime);
2069 
2070     /**
2071      * Returns the battery percentage level at the last time the device was unplugged from power, or
2072      * the last time it booted on battery power.
2073      */
getDischargeStartLevel()2074     public abstract int getDischargeStartLevel();
2075 
2076     /**
2077      * Returns the current battery percentage level if we are in a discharge cycle, otherwise
2078      * returns the level at the last plug event.
2079      */
getDischargeCurrentLevel()2080     public abstract int getDischargeCurrentLevel();
2081 
2082     /**
2083      * Get the amount the battery has discharged since the stats were
2084      * last reset after charging, as a lower-end approximation.
2085      */
getLowDischargeAmountSinceCharge()2086     public abstract int getLowDischargeAmountSinceCharge();
2087 
2088     /**
2089      * Get the amount the battery has discharged since the stats were
2090      * last reset after charging, as an upper-end approximation.
2091      */
getHighDischargeAmountSinceCharge()2092     public abstract int getHighDischargeAmountSinceCharge();
2093 
2094     /**
2095      * Retrieve the discharge amount over the selected discharge period <var>which</var>.
2096      */
getDischargeAmount(int which)2097     public abstract int getDischargeAmount(int which);
2098 
2099     /**
2100      * Get the amount the battery has discharged while the screen was on,
2101      * since the last time power was unplugged.
2102      */
getDischargeAmountScreenOn()2103     public abstract int getDischargeAmountScreenOn();
2104 
2105     /**
2106      * Get the amount the battery has discharged while the screen was on,
2107      * since the last time the device was charged.
2108      */
getDischargeAmountScreenOnSinceCharge()2109     public abstract int getDischargeAmountScreenOnSinceCharge();
2110 
2111     /**
2112      * Get the amount the battery has discharged while the screen was off,
2113      * since the last time power was unplugged.
2114      */
getDischargeAmountScreenOff()2115     public abstract int getDischargeAmountScreenOff();
2116 
2117     /**
2118      * Get the amount the battery has discharged while the screen was off,
2119      * since the last time the device was charged.
2120      */
getDischargeAmountScreenOffSinceCharge()2121     public abstract int getDischargeAmountScreenOffSinceCharge();
2122 
2123     /**
2124      * Returns the total, last, or current battery uptime in microseconds.
2125      *
2126      * @param curTime the elapsed realtime in microseconds.
2127      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2128      */
computeBatteryUptime(long curTime, int which)2129     public abstract long computeBatteryUptime(long curTime, int which);
2130 
2131     /**
2132      * Returns the total, last, or current battery realtime in microseconds.
2133      *
2134      * @param curTime the current elapsed realtime in microseconds.
2135      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2136      */
computeBatteryRealtime(long curTime, int which)2137     public abstract long computeBatteryRealtime(long curTime, int which);
2138 
2139     /**
2140      * Returns the total, last, or current battery screen off uptime in microseconds.
2141      *
2142      * @param curTime the elapsed realtime in microseconds.
2143      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2144      */
computeBatteryScreenOffUptime(long curTime, int which)2145     public abstract long computeBatteryScreenOffUptime(long curTime, int which);
2146 
2147     /**
2148      * Returns the total, last, or current battery screen off realtime in microseconds.
2149      *
2150      * @param curTime the current elapsed realtime in microseconds.
2151      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2152      */
computeBatteryScreenOffRealtime(long curTime, int which)2153     public abstract long computeBatteryScreenOffRealtime(long curTime, int which);
2154 
2155     /**
2156      * Returns the total, last, or current uptime in microseconds.
2157      *
2158      * @param curTime the current elapsed realtime in microseconds.
2159      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2160      */
computeUptime(long curTime, int which)2161     public abstract long computeUptime(long curTime, int which);
2162 
2163     /**
2164      * Returns the total, last, or current realtime in microseconds.
2165      *
2166      * @param curTime the current elapsed realtime in microseconds.
2167      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
2168      */
computeRealtime(long curTime, int which)2169     public abstract long computeRealtime(long curTime, int which);
2170 
2171     /**
2172      * Compute an approximation for how much run time (in microseconds) is remaining on
2173      * the battery.  Returns -1 if no time can be computed: either there is not
2174      * enough current data to make a decision, or the battery is currently
2175      * charging.
2176      *
2177      * @param curTime The current elepsed realtime in microseconds.
2178      */
computeBatteryTimeRemaining(long curTime)2179     public abstract long computeBatteryTimeRemaining(long curTime);
2180 
2181     // The part of a step duration that is the actual time.
2182     public static final long STEP_LEVEL_TIME_MASK = 0x000000ffffffffffL;
2183 
2184     // Bits in a step duration that are the new battery level we are at.
2185     public static final long STEP_LEVEL_LEVEL_MASK = 0x0000ff0000000000L;
2186     public static final int STEP_LEVEL_LEVEL_SHIFT = 40;
2187 
2188     // Bits in a step duration that are the initial mode we were in at that step.
2189     public static final long STEP_LEVEL_INITIAL_MODE_MASK = 0x00ff000000000000L;
2190     public static final int STEP_LEVEL_INITIAL_MODE_SHIFT = 48;
2191 
2192     // Bits in a step duration that indicate which modes changed during that step.
2193     public static final long STEP_LEVEL_MODIFIED_MODE_MASK = 0xff00000000000000L;
2194     public static final int STEP_LEVEL_MODIFIED_MODE_SHIFT = 56;
2195 
2196     // Step duration mode: the screen is on, off, dozed, etc; value is Display.STATE_* - 1.
2197     public static final int STEP_LEVEL_MODE_SCREEN_STATE = 0x03;
2198 
2199     // Step duration mode: power save is on.
2200     public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04;
2201 
2202     // Step duration mode: device is currently in idle mode.
2203     public static final int STEP_LEVEL_MODE_DEVICE_IDLE = 0x08;
2204 
2205     public static final int[] STEP_LEVEL_MODES_OF_INTEREST = new int[] {
2206             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2207             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE,
2208             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
2209             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2210             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
2211             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
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|STEP_LEVEL_MODE_DEVICE_IDLE,
2215             STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE,
2216     };
2217     public static final int[] STEP_LEVEL_MODE_VALUES = new int[] {
2218             (Display.STATE_OFF-1),
2219             (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE,
2220             (Display.STATE_OFF-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
2221             (Display.STATE_ON-1),
2222             (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE,
2223             (Display.STATE_DOZE-1),
2224             (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE,
2225             (Display.STATE_DOZE_SUSPEND-1),
2226             (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE,
2227             (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_DEVICE_IDLE,
2228     };
2229     public static final String[] STEP_LEVEL_MODE_LABELS = new String[] {
2230             "screen off",
2231             "screen off power save",
2232             "screen off device idle",
2233             "screen on",
2234             "screen on power save",
2235             "screen doze",
2236             "screen doze power save",
2237             "screen doze-suspend",
2238             "screen doze-suspend power save",
2239             "screen doze-suspend device idle",
2240     };
2241 
2242     /**
2243      * Return the array of discharge step durations.
2244      */
getDischargeLevelStepTracker()2245     public abstract LevelStepTracker getDischargeLevelStepTracker();
2246 
2247     /**
2248      * Return the array of daily discharge step durations.
2249      */
getDailyDischargeLevelStepTracker()2250     public abstract LevelStepTracker getDailyDischargeLevelStepTracker();
2251 
2252     /**
2253      * Compute an approximation for how much time (in microseconds) remains until the battery
2254      * is fully charged.  Returns -1 if no time can be computed: either there is not
2255      * enough current data to make a decision, or the battery is currently
2256      * discharging.
2257      *
2258      * @param curTime The current elepsed realtime in microseconds.
2259      */
computeChargeTimeRemaining(long curTime)2260     public abstract long computeChargeTimeRemaining(long curTime);
2261 
2262     /**
2263      * Return the array of charge step durations.
2264      */
getChargeLevelStepTracker()2265     public abstract LevelStepTracker getChargeLevelStepTracker();
2266 
2267     /**
2268      * Return the array of daily charge step durations.
2269      */
getDailyChargeLevelStepTracker()2270     public abstract LevelStepTracker getDailyChargeLevelStepTracker();
2271 
getDailyPackageChanges()2272     public abstract ArrayList<PackageChange> getDailyPackageChanges();
2273 
getWakeupReasonStats()2274     public abstract Map<String, ? extends Timer> getWakeupReasonStats();
2275 
getKernelWakelockStats()2276     public abstract Map<String, ? extends Timer> getKernelWakelockStats();
2277 
2278     /** Returns the number of different speeds that the CPU can run at */
getCpuSpeedSteps()2279     public abstract int getCpuSpeedSteps();
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