OSDN Git Service

am 665fc318: am df139acf: am 1cf6ff30: Merge "docs: Fixed Google Play Services versio...
[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.Printer;
33 import android.util.SparseArray;
34 import android.util.SparseIntArray;
35 import android.util.TimeUtils;
36 import android.view.Display;
37 import com.android.internal.os.BatterySipper;
38 import com.android.internal.os.BatteryStatsHelper;
39
40 /**
41  * A class providing access to battery usage statistics, including information on
42  * wakelocks, processes, packages, and services.  All times are represented in microseconds
43  * except where indicated otherwise.
44  * @hide
45  */
46 public abstract class BatteryStats implements Parcelable {
47
48     private static final boolean LOCAL_LOGV = false;
49
50     /** @hide */
51     public static final String SERVICE_NAME = "batterystats";
52
53     /**
54      * A constant indicating a partial wake lock timer.
55      */
56     public static final int WAKE_TYPE_PARTIAL = 0;
57
58     /**
59      * A constant indicating a full wake lock timer.
60      */
61     public static final int WAKE_TYPE_FULL = 1;
62
63     /**
64      * A constant indicating a window wake lock timer.
65      */
66     public static final int WAKE_TYPE_WINDOW = 2;
67     
68     /**
69      * A constant indicating a sensor timer.
70      */
71     public static final int SENSOR = 3;
72     
73     /**
74      * A constant indicating a a wifi running timer
75      */
76     public static final int WIFI_RUNNING = 4;
77     
78     /**
79      * A constant indicating a full wifi lock timer
80      */
81     public static final int FULL_WIFI_LOCK = 5;
82     
83     /**
84      * A constant indicating a wifi scan
85      */
86     public static final int WIFI_SCAN = 6;
87
88      /**
89       * A constant indicating a wifi multicast timer
90       */
91      public static final int WIFI_MULTICAST_ENABLED = 7;
92
93     /**
94      * A constant indicating an audio turn on timer
95      */
96     public static final int AUDIO_TURNED_ON = 7;
97
98     /**
99      * A constant indicating a video turn on timer
100      */
101     public static final int VIDEO_TURNED_ON = 8;
102
103     /**
104      * A constant indicating a vibrator on timer
105      */
106     public static final int VIBRATOR_ON = 9;
107
108     /**
109      * A constant indicating a foreground activity timer
110      */
111     public static final int FOREGROUND_ACTIVITY = 10;
112
113     /**
114      * A constant indicating a wifi batched scan is active
115      */
116     public static final int WIFI_BATCHED_SCAN = 11;
117
118     /**
119      * A constant indicating a process state timer
120      */
121     public static final int PROCESS_STATE = 12;
122
123     /**
124      * A constant indicating a sync timer
125      */
126     public static final int SYNC = 13;
127
128     /**
129      * A constant indicating a job timer
130      */
131     public static final int JOB = 14;
132
133     /**
134      * Include all of the data in the stats, including previously saved data.
135      */
136     public static final int STATS_SINCE_CHARGED = 0;
137
138     /**
139      * Include only the current run in the stats.
140      */
141     public static final int STATS_CURRENT = 1;
142
143     /**
144      * Include only the run since the last time the device was unplugged in the stats.
145      */
146     public static final int STATS_SINCE_UNPLUGGED = 2;
147
148     // NOTE: Update this list if you add/change any stats above.
149     // These characters are supposed to represent "total", "last", "current", 
150     // and "unplugged". They were shortened for efficiency sake.
151     private static final String[] STAT_NAMES = { "l", "c", "u" };
152
153     /**
154      * Bump the version on this if the checkin format changes.
155      */
156     private static final int BATTERY_STATS_CHECKIN_VERSION = 9;
157     
158     private static final long BYTES_PER_KB = 1024;
159     private static final long BYTES_PER_MB = 1048576; // 1024^2
160     private static final long BYTES_PER_GB = 1073741824; //1024^3
161     
162     private static final String VERSION_DATA = "vers";
163     private static final String UID_DATA = "uid";
164     private static final String APK_DATA = "apk";
165     private static final String PROCESS_DATA = "pr";
166     private static final String SENSOR_DATA = "sr";
167     private static final String VIBRATOR_DATA = "vib";
168     private static final String FOREGROUND_DATA = "fg";
169     private static final String STATE_TIME_DATA = "st";
170     private static final String WAKELOCK_DATA = "wl";
171     private static final String SYNC_DATA = "sy";
172     private static final String JOB_DATA = "jb";
173     private static final String KERNEL_WAKELOCK_DATA = "kwl";
174     private static final String WAKEUP_REASON_DATA = "wr";
175     private static final String NETWORK_DATA = "nt";
176     private static final String USER_ACTIVITY_DATA = "ua";
177     private static final String BATTERY_DATA = "bt";
178     private static final String BATTERY_DISCHARGE_DATA = "dc";
179     private static final String BATTERY_LEVEL_DATA = "lv";
180     private static final String WIFI_DATA = "wfl";
181     private static final String MISC_DATA = "m";
182     private static final String GLOBAL_NETWORK_DATA = "gn";
183     private static final String HISTORY_STRING_POOL = "hsp";
184     private static final String HISTORY_DATA = "h";
185     private static final String SCREEN_BRIGHTNESS_DATA = "br";
186     private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
187     private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
188     private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
189     private static final String DATA_CONNECTION_TIME_DATA = "dct";
190     private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
191     private static final String WIFI_STATE_TIME_DATA = "wst";
192     private static final String WIFI_STATE_COUNT_DATA = "wsc";
193     private static final String WIFI_SUPPL_STATE_TIME_DATA = "wsst";
194     private static final String WIFI_SUPPL_STATE_COUNT_DATA = "wssc";
195     private static final String WIFI_SIGNAL_STRENGTH_TIME_DATA = "wsgt";
196     private static final String WIFI_SIGNAL_STRENGTH_COUNT_DATA = "wsgc";
197     private static final String BLUETOOTH_STATE_TIME_DATA = "bst";
198     private static final String BLUETOOTH_STATE_COUNT_DATA = "bsc";
199     private static final String POWER_USE_SUMMARY_DATA = "pws";
200     private static final String POWER_USE_ITEM_DATA = "pwi";
201     private static final String DISCHARGE_STEP_DATA = "dsd";
202     private static final String CHARGE_STEP_DATA = "csd";
203     private static final String DISCHARGE_TIME_REMAIN_DATA = "dtr";
204     private static final String CHARGE_TIME_REMAIN_DATA = "ctr";
205
206     private final StringBuilder mFormatBuilder = new StringBuilder(32);
207     private final Formatter mFormatter = new Formatter(mFormatBuilder);
208
209     /**
210      * State for keeping track of counting information.
211      */
212     public static abstract class Counter {
213
214         /**
215          * Returns the count associated with this Counter for the
216          * selected type of statistics.
217          *
218          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
219          */
220         public abstract int getCountLocked(int which);
221
222         /**
223          * Temporary for debugging.
224          */
225         public abstract void logState(Printer pw, String prefix);
226     }
227
228     /**
229      * State for keeping track of long counting information.
230      */
231     public static abstract class LongCounter {
232
233         /**
234          * Returns the count associated with this Counter for the
235          * selected type of statistics.
236          *
237          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
238          */
239         public abstract long getCountLocked(int which);
240
241         /**
242          * Temporary for debugging.
243          */
244         public abstract void logState(Printer pw, String prefix);
245     }
246
247     /**
248      * State for keeping track of timing information.
249      */
250     public static abstract class Timer {
251
252         /**
253          * Returns the count associated with this Timer for the
254          * selected type of statistics.
255          *
256          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
257          */
258         public abstract int getCountLocked(int which);
259
260         /**
261          * Returns the total time in microseconds associated with this Timer for the
262          * selected type of statistics.
263          *
264          * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
265          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
266          * @return a time in microseconds
267          */
268         public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which);
269
270         /**
271          * Temporary for debugging.
272          */
273         public abstract void logState(Printer pw, String prefix);
274     }
275
276     /**
277      * The statistics associated with a particular uid.
278      */
279     public static abstract class Uid {
280
281         /**
282          * Returns a mapping containing wakelock statistics.
283          *
284          * @return a Map from Strings to Uid.Wakelock objects.
285          */
286         public abstract Map<String, ? extends Wakelock> getWakelockStats();
287
288         /**
289          * Returns a mapping containing sync statistics.
290          *
291          * @return a Map from Strings to Timer objects.
292          */
293         public abstract Map<String, ? extends Timer> getSyncStats();
294
295         /**
296          * Returns a mapping containing scheduled job statistics.
297          *
298          * @return a Map from Strings to Timer objects.
299          */
300         public abstract Map<String, ? extends Timer> getJobStats();
301
302         /**
303          * The statistics associated with a particular wake lock.
304          */
305         public static abstract class Wakelock {
306             public abstract Timer getWakeTime(int type);
307         }
308
309         /**
310          * Returns a mapping containing sensor statistics.
311          *
312          * @return a Map from Integer sensor ids to Uid.Sensor objects.
313          */
314         public abstract SparseArray<? extends Sensor> getSensorStats();
315
316         /**
317          * Returns a mapping containing active process data.
318          */
319         public abstract SparseArray<? extends Pid> getPidStats();
320         
321         /**
322          * Returns a mapping containing process statistics.
323          *
324          * @return a Map from Strings to Uid.Proc objects.
325          */
326         public abstract Map<String, ? extends Proc> getProcessStats();
327
328         /**
329          * Returns a mapping containing package statistics.
330          *
331          * @return a Map from Strings to Uid.Pkg objects.
332          */
333         public abstract Map<String, ? extends Pkg> getPackageStats();
334         
335         /**
336          * {@hide}
337          */
338         public abstract int getUid();
339
340         public abstract void noteWifiRunningLocked(long elapsedRealtime);
341         public abstract void noteWifiStoppedLocked(long elapsedRealtime);
342         public abstract void noteFullWifiLockAcquiredLocked(long elapsedRealtime);
343         public abstract void noteFullWifiLockReleasedLocked(long elapsedRealtime);
344         public abstract void noteWifiScanStartedLocked(long elapsedRealtime);
345         public abstract void noteWifiScanStoppedLocked(long elapsedRealtime);
346         public abstract void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime);
347         public abstract void noteWifiBatchedScanStoppedLocked(long elapsedRealtime);
348         public abstract void noteWifiMulticastEnabledLocked(long elapsedRealtime);
349         public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime);
350         public abstract void noteActivityResumedLocked(long elapsedRealtime);
351         public abstract void noteActivityPausedLocked(long elapsedRealtime);
352         public abstract long getWifiRunningTime(long elapsedRealtimeUs, int which);
353         public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which);
354         public abstract long getWifiScanTime(long elapsedRealtimeUs, int which);
355         public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which);
356         public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which);
357         public abstract long getAudioTurnedOnTime(long elapsedRealtimeUs, int which);
358         public abstract long getVideoTurnedOnTime(long elapsedRealtimeUs, int which);
359         public abstract Timer getForegroundActivityTimer();
360
361         // Time this uid has any processes in foreground state.
362         public static final int PROCESS_STATE_FOREGROUND = 0;
363         // Time this uid has any process in active state (not cached).
364         public static final int PROCESS_STATE_ACTIVE = 1;
365         // Time this uid has any processes running at all.
366         public static final int PROCESS_STATE_RUNNING = 2;
367         // Total number of process states we track.
368         public static final int NUM_PROCESS_STATE = 3;
369
370         static final String[] PROCESS_STATE_NAMES = {
371             "Foreground", "Active", "Running"
372         };
373
374         public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which);
375
376         public abstract Timer getVibratorOnTimer();
377
378         public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5;
379
380         /**
381          * Note that these must match the constants in android.os.PowerManager.
382          * Also, if the user activity types change, the BatteryStatsImpl.VERSION must
383          * also be bumped.
384          */
385         static final String[] USER_ACTIVITY_TYPES = {
386             "other", "button", "touch"
387         };
388         
389         public static final int NUM_USER_ACTIVITY_TYPES = 3;
390
391         public abstract void noteUserActivityLocked(int type);
392         public abstract boolean hasUserActivity();
393         public abstract int getUserActivityCount(int type, int which);
394
395         public abstract boolean hasNetworkActivity();
396         public abstract long getNetworkActivityBytes(int type, int which);
397         public abstract long getNetworkActivityPackets(int type, int which);
398         public abstract long getMobileRadioActiveTime(int which);
399         public abstract int getMobileRadioActiveCount(int which);
400
401         public static abstract class Sensor {
402             /*
403              * FIXME: it's not correct to use this magic value because it
404              * could clash with a sensor handle (which are defined by
405              * the sensor HAL, and therefore out of our control
406              */
407             // Magic sensor number for the GPS.
408             public static final int GPS = -10000;
409             
410             public abstract int getHandle();
411             
412             public abstract Timer getSensorTime();
413         }
414
415         public class Pid {
416             public int mWakeNesting;
417             public long mWakeSumMs;
418             public long mWakeStartMs;
419         }
420
421         /**
422          * The statistics associated with a particular process.
423          */
424         public static abstract class Proc {
425
426             public static class ExcessivePower {
427                 public static final int TYPE_WAKE = 1;
428                 public static final int TYPE_CPU = 2;
429
430                 public int type;
431                 public long overTime;
432                 public long usedTime;
433             }
434
435             /**
436              * Returns true if this process is still active in the battery stats.
437              */
438             public abstract boolean isActive();
439
440             /**
441              * Returns the total time (in 1/100 sec) spent executing in user code.
442              *
443              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
444              */
445             public abstract long getUserTime(int which);
446
447             /**
448              * Returns the total time (in 1/100 sec) spent executing in system code.
449              *
450              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
451              */
452             public abstract long getSystemTime(int which);
453
454             /**
455              * Returns the number of times the process has been started.
456              *
457              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
458              */
459             public abstract int getStarts(int which);
460
461             /**
462              * Returns the cpu time spent in microseconds while the process was in the foreground.
463              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
464              * @return foreground cpu time in microseconds
465              */
466             public abstract long getForegroundTime(int which);
467
468             /**
469              * Returns the approximate cpu time spent in microseconds, at a certain CPU speed.
470              * @param speedStep the index of the CPU speed. This is not the actual speed of the
471              * CPU.
472              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
473              * @see BatteryStats#getCpuSpeedSteps()
474              */
475             public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
476
477             public abstract int countExcessivePowers();
478
479             public abstract ExcessivePower getExcessivePower(int i);
480         }
481
482         /**
483          * The statistics associated with a particular package.
484          */
485         public static abstract class Pkg {
486
487             /**
488              * Returns the number of times this package has done something that could wake up the
489              * device from sleep.
490              *
491              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
492              */
493             public abstract int getWakeups(int which);
494
495             /**
496              * Returns a mapping containing service statistics.
497              */
498             public abstract Map<String, ? extends Serv> getServiceStats();
499
500             /**
501              * The statistics associated with a particular service.
502              */
503             public abstract class Serv {
504
505                 /**
506                  * Returns the amount of time spent started.
507                  *
508                  * @param batteryUptime elapsed uptime on battery in microseconds.
509                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
510                  * @return
511                  */
512                 public abstract long getStartTime(long batteryUptime, int which);
513
514                 /**
515                  * Returns the total number of times startService() has been called.
516                  *
517                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
518                  */
519                 public abstract int getStarts(int which);
520
521                 /**
522                  * Returns the total number times the service has been launched.
523                  *
524                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
525                  */
526                 public abstract int getLaunches(int which);
527             }
528         }
529     }
530
531     public final static class HistoryTag {
532         public String string;
533         public int uid;
534
535         public int poolIdx;
536
537         public void setTo(HistoryTag o) {
538             string = o.string;
539             uid = o.uid;
540             poolIdx = o.poolIdx;
541         }
542
543         public void setTo(String _string, int _uid) {
544             string = _string;
545             uid = _uid;
546             poolIdx = -1;
547         }
548
549         public void writeToParcel(Parcel dest, int flags) {
550             dest.writeString(string);
551             dest.writeInt(uid);
552         }
553
554         public void readFromParcel(Parcel src) {
555             string = src.readString();
556             uid = src.readInt();
557             poolIdx = -1;
558         }
559
560         @Override
561         public boolean equals(Object o) {
562             if (this == o) return true;
563             if (o == null || getClass() != o.getClass()) return false;
564
565             HistoryTag that = (HistoryTag) o;
566
567             if (uid != that.uid) return false;
568             if (!string.equals(that.string)) return false;
569
570             return true;
571         }
572
573         @Override
574         public int hashCode() {
575             int result = string.hashCode();
576             result = 31 * result + uid;
577             return result;
578         }
579     }
580
581     public final static class HistoryItem implements Parcelable {
582         public HistoryItem next;
583
584         // The time of this event in milliseconds, as per SystemClock.elapsedRealtime().
585         public long time;
586
587         public static final byte CMD_UPDATE = 0;        // These can be written as deltas
588         public static final byte CMD_NULL = -1;
589         public static final byte CMD_START = 4;
590         public static final byte CMD_CURRENT_TIME = 5;
591         public static final byte CMD_OVERFLOW = 6;
592         public static final byte CMD_RESET = 7;
593
594         public byte cmd = CMD_NULL;
595         
596         /**
597          * Return whether the command code is a delta data update.
598          */
599         public boolean isDeltaData() {
600             return cmd == CMD_UPDATE;
601         }
602
603         public byte batteryLevel;
604         public byte batteryStatus;
605         public byte batteryHealth;
606         public byte batteryPlugType;
607         
608         public short batteryTemperature;
609         public char batteryVoltage;
610         
611         // Constants from SCREEN_BRIGHTNESS_*
612         public static final int STATE_BRIGHTNESS_SHIFT = 0;
613         public static final int STATE_BRIGHTNESS_MASK = 0x7;
614         // Constants from SIGNAL_STRENGTH_*
615         public static final int STATE_PHONE_SIGNAL_STRENGTH_SHIFT = 3;
616         public static final int STATE_PHONE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_PHONE_SIGNAL_STRENGTH_SHIFT;
617         // Constants from ServiceState.STATE_*
618         public static final int STATE_PHONE_STATE_SHIFT = 6;
619         public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT;
620         // Constants from DATA_CONNECTION_*
621         public static final int STATE_DATA_CONNECTION_SHIFT = 9;
622         public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT;
623
624         // These states always appear directly in the first int token
625         // of a delta change; they should be ones that change relatively
626         // frequently.
627         public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
628         public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
629         public static final int STATE_GPS_ON_FLAG = 1<<29;
630         public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
631         public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
632         public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<26;
633         public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
634         // These are on the lower bits used for the command; if they change
635         // we need to write another int of data.
636         public static final int STATE_SENSOR_ON_FLAG = 1<<23;
637         public static final int STATE_AUDIO_ON_FLAG = 1<<22;
638         public static final int STATE_PHONE_SCANNING_FLAG = 1<<21;
639         public static final int STATE_SCREEN_ON_FLAG = 1<<20;
640         public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19;
641         public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18;
642         public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16;
643
644         public static final int MOST_INTERESTING_STATES =
645             STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG
646             | STATE_PHONE_IN_CALL_FLAG | STATE_BLUETOOTH_ON_FLAG;
647
648         public int states;
649
650         // Constants from WIFI_SUPPL_STATE_*
651         public static final int STATE2_WIFI_SUPPL_STATE_SHIFT = 0;
652         public static final int STATE2_WIFI_SUPPL_STATE_MASK = 0xf;
653         // Values for NUM_WIFI_SIGNAL_STRENGTH_BINS
654         public static final int STATE2_WIFI_SIGNAL_STRENGTH_SHIFT = 4;
655         public static final int STATE2_WIFI_SIGNAL_STRENGTH_MASK =
656                 0x7 << STATE2_WIFI_SIGNAL_STRENGTH_SHIFT;
657
658         public static final int STATE2_LOW_POWER_FLAG = 1<<31;
659         public static final int STATE2_VIDEO_ON_FLAG = 1<<30;
660         public static final int STATE2_WIFI_RUNNING_FLAG = 1<<29;
661         public static final int STATE2_WIFI_ON_FLAG = 1<<28;
662         public static final int STATE2_FLASHLIGHT_FLAG = 1<<27;
663
664         public static final int MOST_INTERESTING_STATES2 =
665             STATE2_LOW_POWER_FLAG | STATE2_WIFI_ON_FLAG;
666
667         public int states2;
668
669         // The wake lock that was acquired at this point.
670         public HistoryTag wakelockTag;
671
672         // Kernel wakeup reason at this point.
673         public HistoryTag wakeReasonTag;
674
675         public static final int EVENT_FLAG_START = 0x8000;
676         public static final int EVENT_FLAG_FINISH = 0x4000;
677
678         // No event in this item.
679         public static final int EVENT_NONE = 0x0000;
680         // Event is about a process that is running.
681         public static final int EVENT_PROC = 0x0001;
682         // Event is about an application package that is in the foreground.
683         public static final int EVENT_FOREGROUND = 0x0002;
684         // Event is about an application package that is at the top of the screen.
685         public static final int EVENT_TOP = 0x0003;
686         // Event is about active sync operations.
687         public static final int EVENT_SYNC = 0x0004;
688         // Events for all additional wake locks aquired/release within a wake block.
689         // These are not generated by default.
690         public static final int EVENT_WAKE_LOCK = 0x0005;
691         // Event is about an application executing a scheduled job.
692         public static final int EVENT_JOB = 0x0006;
693         // Events for users running.
694         public static final int EVENT_USER_RUNNING = 0x0007;
695         // Events for foreground user.
696         public static final int EVENT_USER_FOREGROUND = 0x0008;
697         // Number of event types.
698         public static final int EVENT_COUNT = 0x0009;
699         // Mask to extract out only the type part of the event.
700         public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
701
702         public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
703         public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
704         public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START;
705         public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
706         public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
707         public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
708         public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
709         public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
710         public static final int EVENT_WAKE_LOCK_START = EVENT_WAKE_LOCK | EVENT_FLAG_START;
711         public static final int EVENT_WAKE_LOCK_FINISH = EVENT_WAKE_LOCK | EVENT_FLAG_FINISH;
712         public static final int EVENT_JOB_START = EVENT_JOB | EVENT_FLAG_START;
713         public static final int EVENT_JOB_FINISH = EVENT_JOB | EVENT_FLAG_FINISH;
714         public static final int EVENT_USER_RUNNING_START = EVENT_USER_RUNNING | EVENT_FLAG_START;
715         public static final int EVENT_USER_RUNNING_FINISH = EVENT_USER_RUNNING | EVENT_FLAG_FINISH;
716         public static final int EVENT_USER_FOREGROUND_START =
717                 EVENT_USER_FOREGROUND | EVENT_FLAG_START;
718         public static final int EVENT_USER_FOREGROUND_FINISH =
719                 EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
720
721         // For CMD_EVENT.
722         public int eventCode;
723         public HistoryTag eventTag;
724
725         // Only set for CMD_CURRENT_TIME or CMD_RESET, as per System.currentTimeMillis().
726         public long currentTime;
727
728         // Meta-data when reading.
729         public int numReadInts;
730
731         // Pre-allocated objects.
732         public final HistoryTag localWakelockTag = new HistoryTag();
733         public final HistoryTag localWakeReasonTag = new HistoryTag();
734         public final HistoryTag localEventTag = new HistoryTag();
735
736         public HistoryItem() {
737         }
738         
739         public HistoryItem(long time, Parcel src) {
740             this.time = time;
741             numReadInts = 2;
742             readFromParcel(src);
743         }
744         
745         public int describeContents() {
746             return 0;
747         }
748
749         public void writeToParcel(Parcel dest, int flags) {
750             dest.writeLong(time);
751             int bat = (((int)cmd)&0xff)
752                     | ((((int)batteryLevel)<<8)&0xff00)
753                     | ((((int)batteryStatus)<<16)&0xf0000)
754                     | ((((int)batteryHealth)<<20)&0xf00000)
755                     | ((((int)batteryPlugType)<<24)&0xf000000)
756                     | (wakelockTag != null ? 0x10000000 : 0)
757                     | (wakeReasonTag != null ? 0x20000000 : 0)
758                     | (eventCode != EVENT_NONE ? 0x40000000 : 0);
759             dest.writeInt(bat);
760             bat = (((int)batteryTemperature)&0xffff)
761                     | ((((int)batteryVoltage)<<16)&0xffff0000);
762             dest.writeInt(bat);
763             dest.writeInt(states);
764             dest.writeInt(states2);
765             if (wakelockTag != null) {
766                 wakelockTag.writeToParcel(dest, flags);
767             }
768             if (wakeReasonTag != null) {
769                 wakeReasonTag.writeToParcel(dest, flags);
770             }
771             if (eventCode != EVENT_NONE) {
772                 dest.writeInt(eventCode);
773                 eventTag.writeToParcel(dest, flags);
774             }
775             if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
776                 dest.writeLong(currentTime);
777             }
778         }
779
780         public void readFromParcel(Parcel src) {
781             int start = src.dataPosition();
782             int bat = src.readInt();
783             cmd = (byte)(bat&0xff);
784             batteryLevel = (byte)((bat>>8)&0xff);
785             batteryStatus = (byte)((bat>>16)&0xf);
786             batteryHealth = (byte)((bat>>20)&0xf);
787             batteryPlugType = (byte)((bat>>24)&0xf);
788             int bat2 = src.readInt();
789             batteryTemperature = (short)(bat2&0xffff);
790             batteryVoltage = (char)((bat2>>16)&0xffff);
791             states = src.readInt();
792             states2 = src.readInt();
793             if ((bat&0x10000000) != 0) {
794                 wakelockTag = localWakelockTag;
795                 wakelockTag.readFromParcel(src);
796             } else {
797                 wakelockTag = null;
798             }
799             if ((bat&0x20000000) != 0) {
800                 wakeReasonTag = localWakeReasonTag;
801                 wakeReasonTag.readFromParcel(src);
802             } else {
803                 wakeReasonTag = null;
804             }
805             if ((bat&0x40000000) != 0) {
806                 eventCode = src.readInt();
807                 eventTag = localEventTag;
808                 eventTag.readFromParcel(src);
809             } else {
810                 eventCode = EVENT_NONE;
811                 eventTag = null;
812             }
813             if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
814                 currentTime = src.readLong();
815             } else {
816                 currentTime = 0;
817             }
818             numReadInts += (src.dataPosition()-start)/4;
819         }
820
821         public void clear() {
822             time = 0;
823             cmd = CMD_NULL;
824             batteryLevel = 0;
825             batteryStatus = 0;
826             batteryHealth = 0;
827             batteryPlugType = 0;
828             batteryTemperature = 0;
829             batteryVoltage = 0;
830             states = 0;
831             states2 = 0;
832             wakelockTag = null;
833             wakeReasonTag = null;
834             eventCode = EVENT_NONE;
835             eventTag = null;
836         }
837         
838         public void setTo(HistoryItem o) {
839             time = o.time;
840             cmd = o.cmd;
841             setToCommon(o);
842         }
843
844         public void setTo(long time, byte cmd, HistoryItem o) {
845             this.time = time;
846             this.cmd = cmd;
847             setToCommon(o);
848         }
849
850         private void setToCommon(HistoryItem o) {
851             batteryLevel = o.batteryLevel;
852             batteryStatus = o.batteryStatus;
853             batteryHealth = o.batteryHealth;
854             batteryPlugType = o.batteryPlugType;
855             batteryTemperature = o.batteryTemperature;
856             batteryVoltage = o.batteryVoltage;
857             states = o.states;
858             states2 = o.states2;
859             if (o.wakelockTag != null) {
860                 wakelockTag = localWakelockTag;
861                 wakelockTag.setTo(o.wakelockTag);
862             } else {
863                 wakelockTag = null;
864             }
865             if (o.wakeReasonTag != null) {
866                 wakeReasonTag = localWakeReasonTag;
867                 wakeReasonTag.setTo(o.wakeReasonTag);
868             } else {
869                 wakeReasonTag = null;
870             }
871             eventCode = o.eventCode;
872             if (o.eventTag != null) {
873                 eventTag = localEventTag;
874                 eventTag.setTo(o.eventTag);
875             } else {
876                 eventTag = null;
877             }
878             currentTime = o.currentTime;
879         }
880
881         public boolean sameNonEvent(HistoryItem o) {
882             return batteryLevel == o.batteryLevel
883                     && batteryStatus == o.batteryStatus
884                     && batteryHealth == o.batteryHealth
885                     && batteryPlugType == o.batteryPlugType
886                     && batteryTemperature == o.batteryTemperature
887                     && batteryVoltage == o.batteryVoltage
888                     && states == o.states
889                     && states2 == o.states2
890                     && currentTime == o.currentTime;
891         }
892
893         public boolean same(HistoryItem o) {
894             if (!sameNonEvent(o) || eventCode != o.eventCode) {
895                 return false;
896             }
897             if (wakelockTag != o.wakelockTag) {
898                 if (wakelockTag == null || o.wakelockTag == null) {
899                     return false;
900                 }
901                 if (!wakelockTag.equals(o.wakelockTag)) {
902                     return false;
903                 }
904             }
905             if (wakeReasonTag != o.wakeReasonTag) {
906                 if (wakeReasonTag == null || o.wakeReasonTag == null) {
907                     return false;
908                 }
909                 if (!wakeReasonTag.equals(o.wakeReasonTag)) {
910                     return false;
911                 }
912             }
913             if (eventTag != o.eventTag) {
914                 if (eventTag == null || o.eventTag == null) {
915                     return false;
916                 }
917                 if (!eventTag.equals(o.eventTag)) {
918                     return false;
919                 }
920             }
921             return true;
922         }
923     }
924
925     public final static class HistoryEventTracker {
926         private final HashMap<String, SparseIntArray>[] mActiveEvents
927                 = (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
928
929         public boolean updateState(int code, String name, int uid, int poolIdx) {
930             if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
931                 int idx = code&HistoryItem.EVENT_TYPE_MASK;
932                 HashMap<String, SparseIntArray> active = mActiveEvents[idx];
933                 if (active == null) {
934                     active = new HashMap<String, SparseIntArray>();
935                     mActiveEvents[idx] = active;
936                 }
937                 SparseIntArray uids = active.get(name);
938                 if (uids == null) {
939                     uids = new SparseIntArray();
940                     active.put(name, uids);
941                 }
942                 if (uids.indexOfKey(uid) >= 0) {
943                     // Already set, nothing to do!
944                     return false;
945                 }
946                 uids.put(uid, poolIdx);
947             } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
948                 int idx = code&HistoryItem.EVENT_TYPE_MASK;
949                 HashMap<String, SparseIntArray> active = mActiveEvents[idx];
950                 if (active == null) {
951                     // not currently active, nothing to do.
952                     return false;
953                 }
954                 SparseIntArray uids = active.get(name);
955                 if (uids == null) {
956                     // not currently active, nothing to do.
957                     return false;
958                 }
959                 idx = uids.indexOfKey(uid);
960                 if (idx < 0) {
961                     // not currently active, nothing to do.
962                     return false;
963                 }
964                 uids.removeAt(idx);
965                 if (uids.size() <= 0) {
966                     active.remove(name);
967                 }
968             }
969             return true;
970         }
971
972         public void removeEvents(int code) {
973             int idx = code&HistoryItem.EVENT_TYPE_MASK;
974             mActiveEvents[idx] = null;
975         }
976
977         public HashMap<String, SparseIntArray> getStateForEvent(int code) {
978             return mActiveEvents[code];
979         }
980     }
981
982     public static final class BitDescription {
983         public final int mask;
984         public final int shift;
985         public final String name;
986         public final String shortName;
987         public final String[] values;
988         public final String[] shortValues;
989         
990         public BitDescription(int mask, String name, String shortName) {
991             this.mask = mask;
992             this.shift = -1;
993             this.name = name;
994             this.shortName = shortName;
995             this.values = null;
996             this.shortValues = null;
997         }
998         
999         public BitDescription(int mask, int shift, String name, String shortName,
1000                 String[] values, String[] shortValues) {
1001             this.mask = mask;
1002             this.shift = shift;
1003             this.name = name;
1004             this.shortName = shortName;
1005             this.values = values;
1006             this.shortValues = shortValues;
1007         }
1008     }
1009
1010     /**
1011      * Don't allow any more batching in to the current history event.  This
1012      * is called when printing partial histories, so to ensure that the next
1013      * history event will go in to a new batch after what was printed in the
1014      * last partial history.
1015      */
1016     public abstract void commitCurrentHistoryBatchLocked();
1017
1018     public abstract int getHistoryTotalSize();
1019
1020     public abstract int getHistoryUsedSize();
1021
1022     public abstract boolean startIteratingHistoryLocked();
1023
1024     public abstract int getHistoryStringPoolSize();
1025
1026     public abstract int getHistoryStringPoolBytes();
1027
1028     public abstract String getHistoryTagPoolString(int index);
1029
1030     public abstract int getHistoryTagPoolUid(int index);
1031
1032     public abstract boolean getNextHistoryLocked(HistoryItem out);
1033
1034     public abstract void finishIteratingHistoryLocked();
1035
1036     public abstract boolean startIteratingOldHistoryLocked();
1037
1038     public abstract boolean getNextOldHistoryLocked(HistoryItem out);
1039
1040     public abstract void finishIteratingOldHistoryLocked();
1041
1042     /**
1043      * Return the base time offset for the battery history.
1044      */
1045     public abstract long getHistoryBaseTime();
1046     
1047     /**
1048      * Returns the number of times the device has been started.
1049      */
1050     public abstract int getStartCount();
1051     
1052     /**
1053      * Returns the time in microseconds that the screen has been on while the device was
1054      * running on battery.
1055      * 
1056      * {@hide}
1057      */
1058     public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
1059     
1060     /**
1061      * Returns the number of times the screen was turned on.
1062      *
1063      * {@hide}
1064      */
1065     public abstract int getScreenOnCount(int which);
1066
1067     public abstract long getInteractiveTime(long elapsedRealtimeUs, int which);
1068
1069     public static final int SCREEN_BRIGHTNESS_DARK = 0;
1070     public static final int SCREEN_BRIGHTNESS_DIM = 1;
1071     public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
1072     public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
1073     public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
1074     
1075     static final String[] SCREEN_BRIGHTNESS_NAMES = {
1076         "dark", "dim", "medium", "light", "bright"
1077     };
1078     
1079     static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
1080         "0", "1", "2", "3", "4"
1081     };
1082
1083     public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
1084
1085     /**
1086      * Returns the time in microseconds that the screen has been on with
1087      * the given brightness
1088      * 
1089      * {@hide}
1090      */
1091     public abstract long getScreenBrightnessTime(int brightnessBin,
1092             long elapsedRealtimeUs, int which);
1093
1094     /**
1095      * Returns the time in microseconds that low power mode has been enabled while the device was
1096      * running on battery.
1097      *
1098      * {@hide}
1099      */
1100     public abstract long getLowPowerModeEnabledTime(long elapsedRealtimeUs, int which);
1101
1102     /**
1103      * Returns the number of times that low power mode was enabled.
1104      *
1105      * {@hide}
1106      */
1107     public abstract int getLowPowerModeEnabledCount(int which);
1108
1109     /**
1110      * Returns the time in microseconds that the phone has been on while the device was
1111      * running on battery.
1112      * 
1113      * {@hide}
1114      */
1115     public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
1116     
1117     /**
1118      * Returns the number of times a phone call was activated.
1119      *
1120      * {@hide}
1121      */
1122     public abstract int getPhoneOnCount(int which);
1123
1124     /**
1125      * Returns the time in microseconds that the phone has been running with
1126      * the given signal strength.
1127      * 
1128      * {@hide}
1129      */
1130     public abstract long getPhoneSignalStrengthTime(int strengthBin,
1131             long elapsedRealtimeUs, int which);
1132
1133     /**
1134      * Returns the time in microseconds that the phone has been trying to
1135      * acquire a signal.
1136      *
1137      * {@hide}
1138      */
1139     public abstract long getPhoneSignalScanningTime(
1140             long elapsedRealtimeUs, int which);
1141
1142     /**
1143      * Returns the number of times the phone has entered the given signal strength.
1144      * 
1145      * {@hide}
1146      */
1147     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
1148
1149     /**
1150      * Returns the time in microseconds that the mobile network has been active
1151      * (in a high power state).
1152      *
1153      * {@hide}
1154      */
1155     public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which);
1156
1157     /**
1158      * Returns the number of times that the mobile network has transitioned to the
1159      * active state.
1160      *
1161      * {@hide}
1162      */
1163     public abstract int getMobileRadioActiveCount(int which);
1164
1165     /**
1166      * Returns the time in microseconds that is the difference between the mobile radio
1167      * time we saw based on the elapsed timestamp when going down vs. the given time stamp
1168      * from the radio.
1169      *
1170      * {@hide}
1171      */
1172     public abstract long getMobileRadioActiveAdjustedTime(int which);
1173
1174     /**
1175      * Returns the time in microseconds that the mobile network has been active
1176      * (in a high power state) but not being able to blame on an app.
1177      *
1178      * {@hide}
1179      */
1180     public abstract long getMobileRadioActiveUnknownTime(int which);
1181
1182     /**
1183      * Return count of number of times radio was up that could not be blamed on apps.
1184      *
1185      * {@hide}
1186      */
1187     public abstract int getMobileRadioActiveUnknownCount(int which);
1188
1189     public static final int DATA_CONNECTION_NONE = 0;
1190     public static final int DATA_CONNECTION_GPRS = 1;
1191     public static final int DATA_CONNECTION_EDGE = 2;
1192     public static final int DATA_CONNECTION_UMTS = 3;
1193     public static final int DATA_CONNECTION_CDMA = 4;
1194     public static final int DATA_CONNECTION_EVDO_0 = 5;
1195     public static final int DATA_CONNECTION_EVDO_A = 6;
1196     public static final int DATA_CONNECTION_1xRTT = 7;
1197     public static final int DATA_CONNECTION_HSDPA = 8;
1198     public static final int DATA_CONNECTION_HSUPA = 9;
1199     public static final int DATA_CONNECTION_HSPA = 10;
1200     public static final int DATA_CONNECTION_IDEN = 11;
1201     public static final int DATA_CONNECTION_EVDO_B = 12;
1202     public static final int DATA_CONNECTION_LTE = 13;
1203     public static final int DATA_CONNECTION_EHRPD = 14;
1204     public static final int DATA_CONNECTION_HSPAP = 15;
1205     public static final int DATA_CONNECTION_OTHER = 16;
1206
1207     static final String[] DATA_CONNECTION_NAMES = {
1208         "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
1209         "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
1210         "ehrpd", "hspap", "other"
1211     };
1212     
1213     public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
1214     
1215     /**
1216      * Returns the time in microseconds that the phone has been running with
1217      * the given data connection.
1218      * 
1219      * {@hide}
1220      */
1221     public abstract long getPhoneDataConnectionTime(int dataType,
1222             long elapsedRealtimeUs, int which);
1223
1224     /**
1225      * Returns the number of times the phone has entered the given data
1226      * connection type.
1227      * 
1228      * {@hide}
1229      */
1230     public abstract int getPhoneDataConnectionCount(int dataType, int which);
1231
1232     public static final int WIFI_SUPPL_STATE_INVALID = 0;
1233     public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1;
1234     public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2;
1235     public static final int WIFI_SUPPL_STATE_INACTIVE = 3;
1236     public static final int WIFI_SUPPL_STATE_SCANNING = 4;
1237     public static final int WIFI_SUPPL_STATE_AUTHENTICATING = 5;
1238     public static final int WIFI_SUPPL_STATE_ASSOCIATING = 6;
1239     public static final int WIFI_SUPPL_STATE_ASSOCIATED = 7;
1240     public static final int WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE = 8;
1241     public static final int WIFI_SUPPL_STATE_GROUP_HANDSHAKE = 9;
1242     public static final int WIFI_SUPPL_STATE_COMPLETED = 10;
1243     public static final int WIFI_SUPPL_STATE_DORMANT = 11;
1244     public static final int WIFI_SUPPL_STATE_UNINITIALIZED = 12;
1245
1246     public static final int NUM_WIFI_SUPPL_STATES = WIFI_SUPPL_STATE_UNINITIALIZED+1;
1247
1248     static final String[] WIFI_SUPPL_STATE_NAMES = {
1249         "invalid", "disconn", "disabled", "inactive", "scanning",
1250         "authenticating", "associating", "associated", "4-way-handshake",
1251         "group-handshake", "completed", "dormant", "uninit"
1252     };
1253
1254     static final String[] WIFI_SUPPL_STATE_SHORT_NAMES = {
1255         "inv", "dsc", "dis", "inact", "scan",
1256         "auth", "ascing", "asced", "4-way",
1257         "group", "compl", "dorm", "uninit"
1258     };
1259
1260     public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
1261             = new BitDescription[] {
1262         new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
1263         new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
1264         new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
1265         new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
1266         new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
1267         new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
1268         new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
1269         new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
1270         new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
1271         new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
1272         new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
1273         new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
1274         new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
1275         new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
1276         new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
1277                 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
1278                 DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
1279         new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
1280                 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
1281                 new String[] {"in", "out", "emergency", "off"},
1282                 new String[] {"in", "out", "em", "off"}),
1283         new BitDescription(HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK,
1284                 HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT, "phone_signal_strength", "Pss",
1285                 SignalStrength.SIGNAL_STRENGTH_NAMES,
1286                 new String[] { "0", "1", "2", "3", "4" }),
1287         new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
1288                 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
1289                 SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
1290     };
1291
1292     public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
1293             = new BitDescription[] {
1294         new BitDescription(HistoryItem.STATE2_LOW_POWER_FLAG, "low_power", "lp"),
1295         new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
1296         new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Wr"),
1297         new BitDescription(HistoryItem.STATE2_WIFI_ON_FLAG, "wifi", "W"),
1298         new BitDescription(HistoryItem.STATE2_FLASHLIGHT_FLAG, "flashlight", "fl"),
1299         new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
1300                 HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT, "wifi_signal_strength", "Wss",
1301                 new String[] { "0", "1", "2", "3", "4" },
1302                 new String[] { "0", "1", "2", "3", "4" }),
1303         new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK,
1304                 HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp",
1305                 WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES),
1306     };
1307
1308     public static final String[] HISTORY_EVENT_NAMES = new String[] {
1309             "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg"
1310     };
1311
1312     public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
1313             "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf"
1314     };
1315
1316     /**
1317      * Returns the time in microseconds that wifi has been on while the device was
1318      * running on battery.
1319      * 
1320      * {@hide}
1321      */
1322     public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
1323
1324     /**
1325      * Returns the time in microseconds that wifi has been on and the driver has
1326      * been in the running state while the device was running on battery.
1327      *
1328      * {@hide}
1329      */
1330     public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
1331
1332     public static final int WIFI_STATE_OFF = 0;
1333     public static final int WIFI_STATE_OFF_SCANNING = 1;
1334     public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
1335     public static final int WIFI_STATE_ON_DISCONNECTED = 3;
1336     public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
1337     public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
1338     public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
1339     public static final int WIFI_STATE_SOFT_AP = 7;
1340
1341     static final String[] WIFI_STATE_NAMES = {
1342         "off", "scanning", "no_net", "disconn",
1343         "sta", "p2p", "sta_p2p", "soft_ap"
1344     };
1345
1346     public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1;
1347
1348     /**
1349      * Returns the time in microseconds that WiFi has been running in the given state.
1350      *
1351      * {@hide}
1352      */
1353     public abstract long getWifiStateTime(int wifiState,
1354             long elapsedRealtimeUs, int which);
1355
1356     /**
1357      * Returns the number of times that WiFi has entered the given state.
1358      *
1359      * {@hide}
1360      */
1361     public abstract int getWifiStateCount(int wifiState, int which);
1362
1363     /**
1364      * Returns the time in microseconds that the wifi supplicant has been
1365      * in a given state.
1366      *
1367      * {@hide}
1368      */
1369     public abstract long getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which);
1370
1371     /**
1372      * Returns the number of times that the wifi supplicant has transitioned
1373      * to a given state.
1374      *
1375      * {@hide}
1376      */
1377     public abstract int getWifiSupplStateCount(int state, int which);
1378
1379     public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5;
1380
1381     /**
1382      * Returns the time in microseconds that WIFI has been running with
1383      * the given signal strength.
1384      *
1385      * {@hide}
1386      */
1387     public abstract long getWifiSignalStrengthTime(int strengthBin,
1388             long elapsedRealtimeUs, int which);
1389
1390     /**
1391      * Returns the number of times WIFI has entered the given signal strength.
1392      *
1393      * {@hide}
1394      */
1395     public abstract int getWifiSignalStrengthCount(int strengthBin, int which);
1396
1397     /**
1398      * Returns the time in microseconds that bluetooth has been on while the device was
1399      * running on battery.
1400      * 
1401      * {@hide}
1402      */
1403     public abstract long getBluetoothOnTime(long elapsedRealtimeUs, int which);
1404     
1405     public abstract int getBluetoothPingCount();
1406
1407     public static final int BLUETOOTH_STATE_INACTIVE = 0;
1408     public static final int BLUETOOTH_STATE_LOW = 1;
1409     public static final int BLUETOOTH_STATE_MEDIUM = 2;
1410     public static final int BLUETOOTH_STATE_HIGH = 3;
1411
1412     static final String[] BLUETOOTH_STATE_NAMES = {
1413         "inactive", "low", "med", "high"
1414     };
1415
1416     public static final int NUM_BLUETOOTH_STATES = BLUETOOTH_STATE_HIGH +1;
1417
1418     /**
1419      * Returns the time in microseconds that Bluetooth has been running in the
1420      * given active state.
1421      *
1422      * {@hide}
1423      */
1424     public abstract long getBluetoothStateTime(int bluetoothState,
1425             long elapsedRealtimeUs, int which);
1426
1427     /**
1428      * Returns the number of times that Bluetooth has entered the given active state.
1429      *
1430      * {@hide}
1431      */
1432     public abstract int getBluetoothStateCount(int bluetoothState, int which);
1433
1434     /**
1435      * Returns the time in microseconds that the flashlight has been on while the device was
1436      * running on battery.
1437      *
1438      * {@hide}
1439      */
1440     public abstract long getFlashlightOnTime(long elapsedRealtimeUs, int which);
1441
1442     /**
1443      * Returns the number of times that the flashlight has been turned on while the device was
1444      * running on battery.
1445      *
1446      * {@hide}
1447      */
1448     public abstract long getFlashlightOnCount(int which);
1449
1450     public static final int NETWORK_MOBILE_RX_DATA = 0;
1451     public static final int NETWORK_MOBILE_TX_DATA = 1;
1452     public static final int NETWORK_WIFI_RX_DATA = 2;
1453     public static final int NETWORK_WIFI_TX_DATA = 3;
1454
1455     public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1;
1456
1457     public abstract long getNetworkActivityBytes(int type, int which);
1458     public abstract long getNetworkActivityPackets(int type, int which);
1459
1460     /**
1461      * Return the wall clock time when battery stats data collection started.
1462      */
1463     public abstract long getStartClockTime();
1464
1465     /**
1466      * Return platform version tag that we were running in when the battery stats started.
1467      */
1468     public abstract String getStartPlatformVersion();
1469
1470     /**
1471      * Return platform version tag that we were running in when the battery stats ended.
1472      */
1473     public abstract String getEndPlatformVersion();
1474
1475     /**
1476      * Return the internal version code of the parcelled format.
1477      */
1478     public abstract int getParcelVersion();
1479
1480     /**
1481      * Return whether we are currently running on battery.
1482      */
1483     public abstract boolean getIsOnBattery();
1484     
1485     /**
1486      * Returns a SparseArray containing the statistics for each uid.
1487      */
1488     public abstract SparseArray<? extends Uid> getUidStats();
1489
1490     /**
1491      * Returns the current battery uptime in microseconds.
1492      *
1493      * @param curTime the amount of elapsed realtime in microseconds.
1494      */
1495     public abstract long getBatteryUptime(long curTime);
1496
1497     /**
1498      * Returns the current battery realtime in microseconds.
1499      *
1500      * @param curTime the amount of elapsed realtime in microseconds.
1501      */
1502     public abstract long getBatteryRealtime(long curTime);
1503     
1504     /**
1505      * Returns the battery percentage level at the last time the device was unplugged from power, or
1506      * the last time it booted on battery power. 
1507      */
1508     public abstract int getDischargeStartLevel();
1509     
1510     /**
1511      * Returns the current battery percentage level if we are in a discharge cycle, otherwise
1512      * returns the level at the last plug event.
1513      */
1514     public abstract int getDischargeCurrentLevel();
1515
1516     /**
1517      * Get the amount the battery has discharged since the stats were
1518      * last reset after charging, as a lower-end approximation.
1519      */
1520     public abstract int getLowDischargeAmountSinceCharge();
1521
1522     /**
1523      * Get the amount the battery has discharged since the stats were
1524      * last reset after charging, as an upper-end approximation.
1525      */
1526     public abstract int getHighDischargeAmountSinceCharge();
1527
1528     /**
1529      * Retrieve the discharge amount over the selected discharge period <var>which</var>.
1530      */
1531     public abstract int getDischargeAmount(int which);
1532
1533     /**
1534      * Get the amount the battery has discharged while the screen was on,
1535      * since the last time power was unplugged.
1536      */
1537     public abstract int getDischargeAmountScreenOn();
1538
1539     /**
1540      * Get the amount the battery has discharged while the screen was on,
1541      * since the last time the device was charged.
1542      */
1543     public abstract int getDischargeAmountScreenOnSinceCharge();
1544
1545     /**
1546      * Get the amount the battery has discharged while the screen was off,
1547      * since the last time power was unplugged.
1548      */
1549     public abstract int getDischargeAmountScreenOff();
1550
1551     /**
1552      * Get the amount the battery has discharged while the screen was off,
1553      * since the last time the device was charged.
1554      */
1555     public abstract int getDischargeAmountScreenOffSinceCharge();
1556
1557     /**
1558      * Returns the total, last, or current battery uptime in microseconds.
1559      *
1560      * @param curTime the elapsed realtime in microseconds.
1561      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1562      */
1563     public abstract long computeBatteryUptime(long curTime, int which);
1564
1565     /**
1566      * Returns the total, last, or current battery realtime in microseconds.
1567      *
1568      * @param curTime the current elapsed realtime in microseconds.
1569      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1570      */
1571     public abstract long computeBatteryRealtime(long curTime, int which);
1572
1573     /**
1574      * Returns the total, last, or current battery screen off uptime in microseconds.
1575      *
1576      * @param curTime the elapsed realtime in microseconds.
1577      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1578      */
1579     public abstract long computeBatteryScreenOffUptime(long curTime, int which);
1580
1581     /**
1582      * Returns the total, last, or current battery screen off realtime in microseconds.
1583      *
1584      * @param curTime the current elapsed realtime in microseconds.
1585      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1586      */
1587     public abstract long computeBatteryScreenOffRealtime(long curTime, int which);
1588
1589     /**
1590      * Returns the total, last, or current uptime in microseconds.
1591      *
1592      * @param curTime the current elapsed realtime in microseconds.
1593      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1594      */
1595     public abstract long computeUptime(long curTime, int which);
1596
1597     /**
1598      * Returns the total, last, or current realtime in microseconds.
1599      *
1600      * @param curTime the current elapsed realtime in microseconds.
1601      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1602      */
1603     public abstract long computeRealtime(long curTime, int which);
1604
1605     /**
1606      * Compute an approximation for how much run time (in microseconds) is remaining on
1607      * the battery.  Returns -1 if no time can be computed: either there is not
1608      * enough current data to make a decision, or the battery is currently
1609      * charging.
1610      *
1611      * @param curTime The current elepsed realtime in microseconds.
1612      */
1613     public abstract long computeBatteryTimeRemaining(long curTime);
1614
1615     // The part of a step duration that is the actual time.
1616     public static final long STEP_LEVEL_TIME_MASK = 0x000000ffffffffffL;
1617
1618     // Bits in a step duration that are the new battery level we are at.
1619     public static final long STEP_LEVEL_LEVEL_MASK = 0x0000ff0000000000L;
1620     public static final long STEP_LEVEL_LEVEL_SHIFT = 40;
1621
1622     // Bits in a step duration that are the initial mode we were in at that step.
1623     public static final long STEP_LEVEL_INITIAL_MODE_MASK = 0x00ff000000000000L;
1624     public static final long STEP_LEVEL_INITIAL_MODE_SHIFT = 48;
1625
1626     // Bits in a step duration that indicate which modes changed during that step.
1627     public static final long STEP_LEVEL_MODIFIED_MODE_MASK = 0xff00000000000000L;
1628     public static final long STEP_LEVEL_MODIFIED_MODE_SHIFT = 56;
1629
1630     // Step duration mode: the screen is on, off, dozed, etc; value is Display.STATE_* - 1.
1631     public static final int STEP_LEVEL_MODE_SCREEN_STATE = 0x03;
1632
1633     // Step duration mode: power save is on.
1634     public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04;
1635
1636     /**
1637      * Return the historical number of discharge steps we currently have.
1638      */
1639     public abstract int getNumDischargeStepDurations();
1640
1641     /**
1642      * Return the array of discharge step durations; the number of valid
1643      * items in it is returned by {@link #getNumDischargeStepDurations()}.
1644      * These values are in milliseconds.
1645      */
1646     public abstract long[] getDischargeStepDurationsArray();
1647
1648     /**
1649      * Compute an approximation for how much time (in microseconds) remains until the battery
1650      * is fully charged.  Returns -1 if no time can be computed: either there is not
1651      * enough current data to make a decision, or the battery is currently
1652      * discharging.
1653      *
1654      * @param curTime The current elepsed realtime in microseconds.
1655      */
1656     public abstract long computeChargeTimeRemaining(long curTime);
1657
1658     /**
1659      * Return the historical number of charge steps we currently have.
1660      */
1661     public abstract int getNumChargeStepDurations();
1662
1663     /**
1664      * Return the array of charge step durations; the number of valid
1665      * items in it is returned by {@link #getNumChargeStepDurations()}.
1666      * These values are in milliseconds.
1667      */
1668     public abstract long[] getChargeStepDurationsArray();
1669
1670     public abstract Map<String, ? extends LongCounter> getWakeupReasonStats();
1671
1672     public abstract Map<String, ? extends Timer> getKernelWakelockStats();
1673
1674     /** Returns the number of different speeds that the CPU can run at */
1675     public abstract int getCpuSpeedSteps();
1676
1677     public abstract void writeToParcelWithoutUids(Parcel out, int flags);
1678
1679     private final static void formatTimeRaw(StringBuilder out, long seconds) {
1680         long days = seconds / (60 * 60 * 24);
1681         if (days != 0) {
1682             out.append(days);
1683             out.append("d ");
1684         }
1685         long used = days * 60 * 60 * 24;
1686
1687         long hours = (seconds - used) / (60 * 60);
1688         if (hours != 0 || used != 0) {
1689             out.append(hours);
1690             out.append("h ");
1691         }
1692         used += hours * 60 * 60;
1693
1694         long mins = (seconds-used) / 60;
1695         if (mins != 0 || used != 0) {
1696             out.append(mins);
1697             out.append("m ");
1698         }
1699         used += mins * 60;
1700
1701         if (seconds != 0 || used != 0) {
1702             out.append(seconds-used);
1703             out.append("s ");
1704         }
1705     }
1706
1707     public final static void formatTime(StringBuilder sb, long time) {
1708         long sec = time / 100;
1709         formatTimeRaw(sb, sec);
1710         sb.append((time - (sec * 100)) * 10);
1711         sb.append("ms ");
1712     }
1713
1714     public final static void formatTimeMs(StringBuilder sb, long time) {
1715         long sec = time / 1000;
1716         formatTimeRaw(sb, sec);
1717         sb.append(time - (sec * 1000));
1718         sb.append("ms ");
1719     }
1720
1721     public final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
1722         long sec = time / 1000;
1723         formatTimeRaw(sb, sec);
1724         sb.append(time - (sec * 1000));
1725         sb.append("ms");
1726     }
1727
1728     public final String formatRatioLocked(long num, long den) {
1729         if (den == 0L) {
1730             return "--%";
1731         }
1732         float perc = ((float)num) / ((float)den) * 100;
1733         mFormatBuilder.setLength(0);
1734         mFormatter.format("%.1f%%", perc);
1735         return mFormatBuilder.toString();
1736     }
1737
1738     final String formatBytesLocked(long bytes) {
1739         mFormatBuilder.setLength(0);
1740         
1741         if (bytes < BYTES_PER_KB) {
1742             return bytes + "B";
1743         } else if (bytes < BYTES_PER_MB) {
1744             mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
1745             return mFormatBuilder.toString();
1746         } else if (bytes < BYTES_PER_GB){
1747             mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
1748             return mFormatBuilder.toString();
1749         } else {
1750             mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
1751             return mFormatBuilder.toString();
1752         }
1753     }
1754
1755     private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) {
1756         if (timer != null) {
1757             // Convert from microseconds to milliseconds with rounding
1758             long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
1759             long totalTimeMillis = (totalTimeMicros + 500) / 1000;
1760             return totalTimeMillis;
1761         }
1762         return 0;
1763     }
1764
1765     /**
1766      *
1767      * @param sb a StringBuilder object.
1768      * @param timer a Timer object contining the wakelock times.
1769      * @param elapsedRealtimeUs the current on-battery time in microseconds.
1770      * @param name the name of the wakelock.
1771      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1772      * @param linePrefix a String to be prepended to each line of output.
1773      * @return the line prefix
1774      */
1775     private static final String printWakeLock(StringBuilder sb, Timer timer,
1776             long elapsedRealtimeUs, String name, int which, String linePrefix) {
1777         
1778         if (timer != null) {
1779             long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which);
1780             
1781             int count = timer.getCountLocked(which);
1782             if (totalTimeMillis != 0) {
1783                 sb.append(linePrefix);
1784                 formatTimeMs(sb, totalTimeMillis);
1785                 if (name != null) {
1786                     sb.append(name);
1787                     sb.append(' ');
1788                 }
1789                 sb.append('(');
1790                 sb.append(count);
1791                 sb.append(" times)");
1792                 return ", ";
1793             }
1794         }
1795         return linePrefix;
1796     }
1797     
1798     /**
1799      * Checkin version of wakelock printer. Prints simple comma-separated list.
1800      * 
1801      * @param sb a StringBuilder object.
1802      * @param timer a Timer object contining the wakelock times.
1803      * @param elapsedRealtimeUs the current time in microseconds.
1804      * @param name the name of the wakelock.
1805      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
1806      * @param linePrefix a String to be prepended to each line of output.
1807      * @return the line prefix
1808      */
1809     private static final String printWakeLockCheckin(StringBuilder sb, Timer timer,
1810             long elapsedRealtimeUs, String name, int which, String linePrefix) {
1811         long totalTimeMicros = 0;
1812         int count = 0;
1813         if (timer != null) {
1814             totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
1815             count = timer.getCountLocked(which); 
1816         }
1817         sb.append(linePrefix);
1818         sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
1819         sb.append(',');
1820         sb.append(name != null ? name + "," : "");
1821         sb.append(count);
1822         return ",";
1823     }
1824     
1825     /**
1826      * Dump a comma-separated line of values for terse checkin mode.
1827      * 
1828      * @param pw the PageWriter to dump log to
1829      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
1830      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
1831      * @param args type-dependent data arguments
1832      */
1833     private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 
1834            Object... args ) {
1835         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
1836         pw.print(uid); pw.print(',');
1837         pw.print(category); pw.print(',');
1838         pw.print(type);
1839         
1840         for (Object arg : args) {  
1841             pw.print(',');
1842             pw.print(arg);
1843         }
1844         pw.println();
1845     }
1846
1847     /**
1848      * Temporary for settings.
1849      */
1850     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
1851         dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
1852     }
1853
1854     /**
1855      * Checkin server version of dump to produce more compact, computer-readable log.
1856      * 
1857      * NOTE: all times are expressed in 'ms'.
1858      */
1859     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
1860             boolean wifiOnly) {
1861         final long rawUptime = SystemClock.uptimeMillis() * 1000;
1862         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
1863         final long batteryUptime = getBatteryUptime(rawUptime);
1864         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
1865         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
1866         final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
1867         final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
1868                 which);
1869         final long totalRealtime = computeRealtime(rawRealtime, which);
1870         final long totalUptime = computeUptime(rawUptime, which);
1871         final long screenOnTime = getScreenOnTime(rawRealtime, which);
1872         final long interactiveTime = getInteractiveTime(rawRealtime, which);
1873         final long lowPowerModeEnabledTime = getLowPowerModeEnabledTime(rawRealtime, which);
1874         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
1875         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
1876         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
1877         final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which);
1878
1879         StringBuilder sb = new StringBuilder(128);
1880         
1881         SparseArray<? extends Uid> uidStats = getUidStats();
1882         final int NU = uidStats.size();
1883         
1884         String category = STAT_NAMES[which];
1885
1886         // Dump "battery" stat
1887         dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 
1888                 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
1889                 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
1890                 totalRealtime / 1000, totalUptime / 1000,
1891                 getStartClockTime(),
1892                 whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000);
1893         
1894         // Calculate wakelock times across all uids.
1895         long fullWakeLockTimeTotal = 0;
1896         long partialWakeLockTimeTotal = 0;
1897         
1898         for (int iu = 0; iu < NU; iu++) {
1899             Uid u = uidStats.valueAt(iu);
1900
1901             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1902             if (wakelocks.size() > 0) {
1903                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 
1904                         : wakelocks.entrySet()) {
1905                     Uid.Wakelock wl = ent.getValue();
1906                     
1907                     Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1908                     if (fullWakeTimer != null) {
1909                         fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
1910                                 which);
1911                     }
1912
1913                     Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1914                     if (partialWakeTimer != null) {
1915                         partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
1916                             rawRealtime, which);
1917                     }
1918                 }
1919             }
1920         }
1921         
1922         long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
1923         long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
1924         long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
1925         long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
1926         long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
1927         long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
1928         long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
1929         long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
1930
1931         // Dump network stats
1932         dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
1933                 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
1934                 mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets);
1935
1936         // Dump misc stats
1937         dumpLine(pw, 0 /* uid */, category, MISC_DATA,
1938                 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
1939                 wifiRunningTime / 1000, bluetoothOnTime / 1000,
1940                 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
1941                 fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000,
1942                 0 /*legacy input event count*/, getMobileRadioActiveTime(rawRealtime, which) / 1000,
1943                 getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000,
1944                 lowPowerModeEnabledTime / 1000);
1945         
1946         // Dump screen brightness stats
1947         Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
1948         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1949             args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
1950         }
1951         dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
1952         
1953         // Dump signal strength stats
1954         args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
1955         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
1956             args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
1957         }
1958         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
1959         dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
1960                 getPhoneSignalScanningTime(rawRealtime, which) / 1000);
1961         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
1962             args[i] = getPhoneSignalStrengthCount(i, which);
1963         }
1964         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
1965
1966         // Dump network type stats
1967         args = new Object[NUM_DATA_CONNECTION_TYPES];
1968         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1969             args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
1970         }
1971         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
1972         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1973             args[i] = getPhoneDataConnectionCount(i, which);
1974         }
1975         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
1976
1977         // Dump wifi state stats
1978         args = new Object[NUM_WIFI_STATES];
1979         for (int i=0; i<NUM_WIFI_STATES; i++) {
1980             args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
1981         }
1982         dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args);
1983         for (int i=0; i<NUM_WIFI_STATES; i++) {
1984             args[i] = getWifiStateCount(i, which);
1985         }
1986         dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args);
1987
1988         // Dump wifi suppl state stats
1989         args = new Object[NUM_WIFI_SUPPL_STATES];
1990         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
1991             args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
1992         }
1993         dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_TIME_DATA, args);
1994         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
1995             args[i] = getWifiSupplStateCount(i, which);
1996         }
1997         dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_COUNT_DATA, args);
1998
1999         // Dump wifi signal strength stats
2000         args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
2001         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
2002             args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
2003         }
2004         dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
2005         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
2006             args[i] = getWifiSignalStrengthCount(i, which);
2007         }
2008         dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
2009
2010         // Dump bluetooth state stats
2011         args = new Object[NUM_BLUETOOTH_STATES];
2012         for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
2013             args[i] = getBluetoothStateTime(i, rawRealtime, which) / 1000;
2014         }
2015         dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_TIME_DATA, args);
2016         for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
2017             args[i] = getBluetoothStateCount(i, which);
2018         }
2019         dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_COUNT_DATA, args);
2020
2021         if (which == STATS_SINCE_UNPLUGGED) {
2022             dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
2023                     getDischargeCurrentLevel());
2024         }
2025         
2026         if (which == STATS_SINCE_UNPLUGGED) {
2027             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
2028                     getDischargeStartLevel()-getDischargeCurrentLevel(),
2029                     getDischargeStartLevel()-getDischargeCurrentLevel(),
2030                     getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
2031         } else {
2032             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
2033                     getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
2034                     getDischargeAmountScreenOnSinceCharge(),
2035                     getDischargeAmountScreenOffSinceCharge());
2036         }
2037         
2038         if (reqUid < 0) {
2039             Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
2040             if (kernelWakelocks.size() > 0) {
2041                 for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
2042                     sb.setLength(0);
2043                     printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
2044                     dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
2045                             sb.toString());
2046                 }
2047             }
2048             Map<String, ? extends LongCounter> wakeupReasons = getWakeupReasonStats();
2049             if (wakeupReasons.size() > 0) {
2050                 for (Map.Entry<String, ? extends LongCounter> ent : wakeupReasons.entrySet()) {
2051                     dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA,
2052                             "\"" + ent.getKey() + "\"", ent.getValue().getCountLocked(which));
2053                 }
2054             }
2055         }
2056         
2057         BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
2058         helper.create(this);
2059         helper.refreshStats(which, UserHandle.USER_ALL);
2060         List<BatterySipper> sippers = helper.getUsageList();
2061         if (sippers != null && sippers.size() > 0) {
2062             dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
2063                     BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
2064                     BatteryStatsHelper.makemAh(helper.getComputedPower()),
2065                     BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
2066                     BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
2067             for (int i=0; i<sippers.size(); i++) {
2068                 BatterySipper bs = sippers.get(i);
2069                 int uid = 0;
2070                 String label;
2071                 switch (bs.drainType) {
2072                     case IDLE:
2073                         label="idle";
2074                         break;
2075                     case CELL:
2076                         label="cell";
2077                         break;
2078                     case PHONE:
2079                         label="phone";
2080                         break;
2081                     case WIFI:
2082                         label="wifi";
2083                         break;
2084                     case BLUETOOTH:
2085                         label="blue";
2086                         break;
2087                     case SCREEN:
2088                         label="scrn";
2089                         break;
2090                     case FLASHLIGHT:
2091                         label="flashlight";
2092                         break;
2093                     case APP:
2094                         uid = bs.uidObj.getUid();
2095                         label = "uid";
2096                         break;
2097                     case USER:
2098                         uid = UserHandle.getUid(bs.userId, 0);
2099                         label = "user";
2100                         break;
2101                     case UNACCOUNTED:
2102                         label = "unacc";
2103                         break;
2104                     case OVERCOUNTED:
2105                         label = "over";
2106                         break;
2107                     default:
2108                         label = "???";
2109                 }
2110                 dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
2111                         BatteryStatsHelper.makemAh(bs.value));
2112             }
2113         }
2114
2115         for (int iu = 0; iu < NU; iu++) {
2116             final int uid = uidStats.keyAt(iu);
2117             if (reqUid >= 0 && uid != reqUid) {
2118                 continue;
2119             }
2120             Uid u = uidStats.valueAt(iu);
2121             // Dump Network stats per uid, if any
2122             long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
2123             long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
2124             long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
2125             long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
2126             long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
2127             long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
2128             long mobileActiveTime = u.getMobileRadioActiveTime(which);
2129             int mobileActiveCount = u.getMobileRadioActiveCount(which);
2130             long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
2131             long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
2132             long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
2133             long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
2134             long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
2135
2136             if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
2137                     || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
2138                     || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0) {
2139                 dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
2140                         wifiBytesRx, wifiBytesTx,
2141                         mobilePacketsRx, mobilePacketsTx,
2142                         wifiPacketsRx, wifiPacketsTx,
2143                         mobileActiveTime, mobileActiveCount);
2144             }
2145
2146             if (fullWifiLockOnTime != 0 || wifiScanTime != 0
2147                     || uidWifiRunningTime != 0) {
2148                 dumpLine(pw, uid, category, WIFI_DATA,
2149                         fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime);
2150             }
2151
2152             if (u.hasUserActivity()) {
2153                 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
2154                 boolean hasData = false;
2155                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
2156                     int val = u.getUserActivityCount(i, which);
2157                     args[i] = val;
2158                     if (val != 0) hasData = true;
2159                 }
2160                 if (hasData) {
2161                     dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args);
2162                 }
2163             }
2164             
2165             Map<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
2166             if (wakelocks.size() > 0) {
2167                 for (Map.Entry<String, ? extends Uid.Wakelock> ent : wakelocks.entrySet()) {
2168                     Uid.Wakelock wl = ent.getValue();
2169                     String linePrefix = "";
2170                     sb.setLength(0);
2171                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), 
2172                             rawRealtime, "f", which, linePrefix);
2173                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), 
2174                             rawRealtime, "p", which, linePrefix);
2175                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), 
2176                             rawRealtime, "w", which, linePrefix);
2177                     
2178                     // Only log if we had at lease one wakelock...
2179                     if (sb.length() > 0) {
2180                         String name = ent.getKey();
2181                         if (name.indexOf(',') >= 0) {
2182                             name = name.replace(',', '_');
2183                         }
2184                         dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
2185                     }
2186                 }
2187             }
2188
2189             Map<String, ? extends Timer> syncs = u.getSyncStats();
2190             if (syncs.size() > 0) {
2191                 for (Map.Entry<String, ? extends Timer> ent : syncs.entrySet()) {
2192                     Timer timer = ent.getValue();
2193                     // Convert from microseconds to milliseconds with rounding
2194                     long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2195                     int count = timer.getCountLocked(which);
2196                     if (totalTime != 0) {
2197                         dumpLine(pw, uid, category, SYNC_DATA, ent.getKey(), totalTime, count);
2198                     }
2199                 }
2200             }
2201
2202             Map<String, ? extends Timer> jobs = u.getJobStats();
2203             if (jobs.size() > 0) {
2204                 for (Map.Entry<String, ? extends Timer> ent : jobs.entrySet()) {
2205                     Timer timer = ent.getValue();
2206                     // Convert from microseconds to milliseconds with rounding
2207                     long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2208                     int count = timer.getCountLocked(which);
2209                     if (totalTime != 0) {
2210                         dumpLine(pw, uid, category, JOB_DATA, ent.getKey(), totalTime, count);
2211                     }
2212                 }
2213             }
2214
2215             SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
2216             int NSE = sensors.size();
2217             for (int ise=0; ise<NSE; ise++) {
2218                 Uid.Sensor se = sensors.valueAt(ise);
2219                 int sensorNumber = sensors.keyAt(ise);
2220                 Timer timer = se.getSensorTime();
2221                 if (timer != null) {
2222                     // Convert from microseconds to milliseconds with rounding
2223                     long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2224                     int count = timer.getCountLocked(which);
2225                     if (totalTime != 0) {
2226                         dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
2227                     }
2228                 }
2229             }
2230
2231             Timer vibTimer = u.getVibratorOnTimer();
2232             if (vibTimer != null) {
2233                 // Convert from microseconds to milliseconds with rounding
2234                 long totalTime = (vibTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2235                 int count = vibTimer.getCountLocked(which);
2236                 if (totalTime != 0) {
2237                     dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count);
2238                 }
2239             }
2240
2241             Timer fgTimer = u.getForegroundActivityTimer();
2242             if (fgTimer != null) {
2243                 // Convert from microseconds to milliseconds with rounding
2244                 long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
2245                 int count = fgTimer.getCountLocked(which);
2246                 if (totalTime != 0) {
2247                     dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count);
2248                 }
2249             }
2250
2251             Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
2252             long totalStateTime = 0;
2253             for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
2254                 totalStateTime += u.getProcessStateTime(ips, rawRealtime, which);
2255                 stateTimes[ips] = (totalStateTime + 500) / 1000;
2256             }
2257             if (totalStateTime > 0) {
2258                 dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
2259             }
2260
2261             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
2262             if (processStats.size() > 0) {
2263                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
2264                         : processStats.entrySet()) {
2265                     Uid.Proc ps = ent.getValue();
2266
2267                     final long userMillis = ps.getUserTime(which) * 10;
2268                     final long systemMillis = ps.getSystemTime(which) * 10;
2269                     final long foregroundMillis = ps.getForegroundTime(which) * 10;
2270                     final long starts = ps.getStarts(which);
2271
2272                     if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
2273                             || starts != 0) {
2274                         dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis,
2275                                 systemMillis, foregroundMillis, starts);
2276                     }
2277                 }
2278             }
2279
2280             Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
2281             if (packageStats.size() > 0) {
2282                 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
2283                         : packageStats.entrySet()) {
2284               
2285                     Uid.Pkg ps = ent.getValue();
2286                     int wakeups = ps.getWakeups(which);
2287                     Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
2288                     for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
2289                             : serviceStats.entrySet()) {
2290                         BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
2291                         long startTime = ss.getStartTime(batteryUptime, which);
2292                         int starts = ss.getStarts(which);
2293                         int launches = ss.getLaunches(which);
2294                         if (startTime != 0 || starts != 0 || launches != 0) {
2295                             dumpLine(pw, uid, category, APK_DATA, 
2296                                     wakeups, // wakeup alarms
2297                                     ent.getKey(), // Apk
2298                                     sent.getKey(), // service
2299                                     startTime / 1000, // time spent started, in ms
2300                                     starts,
2301                                     launches);
2302                         }
2303                     }
2304                 }
2305             }
2306         }
2307     }
2308
2309     static final class TimerEntry {
2310         final String mName;
2311         final int mId;
2312         final BatteryStats.Timer mTimer;
2313         final long mTime;
2314         TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
2315             mName = name;
2316             mId = id;
2317             mTimer = timer;
2318             mTime = time;
2319         }
2320     }
2321
2322     private void printmAh(PrintWriter printer, double power) {
2323         printer.print(BatteryStatsHelper.makemAh(power));
2324     }
2325
2326     /**
2327      * Temporary for settings.
2328      */
2329     public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which,
2330             int reqUid) {
2331         dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
2332     }
2333
2334     @SuppressWarnings("unused")
2335     public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
2336             int reqUid, boolean wifiOnly) {
2337         final long rawUptime = SystemClock.uptimeMillis() * 1000;
2338         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
2339         final long batteryUptime = getBatteryUptime(rawUptime);
2340
2341         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
2342         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
2343         final long totalRealtime = computeRealtime(rawRealtime, which);
2344         final long totalUptime = computeUptime(rawUptime, which);
2345         final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
2346         final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
2347                 which);
2348         final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
2349         final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
2350
2351         StringBuilder sb = new StringBuilder(128);
2352         
2353         SparseArray<? extends Uid> uidStats = getUidStats();
2354         final int NU = uidStats.size();
2355
2356         sb.setLength(0);
2357         sb.append(prefix);
2358                 sb.append("  Time on battery: ");
2359                 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
2360                 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
2361                 sb.append(") realtime, ");
2362                 formatTimeMs(sb, whichBatteryUptime / 1000);
2363                 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
2364                 sb.append(") uptime");
2365         pw.println(sb.toString());
2366         sb.setLength(0);
2367         sb.append(prefix);
2368                 sb.append("  Time on battery screen off: ");
2369                 formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("(");
2370                 sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime));
2371                 sb.append(") realtime, ");
2372                 formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
2373                 sb.append("(");
2374                 sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime));
2375                 sb.append(") uptime");
2376         pw.println(sb.toString());
2377         sb.setLength(0);
2378         sb.append(prefix);
2379                 sb.append("  Total run time: ");
2380                 formatTimeMs(sb, totalRealtime / 1000);
2381                 sb.append("realtime, ");
2382                 formatTimeMs(sb, totalUptime / 1000);
2383                 sb.append("uptime");
2384         pw.println(sb.toString());
2385         if (batteryTimeRemaining >= 0) {
2386             sb.setLength(0);
2387             sb.append(prefix);
2388                     sb.append("  Battery time remaining: ");
2389                     formatTimeMs(sb, batteryTimeRemaining / 1000);
2390             pw.println(sb.toString());
2391         }
2392         if (chargeTimeRemaining >= 0) {
2393             sb.setLength(0);
2394             sb.append(prefix);
2395                     sb.append("  Charge time remaining: ");
2396                     formatTimeMs(sb, chargeTimeRemaining / 1000);
2397             pw.println(sb.toString());
2398         }
2399         pw.print("  Start clock time: ");
2400         pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
2401
2402         final long screenOnTime = getScreenOnTime(rawRealtime, which);
2403         final long interactiveTime = getInteractiveTime(rawRealtime, which);
2404         final long lowPowerModeEnabledTime = getLowPowerModeEnabledTime(rawRealtime, which);
2405         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
2406         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
2407         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
2408         final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which);
2409         sb.setLength(0);
2410         sb.append(prefix);
2411                 sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
2412                 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
2413                 sb.append(") "); sb.append(getScreenOnCount(which));
2414                 sb.append("x, Interactive: "); formatTimeMs(sb, interactiveTime / 1000);
2415                 sb.append("("); sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime));
2416                 sb.append(")");
2417         pw.println(sb.toString());
2418         sb.setLength(0);
2419         sb.append(prefix);
2420         sb.append("  Screen brightnesses:");
2421         boolean didOne = false;
2422         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
2423             final long time = getScreenBrightnessTime(i, rawRealtime, which);
2424             if (time == 0) {
2425                 continue;
2426             }
2427             sb.append("\n    ");
2428             sb.append(prefix);
2429             didOne = true;
2430             sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
2431             sb.append(" ");
2432             formatTimeMs(sb, time/1000);
2433             sb.append("(");
2434             sb.append(formatRatioLocked(time, screenOnTime));
2435             sb.append(")");
2436         }
2437         if (!didOne) sb.append(" (no activity)");
2438         pw.println(sb.toString());
2439         if (lowPowerModeEnabledTime != 0) {
2440             sb.setLength(0);
2441             sb.append(prefix);
2442                     sb.append("  Low power mode enabled: ");
2443                     formatTimeMs(sb, lowPowerModeEnabledTime / 1000);
2444                     sb.append("(");
2445                     sb.append(formatRatioLocked(lowPowerModeEnabledTime, whichBatteryRealtime));
2446                     sb.append(")");
2447             pw.println(sb.toString());
2448         }
2449         if (phoneOnTime != 0) {
2450             sb.setLength(0);
2451             sb.append(prefix);
2452                     sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
2453                     sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
2454                     sb.append(") "); sb.append(getPhoneOnCount(which));
2455         }
2456
2457         // Calculate wakelock times across all uids.
2458         long fullWakeLockTimeTotalMicros = 0;
2459         long partialWakeLockTimeTotalMicros = 0;
2460
2461         final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
2462
2463         for (int iu = 0; iu < NU; iu++) {
2464             Uid u = uidStats.valueAt(iu);
2465
2466             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
2467             if (wakelocks.size() > 0) {
2468                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 
2469                         : wakelocks.entrySet()) {
2470                     Uid.Wakelock wl = ent.getValue();
2471                     
2472                     Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
2473                     if (fullWakeTimer != null) {
2474                         fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
2475                                 rawRealtime, which);
2476                     }
2477
2478                     Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
2479                     if (partialWakeTimer != null) {
2480                         long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
2481                                 rawRealtime, which);
2482                         if (totalTimeMicros > 0) {
2483                             if (reqUid < 0) {
2484                                 // Only show the ordered list of all wake
2485                                 // locks if the caller is not asking for data
2486                                 // about a specific uid.
2487                                 timers.add(new TimerEntry(ent.getKey(), u.getUid(),
2488                                         partialWakeTimer, totalTimeMicros));
2489                             }
2490                             partialWakeLockTimeTotalMicros += totalTimeMicros;
2491                         }
2492                     }
2493                 }
2494             }
2495         }
2496         
2497         long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
2498         long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
2499         long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
2500         long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
2501         long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
2502         long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
2503         long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
2504         long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
2505
2506         if (fullWakeLockTimeTotalMicros != 0) {
2507             sb.setLength(0);
2508             sb.append(prefix);
2509                     sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
2510                             (fullWakeLockTimeTotalMicros + 500) / 1000);
2511             pw.println(sb.toString());
2512         }
2513
2514         if (partialWakeLockTimeTotalMicros != 0) {
2515             sb.setLength(0);
2516             sb.append(prefix);
2517                     sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
2518                             (partialWakeLockTimeTotalMicros + 500) / 1000);
2519             pw.println(sb.toString());
2520         }
2521
2522         pw.print(prefix);
2523                 pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
2524                 pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
2525                 pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
2526                 pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
2527         sb.setLength(0);
2528         sb.append(prefix);
2529         sb.append("  Phone signal levels:");
2530         didOne = false;
2531         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
2532             final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
2533             if (time == 0) {
2534                 continue;
2535             }
2536             sb.append("\n    ");
2537             sb.append(prefix);
2538             didOne = true;
2539             sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
2540             sb.append(" ");
2541             formatTimeMs(sb, time/1000);
2542             sb.append("(");
2543             sb.append(formatRatioLocked(time, whichBatteryRealtime));
2544             sb.append(") ");
2545             sb.append(getPhoneSignalStrengthCount(i, which));
2546             sb.append("x");
2547         }
2548         if (!didOne) sb.append(" (no activity)");
2549         pw.println(sb.toString());
2550
2551         sb.setLength(0);
2552         sb.append(prefix);
2553         sb.append("  Signal scanning time: ");
2554         formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
2555         pw.println(sb.toString());
2556
2557         sb.setLength(0);
2558         sb.append(prefix);
2559         sb.append("  Radio types:");
2560         didOne = false;
2561         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
2562             final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
2563             if (time == 0) {
2564                 continue;
2565             }
2566             sb.append("\n    ");
2567             sb.append(prefix);
2568             didOne = true;
2569             sb.append(DATA_CONNECTION_NAMES[i]);
2570             sb.append(" ");
2571             formatTimeMs(sb, time/1000);
2572             sb.append("(");
2573             sb.append(formatRatioLocked(time, whichBatteryRealtime));
2574             sb.append(") ");
2575             sb.append(getPhoneDataConnectionCount(i, which));
2576             sb.append("x");
2577         }
2578         if (!didOne) sb.append(" (no activity)");
2579         pw.println(sb.toString());
2580
2581         sb.setLength(0);
2582         sb.append(prefix);
2583         sb.append("  Mobile radio active time: ");
2584         final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
2585         formatTimeMs(sb, mobileActiveTime / 1000);
2586         sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
2587         sb.append(") "); sb.append(getMobileRadioActiveCount(which));
2588         sb.append("x");
2589         pw.println(sb.toString());
2590
2591         final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
2592         if (mobileActiveUnknownTime != 0) {
2593             sb.setLength(0);
2594             sb.append(prefix);
2595             sb.append("  Mobile radio active unknown time: ");
2596             formatTimeMs(sb, mobileActiveUnknownTime / 1000);
2597             sb.append("(");
2598             sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
2599             sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which));
2600             sb.append("x");
2601             pw.println(sb.toString());
2602         }
2603
2604         final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which);
2605         if (mobileActiveAdjustedTime != 0) {
2606             sb.setLength(0);
2607             sb.append(prefix);
2608             sb.append("  Mobile radio active adjusted time: ");
2609             formatTimeMs(sb, mobileActiveAdjustedTime / 1000);
2610             sb.append("(");
2611             sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime));
2612             sb.append(")");
2613             pw.println(sb.toString());
2614         }
2615
2616         pw.print(prefix);
2617                 pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
2618                 pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
2619                 pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
2620                 pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
2621         sb.setLength(0);
2622         sb.append(prefix);
2623                 sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
2624                 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
2625                 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
2626                 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
2627                 sb.append(")");
2628         pw.println(sb.toString());
2629
2630         sb.setLength(0);
2631         sb.append(prefix);
2632         sb.append("  Wifi states:");
2633         didOne = false;
2634         for (int i=0; i<NUM_WIFI_STATES; i++) {
2635             final long time = getWifiStateTime(i, rawRealtime, which);
2636             if (time == 0) {
2637                 continue;
2638             }
2639             sb.append("\n    ");
2640             didOne = true;
2641             sb.append(WIFI_STATE_NAMES[i]);
2642             sb.append(" ");
2643             formatTimeMs(sb, time/1000);
2644             sb.append("(");
2645             sb.append(formatRatioLocked(time, whichBatteryRealtime));
2646             sb.append(") ");
2647             sb.append(getWifiStateCount(i, which));
2648             sb.append("x");
2649         }
2650         if (!didOne) sb.append(" (no activity)");
2651         pw.println(sb.toString());
2652
2653         sb.setLength(0);
2654         sb.append(prefix);
2655         sb.append("  Wifi supplicant states:");
2656         didOne = false;
2657         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
2658             final long time = getWifiSupplStateTime(i, rawRealtime, which);
2659             if (time == 0) {
2660                 continue;
2661             }
2662             sb.append("\n    ");
2663             didOne = true;
2664             sb.append(WIFI_SUPPL_STATE_NAMES[i]);
2665             sb.append(" ");
2666             formatTimeMs(sb, time/1000);
2667             sb.append("(");
2668             sb.append(formatRatioLocked(time, whichBatteryRealtime));
2669             sb.append(") ");
2670             sb.append(getWifiSupplStateCount(i, which));
2671             sb.append("x");
2672         }
2673         if (!didOne) sb.append(" (no activity)");
2674         pw.println(sb.toString());
2675
2676         sb.setLength(0);
2677         sb.append(prefix);
2678         sb.append("  Wifi signal levels:");
2679         didOne = false;
2680         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
2681             final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
2682             if (time == 0) {
2683                 continue;
2684             }
2685             sb.append("\n    ");
2686             sb.append(prefix);
2687             didOne = true;
2688             sb.append("level(");
2689             sb.append(i);
2690             sb.append(") ");
2691             formatTimeMs(sb, time/1000);
2692             sb.append("(");
2693             sb.append(formatRatioLocked(time, whichBatteryRealtime));
2694             sb.append(") ");
2695             sb.append(getWifiSignalStrengthCount(i, which));
2696             sb.append("x");
2697         }
2698         if (!didOne) sb.append(" (no activity)");
2699         pw.println(sb.toString());
2700
2701         sb.setLength(0);
2702         sb.append(prefix);
2703                 sb.append("  Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
2704                 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
2705                 sb.append(")");
2706         pw.println(sb.toString());
2707
2708         sb.setLength(0);
2709         sb.append(prefix);
2710         sb.append("  Bluetooth states:");
2711         didOne = false;
2712         for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
2713             final long time = getBluetoothStateTime(i, rawRealtime, which);
2714             if (time == 0) {
2715                 continue;
2716             }
2717             sb.append("\n    ");
2718             didOne = true;
2719             sb.append(BLUETOOTH_STATE_NAMES[i]);
2720             sb.append(" ");
2721             formatTimeMs(sb, time/1000);
2722             sb.append("(");
2723             sb.append(formatRatioLocked(time, whichBatteryRealtime));
2724             sb.append(") ");
2725             sb.append(getPhoneDataConnectionCount(i, which));
2726             sb.append("x");
2727         }
2728         if (!didOne) sb.append(" (no activity)");
2729         pw.println(sb.toString());
2730
2731         pw.println();
2732
2733         if (which == STATS_SINCE_UNPLUGGED) {
2734             if (getIsOnBattery()) {
2735                 pw.print(prefix); pw.println("  Device is currently unplugged");
2736                 pw.print(prefix); pw.print("    Discharge cycle start level: "); 
2737                         pw.println(getDischargeStartLevel());
2738                 pw.print(prefix); pw.print("    Discharge cycle current level: ");
2739                         pw.println(getDischargeCurrentLevel());
2740             } else {
2741                 pw.print(prefix); pw.println("  Device is currently plugged into power");
2742                 pw.print(prefix); pw.print("    Last discharge cycle start level: "); 
2743                         pw.println(getDischargeStartLevel());
2744                 pw.print(prefix); pw.print("    Last discharge cycle end level: "); 
2745                         pw.println(getDischargeCurrentLevel());
2746             }
2747             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
2748                     pw.println(getDischargeAmountScreenOn());
2749             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
2750                     pw.println(getDischargeAmountScreenOff());
2751             pw.println(" ");
2752         } else {
2753             pw.print(prefix); pw.println("  Device battery use since last full charge");
2754             pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
2755                     pw.println(getLowDischargeAmountSinceCharge());
2756             pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
2757                     pw.println(getHighDischargeAmountSinceCharge());
2758             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
2759                     pw.println(getDischargeAmountScreenOnSinceCharge());
2760             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
2761                     pw.println(getDischargeAmountScreenOffSinceCharge());
2762             pw.println();
2763         }
2764
2765         BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
2766         helper.create(this);
2767         helper.refreshStats(which, UserHandle.USER_ALL);
2768         List<BatterySipper> sippers = helper.getUsageList();
2769         if (sippers != null && sippers.size() > 0) {
2770             pw.print(prefix); pw.println("  Estimated power use (mAh):");
2771             pw.print(prefix); pw.print("    Capacity: ");
2772                     printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
2773                     pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
2774                     pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower());
2775                     if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
2776                         pw.print("-"); printmAh(pw, helper.getMaxDrainedPower());
2777                     }
2778                     pw.println();
2779             for (int i=0; i<sippers.size(); i++) {
2780                 BatterySipper bs = sippers.get(i);
2781                 switch (bs.drainType) {
2782                     case IDLE:
2783                         pw.print(prefix); pw.print("    Idle: "); printmAh(pw, bs.value);
2784                         pw.println();
2785                         break;
2786                     case CELL:
2787                         pw.print(prefix); pw.print("    Cell standby: "); printmAh(pw, bs.value);
2788                         pw.println();
2789                         break;
2790                     case PHONE:
2791                         pw.print(prefix); pw.print("    Phone calls: "); printmAh(pw, bs.value);
2792                         pw.println();
2793                         break;
2794                     case WIFI:
2795                         pw.print(prefix); pw.print("    Wifi: "); printmAh(pw, bs.value);
2796                         pw.println();
2797                         break;
2798                     case BLUETOOTH:
2799                         pw.print(prefix); pw.print("    Bluetooth: "); printmAh(pw, bs.value);
2800                         pw.println();
2801                         break;
2802                     case SCREEN:
2803                         pw.print(prefix); pw.print("    Screen: "); printmAh(pw, bs.value);
2804                         pw.println();
2805                         break;
2806                     case FLASHLIGHT:
2807                         pw.print(prefix); pw.print("    Flashlight: "); printmAh(pw, bs.value);
2808                         pw.println();
2809                         break;
2810                     case APP:
2811                         pw.print(prefix); pw.print("    Uid ");
2812                         UserHandle.formatUid(pw, bs.uidObj.getUid());
2813                         pw.print(": "); printmAh(pw, bs.value); pw.println();
2814                         break;
2815                     case USER:
2816                         pw.print(prefix); pw.print("    User "); pw.print(bs.userId);
2817                         pw.print(": "); printmAh(pw, bs.value); pw.println();
2818                         break;
2819                     case UNACCOUNTED:
2820                         pw.print(prefix); pw.print("    Unaccounted: "); printmAh(pw, bs.value);
2821                         pw.println();
2822                         break;
2823                     case OVERCOUNTED:
2824                         pw.print(prefix); pw.print("    Over-counted: "); printmAh(pw, bs.value);
2825                         pw.println();
2826                         break;
2827                 }
2828             }
2829             pw.println();
2830         }
2831
2832         sippers = helper.getMobilemsppList();
2833         if (sippers != null && sippers.size() > 0) {
2834             pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
2835             long totalTime = 0;
2836             for (int i=0; i<sippers.size(); i++) {
2837                 BatterySipper bs = sippers.get(i);
2838                 sb.setLength(0);
2839                 sb.append(prefix); sb.append("    Uid ");
2840                 UserHandle.formatUid(sb, bs.uidObj.getUid());
2841                 sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
2842                 sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
2843                 sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
2844                 sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
2845                 pw.println(sb.toString());
2846                 totalTime += bs.mobileActive;
2847             }
2848             sb.setLength(0);
2849             sb.append(prefix);
2850             sb.append("    TOTAL TIME: ");
2851             formatTimeMs(sb, totalTime);
2852             sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
2853             sb.append(")");
2854             pw.println(sb.toString());
2855             pw.println();
2856         }
2857
2858         final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
2859             @Override
2860             public int compare(TimerEntry lhs, TimerEntry rhs) {
2861                 long lhsTime = lhs.mTime;
2862                 long rhsTime = rhs.mTime;
2863                 if (lhsTime < rhsTime) {
2864                     return 1;
2865                 }
2866                 if (lhsTime > rhsTime) {
2867                     return -1;
2868                 }
2869                 return 0;
2870             }
2871         };
2872
2873         if (reqUid < 0) {
2874             Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
2875             if (kernelWakelocks.size() > 0) {
2876                 final ArrayList<TimerEntry> ktimers = new ArrayList<TimerEntry>();
2877                 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
2878                     BatteryStats.Timer timer = ent.getValue();
2879                     long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
2880                     if (totalTimeMillis > 0) {
2881                         ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
2882                     }
2883                 }
2884                 if (ktimers.size() > 0) {
2885                     Collections.sort(ktimers, timerComparator);
2886                     pw.print(prefix); pw.println("  All kernel wake locks:");
2887                     for (int i=0; i<ktimers.size(); i++) {
2888                         TimerEntry timer = ktimers.get(i);
2889                         String linePrefix = ": ";
2890                         sb.setLength(0);
2891                         sb.append(prefix);
2892                         sb.append("  Kernel Wake lock ");
2893                         sb.append(timer.mName);
2894                         linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null,
2895                                 which, linePrefix);
2896                         if (!linePrefix.equals(": ")) {
2897                             sb.append(" realtime");
2898                             // Only print out wake locks that were held
2899                             pw.println(sb.toString());
2900                         }
2901                     }
2902                     pw.println();
2903                 }
2904             }
2905
2906             if (timers.size() > 0) {
2907                 Collections.sort(timers, timerComparator);
2908                 pw.print(prefix); pw.println("  All partial wake locks:");
2909                 for (int i=0; i<timers.size(); i++) {
2910                     TimerEntry timer = timers.get(i);
2911                     sb.setLength(0);
2912                     sb.append("  Wake lock ");
2913                     UserHandle.formatUid(sb, timer.mId);
2914                     sb.append(" ");
2915                     sb.append(timer.mName);
2916                     printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
2917                     sb.append(" realtime");
2918                     pw.println(sb.toString());
2919                 }
2920                 timers.clear();
2921                 pw.println();
2922             }
2923
2924             Map<String, ? extends LongCounter> wakeupReasons = getWakeupReasonStats();
2925             if (wakeupReasons.size() > 0) {
2926                 pw.print(prefix); pw.println("  All wakeup reasons:");
2927                 final ArrayList<TimerEntry> reasons = new ArrayList<TimerEntry>();
2928                 for (Map.Entry<String, ? extends LongCounter> ent : wakeupReasons.entrySet()) {
2929                     BatteryStats.LongCounter counter = ent.getValue();
2930                     reasons.add(new TimerEntry(ent.getKey(), 0, null,
2931                             ent.getValue().getCountLocked(which)));
2932                 }
2933                 Collections.sort(reasons, timerComparator);
2934                 for (int i=0; i<reasons.size(); i++) {
2935                     TimerEntry timer = reasons.get(i);
2936                     String linePrefix = ": ";
2937                     sb.setLength(0);
2938                     sb.append(prefix);
2939                     sb.append("  Wakeup reason ");
2940                     sb.append(timer.mName);
2941                     sb.append(": ");
2942                     formatTimeMs(sb, timer.mTime);
2943                     sb.append("realtime");
2944                     pw.println(sb.toString());
2945                 }
2946                 pw.println();
2947             }
2948         }
2949
2950         for (int iu=0; iu<NU; iu++) {
2951             final int uid = uidStats.keyAt(iu);
2952             if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
2953                 continue;
2954             }
2955             
2956             Uid u = uidStats.valueAt(iu);
2957
2958             pw.print(prefix);
2959             pw.print("  ");
2960             UserHandle.formatUid(pw, uid);
2961             pw.println(":");
2962             boolean uidActivity = false;
2963
2964             long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
2965             long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
2966             long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
2967             long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
2968             long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
2969             long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
2970             long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
2971             int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
2972             long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
2973             long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
2974             long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
2975             long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
2976             long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
2977
2978             if (mobileRxBytes > 0 || mobileTxBytes > 0
2979                     || mobileRxPackets > 0 || mobileTxPackets > 0) {
2980                 pw.print(prefix); pw.print("    Mobile network: ");
2981                         pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
2982                         pw.print(formatBytesLocked(mobileTxBytes));
2983                         pw.print(" sent (packets "); pw.print(mobileRxPackets);
2984                         pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
2985             }
2986             if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
2987                 sb.setLength(0);
2988                 sb.append(prefix); sb.append("    Mobile radio active: ");
2989                 formatTimeMs(sb, uidMobileActiveTime / 1000);
2990                 sb.append("(");
2991                 sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
2992                 sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
2993                 long packets = mobileRxPackets + mobileTxPackets;
2994                 if (packets == 0) {
2995                     packets = 1;
2996                 }
2997                 sb.append(" @ ");
2998                 sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
2999                 sb.append(" mspp");
3000                 pw.println(sb.toString());
3001             }
3002
3003             if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
3004                 pw.print(prefix); pw.print("    Wi-Fi network: ");
3005                         pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
3006                         pw.print(formatBytesLocked(wifiTxBytes));
3007                         pw.print(" sent (packets "); pw.print(wifiRxPackets);
3008                         pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
3009             }
3010
3011             if (fullWifiLockOnTime != 0 || wifiScanTime != 0
3012                     || uidWifiRunningTime != 0) {
3013                 sb.setLength(0);
3014                 sb.append(prefix); sb.append("    Wifi Running: ");
3015                         formatTimeMs(sb, uidWifiRunningTime / 1000);
3016                         sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
3017                                 whichBatteryRealtime)); sb.append(")\n");
3018                 sb.append(prefix); sb.append("    Full Wifi Lock: "); 
3019                         formatTimeMs(sb, fullWifiLockOnTime / 1000);
3020                         sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
3021                                 whichBatteryRealtime)); sb.append(")\n");
3022                 sb.append(prefix); sb.append("    Wifi Scan: ");
3023                         formatTimeMs(sb, wifiScanTime / 1000);
3024                         sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
3025                                 whichBatteryRealtime)); sb.append(")");
3026                 pw.println(sb.toString());
3027             }
3028
3029             if (u.hasUserActivity()) {
3030                 boolean hasData = false;
3031                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3032                     int val = u.getUserActivityCount(i, which);
3033                     if (val != 0) {
3034                         if (!hasData) {
3035                             sb.setLength(0);
3036                             sb.append("    User activity: ");
3037                             hasData = true;
3038                         } else {
3039                             sb.append(", ");
3040                         }
3041                         sb.append(val);
3042                         sb.append(" ");
3043                         sb.append(Uid.USER_ACTIVITY_TYPES[i]);
3044                     }
3045                 }
3046                 if (hasData) {
3047                     pw.println(sb.toString());
3048                 }
3049             }
3050
3051             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
3052             if (wakelocks.size() > 0) {
3053                 long totalFull = 0, totalPartial = 0, totalWindow = 0;
3054                 int count = 0;
3055                 for (Map.Entry<String, ? extends Uid.Wakelock> ent : wakelocks.entrySet()) {
3056                     Uid.Wakelock wl = ent.getValue();
3057                     String linePrefix = ": ";
3058                     sb.setLength(0);
3059                     sb.append(prefix);
3060                     sb.append("    Wake lock ");
3061                     sb.append(ent.getKey());
3062                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
3063                             "full", which, linePrefix);
3064                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
3065                             "partial", which, linePrefix);
3066                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
3067                             "window", which, linePrefix);
3068                     if (true || !linePrefix.equals(": ")) {
3069                         sb.append(" realtime");
3070                         // Only print out wake locks that were held
3071                         pw.println(sb.toString());
3072                         uidActivity = true;
3073                         count++;
3074                     }
3075                     totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
3076                             rawRealtime, which);
3077                     totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
3078                             rawRealtime, which);
3079                     totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
3080                             rawRealtime, which);
3081                 }
3082                 if (count > 1) {
3083                     if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) {
3084                         sb.setLength(0);
3085                         sb.append(prefix);
3086                         sb.append("    TOTAL wake: ");
3087                         boolean needComma = false;
3088                         if (totalFull != 0) {
3089                             needComma = true;
3090                             formatTimeMs(sb, totalFull);
3091                             sb.append("full");
3092                         }
3093                         if (totalPartial != 0) {
3094                             if (needComma) {
3095                                 sb.append(", ");
3096                             }
3097                             needComma = true;
3098                             formatTimeMs(sb, totalPartial);
3099                             sb.append("partial");
3100                         }
3101                         if (totalWindow != 0) {
3102                             if (needComma) {
3103                                 sb.append(", ");
3104                             }
3105                             needComma = true;
3106                             formatTimeMs(sb, totalWindow);
3107                             sb.append("window");
3108                         }
3109                         sb.append(" realtime");
3110                         pw.println(sb.toString());
3111                     }
3112                 }
3113             }
3114
3115             Map<String, ? extends Timer> syncs = u.getSyncStats();
3116             if (syncs.size() > 0) {
3117                 for (Map.Entry<String, ? extends Timer> ent : syncs.entrySet()) {
3118                     Timer timer = ent.getValue();
3119                     // Convert from microseconds to milliseconds with rounding
3120                     long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
3121                     int count = timer.getCountLocked(which);
3122                     sb.setLength(0);
3123                     sb.append(prefix);
3124                     sb.append("    Sync ");
3125                     sb.append(ent.getKey());
3126                     sb.append(": ");
3127                     if (totalTime != 0) {
3128                         formatTimeMs(sb, totalTime);
3129                         sb.append("realtime (");
3130                         sb.append(count);
3131                         sb.append(" times)");
3132                     } else {
3133                         sb.append("(not used)");
3134                     }
3135                     pw.println(sb.toString());
3136                     uidActivity = true;
3137                 }
3138             }
3139
3140             Map<String, ? extends Timer> jobs = u.getJobStats();
3141             if (syncs.size() > 0) {
3142                 for (Map.Entry<String, ? extends Timer> ent : jobs.entrySet()) {
3143                     Timer timer = ent.getValue();
3144                     // Convert from microseconds to milliseconds with rounding
3145                     long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
3146                     int count = timer.getCountLocked(which);
3147                     sb.setLength(0);
3148                     sb.append(prefix);
3149                     sb.append("    Job ");
3150                     sb.append(ent.getKey());
3151                     sb.append(": ");
3152                     if (totalTime != 0) {
3153                         formatTimeMs(sb, totalTime);
3154                         sb.append("realtime (");
3155                         sb.append(count);
3156                         sb.append(" times)");
3157                     } else {
3158                         sb.append("(not used)");
3159                     }
3160                     pw.println(sb.toString());
3161                     uidActivity = true;
3162                 }
3163             }
3164
3165             SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
3166             int NSE = sensors.size();
3167             for (int ise=0; ise<NSE; ise++) {
3168                 Uid.Sensor se = sensors.valueAt(ise);
3169                 int sensorNumber = sensors.keyAt(ise);
3170                 sb.setLength(0);
3171                 sb.append(prefix);
3172                 sb.append("    Sensor ");
3173                 int handle = se.getHandle();
3174                 if (handle == Uid.Sensor.GPS) {
3175                     sb.append("GPS");
3176                 } else {
3177                     sb.append(handle);
3178                 }
3179                 sb.append(": ");
3180
3181                 Timer timer = se.getSensorTime();
3182                 if (timer != null) {
3183                     // Convert from microseconds to milliseconds with rounding
3184                     long totalTime = (timer.getTotalTimeLocked(
3185                             rawRealtime, which) + 500) / 1000;
3186                     int count = timer.getCountLocked(which);
3187                     //timer.logState();
3188                     if (totalTime != 0) {
3189                         formatTimeMs(sb, totalTime);
3190                         sb.append("realtime (");
3191                         sb.append(count);
3192                         sb.append(" times)");
3193                     } else {
3194                         sb.append("(not used)");
3195                     }
3196                 } else {
3197                     sb.append("(not used)");
3198                 }
3199
3200                 pw.println(sb.toString());
3201                 uidActivity = true;
3202             }
3203
3204             Timer vibTimer = u.getVibratorOnTimer();
3205             if (vibTimer != null) {
3206                 // Convert from microseconds to milliseconds with rounding
3207                 long totalTime = (vibTimer.getTotalTimeLocked(
3208                         rawRealtime, which) + 500) / 1000;
3209                 int count = vibTimer.getCountLocked(which);
3210                 //timer.logState();
3211                 if (totalTime != 0) {
3212                     sb.setLength(0);
3213                     sb.append(prefix);
3214                     sb.append("    Vibrator: ");
3215                     formatTimeMs(sb, totalTime);
3216                     sb.append("realtime (");
3217                     sb.append(count);
3218                     sb.append(" times)");
3219                     pw.println(sb.toString());
3220                     uidActivity = true;
3221                 }
3222             }
3223
3224             Timer fgTimer = u.getForegroundActivityTimer();
3225             if (fgTimer != null) {
3226                 // Convert from microseconds to milliseconds with rounding
3227                 long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
3228                 int count = fgTimer.getCountLocked(which);
3229                 if (totalTime != 0) {
3230                     sb.setLength(0);
3231                     sb.append(prefix);
3232                     sb.append("    Foreground activities: ");
3233                     formatTimeMs(sb, totalTime);
3234                     sb.append("realtime (");
3235                     sb.append(count);
3236                     sb.append(" times)");
3237                     pw.println(sb.toString());
3238                     uidActivity = true;
3239                 }
3240             }
3241
3242             long totalStateTime = 0;
3243             for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
3244                 long time = u.getProcessStateTime(ips, rawRealtime, which);
3245                 if (time > 0) {
3246                     totalStateTime += time;
3247                     sb.setLength(0);
3248                     sb.append(prefix);
3249                     sb.append("    ");
3250                     sb.append(Uid.PROCESS_STATE_NAMES[ips]);
3251                     sb.append(" for: ");
3252                     formatTimeMs(sb, (totalStateTime + 500) / 1000);
3253                     pw.println(sb.toString());
3254                     uidActivity = true;
3255                 }
3256             }
3257
3258             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
3259             if (processStats.size() > 0) {
3260                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
3261                     : processStats.entrySet()) {
3262                     Uid.Proc ps = ent.getValue();
3263                     long userTime;
3264                     long systemTime;
3265                     long foregroundTime;
3266                     int starts;
3267                     int numExcessive;
3268
3269                     userTime = ps.getUserTime(which);
3270                     systemTime = ps.getSystemTime(which);
3271                     foregroundTime = ps.getForegroundTime(which);
3272                     starts = ps.getStarts(which);
3273                     numExcessive = which == STATS_SINCE_CHARGED
3274                             ? ps.countExcessivePowers() : 0;
3275
3276                     if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
3277                             || numExcessive != 0) {
3278                         sb.setLength(0);
3279                         sb.append(prefix); sb.append("    Proc ");
3280                                 sb.append(ent.getKey()); sb.append(":\n");
3281                         sb.append(prefix); sb.append("      CPU: ");
3282                                 formatTime(sb, userTime); sb.append("usr + ");
3283                                 formatTime(sb, systemTime); sb.append("krn ; ");
3284                                 formatTime(sb, foregroundTime); sb.append("fg");
3285                         if (starts != 0) {
3286                             sb.append("\n"); sb.append(prefix); sb.append("      ");
3287                                     sb.append(starts); sb.append(" proc starts");
3288                         }
3289                         pw.println(sb.toString());
3290                         for (int e=0; e<numExcessive; e++) {
3291                             Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
3292                             if (ew != null) {
3293                                 pw.print(prefix); pw.print("      * Killed for ");
3294                                         if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
3295                                             pw.print("wake lock");
3296                                         } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
3297                                             pw.print("cpu");
3298                                         } else {
3299                                             pw.print("unknown");
3300                                         }
3301                                         pw.print(" use: ");
3302                                         TimeUtils.formatDuration(ew.usedTime, pw);
3303                                         pw.print(" over ");
3304                                         TimeUtils.formatDuration(ew.overTime, pw);
3305                                         if (ew.overTime != 0) {
3306                                             pw.print(" (");
3307                                             pw.print((ew.usedTime*100)/ew.overTime);
3308                                             pw.println("%)");
3309                                         }
3310                             }
3311                         }
3312                         uidActivity = true;
3313                     }
3314                 }
3315             }
3316
3317             Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
3318             if (packageStats.size() > 0) {
3319                 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
3320                     : packageStats.entrySet()) {
3321                     pw.print(prefix); pw.print("    Apk "); pw.print(ent.getKey()); pw.println(":");
3322                     boolean apkActivity = false;
3323                     Uid.Pkg ps = ent.getValue();
3324                     int wakeups = ps.getWakeups(which);
3325                     if (wakeups != 0) {
3326                         pw.print(prefix); pw.print("      ");
3327                                 pw.print(wakeups); pw.println(" wakeup alarms");
3328                         apkActivity = true;
3329                     }
3330                     Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
3331                     if (serviceStats.size() > 0) {
3332                         for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
3333                                 : serviceStats.entrySet()) {
3334                             BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
3335                             long startTime = ss.getStartTime(batteryUptime, which);
3336                             int starts = ss.getStarts(which);
3337                             int launches = ss.getLaunches(which);
3338                             if (startTime != 0 || starts != 0 || launches != 0) {
3339                                 sb.setLength(0);
3340                                 sb.append(prefix); sb.append("      Service ");
3341                                         sb.append(sent.getKey()); sb.append(":\n");
3342                                 sb.append(prefix); sb.append("        Created for: ");
3343                                         formatTimeMs(sb, startTime / 1000);
3344                                         sb.append("uptime\n");
3345                                 sb.append(prefix); sb.append("        Starts: ");
3346                                         sb.append(starts);
3347                                         sb.append(", launches: "); sb.append(launches);
3348                                 pw.println(sb.toString());
3349                                 apkActivity = true;
3350                             }
3351                         }
3352                     }
3353                     if (!apkActivity) {
3354                         pw.print(prefix); pw.println("      (nothing executed)");
3355                     }
3356                     uidActivity = true;
3357                 }
3358             }
3359             if (!uidActivity) {
3360                 pw.print(prefix); pw.println("    (nothing executed)");
3361             }
3362         }
3363     }
3364
3365     static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag,
3366             BitDescription[] descriptions, boolean longNames) {
3367         int diff = oldval ^ newval;
3368         if (diff == 0) return;
3369         boolean didWake = false;
3370         for (int i=0; i<descriptions.length; i++) {
3371             BitDescription bd = descriptions[i];
3372             if ((diff&bd.mask) != 0) {
3373                 pw.print(longNames ? " " : ",");
3374                 if (bd.shift < 0) {
3375                     pw.print((newval&bd.mask) != 0 ? "+" : "-");
3376                     pw.print(longNames ? bd.name : bd.shortName);
3377                     if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
3378                         didWake = true;
3379                         pw.print("=");
3380                         if (longNames) {
3381                             UserHandle.formatUid(pw, wakelockTag.uid);
3382                             pw.print(":\"");
3383                             pw.print(wakelockTag.string);
3384                             pw.print("\"");
3385                         } else {
3386                             pw.print(wakelockTag.poolIdx);
3387                         }
3388                     }
3389                 } else {
3390                     pw.print(longNames ? bd.name : bd.shortName);
3391                     pw.print("=");
3392                     int val = (newval&bd.mask)>>bd.shift;
3393                     if (bd.values != null && val >= 0 && val < bd.values.length) {
3394                         pw.print(longNames? bd.values[val] : bd.shortValues[val]);
3395                     } else {
3396                         pw.print(val);
3397                     }
3398                 }
3399             }
3400         }
3401         if (!didWake && wakelockTag != null) {
3402             pw.print(longNames ? " wake_lock=" : ",w=");
3403             if (longNames) {
3404                 UserHandle.formatUid(pw, wakelockTag.uid);
3405                 pw.print(":\"");
3406                 pw.print(wakelockTag.string);
3407                 pw.print("\"");
3408             } else {
3409                 pw.print(wakelockTag.poolIdx);
3410             }
3411         }
3412     }
3413     
3414     public void prepareForDumpLocked() {
3415     }
3416
3417     public static class HistoryPrinter {
3418         int oldState = 0;
3419         int oldState2 = 0;
3420         int oldLevel = -1;
3421         int oldStatus = -1;
3422         int oldHealth = -1;
3423         int oldPlug = -1;
3424         int oldTemp = -1;
3425         int oldVolt = -1;
3426         long lastTime = -1;
3427
3428         void reset() {
3429             oldState = oldState2 = 0;
3430             oldLevel = -1;
3431             oldStatus = -1;
3432             oldHealth = -1;
3433             oldPlug = -1;
3434             oldTemp = -1;
3435             oldVolt = -1;
3436         }
3437
3438         public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
3439                 boolean verbose) {
3440             if (!checkin) {
3441                 pw.print("  ");
3442                 TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
3443                 pw.print(" (");
3444                 pw.print(rec.numReadInts);
3445                 pw.print(") ");
3446             } else {
3447                 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
3448                 pw.print(HISTORY_DATA); pw.print(',');
3449                 if (lastTime < 0) {
3450                     pw.print(rec.time - baseTime);
3451                 } else {
3452                     pw.print(rec.time - lastTime);
3453                 }
3454                 lastTime = rec.time;
3455             }
3456             if (rec.cmd == HistoryItem.CMD_START) {
3457                 if (checkin) {
3458                     pw.print(":");
3459                 }
3460                 pw.println("START");
3461                 reset();
3462             } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
3463                     || rec.cmd == HistoryItem.CMD_RESET) {
3464                 if (checkin) {
3465                     pw.print(":");
3466                 }
3467                 if (rec.cmd == HistoryItem.CMD_RESET) {
3468                     pw.print("RESET:");
3469                     reset();
3470                 }
3471                 pw.print("TIME:");
3472                 if (checkin) {
3473                     pw.println(rec.currentTime);
3474                 } else {
3475                     pw.print(" ");
3476                     pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
3477                             rec.currentTime).toString());
3478                 }
3479             } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
3480                 if (checkin) {
3481                     pw.print(":");
3482                 }
3483                 pw.println("*OVERFLOW*");
3484             } else {
3485                 if (!checkin) {
3486                     if (rec.batteryLevel < 10) pw.print("00");
3487                     else if (rec.batteryLevel < 100) pw.print("0");
3488                     pw.print(rec.batteryLevel);
3489                     if (verbose) {
3490                         pw.print(" ");
3491                         if (rec.states < 0) ;
3492                         else if (rec.states < 0x10) pw.print("0000000");
3493                         else if (rec.states < 0x100) pw.print("000000");
3494                         else if (rec.states < 0x1000) pw.print("00000");
3495                         else if (rec.states < 0x10000) pw.print("0000");
3496                         else if (rec.states < 0x100000) pw.print("000");
3497                         else if (rec.states < 0x1000000) pw.print("00");
3498                         else if (rec.states < 0x10000000) pw.print("0");
3499                         pw.print(Integer.toHexString(rec.states));
3500                     }
3501                 } else {
3502                     if (oldLevel != rec.batteryLevel) {
3503                         oldLevel = rec.batteryLevel;
3504                         pw.print(",Bl="); pw.print(rec.batteryLevel);
3505                     }
3506                 }
3507                 if (oldStatus != rec.batteryStatus) {
3508                     oldStatus = rec.batteryStatus;
3509                     pw.print(checkin ? ",Bs=" : " status=");
3510                     switch (oldStatus) {
3511                         case BatteryManager.BATTERY_STATUS_UNKNOWN:
3512                             pw.print(checkin ? "?" : "unknown");
3513                             break;
3514                         case BatteryManager.BATTERY_STATUS_CHARGING:
3515                             pw.print(checkin ? "c" : "charging");
3516                             break;
3517                         case BatteryManager.BATTERY_STATUS_DISCHARGING:
3518                             pw.print(checkin ? "d" : "discharging");
3519                             break;
3520                         case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
3521                             pw.print(checkin ? "n" : "not-charging");
3522                             break;
3523                         case BatteryManager.BATTERY_STATUS_FULL:
3524                             pw.print(checkin ? "f" : "full");
3525                             break;
3526                         default:
3527                             pw.print(oldStatus);
3528                             break;
3529                     }
3530                 }
3531                 if (oldHealth != rec.batteryHealth) {
3532                     oldHealth = rec.batteryHealth;
3533                     pw.print(checkin ? ",Bh=" : " health=");
3534                     switch (oldHealth) {
3535                         case BatteryManager.BATTERY_HEALTH_UNKNOWN:
3536                             pw.print(checkin ? "?" : "unknown");
3537                             break;
3538                         case BatteryManager.BATTERY_HEALTH_GOOD:
3539                             pw.print(checkin ? "g" : "good");
3540                             break;
3541                         case BatteryManager.BATTERY_HEALTH_OVERHEAT:
3542                             pw.print(checkin ? "h" : "overheat");
3543                             break;
3544                         case BatteryManager.BATTERY_HEALTH_DEAD:
3545                             pw.print(checkin ? "d" : "dead");
3546                             break;
3547                         case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
3548                             pw.print(checkin ? "v" : "over-voltage");
3549                             break;
3550                         case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
3551                             pw.print(checkin ? "f" : "failure");
3552                             break;
3553                         case BatteryManager.BATTERY_HEALTH_COLD:
3554                             pw.print(checkin ? "c" : "cold");
3555                             break;
3556                         default:
3557                             pw.print(oldHealth);
3558                             break;
3559                     }
3560                 }
3561                 if (oldPlug != rec.batteryPlugType) {
3562                     oldPlug = rec.batteryPlugType;
3563                     pw.print(checkin ? ",Bp=" : " plug=");
3564                     switch (oldPlug) {
3565                         case 0:
3566                             pw.print(checkin ? "n" : "none");
3567                             break;
3568                         case BatteryManager.BATTERY_PLUGGED_AC:
3569                             pw.print(checkin ? "a" : "ac");
3570                             break;
3571                         case BatteryManager.BATTERY_PLUGGED_USB:
3572                             pw.print(checkin ? "u" : "usb");
3573                             break;
3574                         case BatteryManager.BATTERY_PLUGGED_WIRELESS:
3575                             pw.print(checkin ? "w" : "wireless");
3576                             break;
3577                         default:
3578                             pw.print(oldPlug);
3579                             break;
3580                     }
3581                 }
3582                 if (oldTemp != rec.batteryTemperature) {
3583                     oldTemp = rec.batteryTemperature;
3584                     pw.print(checkin ? ",Bt=" : " temp=");
3585                     pw.print(oldTemp);
3586                 }
3587                 if (oldVolt != rec.batteryVoltage) {
3588                     oldVolt = rec.batteryVoltage;
3589                     pw.print(checkin ? ",Bv=" : " volt=");
3590                     pw.print(oldVolt);
3591                 }
3592                 printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
3593                         HISTORY_STATE_DESCRIPTIONS, !checkin);
3594                 printBitDescriptions(pw, oldState2, rec.states2, null,
3595                         HISTORY_STATE2_DESCRIPTIONS, !checkin);
3596                 if (rec.wakeReasonTag != null) {
3597                     if (checkin) {
3598                         pw.print(",wr=");
3599                         pw.print(rec.wakeReasonTag.poolIdx);
3600                     } else {
3601                         pw.print(" wake_reason=");
3602                         pw.print(rec.wakeReasonTag.uid);
3603                         pw.print(":\"");
3604                         pw.print(rec.wakeReasonTag.string);
3605                         pw.print("\"");
3606                     }
3607                 }
3608                 if (rec.eventCode != HistoryItem.EVENT_NONE) {
3609                     pw.print(checkin ? "," : " ");
3610                     if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
3611                         pw.print("+");
3612                     } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
3613                         pw.print("-");
3614                     }
3615                     String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
3616                             : HISTORY_EVENT_NAMES;
3617                     int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
3618                             | HistoryItem.EVENT_FLAG_FINISH);
3619                     if (idx >= 0 && idx < eventNames.length) {
3620                         pw.print(eventNames[idx]);
3621                     } else {
3622                         pw.print(checkin ? "Ev" : "event");
3623                         pw.print(idx);
3624                     }
3625                     pw.print("=");
3626                     if (checkin) {
3627                         pw.print(rec.eventTag.poolIdx);
3628                     } else {
3629                         UserHandle.formatUid(pw, rec.eventTag.uid);
3630                         pw.print(":\"");
3631                         pw.print(rec.eventTag.string);
3632                         pw.print("\"");
3633                     }
3634                 }
3635                 pw.println();
3636                 oldState = rec.states;
3637                 oldState2 = rec.states2;
3638             }
3639         }
3640     }
3641
3642     private void printSizeValue(PrintWriter pw, long size) {
3643         float result = size;
3644         String suffix = "";
3645         if (result >= 10*1024) {
3646             suffix = "KB";
3647             result = result / 1024;
3648         }
3649         if (result >= 10*1024) {
3650             suffix = "MB";
3651             result = result / 1024;
3652         }
3653         if (result >= 10*1024) {
3654             suffix = "GB";
3655             result = result / 1024;
3656         }
3657         if (result >= 10*1024) {
3658             suffix = "TB";
3659             result = result / 1024;
3660         }
3661         if (result >= 10*1024) {
3662             suffix = "PB";
3663             result = result / 1024;
3664         }
3665         pw.print((int)result);
3666         pw.print(suffix);
3667     }
3668
3669     private static boolean dumpDurationSteps(PrintWriter pw, String header, long[] steps,
3670             int count, boolean checkin) {
3671         if (count <= 0) {
3672             return false;
3673         }
3674         if (!checkin) {
3675             pw.println(header);
3676         }
3677         String[] lineArgs = new String[4];
3678         for (int i=0; i<count; i++) {
3679             long duration = steps[i] & STEP_LEVEL_TIME_MASK;
3680             int level = (int)((steps[i] & STEP_LEVEL_LEVEL_MASK)
3681                     >> STEP_LEVEL_LEVEL_SHIFT);
3682             long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK)
3683                     >> STEP_LEVEL_INITIAL_MODE_SHIFT;
3684             long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK)
3685                     >> STEP_LEVEL_MODIFIED_MODE_SHIFT;
3686             if (checkin) {
3687                 lineArgs[0] = Long.toString(duration);
3688                 lineArgs[1] = Integer.toString(level);
3689                 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
3690                     switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
3691                         case Display.STATE_OFF: lineArgs[2] = "s-"; break;
3692                         case Display.STATE_ON: lineArgs[2] = "s+"; break;
3693                         case Display.STATE_DOZE: lineArgs[2] = "sd"; break;
3694                         case Display.STATE_DOZE_SUSPEND: lineArgs[2] = "sds"; break;
3695                         default: lineArgs[1] = "?"; break;
3696                     }
3697                 } else {
3698                     lineArgs[2] = "";
3699                 }
3700                 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
3701                     lineArgs[3] = (initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 ? "p+" : "p-";
3702                 } else {
3703                     lineArgs[3] = "";
3704                 }
3705                 dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs);
3706             } else {
3707                 pw.print("  #"); pw.print(i); pw.print(": ");
3708                 TimeUtils.formatDuration(duration, pw);
3709                 pw.print(" to "); pw.print(level);
3710                 boolean haveModes = false;
3711                 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
3712                     pw.print(" (");
3713                     switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
3714                         case Display.STATE_OFF: pw.print("screen-off"); break;
3715                         case Display.STATE_ON: pw.print("screen-on"); break;
3716                         case Display.STATE_DOZE: pw.print("screen-doze"); break;
3717                         case Display.STATE_DOZE_SUSPEND: pw.print("screen-doze-suspend"); break;
3718                         default: lineArgs[1] = "screen-?"; break;
3719                     }
3720                     haveModes = true;
3721                 }
3722                 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
3723                     pw.print(haveModes ? ", " : " (");
3724                     pw.print((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0
3725                             ? "power-save-on" : "power-save-off");
3726                     haveModes = true;
3727                 }
3728                 if (haveModes) {
3729                     pw.print(")");
3730                 }
3731                 pw.println();
3732             }
3733         }
3734         return true;
3735     }
3736
3737     public static final int DUMP_UNPLUGGED_ONLY = 1<<0;
3738     public static final int DUMP_CHARGED_ONLY = 1<<1;
3739     public static final int DUMP_HISTORY_ONLY = 1<<2;
3740     public static final int DUMP_INCLUDE_HISTORY = 1<<3;
3741     public static final int DUMP_VERBOSE = 1<<4;
3742     public static final int DUMP_DEVICE_WIFI_ONLY = 1<<5;
3743
3744     private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
3745         final HistoryPrinter hprinter = new HistoryPrinter();
3746         final HistoryItem rec = new HistoryItem();
3747         long lastTime = -1;
3748         long baseTime = -1;
3749         boolean printed = false;
3750         HistoryEventTracker tracker = null;
3751         while (getNextHistoryLocked(rec)) {
3752             lastTime = rec.time;
3753             if (baseTime < 0) {
3754                 baseTime = lastTime;
3755             }
3756             if (rec.time >= histStart) {
3757                 if (histStart >= 0 && !printed) {
3758                     if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
3759                             || rec.cmd == HistoryItem.CMD_RESET
3760                             || rec.cmd == HistoryItem.CMD_START) {
3761                         printed = true;
3762                         hprinter.printNextItem(pw, rec, baseTime, checkin,
3763                                 (flags&DUMP_VERBOSE) != 0);
3764                         rec.cmd = HistoryItem.CMD_UPDATE;
3765                     } else if (rec.currentTime != 0) {
3766                         printed = true;
3767                         byte cmd = rec.cmd;
3768                         rec.cmd = HistoryItem.CMD_CURRENT_TIME;
3769                         hprinter.printNextItem(pw, rec, baseTime, checkin,
3770                                 (flags&DUMP_VERBOSE) != 0);
3771                         rec.cmd = cmd;
3772                     }
3773                     if (tracker != null) {
3774                         if (rec.cmd != HistoryItem.CMD_UPDATE) {
3775                             hprinter.printNextItem(pw, rec, baseTime, checkin,
3776                                     (flags&DUMP_VERBOSE) != 0);
3777                             rec.cmd = HistoryItem.CMD_UPDATE;
3778                         }
3779                         int oldEventCode = rec.eventCode;
3780                         HistoryTag oldEventTag = rec.eventTag;
3781                         rec.eventTag = new HistoryTag();
3782                         for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
3783                             HashMap<String, SparseIntArray> active
3784                                     = tracker.getStateForEvent(i);
3785                             if (active == null) {
3786                                 continue;
3787                             }
3788                             for (HashMap.Entry<String, SparseIntArray> ent
3789                                     : active.entrySet()) {
3790                                 SparseIntArray uids = ent.getValue();
3791                                 for (int j=0; j<uids.size(); j++) {
3792                                     rec.eventCode = i;
3793                                     rec.eventTag.string = ent.getKey();
3794                                     rec.eventTag.uid = uids.keyAt(j);
3795                                     rec.eventTag.poolIdx = uids.valueAt(j);
3796                                     hprinter.printNextItem(pw, rec, baseTime, checkin,
3797                                             (flags&DUMP_VERBOSE) != 0);
3798                                     rec.wakeReasonTag = null;
3799                                     rec.wakelockTag = null;
3800                                 }
3801                             }
3802                         }
3803                         rec.eventCode = oldEventCode;
3804                         rec.eventTag = oldEventTag;
3805                         tracker = null;
3806                     }
3807                 }
3808                 hprinter.printNextItem(pw, rec, baseTime, checkin,
3809                         (flags&DUMP_VERBOSE) != 0);
3810             } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) {
3811                 // This is an attempt to aggregate the previous state and generate
3812                 // fake events to reflect that state at the point where we start
3813                 // printing real events.  It doesn't really work right, so is turned off.
3814                 if (tracker == null) {
3815                     tracker = new HistoryEventTracker();
3816                 }
3817                 tracker.updateState(rec.eventCode, rec.eventTag.string,
3818                         rec.eventTag.uid, rec.eventTag.poolIdx);
3819             }
3820         }
3821         if (histStart >= 0) {
3822             commitCurrentHistoryBatchLocked();
3823             pw.print(checkin ? "NEXT: " : "  NEXT: "); pw.println(lastTime+1);
3824         }
3825     }
3826
3827     /**
3828      * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
3829      *
3830      * @param pw a Printer to receive the dump output.
3831      */
3832     @SuppressWarnings("unused")
3833     public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
3834         prepareForDumpLocked();
3835
3836         final boolean filtering =
3837                 (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;
3838
3839         if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
3840             final long historyTotalSize = getHistoryTotalSize();
3841             final long historyUsedSize = getHistoryUsedSize();
3842             if (startIteratingHistoryLocked()) {
3843                 try {
3844                     pw.print("Battery History (");
3845                     pw.print((100*historyUsedSize)/historyTotalSize);
3846                     pw.print("% used, ");
3847                     printSizeValue(pw, historyUsedSize);
3848                     pw.print(" used of ");
3849                     printSizeValue(pw, historyTotalSize);
3850                     pw.print(", ");
3851                     pw.print(getHistoryStringPoolSize());
3852                     pw.print(" strings using ");
3853                     printSizeValue(pw, getHistoryStringPoolBytes());
3854                     pw.println("):");
3855                     dumpHistoryLocked(pw, flags, histStart, false);
3856                     pw.println();
3857                 } finally {
3858                     finishIteratingHistoryLocked();
3859                 }
3860             }
3861
3862             if (startIteratingOldHistoryLocked()) {
3863                 try {
3864                     final HistoryItem rec = new HistoryItem();
3865                     pw.println("Old battery History:");
3866                     HistoryPrinter hprinter = new HistoryPrinter();
3867                     long baseTime = -1;
3868                     while (getNextOldHistoryLocked(rec)) {
3869                         if (baseTime < 0) {
3870                             baseTime = rec.time;
3871                         }
3872                         hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0);
3873                     }
3874                     pw.println();
3875                 } finally {
3876                     finishIteratingOldHistoryLocked();
3877                 }
3878             }
3879         }
3880
3881         if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) {
3882             return;
3883         }
3884
3885         if (!filtering) {
3886             SparseArray<? extends Uid> uidStats = getUidStats();
3887             final int NU = uidStats.size();
3888             boolean didPid = false;
3889             long nowRealtime = SystemClock.elapsedRealtime();
3890             for (int i=0; i<NU; i++) {
3891                 Uid uid = uidStats.valueAt(i);
3892                 SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
3893                 if (pids != null) {
3894                     for (int j=0; j<pids.size(); j++) {
3895                         Uid.Pid pid = pids.valueAt(j);
3896                         if (!didPid) {
3897                             pw.println("Per-PID Stats:");
3898                             didPid = true;
3899                         }
3900                         long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
3901                                 ? (nowRealtime - pid.mWakeStartMs) : 0);
3902                         pw.print("  PID "); pw.print(pids.keyAt(j));
3903                                 pw.print(" wake time: ");
3904                                 TimeUtils.formatDuration(time, pw);
3905                                 pw.println("");
3906                     }
3907                 }
3908             }
3909             if (didPid) {
3910                 pw.println();
3911             }
3912         }
3913
3914         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
3915             if (dumpDurationSteps(pw, "Discharge step durations:", getDischargeStepDurationsArray(),
3916                     getNumDischargeStepDurations(), false)) {
3917                 long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
3918                 if (timeRemaining >= 0) {
3919                     pw.print("  Estimated discharge time remaining: ");
3920                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
3921                     pw.println();
3922                 }
3923                 pw.println();
3924             }
3925             if (dumpDurationSteps(pw, "Charge step durations:", getChargeStepDurationsArray(),
3926                     getNumChargeStepDurations(), false)) {
3927                 long timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
3928                 if (timeRemaining >= 0) {
3929                     pw.print("  Estimated charge time remaining: ");
3930                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
3931                     pw.println();
3932                 }
3933                 pw.println();
3934             }
3935             pw.println("Statistics since last charge:");
3936             pw.println("  System starts: " + getStartCount()
3937                     + ", currently on battery: " + getIsOnBattery());
3938             dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
3939                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
3940             pw.println();
3941         }
3942         if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
3943             pw.println("Statistics since last unplugged:");
3944             dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid,
3945                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
3946         }
3947     }
3948     
3949     @SuppressWarnings("unused")
3950     public void dumpCheckinLocked(Context context, PrintWriter pw,
3951             List<ApplicationInfo> apps, int flags, long histStart) {
3952         prepareForDumpLocked();
3953
3954         dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
3955                 "10", getParcelVersion(), getStartPlatformVersion(), getEndPlatformVersion());
3956
3957         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
3958
3959         final boolean filtering =
3960                 (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;
3961
3962         if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) {
3963             if (startIteratingHistoryLocked()) {
3964                 try {
3965                     for (int i=0; i<getHistoryStringPoolSize(); i++) {
3966                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
3967                         pw.print(HISTORY_STRING_POOL); pw.print(',');
3968                         pw.print(i);
3969                         pw.print(",");
3970                         pw.print(getHistoryTagPoolUid(i));
3971                         pw.print(",\"");
3972                         String str = getHistoryTagPoolString(i);
3973                         str = str.replace("\\", "\\\\");
3974                         str = str.replace("\"", "\\\"");
3975                         pw.print(str);
3976                         pw.print("\"");
3977                         pw.println();
3978                     }
3979                     dumpHistoryLocked(pw, flags, histStart, true);
3980                 } finally {
3981                     finishIteratingHistoryLocked();
3982                 }
3983             }
3984         }
3985
3986         if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) {
3987             return;
3988         }
3989
3990         if (apps != null) {
3991             SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
3992             for (int i=0; i<apps.size(); i++) {
3993                 ApplicationInfo ai = apps.get(i);
3994                 ArrayList<String> pkgs = uids.get(ai.uid);
3995                 if (pkgs == null) {
3996                     pkgs = new ArrayList<String>();
3997                     uids.put(ai.uid, pkgs);
3998                 }
3999                 pkgs.add(ai.packageName);
4000             }
4001             SparseArray<? extends Uid> uidStats = getUidStats();
4002             final int NU = uidStats.size();
4003             String[] lineArgs = new String[2];
4004             for (int i=0; i<NU; i++) {
4005                 int uid = uidStats.keyAt(i);
4006                 ArrayList<String> pkgs = uids.get(uid);
4007                 if (pkgs != null) {
4008                     for (int j=0; j<pkgs.size(); j++) {
4009                         lineArgs[0] = Integer.toString(uid);
4010                         lineArgs[1] = pkgs.get(j);
4011                         dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
4012                                 (Object[])lineArgs);
4013                     }
4014                 }
4015             }
4016         }
4017         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
4018             dumpDurationSteps(pw, DISCHARGE_STEP_DATA, getDischargeStepDurationsArray(),
4019                     getNumDischargeStepDurations(), true);
4020             String[] lineArgs = new String[1];
4021             long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
4022             if (timeRemaining >= 0) {
4023                 lineArgs[0] = Long.toString(timeRemaining);
4024                 dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA,
4025                         (Object[])lineArgs);
4026             }
4027             dumpDurationSteps(pw, CHARGE_STEP_DATA, getChargeStepDurationsArray(),
4028                     getNumChargeStepDurations(), true);
4029             timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
4030             if (timeRemaining >= 0) {
4031                 lineArgs[0] = Long.toString(timeRemaining);
4032                 dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA,
4033                         (Object[])lineArgs);
4034             }
4035             dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
4036                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
4037         }
4038         if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
4039             dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1,
4040                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
4041         }
4042     }
4043 }