• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import java.io.PrintWriter;
20 import java.util.ArrayList;
21 import java.util.Formatter;
22 import java.util.List;
23 import java.util.Map;
24 
25 import android.content.pm.ApplicationInfo;
26 import android.telephony.SignalStrength;
27 import android.util.Log;
28 import android.util.Printer;
29 import android.util.Slog;
30 import android.util.SparseArray;
31 import android.util.TimeUtils;
32 
33 /**
34  * A class providing access to battery usage statistics, including information on
35  * wakelocks, processes, packages, and services.  All times are represented in microseconds
36  * except where indicated otherwise.
37  * @hide
38  */
39 public abstract class BatteryStats implements Parcelable {
40 
41     private static final boolean LOCAL_LOGV = false;
42 
43     /**
44      * A constant indicating a partial wake lock timer.
45      */
46     public static final int WAKE_TYPE_PARTIAL = 0;
47 
48     /**
49      * A constant indicating a full wake lock timer.
50      */
51     public static final int WAKE_TYPE_FULL = 1;
52 
53     /**
54      * A constant indicating a window wake lock timer.
55      */
56     public static final int WAKE_TYPE_WINDOW = 2;
57 
58     /**
59      * A constant indicating a sensor timer.
60      */
61     public static final int SENSOR = 3;
62 
63     /**
64      * A constant indicating a a wifi running timer
65      */
66     public static final int WIFI_RUNNING = 4;
67 
68     /**
69      * A constant indicating a full wifi lock timer
70      */
71     public static final int FULL_WIFI_LOCK = 5;
72 
73     /**
74      * A constant indicating a scan wifi lock timer
75      */
76     public static final int SCAN_WIFI_LOCK = 6;
77 
78      /**
79       * A constant indicating a wifi multicast timer
80       */
81      public static final int WIFI_MULTICAST_ENABLED = 7;
82 
83     /**
84      * A constant indicating an audio turn on timer
85      */
86     public static final int AUDIO_TURNED_ON = 7;
87 
88     /**
89      * A constant indicating a video turn on timer
90      */
91     public static final int VIDEO_TURNED_ON = 8;
92 
93     /**
94      * Include all of the data in the stats, including previously saved data.
95      */
96     public static final int STATS_SINCE_CHARGED = 0;
97 
98     /**
99      * Include only the last run in the stats.
100      */
101     public static final int STATS_LAST = 1;
102 
103     /**
104      * Include only the current run in the stats.
105      */
106     public static final int STATS_CURRENT = 2;
107 
108     /**
109      * Include only the run since the last time the device was unplugged in the stats.
110      */
111     public static final int STATS_SINCE_UNPLUGGED = 3;
112 
113     // NOTE: Update this list if you add/change any stats above.
114     // These characters are supposed to represent "total", "last", "current",
115     // and "unplugged". They were shortened for efficiency sake.
116     private static final String[] STAT_NAMES = { "t", "l", "c", "u" };
117 
118     /**
119      * Bump the version on this if the checkin format changes.
120      */
121     private static final int BATTERY_STATS_CHECKIN_VERSION = 5;
122 
123     private static final long BYTES_PER_KB = 1024;
124     private static final long BYTES_PER_MB = 1048576; // 1024^2
125     private static final long BYTES_PER_GB = 1073741824; //1024^3
126 
127 
128     private static final String UID_DATA = "uid";
129     private static final String APK_DATA = "apk";
130     private static final String PROCESS_DATA = "pr";
131     private static final String SENSOR_DATA = "sr";
132     private static final String WAKELOCK_DATA = "wl";
133     private static final String KERNEL_WAKELOCK_DATA = "kwl";
134     private static final String NETWORK_DATA = "nt";
135     private static final String USER_ACTIVITY_DATA = "ua";
136     private static final String BATTERY_DATA = "bt";
137     private static final String BATTERY_DISCHARGE_DATA = "dc";
138     private static final String BATTERY_LEVEL_DATA = "lv";
139     private static final String WIFI_LOCK_DATA = "wfl";
140     private static final String MISC_DATA = "m";
141     private static final String SCREEN_BRIGHTNESS_DATA = "br";
142     private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
143     private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
144     private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
145     private static final String DATA_CONNECTION_TIME_DATA = "dct";
146     private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
147 
148     private final StringBuilder mFormatBuilder = new StringBuilder(32);
149     private final Formatter mFormatter = new Formatter(mFormatBuilder);
150 
151     /**
152      * State for keeping track of counting information.
153      */
154     public static abstract class Counter {
155 
156         /**
157          * Returns the count associated with this Counter for the
158          * selected type of statistics.
159          *
160          * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
161          */
getCountLocked(int which)162         public abstract int getCountLocked(int which);
163 
164         /**
165          * Temporary for debugging.
166          */
logState(Printer pw, String prefix)167         public abstract void logState(Printer pw, String prefix);
168     }
169 
170     /**
171      * State for keeping track of timing information.
172      */
173     public static abstract class Timer {
174 
175         /**
176          * Returns the count associated with this Timer for the
177          * selected type of statistics.
178          *
179          * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
180          */
getCountLocked(int which)181         public abstract int getCountLocked(int which);
182 
183         /**
184          * Returns the total time in microseconds associated with this Timer for the
185          * selected type of statistics.
186          *
187          * @param batteryRealtime system realtime on  battery in microseconds
188          * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
189          * @return a time in microseconds
190          */
getTotalTimeLocked(long batteryRealtime, int which)191         public abstract long getTotalTimeLocked(long batteryRealtime, int which);
192 
193         /**
194          * Temporary for debugging.
195          */
logState(Printer pw, String prefix)196         public abstract void logState(Printer pw, String prefix);
197     }
198 
199     /**
200      * The statistics associated with a particular uid.
201      */
202     public static abstract class Uid {
203 
204         /**
205          * Returns a mapping containing wakelock statistics.
206          *
207          * @return a Map from Strings to Uid.Wakelock objects.
208          */
getWakelockStats()209         public abstract Map<String, ? extends Wakelock> getWakelockStats();
210 
211         /**
212          * The statistics associated with a particular wake lock.
213          */
214         public static abstract class Wakelock {
getWakeTime(int type)215             public abstract Timer getWakeTime(int type);
216         }
217 
218         /**
219          * Returns a mapping containing sensor statistics.
220          *
221          * @return a Map from Integer sensor ids to Uid.Sensor objects.
222          */
getSensorStats()223         public abstract Map<Integer, ? extends Sensor> getSensorStats();
224 
225         /**
226          * Returns a mapping containing active process data.
227          */
getPidStats()228         public abstract SparseArray<? extends Pid> getPidStats();
229 
230         /**
231          * Returns a mapping containing process statistics.
232          *
233          * @return a Map from Strings to Uid.Proc objects.
234          */
getProcessStats()235         public abstract Map<String, ? extends Proc> getProcessStats();
236 
237         /**
238          * Returns a mapping containing package statistics.
239          *
240          * @return a Map from Strings to Uid.Pkg objects.
241          */
getPackageStats()242         public abstract Map<String, ? extends Pkg> getPackageStats();
243 
244         /**
245          * {@hide}
246          */
getUid()247         public abstract int getUid();
248 
249         /**
250          * {@hide}
251          */
getTcpBytesReceived(int which)252         public abstract long getTcpBytesReceived(int which);
253 
254         /**
255          * {@hide}
256          */
getTcpBytesSent(int which)257         public abstract long getTcpBytesSent(int which);
258 
noteWifiRunningLocked()259         public abstract void noteWifiRunningLocked();
noteWifiStoppedLocked()260         public abstract void noteWifiStoppedLocked();
noteFullWifiLockAcquiredLocked()261         public abstract void noteFullWifiLockAcquiredLocked();
noteFullWifiLockReleasedLocked()262         public abstract void noteFullWifiLockReleasedLocked();
noteScanWifiLockAcquiredLocked()263         public abstract void noteScanWifiLockAcquiredLocked();
noteScanWifiLockReleasedLocked()264         public abstract void noteScanWifiLockReleasedLocked();
noteWifiMulticastEnabledLocked()265         public abstract void noteWifiMulticastEnabledLocked();
noteWifiMulticastDisabledLocked()266         public abstract void noteWifiMulticastDisabledLocked();
noteAudioTurnedOnLocked()267         public abstract void noteAudioTurnedOnLocked();
noteAudioTurnedOffLocked()268         public abstract void noteAudioTurnedOffLocked();
noteVideoTurnedOnLocked()269         public abstract void noteVideoTurnedOnLocked();
noteVideoTurnedOffLocked()270         public abstract void noteVideoTurnedOffLocked();
getWifiRunningTime(long batteryRealtime, int which)271         public abstract long getWifiRunningTime(long batteryRealtime, int which);
getFullWifiLockTime(long batteryRealtime, int which)272         public abstract long getFullWifiLockTime(long batteryRealtime, int which);
getScanWifiLockTime(long batteryRealtime, int which)273         public abstract long getScanWifiLockTime(long batteryRealtime, int which);
getWifiMulticastTime(long batteryRealtime, int which)274         public abstract long getWifiMulticastTime(long batteryRealtime,
275                                                   int which);
getAudioTurnedOnTime(long batteryRealtime, int which)276         public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
getVideoTurnedOnTime(long batteryRealtime, int which)277         public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
278 
279         /**
280          * Note that these must match the constants in android.os.LocalPowerManager.
281          */
282         static final String[] USER_ACTIVITY_TYPES = {
283             "other", "cheek", "touch", "long_touch", "touch_up", "button", "unknown"
284         };
285 
286         public static final int NUM_USER_ACTIVITY_TYPES = 7;
287 
noteUserActivityLocked(int type)288         public abstract void noteUserActivityLocked(int type);
hasUserActivity()289         public abstract boolean hasUserActivity();
getUserActivityCount(int type, int which)290         public abstract int getUserActivityCount(int type, int which);
291 
292         public static abstract class Sensor {
293             // Magic sensor number for the GPS.
294             public static final int GPS = -10000;
295 
getHandle()296             public abstract int getHandle();
297 
getSensorTime()298             public abstract Timer getSensorTime();
299         }
300 
301         public class Pid {
302             public long mWakeSum;
303             public long mWakeStart;
304         }
305 
306         /**
307          * The statistics associated with a particular process.
308          */
309         public static abstract class Proc {
310 
311             public static class ExcessivePower {
312                 public static final int TYPE_WAKE = 1;
313                 public static final int TYPE_CPU = 2;
314 
315                 public int type;
316                 public long overTime;
317                 public long usedTime;
318             }
319 
320             /**
321              * Returns the total time (in 1/100 sec) spent executing in user code.
322              *
323              * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
324              */
getUserTime(int which)325             public abstract long getUserTime(int which);
326 
327             /**
328              * Returns the total time (in 1/100 sec) spent executing in system code.
329              *
330              * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
331              */
getSystemTime(int which)332             public abstract long getSystemTime(int which);
333 
334             /**
335              * Returns the number of times the process has been started.
336              *
337              * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
338              */
getStarts(int which)339             public abstract int getStarts(int which);
340 
341             /**
342              * Returns the cpu time spent in microseconds while the process was in the foreground.
343              * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
344              * @return foreground cpu time in microseconds
345              */
getForegroundTime(int which)346             public abstract long getForegroundTime(int which);
347 
348             /**
349              * Returns the approximate cpu time spent in microseconds, at a certain CPU speed.
350              * @param speedStep the index of the CPU speed. This is not the actual speed of the
351              * CPU.
352              * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
353              * @see BatteryStats#getCpuSpeedSteps()
354              */
getTimeAtCpuSpeedStep(int speedStep, int which)355             public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
356 
countExcessivePowers()357             public abstract int countExcessivePowers();
358 
getExcessivePower(int i)359             public abstract ExcessivePower getExcessivePower(int i);
360         }
361 
362         /**
363          * The statistics associated with a particular package.
364          */
365         public static abstract class Pkg {
366 
367             /**
368              * Returns the number of times this package has done something that could wake up the
369              * device from sleep.
370              *
371              * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
372              */
getWakeups(int which)373             public abstract int getWakeups(int which);
374 
375             /**
376              * Returns a mapping containing service statistics.
377              */
getServiceStats()378             public abstract Map<String, ? extends Serv> getServiceStats();
379 
380             /**
381              * The statistics associated with a particular service.
382              */
383             public abstract class Serv {
384 
385                 /**
386                  * Returns the amount of time spent started.
387                  *
388                  * @param batteryUptime elapsed uptime on battery in microseconds.
389                  * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
390                  * @return
391                  */
getStartTime(long batteryUptime, int which)392                 public abstract long getStartTime(long batteryUptime, int which);
393 
394                 /**
395                  * Returns the total number of times startService() has been called.
396                  *
397                  * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
398                  */
getStarts(int which)399                 public abstract int getStarts(int which);
400 
401                 /**
402                  * Returns the total number times the service has been launched.
403                  *
404                  * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
405                  */
getLaunches(int which)406                 public abstract int getLaunches(int which);
407             }
408         }
409     }
410 
411     public final static class HistoryItem implements Parcelable {
412         static final String TAG = "HistoryItem";
413         static final boolean DEBUG = false;
414 
415         public HistoryItem next;
416 
417         public long time;
418 
419         public static final byte CMD_NULL = 0;
420         public static final byte CMD_UPDATE = 1;
421         public static final byte CMD_START = 2;
422         public static final byte CMD_OVERFLOW = 3;
423 
424         public byte cmd = CMD_NULL;
425 
426         public byte batteryLevel;
427         public byte batteryStatus;
428         public byte batteryHealth;
429         public byte batteryPlugType;
430 
431         public char batteryTemperature;
432         public char batteryVoltage;
433 
434         // Constants from SCREEN_BRIGHTNESS_*
435         public static final int STATE_BRIGHTNESS_MASK = 0x0000000f;
436         public static final int STATE_BRIGHTNESS_SHIFT = 0;
437         // Constants from SIGNAL_STRENGTH_*
438         public static final int STATE_SIGNAL_STRENGTH_MASK = 0x000000f0;
439         public static final int STATE_SIGNAL_STRENGTH_SHIFT = 4;
440         // Constants from ServiceState.STATE_*
441         public static final int STATE_PHONE_STATE_MASK = 0x00000f00;
442         public static final int STATE_PHONE_STATE_SHIFT = 8;
443         // Constants from DATA_CONNECTION_*
444         public static final int STATE_DATA_CONNECTION_MASK = 0x0000f000;
445         public static final int STATE_DATA_CONNECTION_SHIFT = 12;
446 
447         // These states always appear directly in the first int token
448         // of a delta change; they should be ones that change relatively
449         // frequently.
450         public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
451         public static final int STATE_SENSOR_ON_FLAG = 1<<29;
452         public static final int STATE_GPS_ON_FLAG = 1<<28;
453         public static final int STATE_PHONE_SCANNING_FLAG = 1<<27;
454         public static final int STATE_WIFI_RUNNING_FLAG = 1<<26;
455         public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<25;
456         public static final int STATE_WIFI_SCAN_LOCK_FLAG = 1<<24;
457         public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<23;
458         // These are on the lower bits used for the command; if they change
459         // we need to write another int of data.
460         public static final int STATE_AUDIO_ON_FLAG = 1<<22;
461         public static final int STATE_VIDEO_ON_FLAG = 1<<21;
462         public static final int STATE_SCREEN_ON_FLAG = 1<<20;
463         public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19;
464         public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18;
465         public static final int STATE_WIFI_ON_FLAG = 1<<17;
466         public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16;
467 
468         public static final int MOST_INTERESTING_STATES =
469             STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG
470             | STATE_GPS_ON_FLAG | STATE_PHONE_IN_CALL_FLAG;
471 
472         public int states;
473 
HistoryItem()474         public HistoryItem() {
475         }
476 
HistoryItem(long time, Parcel src)477         public HistoryItem(long time, Parcel src) {
478             this.time = time;
479             readFromParcel(src);
480         }
481 
describeContents()482         public int describeContents() {
483             return 0;
484         }
485 
writeToParcel(Parcel dest, int flags)486         public void writeToParcel(Parcel dest, int flags) {
487             dest.writeLong(time);
488             int bat = (((int)cmd)&0xff)
489                     | ((((int)batteryLevel)<<8)&0xff00)
490                     | ((((int)batteryStatus)<<16)&0xf0000)
491                     | ((((int)batteryHealth)<<20)&0xf00000)
492                     | ((((int)batteryPlugType)<<24)&0xf000000);
493             dest.writeInt(bat);
494             bat = (((int)batteryTemperature)&0xffff)
495                     | ((((int)batteryVoltage)<<16)&0xffff0000);
496             dest.writeInt(bat);
497             dest.writeInt(states);
498         }
499 
readFromParcel(Parcel src)500         private void readFromParcel(Parcel src) {
501             int bat = src.readInt();
502             cmd = (byte)(bat&0xff);
503             batteryLevel = (byte)((bat>>8)&0xff);
504             batteryStatus = (byte)((bat>>16)&0xf);
505             batteryHealth = (byte)((bat>>20)&0xf);
506             batteryPlugType = (byte)((bat>>24)&0xf);
507             bat = src.readInt();
508             batteryTemperature = (char)(bat&0xffff);
509             batteryVoltage = (char)((bat>>16)&0xffff);
510             states = src.readInt();
511         }
512 
513         // Part of initial delta int that specifies the time delta.
514         static final int DELTA_TIME_MASK = 0x3ffff;
515         static final int DELTA_TIME_ABS = 0x3fffd;    // Following is an entire abs update.
516         static final int DELTA_TIME_INT = 0x3fffe;    // The delta is a following int
517         static final int DELTA_TIME_LONG = 0x3ffff;   // The delta is a following long
518         // Part of initial delta int holding the command code.
519         static final int DELTA_CMD_MASK = 0x3;
520         static final int DELTA_CMD_SHIFT = 18;
521         // Flag in delta int: a new battery level int follows.
522         static final int DELTA_BATTERY_LEVEL_FLAG = 1<<20;
523         // Flag in delta int: a new full state and battery status int follows.
524         static final int DELTA_STATE_FLAG = 1<<21;
525         static final int DELTA_STATE_MASK = 0xffc00000;
526 
writeDelta(Parcel dest, HistoryItem last)527         public void writeDelta(Parcel dest, HistoryItem last) {
528             if (last == null || last.cmd != CMD_UPDATE) {
529                 dest.writeInt(DELTA_TIME_ABS);
530                 writeToParcel(dest, 0);
531                 return;
532             }
533 
534             final long deltaTime = time - last.time;
535             final int lastBatteryLevelInt = last.buildBatteryLevelInt();
536             final int lastStateInt = last.buildStateInt();
537 
538             int deltaTimeToken;
539             if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
540                 deltaTimeToken = DELTA_TIME_LONG;
541             } else if (deltaTime >= DELTA_TIME_ABS) {
542                 deltaTimeToken = DELTA_TIME_INT;
543             } else {
544                 deltaTimeToken = (int)deltaTime;
545             }
546             int firstToken = deltaTimeToken
547                     | (cmd<<DELTA_CMD_SHIFT)
548                     | (states&DELTA_STATE_MASK);
549             final int batteryLevelInt = buildBatteryLevelInt();
550             final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
551             if (batteryLevelIntChanged) {
552                 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
553             }
554             final int stateInt = buildStateInt();
555             final boolean stateIntChanged = stateInt != lastStateInt;
556             if (stateIntChanged) {
557                 firstToken |= DELTA_STATE_FLAG;
558             }
559             dest.writeInt(firstToken);
560             if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
561                     + " deltaTime=" + deltaTime);
562 
563             if (deltaTimeToken >= DELTA_TIME_INT) {
564                 if (deltaTimeToken == DELTA_TIME_INT) {
565                     if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
566                     dest.writeInt((int)deltaTime);
567                 } else {
568                     if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
569                     dest.writeLong(deltaTime);
570                 }
571             }
572             if (batteryLevelIntChanged) {
573                 dest.writeInt(batteryLevelInt);
574                 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
575                         + Integer.toHexString(batteryLevelInt)
576                         + " batteryLevel=" + batteryLevel
577                         + " batteryTemp=" + (int)batteryTemperature
578                         + " batteryVolt=" + (int)batteryVoltage);
579             }
580             if (stateIntChanged) {
581                 dest.writeInt(stateInt);
582                 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
583                         + Integer.toHexString(stateInt)
584                         + " batteryStatus=" + batteryStatus
585                         + " batteryHealth=" + batteryHealth
586                         + " batteryPlugType=" + batteryPlugType
587                         + " states=0x" + Integer.toHexString(states));
588             }
589         }
590 
buildBatteryLevelInt()591         private int buildBatteryLevelInt() {
592             return ((((int)batteryLevel)<<24)&0xff000000)
593                     | ((((int)batteryTemperature)<<14)&0x00ffc000)
594                     | (((int)batteryVoltage)&0x00003fff);
595         }
596 
buildStateInt()597         private int buildStateInt() {
598             return ((((int)batteryStatus)<<28)&0xf0000000)
599                     | ((((int)batteryHealth)<<24)&0x0f000000)
600                     | ((((int)batteryPlugType)<<22)&0x00c00000)
601                     | (states&(~DELTA_STATE_MASK));
602         }
603 
readDelta(Parcel src)604         public void readDelta(Parcel src) {
605             int firstToken = src.readInt();
606             int deltaTimeToken = firstToken&DELTA_TIME_MASK;
607             cmd = (byte)((firstToken>>DELTA_CMD_SHIFT)&DELTA_CMD_MASK);
608             if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
609                     + " deltaTimeToken=" + deltaTimeToken);
610 
611             if (deltaTimeToken < DELTA_TIME_ABS) {
612                 time += deltaTimeToken;
613             } else if (deltaTimeToken == DELTA_TIME_ABS) {
614                 time = src.readLong();
615                 readFromParcel(src);
616                 return;
617             } else if (deltaTimeToken == DELTA_TIME_INT) {
618                 int delta = src.readInt();
619                 time += delta;
620                 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + time);
621             } else {
622                 long delta = src.readLong();
623                 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + time);
624                 time += delta;
625             }
626 
627             if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
628                 int batteryLevelInt = src.readInt();
629                 batteryLevel = (byte)((batteryLevelInt>>24)&0xff);
630                 batteryTemperature = (char)((batteryLevelInt>>14)&0x3ff);
631                 batteryVoltage = (char)(batteryLevelInt&0x3fff);
632                 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
633                         + Integer.toHexString(batteryLevelInt)
634                         + " batteryLevel=" + batteryLevel
635                         + " batteryTemp=" + (int)batteryTemperature
636                         + " batteryVolt=" + (int)batteryVoltage);
637             }
638 
639             if ((firstToken&DELTA_STATE_FLAG) != 0) {
640                 int stateInt = src.readInt();
641                 states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
642                 batteryStatus = (byte)((stateInt>>28)&0xf);
643                 batteryHealth = (byte)((stateInt>>24)&0xf);
644                 batteryPlugType = (byte)((stateInt>>22)&0x3);
645                 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
646                         + Integer.toHexString(stateInt)
647                         + " batteryStatus=" + batteryStatus
648                         + " batteryHealth=" + batteryHealth
649                         + " batteryPlugType=" + batteryPlugType
650                         + " states=0x" + Integer.toHexString(states));
651             } else {
652                 states = (firstToken&DELTA_STATE_MASK) | (states&(~DELTA_STATE_MASK));
653             }
654         }
655 
clear()656         public void clear() {
657             time = 0;
658             cmd = CMD_NULL;
659             batteryLevel = 0;
660             batteryStatus = 0;
661             batteryHealth = 0;
662             batteryPlugType = 0;
663             batteryTemperature = 0;
664             batteryVoltage = 0;
665             states = 0;
666         }
667 
setTo(HistoryItem o)668         public void setTo(HistoryItem o) {
669             time = o.time;
670             cmd = o.cmd;
671             batteryLevel = o.batteryLevel;
672             batteryStatus = o.batteryStatus;
673             batteryHealth = o.batteryHealth;
674             batteryPlugType = o.batteryPlugType;
675             batteryTemperature = o.batteryTemperature;
676             batteryVoltage = o.batteryVoltage;
677             states = o.states;
678         }
679 
setTo(long time, byte cmd, HistoryItem o)680         public void setTo(long time, byte cmd, HistoryItem o) {
681             this.time = time;
682             this.cmd = cmd;
683             batteryLevel = o.batteryLevel;
684             batteryStatus = o.batteryStatus;
685             batteryHealth = o.batteryHealth;
686             batteryPlugType = o.batteryPlugType;
687             batteryTemperature = o.batteryTemperature;
688             batteryVoltage = o.batteryVoltage;
689             states = o.states;
690         }
691 
same(HistoryItem o)692         public boolean same(HistoryItem o) {
693             return batteryLevel == o.batteryLevel
694                     && batteryStatus == o.batteryStatus
695                     && batteryHealth == o.batteryHealth
696                     && batteryPlugType == o.batteryPlugType
697                     && batteryTemperature == o.batteryTemperature
698                     && batteryVoltage == o.batteryVoltage
699                     && states == o.states;
700         }
701     }
702 
703     public static final class BitDescription {
704         public final int mask;
705         public final int shift;
706         public final String name;
707         public final String[] values;
708 
BitDescription(int mask, String name)709         public BitDescription(int mask, String name) {
710             this.mask = mask;
711             this.shift = -1;
712             this.name = name;
713             this.values = null;
714         }
715 
BitDescription(int mask, int shift, String name, String[] values)716         public BitDescription(int mask, int shift, String name, String[] values) {
717             this.mask = mask;
718             this.shift = shift;
719             this.name = name;
720             this.values = values;
721         }
722     }
723 
startIteratingHistoryLocked()724     public abstract boolean startIteratingHistoryLocked();
725 
getNextHistoryLocked(HistoryItem out)726     public abstract boolean getNextHistoryLocked(HistoryItem out);
727 
finishIteratingHistoryLocked()728     public abstract void finishIteratingHistoryLocked();
729 
startIteratingOldHistoryLocked()730     public abstract boolean startIteratingOldHistoryLocked();
731 
getNextOldHistoryLocked(HistoryItem out)732     public abstract boolean getNextOldHistoryLocked(HistoryItem out);
733 
finishIteratingOldHistoryLocked()734     public abstract void finishIteratingOldHistoryLocked();
735 
736     /**
737      * Return the base time offset for the battery history.
738      */
getHistoryBaseTime()739     public abstract long getHistoryBaseTime();
740 
741     /**
742      * Returns the number of times the device has been started.
743      */
getStartCount()744     public abstract int getStartCount();
745 
746     /**
747      * Returns the time in microseconds that the screen has been on while the device was
748      * running on battery.
749      *
750      * {@hide}
751      */
getScreenOnTime(long batteryRealtime, int which)752     public abstract long getScreenOnTime(long batteryRealtime, int which);
753 
754     public static final int SCREEN_BRIGHTNESS_DARK = 0;
755     public static final int SCREEN_BRIGHTNESS_DIM = 1;
756     public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
757     public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
758     public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
759 
760     static final String[] SCREEN_BRIGHTNESS_NAMES = {
761         "dark", "dim", "medium", "light", "bright"
762     };
763 
764     public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
765 
766     /**
767      * Returns the time in microseconds that the screen has been on with
768      * the given brightness
769      *
770      * {@hide}
771      */
getScreenBrightnessTime(int brightnessBin, long batteryRealtime, int which)772     public abstract long getScreenBrightnessTime(int brightnessBin,
773             long batteryRealtime, int which);
774 
getInputEventCount(int which)775     public abstract int getInputEventCount(int which);
776 
777     /**
778      * Returns the time in microseconds that the phone has been on while the device was
779      * running on battery.
780      *
781      * {@hide}
782      */
getPhoneOnTime(long batteryRealtime, int which)783     public abstract long getPhoneOnTime(long batteryRealtime, int which);
784 
785     /**
786      * Returns the time in microseconds that the phone has been running with
787      * the given signal strength.
788      *
789      * {@hide}
790      */
getPhoneSignalStrengthTime(int strengthBin, long batteryRealtime, int which)791     public abstract long getPhoneSignalStrengthTime(int strengthBin,
792             long batteryRealtime, int which);
793 
794     /**
795      * Returns the time in microseconds that the phone has been trying to
796      * acquire a signal.
797      *
798      * {@hide}
799      */
getPhoneSignalScanningTime( long batteryRealtime, int which)800     public abstract long getPhoneSignalScanningTime(
801             long batteryRealtime, int which);
802 
803     /**
804      * Returns the number of times the phone has entered the given signal strength.
805      *
806      * {@hide}
807      */
getPhoneSignalStrengthCount(int strengthBin, int which)808     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
809 
810     public static final int DATA_CONNECTION_NONE = 0;
811     public static final int DATA_CONNECTION_GPRS = 1;
812     public static final int DATA_CONNECTION_EDGE = 2;
813     public static final int DATA_CONNECTION_UMTS = 3;
814     public static final int DATA_CONNECTION_CDMA = 4;
815     public static final int DATA_CONNECTION_EVDO_0 = 5;
816     public static final int DATA_CONNECTION_EVDO_A = 6;
817     public static final int DATA_CONNECTION_1xRTT = 7;
818     public static final int DATA_CONNECTION_HSDPA = 8;
819     public static final int DATA_CONNECTION_HSUPA = 9;
820     public static final int DATA_CONNECTION_HSPA = 10;
821     public static final int DATA_CONNECTION_IDEN = 11;
822     public static final int DATA_CONNECTION_EVDO_B = 12;
823     public static final int DATA_CONNECTION_LTE = 13;
824     public static final int DATA_CONNECTION_EHRPD = 14;
825     public static final int DATA_CONNECTION_OTHER = 15;
826 
827     static final String[] DATA_CONNECTION_NAMES = {
828         "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
829         "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
830         "ehrpd", "other"
831     };
832 
833     public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
834 
835     /**
836      * Returns the time in microseconds that the phone has been running with
837      * the given data connection.
838      *
839      * {@hide}
840      */
getPhoneDataConnectionTime(int dataType, long batteryRealtime, int which)841     public abstract long getPhoneDataConnectionTime(int dataType,
842             long batteryRealtime, int which);
843 
844     /**
845      * Returns the number of times the phone has entered the given data
846      * connection type.
847      *
848      * {@hide}
849      */
getPhoneDataConnectionCount(int dataType, int which)850     public abstract int getPhoneDataConnectionCount(int dataType, int which);
851 
852     public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
853             = new BitDescription[] {
854         new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged"),
855         new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen"),
856         new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps"),
857         new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call"),
858         new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning"),
859         new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi"),
860         new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running"),
861         new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock"),
862         new BitDescription(HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG, "wifi_scan_lock"),
863         new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast"),
864         new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth"),
865         new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio"),
866         new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video"),
867         new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock"),
868         new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor"),
869         new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
870                 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness",
871                 SCREEN_BRIGHTNESS_NAMES),
872         new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK,
873                 HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength",
874                 SignalStrength.SIGNAL_STRENGTH_NAMES),
875         new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
876                 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state",
877                 new String[] {"in", "out", "emergency", "off"}),
878         new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
879                 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn",
880                 DATA_CONNECTION_NAMES),
881     };
882 
883     /**
884      * Returns the time in microseconds that wifi has been on while the device was
885      * running on battery.
886      *
887      * {@hide}
888      */
getWifiOnTime(long batteryRealtime, int which)889     public abstract long getWifiOnTime(long batteryRealtime, int which);
890 
891     /**
892      * Returns the time in microseconds that wifi has been on and the driver has
893      * been in the running state while the device was running on battery.
894      *
895      * {@hide}
896      */
getGlobalWifiRunningTime(long batteryRealtime, int which)897     public abstract long getGlobalWifiRunningTime(long batteryRealtime, int which);
898 
899     /**
900      * Returns the time in microseconds that bluetooth has been on while the device was
901      * running on battery.
902      *
903      * {@hide}
904      */
getBluetoothOnTime(long batteryRealtime, int which)905     public abstract long getBluetoothOnTime(long batteryRealtime, int which);
906 
907     /**
908      * Return whether we are currently running on battery.
909      */
getIsOnBattery()910     public abstract boolean getIsOnBattery();
911 
912     /**
913      * Returns a SparseArray containing the statistics for each uid.
914      */
getUidStats()915     public abstract SparseArray<? extends Uid> getUidStats();
916 
917     /**
918      * Returns the current battery uptime in microseconds.
919      *
920      * @param curTime the amount of elapsed realtime in microseconds.
921      */
getBatteryUptime(long curTime)922     public abstract long getBatteryUptime(long curTime);
923 
924     /**
925      * @deprecated use getRadioDataUptime
926      */
getRadioDataUptimeMs()927     public long getRadioDataUptimeMs() {
928         return getRadioDataUptime() / 1000;
929     }
930 
931     /**
932      * Returns the time that the radio was on for data transfers.
933      * @return the uptime in microseconds while unplugged
934      */
getRadioDataUptime()935     public abstract long getRadioDataUptime();
936 
937     /**
938      * Returns the current battery realtime in microseconds.
939      *
940      * @param curTime the amount of elapsed realtime in microseconds.
941      */
getBatteryRealtime(long curTime)942     public abstract long getBatteryRealtime(long curTime);
943 
944     /**
945      * Returns the battery percentage level at the last time the device was unplugged from power, or
946      * the last time it booted on battery power.
947      */
getDischargeStartLevel()948     public abstract int getDischargeStartLevel();
949 
950     /**
951      * Returns the current battery percentage level if we are in a discharge cycle, otherwise
952      * returns the level at the last plug event.
953      */
getDischargeCurrentLevel()954     public abstract int getDischargeCurrentLevel();
955 
956     /**
957      * Get the amount the battery has discharged since the stats were
958      * last reset after charging, as a lower-end approximation.
959      */
getLowDischargeAmountSinceCharge()960     public abstract int getLowDischargeAmountSinceCharge();
961 
962     /**
963      * Get the amount the battery has discharged since the stats were
964      * last reset after charging, as an upper-end approximation.
965      */
getHighDischargeAmountSinceCharge()966     public abstract int getHighDischargeAmountSinceCharge();
967 
968     /**
969      * Get the amount the battery has discharged while the screen was on,
970      * since the last time power was unplugged.
971      */
getDischargeAmountScreenOn()972     public abstract int getDischargeAmountScreenOn();
973 
974     /**
975      * Get the amount the battery has discharged while the screen was on,
976      * since the last time the device was charged.
977      */
getDischargeAmountScreenOnSinceCharge()978     public abstract int getDischargeAmountScreenOnSinceCharge();
979 
980     /**
981      * Get the amount the battery has discharged while the screen was off,
982      * since the last time power was unplugged.
983      */
getDischargeAmountScreenOff()984     public abstract int getDischargeAmountScreenOff();
985 
986     /**
987      * Get the amount the battery has discharged while the screen was off,
988      * since the last time the device was charged.
989      */
getDischargeAmountScreenOffSinceCharge()990     public abstract int getDischargeAmountScreenOffSinceCharge();
991 
992     /**
993      * Returns the total, last, or current battery uptime in microseconds.
994      *
995      * @param curTime the elapsed realtime in microseconds.
996      * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
997      */
computeBatteryUptime(long curTime, int which)998     public abstract long computeBatteryUptime(long curTime, int which);
999 
1000     /**
1001      * Returns the total, last, or current battery realtime in microseconds.
1002      *
1003      * @param curTime the current elapsed realtime in microseconds.
1004      * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1005      */
computeBatteryRealtime(long curTime, int which)1006     public abstract long computeBatteryRealtime(long curTime, int which);
1007 
1008     /**
1009      * Returns the total, last, or current uptime in microseconds.
1010      *
1011      * @param curTime the current elapsed realtime in microseconds.
1012      * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1013      */
computeUptime(long curTime, int which)1014     public abstract long computeUptime(long curTime, int which);
1015 
1016     /**
1017      * Returns the total, last, or current realtime in microseconds.
1018      * *
1019      * @param curTime the current elapsed realtime in microseconds.
1020      * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1021      */
computeRealtime(long curTime, int which)1022     public abstract long computeRealtime(long curTime, int which);
1023 
getKernelWakelockStats()1024     public abstract Map<String, ? extends Timer> getKernelWakelockStats();
1025 
1026     /** Returns the number of different speeds that the CPU can run at */
getCpuSpeedSteps()1027     public abstract int getCpuSpeedSteps();
1028 
formatTimeRaw(StringBuilder out, long seconds)1029     private final static void formatTimeRaw(StringBuilder out, long seconds) {
1030         long days = seconds / (60 * 60 * 24);
1031         if (days != 0) {
1032             out.append(days);
1033             out.append("d ");
1034         }
1035         long used = days * 60 * 60 * 24;
1036 
1037         long hours = (seconds - used) / (60 * 60);
1038         if (hours != 0 || used != 0) {
1039             out.append(hours);
1040             out.append("h ");
1041         }
1042         used += hours * 60 * 60;
1043 
1044         long mins = (seconds-used) / 60;
1045         if (mins != 0 || used != 0) {
1046             out.append(mins);
1047             out.append("m ");
1048         }
1049         used += mins * 60;
1050 
1051         if (seconds != 0 || used != 0) {
1052             out.append(seconds-used);
1053             out.append("s ");
1054         }
1055     }
1056 
formatTime(StringBuilder sb, long time)1057     private final static void formatTime(StringBuilder sb, long time) {
1058         long sec = time / 100;
1059         formatTimeRaw(sb, sec);
1060         sb.append((time - (sec * 100)) * 10);
1061         sb.append("ms ");
1062     }
1063 
formatTimeMs(StringBuilder sb, long time)1064     private final static void formatTimeMs(StringBuilder sb, long time) {
1065         long sec = time / 1000;
1066         formatTimeRaw(sb, sec);
1067         sb.append(time - (sec * 1000));
1068         sb.append("ms ");
1069     }
1070 
formatRatioLocked(long num, long den)1071     private final String formatRatioLocked(long num, long den) {
1072         if (den == 0L) {
1073             return "---%";
1074         }
1075         float perc = ((float)num) / ((float)den) * 100;
1076         mFormatBuilder.setLength(0);
1077         mFormatter.format("%.1f%%", perc);
1078         return mFormatBuilder.toString();
1079     }
1080 
formatBytesLocked(long bytes)1081     private final String formatBytesLocked(long bytes) {
1082         mFormatBuilder.setLength(0);
1083 
1084         if (bytes < BYTES_PER_KB) {
1085             return bytes + "B";
1086         } else if (bytes < BYTES_PER_MB) {
1087             mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
1088             return mFormatBuilder.toString();
1089         } else if (bytes < BYTES_PER_GB){
1090             mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
1091             return mFormatBuilder.toString();
1092         } else {
1093             mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
1094             return mFormatBuilder.toString();
1095         }
1096     }
1097 
computeWakeLock(Timer timer, long batteryRealtime, int which)1098     private static long computeWakeLock(Timer timer, long batteryRealtime, int which) {
1099         if (timer != null) {
1100             // Convert from microseconds to milliseconds with rounding
1101             long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
1102             long totalTimeMillis = (totalTimeMicros + 500) / 1000;
1103             return totalTimeMillis;
1104         }
1105         return 0;
1106     }
1107 
1108     /**
1109      *
1110      * @param sb a StringBuilder object.
1111      * @param timer a Timer object contining the wakelock times.
1112      * @param batteryRealtime the current on-battery time in microseconds.
1113      * @param name the name of the wakelock.
1114      * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1115      * @param linePrefix a String to be prepended to each line of output.
1116      * @return the line prefix
1117      */
printWakeLock(StringBuilder sb, Timer timer, long batteryRealtime, String name, int which, String linePrefix)1118     private static final String printWakeLock(StringBuilder sb, Timer timer,
1119             long batteryRealtime, String name, int which, String linePrefix) {
1120 
1121         if (timer != null) {
1122             long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which);
1123 
1124             int count = timer.getCountLocked(which);
1125             if (totalTimeMillis != 0) {
1126                 sb.append(linePrefix);
1127                 formatTimeMs(sb, totalTimeMillis);
1128                 if (name != null) sb.append(name);
1129                 sb.append(' ');
1130                 sb.append('(');
1131                 sb.append(count);
1132                 sb.append(" times)");
1133                 return ", ";
1134             }
1135         }
1136         return linePrefix;
1137     }
1138 
1139     /**
1140      * Checkin version of wakelock printer. Prints simple comma-separated list.
1141      *
1142      * @param sb a StringBuilder object.
1143      * @param timer a Timer object contining the wakelock times.
1144      * @param now the current time in microseconds.
1145      * @param name the name of the wakelock.
1146      * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1147      * @param linePrefix a String to be prepended to each line of output.
1148      * @return the line prefix
1149      */
printWakeLockCheckin(StringBuilder sb, Timer timer, long now, String name, int which, String linePrefix)1150     private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
1151             String name, int which, String linePrefix) {
1152         long totalTimeMicros = 0;
1153         int count = 0;
1154         if (timer != null) {
1155             totalTimeMicros = timer.getTotalTimeLocked(now, which);
1156             count = timer.getCountLocked(which);
1157         }
1158         sb.append(linePrefix);
1159         sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
1160         sb.append(',');
1161         sb.append(name != null ? name + "," : "");
1162         sb.append(count);
1163         return ",";
1164     }
1165 
1166     /**
1167      * Dump a comma-separated line of values for terse checkin mode.
1168      *
1169      * @param pw the PageWriter to dump log to
1170      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
1171      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
1172      * @param args type-dependent data arguments
1173      */
dumpLine(PrintWriter pw, int uid, String category, String type, Object... args )1174     private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
1175            Object... args ) {
1176         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
1177         pw.print(uid); pw.print(',');
1178         pw.print(category); pw.print(',');
1179         pw.print(type);
1180 
1181         for (Object arg : args) {
1182             pw.print(',');
1183             pw.print(arg);
1184         }
1185         pw.print('\n');
1186     }
1187 
1188     /**
1189      * Checkin server version of dump to produce more compact, computer-readable log.
1190      *
1191      * NOTE: all times are expressed in 'ms'.
1192      */
dumpCheckinLocked(PrintWriter pw, int which, int reqUid)1193     public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) {
1194         final long rawUptime = SystemClock.uptimeMillis() * 1000;
1195         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
1196         final long batteryUptime = getBatteryUptime(rawUptime);
1197         final long batteryRealtime = getBatteryRealtime(rawRealtime);
1198         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
1199         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
1200         final long totalRealtime = computeRealtime(rawRealtime, which);
1201         final long totalUptime = computeUptime(rawUptime, which);
1202         final long screenOnTime = getScreenOnTime(batteryRealtime, which);
1203         final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
1204         final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
1205         final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
1206         final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
1207 
1208         StringBuilder sb = new StringBuilder(128);
1209 
1210         SparseArray<? extends Uid> uidStats = getUidStats();
1211         final int NU = uidStats.size();
1212 
1213         String category = STAT_NAMES[which];
1214 
1215         // Dump "battery" stat
1216         dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
1217                 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
1218                 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
1219                 totalRealtime / 1000, totalUptime / 1000);
1220 
1221         // Calculate total network and wakelock times across all uids.
1222         long rxTotal = 0;
1223         long txTotal = 0;
1224         long fullWakeLockTimeTotal = 0;
1225         long partialWakeLockTimeTotal = 0;
1226 
1227         for (int iu = 0; iu < NU; iu++) {
1228             Uid u = uidStats.valueAt(iu);
1229             rxTotal += u.getTcpBytesReceived(which);
1230             txTotal += u.getTcpBytesSent(which);
1231 
1232             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1233             if (wakelocks.size() > 0) {
1234                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1235                         : wakelocks.entrySet()) {
1236                     Uid.Wakelock wl = ent.getValue();
1237 
1238                     Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1239                     if (fullWakeTimer != null) {
1240                         fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
1241                     }
1242 
1243                     Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1244                     if (partialWakeTimer != null) {
1245                         partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
1246                             batteryRealtime, which);
1247                     }
1248                 }
1249             }
1250         }
1251 
1252         // Dump misc stats
1253         dumpLine(pw, 0 /* uid */, category, MISC_DATA,
1254                 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
1255                 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal,
1256                 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
1257                 getInputEventCount(which));
1258 
1259         // Dump screen brightness stats
1260         Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
1261         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1262             args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
1263         }
1264         dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
1265 
1266         // Dump signal strength stats
1267         args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
1268         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
1269             args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
1270         }
1271         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
1272         dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
1273                 getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
1274         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
1275             args[i] = getPhoneSignalStrengthCount(i, which);
1276         }
1277         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
1278 
1279         // Dump network type stats
1280         args = new Object[NUM_DATA_CONNECTION_TYPES];
1281         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1282             args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
1283         }
1284         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
1285         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1286             args[i] = getPhoneDataConnectionCount(i, which);
1287         }
1288         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
1289 
1290         if (which == STATS_SINCE_UNPLUGGED) {
1291             dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
1292                     getDischargeCurrentLevel());
1293         }
1294 
1295         if (which == STATS_SINCE_UNPLUGGED) {
1296             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
1297                     getDischargeStartLevel()-getDischargeCurrentLevel(),
1298                     getDischargeStartLevel()-getDischargeCurrentLevel(),
1299                     getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
1300         } else {
1301             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
1302                     getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
1303                     getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
1304         }
1305 
1306         if (reqUid < 0) {
1307             Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1308             if (kernelWakelocks.size() > 0) {
1309                 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1310                     sb.setLength(0);
1311                     printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
1312 
1313                     dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
1314                             sb.toString());
1315                 }
1316             }
1317         }
1318 
1319         for (int iu = 0; iu < NU; iu++) {
1320             final int uid = uidStats.keyAt(iu);
1321             if (reqUid >= 0 && uid != reqUid) {
1322                 continue;
1323             }
1324             Uid u = uidStats.valueAt(iu);
1325             // Dump Network stats per uid, if any
1326             long rx = u.getTcpBytesReceived(which);
1327             long tx = u.getTcpBytesSent(which);
1328             long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1329             long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
1330             long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
1331 
1332             if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
1333 
1334             if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
1335                     || uidWifiRunningTime != 0) {
1336                 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
1337                         fullWifiLockOnTime, scanWifiLockOnTime, uidWifiRunningTime);
1338             }
1339 
1340             if (u.hasUserActivity()) {
1341                 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
1342                 boolean hasData = false;
1343                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
1344                     int val = u.getUserActivityCount(i, which);
1345                     args[i] = val;
1346                     if (val != 0) hasData = true;
1347                 }
1348                 if (hasData) {
1349                     dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args);
1350                 }
1351             }
1352 
1353             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1354             if (wakelocks.size() > 0) {
1355                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1356                         : wakelocks.entrySet()) {
1357                     Uid.Wakelock wl = ent.getValue();
1358                     String linePrefix = "";
1359                     sb.setLength(0);
1360                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
1361                             batteryRealtime, "f", which, linePrefix);
1362                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
1363                             batteryRealtime, "p", which, linePrefix);
1364                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
1365                             batteryRealtime, "w", which, linePrefix);
1366 
1367                     // Only log if we had at lease one wakelock...
1368                     if (sb.length() > 0) {
1369                        dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
1370                     }
1371                 }
1372             }
1373 
1374             Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1375             if (sensors.size() > 0)  {
1376                 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1377                         : sensors.entrySet()) {
1378                     Uid.Sensor se = ent.getValue();
1379                     int sensorNumber = ent.getKey();
1380                     Timer timer = se.getSensorTime();
1381                     if (timer != null) {
1382                         // Convert from microseconds to milliseconds with rounding
1383                         long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
1384                         int count = timer.getCountLocked(which);
1385                         if (totalTime != 0) {
1386                             dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
1387                         }
1388                     }
1389                 }
1390             }
1391 
1392             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1393             if (processStats.size() > 0) {
1394                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1395                         : processStats.entrySet()) {
1396                     Uid.Proc ps = ent.getValue();
1397 
1398                     long userTime = ps.getUserTime(which);
1399                     long systemTime = ps.getSystemTime(which);
1400                     int starts = ps.getStarts(which);
1401 
1402                     if (userTime != 0 || systemTime != 0 || starts != 0) {
1403                         dumpLine(pw, uid, category, PROCESS_DATA,
1404                                 ent.getKey(), // proc
1405                                 userTime * 10, // cpu time in ms
1406                                 systemTime * 10, // user time in ms
1407                                 starts); // process starts
1408                     }
1409                 }
1410             }
1411 
1412             Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1413             if (packageStats.size() > 0) {
1414                 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1415                         : packageStats.entrySet()) {
1416 
1417                     Uid.Pkg ps = ent.getValue();
1418                     int wakeups = ps.getWakeups(which);
1419                     Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1420                     for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1421                             : serviceStats.entrySet()) {
1422                         BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1423                         long startTime = ss.getStartTime(batteryUptime, which);
1424                         int starts = ss.getStarts(which);
1425                         int launches = ss.getLaunches(which);
1426                         if (startTime != 0 || starts != 0 || launches != 0) {
1427                             dumpLine(pw, uid, category, APK_DATA,
1428                                     wakeups, // wakeup alarms
1429                                     ent.getKey(), // Apk
1430                                     sent.getKey(), // service
1431                                     startTime / 1000, // time spent started, in ms
1432                                     starts,
1433                                     launches);
1434                         }
1435                     }
1436                 }
1437             }
1438         }
1439     }
1440 
1441     @SuppressWarnings("unused")
dumpLocked(PrintWriter pw, String prefix, int which, int reqUid)1442     public final void dumpLocked(PrintWriter pw, String prefix, int which, int reqUid) {
1443         final long rawUptime = SystemClock.uptimeMillis() * 1000;
1444         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
1445         final long batteryUptime = getBatteryUptime(rawUptime);
1446         final long batteryRealtime = getBatteryRealtime(rawRealtime);
1447 
1448         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
1449         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
1450         final long totalRealtime = computeRealtime(rawRealtime, which);
1451         final long totalUptime = computeUptime(rawUptime, which);
1452 
1453         StringBuilder sb = new StringBuilder(128);
1454 
1455         SparseArray<? extends Uid> uidStats = getUidStats();
1456         final int NU = uidStats.size();
1457 
1458         sb.setLength(0);
1459         sb.append(prefix);
1460                 sb.append("  Time on battery: ");
1461                 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
1462                 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
1463                 sb.append(") realtime, ");
1464                 formatTimeMs(sb, whichBatteryUptime / 1000);
1465                 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
1466                 sb.append(") uptime");
1467         pw.println(sb.toString());
1468         sb.setLength(0);
1469         sb.append(prefix);
1470                 sb.append("  Total run time: ");
1471                 formatTimeMs(sb, totalRealtime / 1000);
1472                 sb.append("realtime, ");
1473                 formatTimeMs(sb, totalUptime / 1000);
1474                 sb.append("uptime, ");
1475         pw.println(sb.toString());
1476 
1477         final long screenOnTime = getScreenOnTime(batteryRealtime, which);
1478         final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
1479         final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
1480         final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
1481         final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
1482         sb.setLength(0);
1483         sb.append(prefix);
1484                 sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
1485                 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
1486                 sb.append("), Input events: "); sb.append(getInputEventCount(which));
1487                 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
1488                 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
1489                 sb.append(")");
1490         pw.println(sb.toString());
1491         sb.setLength(0);
1492         sb.append(prefix);
1493         sb.append("  Screen brightnesses: ");
1494         boolean didOne = false;
1495         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1496             final long time = getScreenBrightnessTime(i, batteryRealtime, which);
1497             if (time == 0) {
1498                 continue;
1499             }
1500             if (didOne) sb.append(", ");
1501             didOne = true;
1502             sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
1503             sb.append(" ");
1504             formatTimeMs(sb, time/1000);
1505             sb.append("(");
1506             sb.append(formatRatioLocked(time, screenOnTime));
1507             sb.append(")");
1508         }
1509         if (!didOne) sb.append("No activity");
1510         pw.println(sb.toString());
1511 
1512         // Calculate total network and wakelock times across all uids.
1513         long rxTotal = 0;
1514         long txTotal = 0;
1515         long fullWakeLockTimeTotalMicros = 0;
1516         long partialWakeLockTimeTotalMicros = 0;
1517 
1518         if (reqUid < 0) {
1519             Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1520             if (kernelWakelocks.size() > 0) {
1521                 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1522 
1523                     String linePrefix = ": ";
1524                     sb.setLength(0);
1525                     sb.append(prefix);
1526                     sb.append("  Kernel Wake lock ");
1527                     sb.append(ent.getKey());
1528                     linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
1529                             linePrefix);
1530                     if (!linePrefix.equals(": ")) {
1531                         sb.append(" realtime");
1532                         // Only print out wake locks that were held
1533                         pw.println(sb.toString());
1534                     }
1535                 }
1536             }
1537         }
1538 
1539         for (int iu = 0; iu < NU; iu++) {
1540             Uid u = uidStats.valueAt(iu);
1541             rxTotal += u.getTcpBytesReceived(which);
1542             txTotal += u.getTcpBytesSent(which);
1543 
1544             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1545             if (wakelocks.size() > 0) {
1546                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1547                         : wakelocks.entrySet()) {
1548                     Uid.Wakelock wl = ent.getValue();
1549 
1550                     Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1551                     if (fullWakeTimer != null) {
1552                         fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
1553                                 batteryRealtime, which);
1554                     }
1555 
1556                     Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1557                     if (partialWakeTimer != null) {
1558                         partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked(
1559                                 batteryRealtime, which);
1560                     }
1561                 }
1562             }
1563         }
1564 
1565         pw.print(prefix);
1566                 pw.print("  Total received: "); pw.print(formatBytesLocked(rxTotal));
1567                 pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal));
1568         sb.setLength(0);
1569         sb.append(prefix);
1570                 sb.append("  Total full wakelock time: "); formatTimeMs(sb,
1571                         (fullWakeLockTimeTotalMicros + 500) / 1000);
1572                 sb.append(", Total partial waklock time: "); formatTimeMs(sb,
1573                         (partialWakeLockTimeTotalMicros + 500) / 1000);
1574         pw.println(sb.toString());
1575 
1576         sb.setLength(0);
1577         sb.append(prefix);
1578         sb.append("  Signal levels: ");
1579         didOne = false;
1580         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
1581             final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
1582             if (time == 0) {
1583                 continue;
1584             }
1585             if (didOne) sb.append(", ");
1586             didOne = true;
1587             sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
1588             sb.append(" ");
1589             formatTimeMs(sb, time/1000);
1590             sb.append("(");
1591             sb.append(formatRatioLocked(time, whichBatteryRealtime));
1592             sb.append(") ");
1593             sb.append(getPhoneSignalStrengthCount(i, which));
1594             sb.append("x");
1595         }
1596         if (!didOne) sb.append("No activity");
1597         pw.println(sb.toString());
1598 
1599         sb.setLength(0);
1600         sb.append(prefix);
1601         sb.append("  Signal scanning time: ");
1602         formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
1603         pw.println(sb.toString());
1604 
1605         sb.setLength(0);
1606         sb.append(prefix);
1607         sb.append("  Radio types: ");
1608         didOne = false;
1609         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1610             final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
1611             if (time == 0) {
1612                 continue;
1613             }
1614             if (didOne) sb.append(", ");
1615             didOne = true;
1616             sb.append(DATA_CONNECTION_NAMES[i]);
1617             sb.append(" ");
1618             formatTimeMs(sb, time/1000);
1619             sb.append("(");
1620             sb.append(formatRatioLocked(time, whichBatteryRealtime));
1621             sb.append(") ");
1622             sb.append(getPhoneDataConnectionCount(i, which));
1623             sb.append("x");
1624         }
1625         if (!didOne) sb.append("No activity");
1626         pw.println(sb.toString());
1627 
1628         sb.setLength(0);
1629         sb.append(prefix);
1630         sb.append("  Radio data uptime when unplugged: ");
1631         sb.append(getRadioDataUptime() / 1000);
1632         sb.append(" ms");
1633         pw.println(sb.toString());
1634 
1635         sb.setLength(0);
1636         sb.append(prefix);
1637                 sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
1638                 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
1639                 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
1640                 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
1641                 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
1642                 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
1643                 sb.append(")");
1644         pw.println(sb.toString());
1645 
1646         pw.println(" ");
1647 
1648         if (which == STATS_SINCE_UNPLUGGED) {
1649             if (getIsOnBattery()) {
1650                 pw.print(prefix); pw.println("  Device is currently unplugged");
1651                 pw.print(prefix); pw.print("    Discharge cycle start level: ");
1652                         pw.println(getDischargeStartLevel());
1653                 pw.print(prefix); pw.print("    Discharge cycle current level: ");
1654                         pw.println(getDischargeCurrentLevel());
1655             } else {
1656                 pw.print(prefix); pw.println("  Device is currently plugged into power");
1657                 pw.print(prefix); pw.print("    Last discharge cycle start level: ");
1658                         pw.println(getDischargeStartLevel());
1659                 pw.print(prefix); pw.print("    Last discharge cycle end level: ");
1660                         pw.println(getDischargeCurrentLevel());
1661             }
1662             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
1663                     pw.println(getDischargeAmountScreenOn());
1664             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
1665                     pw.println(getDischargeAmountScreenOff());
1666             pw.println(" ");
1667         } else {
1668             pw.print(prefix); pw.println("  Device battery use since last full charge");
1669             pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
1670                     pw.println(getLowDischargeAmountSinceCharge());
1671             pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
1672                     pw.println(getHighDischargeAmountSinceCharge());
1673             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
1674                     pw.println(getDischargeAmountScreenOnSinceCharge());
1675             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
1676                     pw.println(getDischargeAmountScreenOffSinceCharge());
1677             pw.println(" ");
1678         }
1679 
1680 
1681         for (int iu=0; iu<NU; iu++) {
1682             final int uid = uidStats.keyAt(iu);
1683             if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
1684                 continue;
1685             }
1686 
1687             Uid u = uidStats.valueAt(iu);
1688 
1689             pw.println(prefix + "  #" + uid + ":");
1690             boolean uidActivity = false;
1691 
1692             long tcpReceived = u.getTcpBytesReceived(which);
1693             long tcpSent = u.getTcpBytesSent(which);
1694             long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1695             long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
1696             long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
1697 
1698             if (tcpReceived != 0 || tcpSent != 0) {
1699                 pw.print(prefix); pw.print("    Network: ");
1700                         pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, ");
1701                         pw.print(formatBytesLocked(tcpSent)); pw.println(" sent");
1702             }
1703 
1704             if (u.hasUserActivity()) {
1705                 boolean hasData = false;
1706                 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1707                     int val = u.getUserActivityCount(i, which);
1708                     if (val != 0) {
1709                         if (!hasData) {
1710                             sb.setLength(0);
1711                             sb.append("    User activity: ");
1712                             hasData = true;
1713                         } else {
1714                             sb.append(", ");
1715                         }
1716                         sb.append(val);
1717                         sb.append(" ");
1718                         sb.append(Uid.USER_ACTIVITY_TYPES[i]);
1719                     }
1720                 }
1721                 if (hasData) {
1722                     pw.println(sb.toString());
1723                 }
1724             }
1725 
1726             if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
1727                     || uidWifiRunningTime != 0) {
1728                 sb.setLength(0);
1729                 sb.append(prefix); sb.append("    Wifi Running: ");
1730                         formatTimeMs(sb, uidWifiRunningTime / 1000);
1731                         sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
1732                                 whichBatteryRealtime)); sb.append(")\n");
1733                 sb.append(prefix); sb.append("    Full Wifi Lock: ");
1734                         formatTimeMs(sb, fullWifiLockOnTime / 1000);
1735                         sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
1736                                 whichBatteryRealtime)); sb.append(")\n");
1737                 sb.append(prefix); sb.append("    Scan Wifi Lock: ");
1738                         formatTimeMs(sb, scanWifiLockOnTime / 1000);
1739                         sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime,
1740                                 whichBatteryRealtime)); sb.append(")");
1741                 pw.println(sb.toString());
1742             }
1743 
1744             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1745             if (wakelocks.size() > 0) {
1746                 long totalFull = 0, totalPartial = 0, totalWindow = 0;
1747                 int count = 0;
1748                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1749                     : wakelocks.entrySet()) {
1750                     Uid.Wakelock wl = ent.getValue();
1751                     String linePrefix = ": ";
1752                     sb.setLength(0);
1753                     sb.append(prefix);
1754                     sb.append("    Wake lock ");
1755                     sb.append(ent.getKey());
1756                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
1757                             "full", which, linePrefix);
1758                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
1759                             "partial", which, linePrefix);
1760                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
1761                             "window", which, linePrefix);
1762                     if (!linePrefix.equals(": ")) {
1763                         sb.append(" realtime");
1764                         // Only print out wake locks that were held
1765                         pw.println(sb.toString());
1766                         uidActivity = true;
1767                         count++;
1768                     }
1769                     totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
1770                             batteryRealtime, which);
1771                     totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
1772                             batteryRealtime, which);
1773                     totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
1774                             batteryRealtime, which);
1775                 }
1776                 if (count > 1) {
1777                     if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) {
1778                         sb.setLength(0);
1779                         sb.append(prefix);
1780                         sb.append("    TOTAL wake: ");
1781                         boolean needComma = false;
1782                         if (totalFull != 0) {
1783                             needComma = true;
1784                             formatTimeMs(sb, totalFull);
1785                             sb.append("full");
1786                         }
1787                         if (totalPartial != 0) {
1788                             if (needComma) {
1789                                 sb.append(", ");
1790                             }
1791                             needComma = true;
1792                             formatTimeMs(sb, totalPartial);
1793                             sb.append("partial");
1794                         }
1795                         if (totalWindow != 0) {
1796                             if (needComma) {
1797                                 sb.append(", ");
1798                             }
1799                             needComma = true;
1800                             formatTimeMs(sb, totalWindow);
1801                             sb.append("window");
1802                         }
1803                         sb.append(" realtime");
1804                         pw.println(sb.toString());
1805                     }
1806                 }
1807             }
1808 
1809             Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1810             if (sensors.size() > 0) {
1811                 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1812                     : sensors.entrySet()) {
1813                     Uid.Sensor se = ent.getValue();
1814                     int sensorNumber = ent.getKey();
1815                     sb.setLength(0);
1816                     sb.append(prefix);
1817                     sb.append("    Sensor ");
1818                     int handle = se.getHandle();
1819                     if (handle == Uid.Sensor.GPS) {
1820                         sb.append("GPS");
1821                     } else {
1822                         sb.append(handle);
1823                     }
1824                     sb.append(": ");
1825 
1826                     Timer timer = se.getSensorTime();
1827                     if (timer != null) {
1828                         // Convert from microseconds to milliseconds with rounding
1829                         long totalTime = (timer.getTotalTimeLocked(
1830                                 batteryRealtime, which) + 500) / 1000;
1831                         int count = timer.getCountLocked(which);
1832                         //timer.logState();
1833                         if (totalTime != 0) {
1834                             formatTimeMs(sb, totalTime);
1835                             sb.append("realtime (");
1836                             sb.append(count);
1837                             sb.append(" times)");
1838                         } else {
1839                             sb.append("(not used)");
1840                         }
1841                     } else {
1842                         sb.append("(not used)");
1843                     }
1844 
1845                     pw.println(sb.toString());
1846                     uidActivity = true;
1847                 }
1848             }
1849 
1850             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1851             if (processStats.size() > 0) {
1852                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1853                     : processStats.entrySet()) {
1854                     Uid.Proc ps = ent.getValue();
1855                     long userTime;
1856                     long systemTime;
1857                     int starts;
1858                     int numExcessive;
1859 
1860                     userTime = ps.getUserTime(which);
1861                     systemTime = ps.getSystemTime(which);
1862                     starts = ps.getStarts(which);
1863                     numExcessive = which == STATS_SINCE_CHARGED
1864                             ? ps.countExcessivePowers() : 0;
1865 
1866                     if (userTime != 0 || systemTime != 0 || starts != 0
1867                             || numExcessive != 0) {
1868                         sb.setLength(0);
1869                         sb.append(prefix); sb.append("    Proc ");
1870                                 sb.append(ent.getKey()); sb.append(":\n");
1871                         sb.append(prefix); sb.append("      CPU: ");
1872                                 formatTime(sb, userTime); sb.append("usr + ");
1873                                 formatTime(sb, systemTime); sb.append("krn");
1874                         if (starts != 0) {
1875                             sb.append("\n"); sb.append(prefix); sb.append("      ");
1876                                     sb.append(starts); sb.append(" proc starts");
1877                         }
1878                         pw.println(sb.toString());
1879                         for (int e=0; e<numExcessive; e++) {
1880                             Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
1881                             if (ew != null) {
1882                                 pw.print(prefix); pw.print("      * Killed for ");
1883                                         if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
1884                                             pw.print("wake lock");
1885                                         } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
1886                                             pw.print("cpu");
1887                                         } else {
1888                                             pw.print("unknown");
1889                                         }
1890                                         pw.print(" use: ");
1891                                         TimeUtils.formatDuration(ew.usedTime, pw);
1892                                         pw.print(" over ");
1893                                         TimeUtils.formatDuration(ew.overTime, pw);
1894                                         pw.print(" (");
1895                                         pw.print((ew.usedTime*100)/ew.overTime);
1896                                         pw.println("%)");
1897                             }
1898                         }
1899                         uidActivity = true;
1900                     }
1901                 }
1902             }
1903 
1904             Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1905             if (packageStats.size() > 0) {
1906                 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1907                     : packageStats.entrySet()) {
1908                     pw.print(prefix); pw.print("    Apk "); pw.print(ent.getKey()); pw.println(":");
1909                     boolean apkActivity = false;
1910                     Uid.Pkg ps = ent.getValue();
1911                     int wakeups = ps.getWakeups(which);
1912                     if (wakeups != 0) {
1913                         pw.print(prefix); pw.print("      ");
1914                                 pw.print(wakeups); pw.println(" wakeup alarms");
1915                         apkActivity = true;
1916                     }
1917                     Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1918                     if (serviceStats.size() > 0) {
1919                         for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1920                                 : serviceStats.entrySet()) {
1921                             BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1922                             long startTime = ss.getStartTime(batteryUptime, which);
1923                             int starts = ss.getStarts(which);
1924                             int launches = ss.getLaunches(which);
1925                             if (startTime != 0 || starts != 0 || launches != 0) {
1926                                 sb.setLength(0);
1927                                 sb.append(prefix); sb.append("      Service ");
1928                                         sb.append(sent.getKey()); sb.append(":\n");
1929                                 sb.append(prefix); sb.append("        Created for: ");
1930                                         formatTimeMs(sb, startTime / 1000);
1931                                         sb.append(" uptime\n");
1932                                 sb.append(prefix); sb.append("        Starts: ");
1933                                         sb.append(starts);
1934                                         sb.append(", launches: "); sb.append(launches);
1935                                 pw.println(sb.toString());
1936                                 apkActivity = true;
1937                             }
1938                         }
1939                     }
1940                     if (!apkActivity) {
1941                         pw.print(prefix); pw.println("      (nothing executed)");
1942                     }
1943                     uidActivity = true;
1944                 }
1945             }
1946             if (!uidActivity) {
1947                 pw.print(prefix); pw.println("    (nothing executed)");
1948             }
1949         }
1950     }
1951 
printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions)1952     static void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) {
1953         int diff = oldval ^ newval;
1954         if (diff == 0) return;
1955         for (int i=0; i<descriptions.length; i++) {
1956             BitDescription bd = descriptions[i];
1957             if ((diff&bd.mask) != 0) {
1958                 if (bd.shift < 0) {
1959                     pw.print((newval&bd.mask) != 0 ? " +" : " -");
1960                     pw.print(bd.name);
1961                 } else {
1962                     pw.print(" ");
1963                     pw.print(bd.name);
1964                     pw.print("=");
1965                     int val = (newval&bd.mask)>>bd.shift;
1966                     if (bd.values != null && val >= 0 && val < bd.values.length) {
1967                         pw.print(bd.values[val]);
1968                     } else {
1969                         pw.print(val);
1970                     }
1971                 }
1972             }
1973         }
1974     }
1975 
prepareForDumpLocked()1976     public void prepareForDumpLocked() {
1977     }
1978 
1979     public static class HistoryPrinter {
1980         int oldState = 0;
1981         int oldStatus = -1;
1982         int oldHealth = -1;
1983         int oldPlug = -1;
1984         int oldTemp = -1;
1985         int oldVolt = -1;
1986 
printNextItem(PrintWriter pw, HistoryItem rec, long now)1987         public void printNextItem(PrintWriter pw, HistoryItem rec, long now) {
1988             pw.print("  ");
1989             TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
1990             pw.print(" ");
1991             if (rec.cmd == HistoryItem.CMD_START) {
1992                 pw.println(" START");
1993             } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
1994                 pw.println(" *OVERFLOW*");
1995             } else {
1996                 if (rec.batteryLevel < 10) pw.print("00");
1997                 else if (rec.batteryLevel < 100) pw.print("0");
1998                 pw.print(rec.batteryLevel);
1999                 pw.print(" ");
2000                 if (rec.states < 0x10) pw.print("0000000");
2001                 else if (rec.states < 0x100) pw.print("000000");
2002                 else if (rec.states < 0x1000) pw.print("00000");
2003                 else if (rec.states < 0x10000) pw.print("0000");
2004                 else if (rec.states < 0x100000) pw.print("000");
2005                 else if (rec.states < 0x1000000) pw.print("00");
2006                 else if (rec.states < 0x10000000) pw.print("0");
2007                 pw.print(Integer.toHexString(rec.states));
2008                 if (oldStatus != rec.batteryStatus) {
2009                     oldStatus = rec.batteryStatus;
2010                     pw.print(" status=");
2011                     switch (oldStatus) {
2012                         case BatteryManager.BATTERY_STATUS_UNKNOWN:
2013                             pw.print("unknown");
2014                             break;
2015                         case BatteryManager.BATTERY_STATUS_CHARGING:
2016                             pw.print("charging");
2017                             break;
2018                         case BatteryManager.BATTERY_STATUS_DISCHARGING:
2019                             pw.print("discharging");
2020                             break;
2021                         case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
2022                             pw.print("not-charging");
2023                             break;
2024                         case BatteryManager.BATTERY_STATUS_FULL:
2025                             pw.print("full");
2026                             break;
2027                         default:
2028                             pw.print(oldStatus);
2029                             break;
2030                     }
2031                 }
2032                 if (oldHealth != rec.batteryHealth) {
2033                     oldHealth = rec.batteryHealth;
2034                     pw.print(" health=");
2035                     switch (oldHealth) {
2036                         case BatteryManager.BATTERY_HEALTH_UNKNOWN:
2037                             pw.print("unknown");
2038                             break;
2039                         case BatteryManager.BATTERY_HEALTH_GOOD:
2040                             pw.print("good");
2041                             break;
2042                         case BatteryManager.BATTERY_HEALTH_OVERHEAT:
2043                             pw.print("overheat");
2044                             break;
2045                         case BatteryManager.BATTERY_HEALTH_DEAD:
2046                             pw.print("dead");
2047                             break;
2048                         case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
2049                             pw.print("over-voltage");
2050                             break;
2051                         case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
2052                             pw.print("failure");
2053                             break;
2054                         default:
2055                             pw.print(oldHealth);
2056                             break;
2057                     }
2058                 }
2059                 if (oldPlug != rec.batteryPlugType) {
2060                     oldPlug = rec.batteryPlugType;
2061                     pw.print(" plug=");
2062                     switch (oldPlug) {
2063                         case 0:
2064                             pw.print("none");
2065                             break;
2066                         case BatteryManager.BATTERY_PLUGGED_AC:
2067                             pw.print("ac");
2068                             break;
2069                         case BatteryManager.BATTERY_PLUGGED_USB:
2070                             pw.print("usb");
2071                             break;
2072                         default:
2073                             pw.print(oldPlug);
2074                             break;
2075                     }
2076                 }
2077                 if (oldTemp != rec.batteryTemperature) {
2078                     oldTemp = rec.batteryTemperature;
2079                     pw.print(" temp=");
2080                     pw.print(oldTemp);
2081                 }
2082                 if (oldVolt != rec.batteryVoltage) {
2083                     oldVolt = rec.batteryVoltage;
2084                     pw.print(" volt=");
2085                     pw.print(oldVolt);
2086                 }
2087                 printBitDescriptions(pw, oldState, rec.states,
2088                         HISTORY_STATE_DESCRIPTIONS);
2089                 pw.println();
2090             }
2091             oldState = rec.states;
2092         }
2093     }
2094 
2095     /**
2096      * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
2097      *
2098      * @param pw a Printer to receive the dump output.
2099      */
2100     @SuppressWarnings("unused")
dumpLocked(PrintWriter pw)2101     public void dumpLocked(PrintWriter pw) {
2102         prepareForDumpLocked();
2103 
2104         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
2105 
2106         final HistoryItem rec = new HistoryItem();
2107         if (startIteratingHistoryLocked()) {
2108             pw.println("Battery History:");
2109             HistoryPrinter hprinter = new HistoryPrinter();
2110             while (getNextHistoryLocked(rec)) {
2111                 hprinter.printNextItem(pw, rec, now);
2112             }
2113             finishIteratingHistoryLocked();
2114             pw.println("");
2115         }
2116 
2117         if (startIteratingOldHistoryLocked()) {
2118             pw.println("Old battery History:");
2119             HistoryPrinter hprinter = new HistoryPrinter();
2120             while (getNextOldHistoryLocked(rec)) {
2121                 hprinter.printNextItem(pw, rec, now);
2122             }
2123             finishIteratingOldHistoryLocked();
2124             pw.println("");
2125         }
2126 
2127         SparseArray<? extends Uid> uidStats = getUidStats();
2128         final int NU = uidStats.size();
2129         boolean didPid = false;
2130         long nowRealtime = SystemClock.elapsedRealtime();
2131         for (int i=0; i<NU; i++) {
2132             Uid uid = uidStats.valueAt(i);
2133             SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
2134             if (pids != null) {
2135                 for (int j=0; j<pids.size(); j++) {
2136                     Uid.Pid pid = pids.valueAt(j);
2137                     if (!didPid) {
2138                         pw.println("Per-PID Stats:");
2139                         didPid = true;
2140                     }
2141                     long time = pid.mWakeSum + (pid.mWakeStart != 0
2142                             ? (nowRealtime - pid.mWakeStart) : 0);
2143                     pw.print("  PID "); pw.print(pids.keyAt(j));
2144                             pw.print(" wake time: ");
2145                             TimeUtils.formatDuration(time, pw);
2146                             pw.println("");
2147                 }
2148             }
2149         }
2150         if (didPid) {
2151             pw.println("");
2152         }
2153 
2154         pw.println("Statistics since last charge:");
2155         pw.println("  System starts: " + getStartCount()
2156                 + ", currently on battery: " + getIsOnBattery());
2157         dumpLocked(pw, "", STATS_SINCE_CHARGED, -1);
2158         pw.println("");
2159         pw.println("Statistics since last unplugged:");
2160         dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, -1);
2161     }
2162 
2163     @SuppressWarnings("unused")
dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps)2164     public void dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps) {
2165         prepareForDumpLocked();
2166 
2167         boolean isUnpluggedOnly = false;
2168 
2169         for (String arg : args) {
2170             if ("-u".equals(arg)) {
2171                 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
2172                 isUnpluggedOnly = true;
2173             }
2174         }
2175 
2176         if (apps != null) {
2177             SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
2178             for (int i=0; i<apps.size(); i++) {
2179                 ApplicationInfo ai = apps.get(i);
2180                 ArrayList<String> pkgs = uids.get(ai.uid);
2181                 if (pkgs == null) {
2182                     pkgs = new ArrayList<String>();
2183                     uids.put(ai.uid, pkgs);
2184                 }
2185                 pkgs.add(ai.packageName);
2186             }
2187             SparseArray<? extends Uid> uidStats = getUidStats();
2188             final int NU = uidStats.size();
2189             String[] lineArgs = new String[2];
2190             for (int i=0; i<NU; i++) {
2191                 int uid = uidStats.keyAt(i);
2192                 ArrayList<String> pkgs = uids.get(uid);
2193                 if (pkgs != null) {
2194                     for (int j=0; j<pkgs.size(); j++) {
2195                         lineArgs[0] = Integer.toString(uid);
2196                         lineArgs[1] = pkgs.get(j);
2197                         dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
2198                                 (Object[])lineArgs);
2199                     }
2200                 }
2201             }
2202         }
2203         if (isUnpluggedOnly) {
2204             dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
2205         }
2206         else {
2207             dumpCheckinLocked(pw, STATS_SINCE_CHARGED, -1);
2208             dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
2209         }
2210     }
2211 }
2212