OSDN Git Service

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