blob: 438c5366b2b5735c5c0be2f77d18527aa51b607e [file] [log] [blame]
Kenny Root15a4d2f2010-03-11 18:20:12 -08001/*
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080017package android.os;
18
19import java.io.PrintWriter;
Dianne Hackborne4a59512010-12-07 11:08:07 -080020import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import java.util.Formatter;
Dianne Hackborne4a59512010-12-07 11:08:07 -080022import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import java.util.Map;
24
Dianne Hackborne4a59512010-12-07 11:08:07 -080025import android.content.pm.ApplicationInfo;
Wink Saville52840902011-02-18 12:40:47 -080026import android.telephony.SignalStrength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.util.Log;
28import android.util.Printer;
Dianne Hackborn1fadab52011-04-14 17:57:33 -070029import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070031import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032
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 */
39public 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.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 */
61 public static final int SENSOR = 3;
The Android Open Source Project10592532009-03-18 17:39:46 -070062
63 /**
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070064 * A constant indicating a a wifi running timer
Dianne Hackborn617f8772009-03-31 15:04:46 -070065 */
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070066 public static final int WIFI_RUNNING = 4;
Dianne Hackborn617f8772009-03-31 15:04:46 -070067
68 /**
The Android Open Source Project10592532009-03-18 17:39:46 -070069 * A constant indicating a full wifi lock timer
The Android Open Source Project10592532009-03-18 17:39:46 -070070 */
Dianne Hackborn617f8772009-03-31 15:04:46 -070071 public static final int FULL_WIFI_LOCK = 5;
The Android Open Source Project10592532009-03-18 17:39:46 -070072
73 /**
74 * A constant indicating a scan wifi lock timer
The Android Open Source Project10592532009-03-18 17:39:46 -070075 */
Dianne Hackborn617f8772009-03-31 15:04:46 -070076 public static final int SCAN_WIFI_LOCK = 6;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077
Robert Greenwalt5347bd42009-05-13 15:10:16 -070078 /**
79 * A constant indicating a wifi multicast timer
Robert Greenwalt5347bd42009-05-13 15:10:16 -070080 */
81 public static final int WIFI_MULTICAST_ENABLED = 7;
82
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -070084 * A constant indicating an audio turn on timer
Amith Yamasani244fa5c2009-05-22 14:36:07 -070085 */
86 public static final int AUDIO_TURNED_ON = 7;
87
88 /**
89 * A constant indicating a video turn on timer
Amith Yamasani244fa5c2009-05-22 14:36:07 -070090 */
91 public static final int VIDEO_TURNED_ON = 8;
92
93 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 * Include all of the data in the stats, including previously saved data.
95 */
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070096 public static final int STATS_SINCE_CHARGED = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097
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 */
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700111 public static final int STATS_SINCE_UNPLUGGED = 3;
Evan Millare84de8d2009-04-02 22:16:12 -0700112
113 // NOTE: Update this list if you add/change any stats above.
114 // These characters are supposed to represent "total", "last", "current",
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700115 // and "unplugged". They were shortened for efficiency sake.
Evan Millare84de8d2009-04-02 22:16:12 -0700116 private static final String[] STAT_NAMES = { "t", "l", "c", "u" };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117
118 /**
119 * Bump the version on this if the checkin format changes.
120 */
Evan Millarc64edde2009-04-18 12:26:32 -0700121 private static final int BATTERY_STATS_CHECKIN_VERSION = 5;
Evan Millar22ac0432009-03-31 11:33:18 -0700122
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127
Dianne Hackborne4a59512010-12-07 11:08:07 -0800128 private static final String UID_DATA = "uid";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 private static final String APK_DATA = "apk";
Evan Millare84de8d2009-04-02 22:16:12 -0700130 private static final String PROCESS_DATA = "pr";
131 private static final String SENSOR_DATA = "sr";
132 private static final String WAKELOCK_DATA = "wl";
Evan Millarc64edde2009-04-18 12:26:32 -0700133 private static final String KERNEL_WAKELOCK_DATA = "kwl";
Evan Millare84de8d2009-04-02 22:16:12 -0700134 private static final String NETWORK_DATA = "nt";
135 private static final String USER_ACTIVITY_DATA = "ua";
136 private static final String BATTERY_DATA = "bt";
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800137 private static final String BATTERY_DISCHARGE_DATA = "dc";
Evan Millare84de8d2009-04-02 22:16:12 -0700138 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";
Amith Yamasanif37447b2009-10-08 18:28:01 -0700143 private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
Evan Millare84de8d2009-04-02 22:16:12 -0700144 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";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700148 private final StringBuilder mFormatBuilder = new StringBuilder(32);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 private final Formatter mFormatter = new Formatter(mFormatBuilder);
150
151 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700152 * 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 */
Evan Millarc64edde2009-04-18 12:26:32 -0700162 public abstract int getCountLocked(int which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700163
164 /**
165 * Temporary for debugging.
166 */
167 public abstract void logState(Printer pw, String prefix);
168 }
169
170 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 * 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 */
Evan Millarc64edde2009-04-18 12:26:32 -0700181 public abstract int getCountLocked(int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182
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 */
Evan Millarc64edde2009-04-18 12:26:32 -0700191 public abstract long getTotalTimeLocked(long batteryRealtime, int which);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 /**
194 * Temporary for debugging.
195 */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700196 public abstract void logState(Printer pw, String prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 }
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 */
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 {
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 */
223 public abstract Map<Integer, ? extends Sensor> getSensorStats();
224
225 /**
Dianne Hackbornb5e31652010-09-07 12:13:55 -0700226 * Returns a mapping containing active process data.
227 */
228 public abstract SparseArray<? extends Pid> getPidStats();
229
230 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 * Returns a mapping containing process statistics.
232 *
233 * @return a Map from Strings to Uid.Proc objects.
234 */
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 */
242 public abstract Map<String, ? extends Pkg> getPackageStats();
243
244 /**
245 * {@hide}
246 */
247 public abstract int getUid();
248
249 /**
250 * {@hide}
251 */
252 public abstract long getTcpBytesReceived(int which);
253
254 /**
255 * {@hide}
256 */
257 public abstract long getTcpBytesSent(int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700258
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700259 public abstract void noteWifiRunningLocked();
260 public abstract void noteWifiStoppedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700261 public abstract void noteFullWifiLockAcquiredLocked();
262 public abstract void noteFullWifiLockReleasedLocked();
263 public abstract void noteScanWifiLockAcquiredLocked();
264 public abstract void noteScanWifiLockReleasedLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700265 public abstract void noteWifiMulticastEnabledLocked();
266 public abstract void noteWifiMulticastDisabledLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700267 public abstract void noteAudioTurnedOnLocked();
268 public abstract void noteAudioTurnedOffLocked();
269 public abstract void noteVideoTurnedOnLocked();
270 public abstract void noteVideoTurnedOffLocked();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700271 public abstract long getWifiRunningTime(long batteryRealtime, int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700272 public abstract long getFullWifiLockTime(long batteryRealtime, int which);
273 public abstract long getScanWifiLockTime(long batteryRealtime, int which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700274 public abstract long getWifiMulticastTime(long batteryRealtime,
275 int which);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700276 public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
277 public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278
Dianne Hackborn617f8772009-03-31 15:04:46 -0700279 /**
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
288 public abstract void noteUserActivityLocked(int type);
289 public abstract boolean hasUserActivity();
290 public abstract int getUserActivityCount(int type, int which);
291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 public static abstract class Sensor {
293 // Magic sensor number for the GPS.
294 public static final int GPS = -10000;
295
296 public abstract int getHandle();
297
298 public abstract Timer getSensorTime();
299 }
300
Dianne Hackbornb5e31652010-09-07 12:13:55 -0700301 public class Pid {
302 public long mWakeSum;
303 public long mWakeStart;
304 }
305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 /**
307 * The statistics associated with a particular process.
308 */
309 public static abstract class Proc {
310
Dianne Hackborn287952c2010-09-22 22:34:31 -0700311 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;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700316 public long overTime;
317 public long usedTime;
318 }
319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 /**
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 */
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 */
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 */
339 public abstract int getStarts(int which);
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700340
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 */
346 public abstract long getForegroundTime(int which);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700347
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 */
355 public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700356
Dianne Hackborn287952c2010-09-22 22:34:31 -0700357 public abstract int countExcessivePowers();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700358
Dianne Hackborn287952c2010-09-22 22:34:31 -0700359 public abstract ExcessivePower getExcessivePower(int i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 }
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 */
373 public abstract int getWakeups(int which);
374
375 /**
376 * Returns a mapping containing service statistics.
377 */
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 */
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 */
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 */
406 public abstract int getLaunches(int which);
407 }
408 }
409 }
410
Dianne Hackbornce2ef762010-09-20 11:39:14 -0700411 public final static class HistoryItem implements Parcelable {
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700412 static final String TAG = "HistoryItem";
413 static final boolean DEBUG = false;
414
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700415 public HistoryItem next;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700416
417 public long time;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700418
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700419 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;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700423
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700424 public byte cmd = CMD_NULL;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700425
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
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700434 // Constants from SCREEN_BRIGHTNESS_*
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700435 public static final int STATE_BRIGHTNESS_MASK = 0x0000000f;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700436 public static final int STATE_BRIGHTNESS_SHIFT = 0;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700437 // Constants from SIGNAL_STRENGTH_*
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700438 public static final int STATE_SIGNAL_STRENGTH_MASK = 0x000000f0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700439 public static final int STATE_SIGNAL_STRENGTH_SHIFT = 4;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700440 // Constants from ServiceState.STATE_*
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700441 public static final int STATE_PHONE_STATE_MASK = 0x00000f00;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700442 public static final int STATE_PHONE_STATE_SHIFT = 8;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700443 // Constants from DATA_CONNECTION_*
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700444 public static final int STATE_DATA_CONNECTION_MASK = 0x0000f000;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700445 public static final int STATE_DATA_CONNECTION_SHIFT = 12;
446
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700447 // 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;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700452 public static final int STATE_GPS_ON_FLAG = 1<<28;
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700453 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;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700467
Dianne Hackbornf47d8f22010-10-08 10:46:55 -0700468 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
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700472 public int states;
473
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700474 public HistoryItem() {
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700475 }
476
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700477 public HistoryItem(long time, Parcel src) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700478 this.time = time;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700479 readFromParcel(src);
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700480 }
481
482 public int describeContents() {
483 return 0;
484 }
485
486 public void writeToParcel(Parcel dest, int flags) {
487 dest.writeLong(time);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700488 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);
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700497 dest.writeInt(states);
498 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700499
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
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700513 // 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
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
591 private int buildBatteryLevelInt() {
592 return ((((int)batteryLevel)<<24)&0xff000000)
593 | ((((int)batteryTemperature)<<14)&0x00ffc000)
594 | (((int)batteryVoltage)&0x00003fff);
595 }
596
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
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 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700654 }
655
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700656 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
Dianne Hackbornce2ef762010-09-20 11:39:14 -0700668 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
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700680 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 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700691
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 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700701 }
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
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
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 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700722 }
723
Dianne Hackbornce2ef762010-09-20 11:39:14 -0700724 public abstract boolean startIteratingHistoryLocked();
725
726 public abstract boolean getNextHistoryLocked(HistoryItem out);
727
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700728 public abstract void finishIteratingHistoryLocked();
729
730 public abstract boolean startIteratingOldHistoryLocked();
731
732 public abstract boolean getNextOldHistoryLocked(HistoryItem out);
733
734 public abstract void finishIteratingOldHistoryLocked();
735
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736 /**
Dianne Hackbornb5e31652010-09-07 12:13:55 -0700737 * Return the base time offset for the battery history.
738 */
739 public abstract long getHistoryBaseTime();
740
741 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800742 * Returns the number of times the device has been started.
743 */
744 public abstract int getStartCount();
745
746 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700747 * Returns the time in microseconds that the screen has been on while the device was
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 * running on battery.
749 *
750 * {@hide}
751 */
752 public abstract long getScreenOnTime(long batteryRealtime, int which);
753
Dianne Hackborn617f8772009-03-31 15:04:46 -0700754 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 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700767 * Returns the time in microseconds that the screen has been on with
Dianne Hackborn617f8772009-03-31 15:04:46 -0700768 * the given brightness
769 *
770 * {@hide}
771 */
772 public abstract long getScreenBrightnessTime(int brightnessBin,
773 long batteryRealtime, int which);
774
775 public abstract int getInputEventCount(int which);
776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800777 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700778 * Returns the time in microseconds that the phone has been on while the device was
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 * running on battery.
780 *
781 * {@hide}
782 */
783 public abstract long getPhoneOnTime(long batteryRealtime, int which);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700784
785 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700786 * Returns the time in microseconds that the phone has been running with
Dianne Hackborn627bba72009-03-24 22:32:56 -0700787 * the given signal strength.
788 *
789 * {@hide}
790 */
791 public abstract long getPhoneSignalStrengthTime(int strengthBin,
792 long batteryRealtime, int which);
793
Dianne Hackborn617f8772009-03-31 15:04:46 -0700794 /**
Amith Yamasanif37447b2009-10-08 18:28:01 -0700795 * Returns the time in microseconds that the phone has been trying to
796 * acquire a signal.
797 *
798 * {@hide}
799 */
800 public abstract long getPhoneSignalScanningTime(
801 long batteryRealtime, int which);
802
803 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700804 * Returns the number of times the phone has entered the given signal strength.
805 *
806 * {@hide}
807 */
808 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
809
Dianne Hackborn627bba72009-03-24 22:32:56 -0700810 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;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700814 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;
Robert Greenwalt962a9902010-11-02 11:10:25 -0700823 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
Dianne Hackborn627bba72009-03-24 22:32:56 -0700827 static final String[] DATA_CONNECTION_NAMES = {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700828 "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
Robert Greenwalt962a9902010-11-02 11:10:25 -0700829 "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
830 "ehrpd", "other"
Dianne Hackborn627bba72009-03-24 22:32:56 -0700831 };
832
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700833 public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
Dianne Hackborn627bba72009-03-24 22:32:56 -0700834
835 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700836 * Returns the time in microseconds that the phone has been running with
Dianne Hackborn627bba72009-03-24 22:32:56 -0700837 * the given data connection.
838 *
839 * {@hide}
840 */
841 public abstract long getPhoneDataConnectionTime(int dataType,
842 long batteryRealtime, int which);
843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700845 * Returns the number of times the phone has entered the given data
846 * connection type.
847 *
848 * {@hide}
849 */
850 public abstract int getPhoneDataConnectionCount(int dataType, int which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700851
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"),
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700857 new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call"),
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700858 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"),
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700867 new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock"),
868 new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor"),
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700869 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",
Wink Saville52840902011-02-18 12:40:47 -0800874 SignalStrength.SIGNAL_STRENGTH_NAMES),
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700875 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 };
Dianne Hackborn617f8772009-03-31 15:04:46 -0700882
883 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700884 * Returns the time in microseconds that wifi has been on while the device was
The Android Open Source Project10592532009-03-18 17:39:46 -0700885 * running on battery.
886 *
887 * {@hide}
888 */
889 public abstract long getWifiOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700890
891 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700892 * Returns the time in microseconds that wifi has been on and the driver has
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700893 * been in the running state while the device was running on battery.
894 *
895 * {@hide}
896 */
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700897 public abstract long getGlobalWifiRunningTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700898
The Android Open Source Project10592532009-03-18 17:39:46 -0700899 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700900 * Returns the time in microseconds that bluetooth has been on while the device was
The Android Open Source Project10592532009-03-18 17:39:46 -0700901 * running on battery.
902 *
903 * {@hide}
904 */
905 public abstract long getBluetoothOnTime(long batteryRealtime, int which);
906
907 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 * Return whether we are currently running on battery.
909 */
910 public abstract boolean getIsOnBattery();
911
912 /**
913 * Returns a SparseArray containing the statistics for each uid.
914 */
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 */
922 public abstract long getBatteryUptime(long curTime);
923
924 /**
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700925 * @deprecated use getRadioDataUptime
926 */
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 */
935 public abstract long getRadioDataUptime();
936
937 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 * Returns the current battery realtime in microseconds.
939 *
940 * @param curTime the amount of elapsed realtime in microseconds.
941 */
942 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700943
944 /**
Evan Millar633a1742009-04-02 16:36:33 -0700945 * 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.
The Android Open Source Project10592532009-03-18 17:39:46 -0700947 */
Evan Millar633a1742009-04-02 16:36:33 -0700948 public abstract int getDischargeStartLevel();
The Android Open Source Project10592532009-03-18 17:39:46 -0700949
950 /**
Evan Millar633a1742009-04-02 16:36:33 -0700951 * Returns the current battery percentage level if we are in a discharge cycle, otherwise
952 * returns the level at the last plug event.
The Android Open Source Project10592532009-03-18 17:39:46 -0700953 */
Evan Millar633a1742009-04-02 16:36:33 -0700954 public abstract int getDischargeCurrentLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955
956 /**
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700957 * Get the amount the battery has discharged since the stats were
958 * last reset after charging, as a lower-end approximation.
959 */
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 */
966 public abstract int getHighDischargeAmountSinceCharge();
967
968 /**
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800969 * Get the amount the battery has discharged while the screen was on,
970 * since the last time power was unplugged.
971 */
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 */
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 */
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 */
990 public abstract int getDischargeAmountScreenOffSinceCharge();
991
992 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 * 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 */
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 */
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 */
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 */
1022 public abstract long computeRealtime(long curTime, int which);
Evan Millarc64edde2009-04-18 12:26:32 -07001023
1024 public abstract Map<String, ? extends Timer> getKernelWakelockStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025
Amith Yamasanie43530a2009-08-21 13:11:37 -07001026 /** Returns the number of different speeds that the CPU can run at */
1027 public abstract int getCpuSpeedSteps();
1028
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001029 private final static void formatTimeRaw(StringBuilder out, long seconds) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 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
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001057 private final static void formatTime(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 long sec = time / 100;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001059 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 sb.append((time - (sec * 100)) * 10);
1061 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 }
1063
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001064 private final static void formatTimeMs(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 long sec = time / 1000;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001066 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 sb.append(time - (sec * 1000));
1068 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 }
1070
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
Evan Millar22ac0432009-03-31 11:33:18 -07001081 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
Dianne Hackbornc24ab862011-10-18 15:55:03 -07001098 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 /**
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 */
1118 private static final String printWakeLock(StringBuilder sb, Timer timer,
1119 long batteryRealtime, String name, int which, String linePrefix) {
1120
1121 if (timer != null) {
Dianne Hackbornc24ab862011-10-18 15:55:03 -07001122 long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123
Evan Millarc64edde2009-04-18 12:26:32 -07001124 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 if (totalTimeMillis != 0) {
1126 sb.append(linePrefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001127 formatTimeMs(sb, totalTimeMillis);
1128 if (name != null) sb.append(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001129 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 */
1150 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
Evan Millarc64edde2009-04-18 12:26:32 -07001151 String name, int which, String linePrefix) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 long totalTimeMicros = 0;
1153 int count = 0;
1154 if (timer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001155 totalTimeMicros = timer.getTotalTimeLocked(now, which);
1156 count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 }
1158 sb.append(linePrefix);
1159 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
1160 sb.append(',');
Evan Millarc64edde2009-04-18 12:26:32 -07001161 sb.append(name != null ? name + "," : "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 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 */
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'.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001192 */
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001193 public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 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);
The Android Open Source Project10592532009-03-18 17:39:46 -07001204 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001205 final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001206 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001207
1208 StringBuilder sb = new StringBuilder(128);
1209
Evan Millar22ac0432009-03-31 11:33:18 -07001210 SparseArray<? extends Uid> uidStats = getUidStats();
1211 final int NU = uidStats.size();
1212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 String category = STAT_NAMES[which];
1214
1215 // Dump "battery" stat
1216 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001217 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
Dianne Hackborn617f8772009-03-31 15:04:46 -07001218 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
1219 totalRealtime / 1000, totalUptime / 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220
Evan Millar22ac0432009-03-31 11:33:18 -07001221 // 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) {
Evan Millarc64edde2009-04-18 12:26:32 -07001240 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
Evan Millar22ac0432009-03-31 11:33:18 -07001241 }
1242
1243 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1244 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001245 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001246 batteryRealtime, which);
1247 }
1248 }
1249 }
1250 }
1251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 // Dump misc stats
1253 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001254 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
Evan Millar22ac0432009-03-31 11:33:18 -07001255 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal,
Dianne Hackborn617f8772009-03-31 15:04:46 -07001256 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);
The Android Open Source Project10592532009-03-18 17:39:46 -07001265
Dianne Hackborn627bba72009-03-24 22:32:56 -07001266 // Dump signal strength stats
Wink Saville52840902011-02-18 12:40:47 -08001267 args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
1268 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001269 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
1270 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001271 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
Amith Yamasanif37447b2009-10-08 18:28:01 -07001272 dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
1273 getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
Wink Saville52840902011-02-18 12:40:47 -08001274 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07001275 args[i] = getPhoneSignalStrengthCount(i, which);
1276 }
1277 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001278
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 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001284 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);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001289
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001290 if (which == STATS_SINCE_UNPLUGGED) {
Evan Millare84de8d2009-04-02 22:16:12 -07001291 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
Evan Millar633a1742009-04-02 16:36:33 -07001292 getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001295 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
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001306 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 }
Evan Millarc64edde2009-04-18 12:26:32 -07001316 }
1317 }
1318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 for (int iu = 0; iu < NU; iu++) {
1320 final int uid = uidStats.keyAt(iu);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001321 if (reqUid >= 0 && uid != reqUid) {
1322 continue;
1323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 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);
The Android Open Source Project10592532009-03-18 17:39:46 -07001328 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1329 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001330 long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -07001333
Dianne Hackborn617f8772009-03-31 15:04:46 -07001334 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001335 || uidWifiRunningTime != 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001336 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001337 fullWifiLockOnTime, scanWifiLockOnTime, uidWifiRunningTime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001338 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001339
Dianne Hackborn617f8772009-03-31 15:04:46 -07001340 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 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);
Evan Millarc64edde2009-04-18 12:26:32 -07001360 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);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366
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
Evan Millarc64edde2009-04-18 12:26:32 -07001383 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
1384 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 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")
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001442 public final void dumpLocked(PrintWriter pw, String prefix, int which, int reqUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 final long rawUptime = SystemClock.uptimeMillis() * 1000;
1444 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
1445 final long batteryUptime = getBatteryUptime(rawUptime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001446 final long batteryRealtime = getBatteryRealtime(rawRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447
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);
Evan Millar22ac0432009-03-31 11:33:18 -07001454
1455 SparseArray<? extends Uid> uidStats = getUidStats();
1456 final int NU = uidStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001457
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001458 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());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476
The Android Open Source Project10592532009-03-18 17:39:46 -07001477 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
1478 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001479 final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001480 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
1481 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001482 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001483 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);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001493 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(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001504 formatTimeMs(sb, time/1000);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001505 sb.append("(");
1506 sb.append(formatRatioLocked(time, screenOnTime));
1507 sb.append(")");
1508 }
1509 if (!didOne) sb.append("No activity");
1510 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001511
Evan Millar22ac0432009-03-31 11:33:18 -07001512 // 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
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001518 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");
Jason Parks94b916d2010-07-20 12:39:07 -05001532 // Only print out wake locks that were held
1533 pw.println(sb.toString());
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001534 }
Evan Millarc64edde2009-04-18 12:26:32 -07001535 }
Evan Millarc64edde2009-04-18 12:26:32 -07001536 }
1537 }
1538
Evan Millar22ac0432009-03-31 11:33:18 -07001539 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) {
Evan Millarc64edde2009-04-18 12:26:32 -07001552 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001553 batteryRealtime, which);
1554 }
1555
1556 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1557 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001558 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001559 batteryRealtime, which);
1560 }
1561 }
1562 }
1563 }
1564
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001565 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());
Evan Millar22ac0432009-03-31 11:33:18 -07001575
Dianne Hackborn627bba72009-03-24 22:32:56 -07001576 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001577 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001578 sb.append(" Signal levels: ");
1579 didOne = false;
Wink Saville52840902011-02-18 12:40:47 -08001580 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001581 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
1582 if (time == 0) {
1583 continue;
1584 }
1585 if (didOne) sb.append(", ");
1586 didOne = true;
Wink Saville52840902011-02-18 12:40:47 -08001587 sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001588 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001589 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001590 sb.append("(");
1591 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001592 sb.append(") ");
1593 sb.append(getPhoneSignalStrengthCount(i, which));
1594 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001595 }
1596 if (!didOne) sb.append("No activity");
1597 pw.println(sb.toString());
Amith Yamasanif37447b2009-10-08 18:28:01 -07001598
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
Dianne Hackborn627bba72009-03-24 22:32:56 -07001605 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001606 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001607 sb.append(" Radio types: ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001608 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(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001618 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001619 sb.append("(");
1620 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001621 sb.append(") ");
1622 sb.append(getPhoneDataConnectionCount(i, which));
1623 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001624 }
1625 if (!didOne) sb.append("No activity");
1626 pw.println(sb.toString());
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001627
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
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001635 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());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001645
The Android Open Source Project10592532009-03-18 17:39:46 -07001646 pw.println(" ");
1647
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001648 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001649 if (getIsOnBattery()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001650 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());
Dianne Hackborn99d04522010-08-20 13:43:00 -07001655 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001656 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());
The Android Open Source Project10592532009-03-18 17:39:46 -07001661 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001662 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());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001666 pw.println(" ");
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001667 } 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());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001673 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());
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001677 pw.println(" ");
The Android Open Source Project10592532009-03-18 17:39:46 -07001678 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679
Evan Millar22ac0432009-03-31 11:33:18 -07001680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001681 for (int iu=0; iu<NU; iu++) {
1682 final int uid = uidStats.keyAt(iu);
Dianne Hackborne4a59512010-12-07 11:08:07 -08001683 if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001684 continue;
1685 }
1686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 Uid u = uidStats.valueAt(iu);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001689 pw.println(prefix + " #" + uid + ":");
1690 boolean uidActivity = false;
1691
1692 long tcpReceived = u.getTcpBytesReceived(which);
1693 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001694 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1695 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001696 long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001697
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001698 if (tcpReceived != 0 || tcpSent != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001699 pw.print(prefix); pw.print(" Network: ");
1700 pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, ");
1701 pw.print(formatBytesLocked(tcpSent)); pw.println(" sent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001703
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
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001727 || uidWifiRunningTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001728 sb.setLength(0);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001729 sb.append(prefix); sb.append(" Wifi Running: ");
1730 formatTimeMs(sb, uidWifiRunningTime / 1000);
1731 sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001732 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());
The Android Open Source Project10592532009-03-18 17:39:46 -07001742 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001743
1744 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1745 if (wakelocks.size() > 0) {
Dianne Hackbornc24ab862011-10-18 15:55:03 -07001746 long totalFull = 0, totalPartial = 0, totalWindow = 0;
1747 int count = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001748 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");
Jason Parks94b916d2010-07-20 12:39:07 -05001764 // Only print out wake locks that were held
1765 pw.println(sb.toString());
1766 uidActivity = true;
Dianne Hackbornc24ab862011-10-18 15:55:03 -07001767 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());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001805 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001806 }
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
Evan Millarc64edde2009-04-18 12:26:32 -07001829 long totalTime = (timer.getTotalTimeLocked(
1830 batteryRealtime, which) + 500) / 1000;
1831 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832 //timer.logState();
1833 if (totalTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001834 formatTimeMs(sb, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001835 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;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001858 int numExcessive;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001859
1860 userTime = ps.getUserTime(which);
1861 systemTime = ps.getSystemTime(which);
1862 starts = ps.getStarts(which);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001863 numExcessive = which == STATS_SINCE_CHARGED
Dianne Hackborn287952c2010-09-22 22:34:31 -07001864 ? ps.countExcessivePowers() : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001866 if (userTime != 0 || systemTime != 0 || starts != 0
1867 || numExcessive != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001868 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 + ");
Dianne Hackbornb8071d792010-09-09 16:45:15 -07001873 formatTime(sb, systemTime); sb.append("krn");
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001874 if (starts != 0) {
Dianne Hackbornb8071d792010-09-09 16:45:15 -07001875 sb.append("\n"); sb.append(prefix); sb.append(" ");
1876 sb.append(starts); sb.append(" proc starts");
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001877 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001878 pw.println(sb.toString());
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001879 for (int e=0; e<numExcessive; e++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001880 Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001881 if (ew != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001882 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: ");
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001891 TimeUtils.formatDuration(ew.usedTime, pw);
1892 pw.print(" over ");
1893 TimeUtils.formatDuration(ew.overTime, pw);
1894 pw.print(" (");
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001895 pw.print((ew.usedTime*100)/ew.overTime);
1896 pw.println("%)");
1897 }
1898 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001899 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()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001908 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 boolean apkActivity = false;
1910 Uid.Pkg ps = ent.getValue();
1911 int wakeups = ps.getWakeups(which);
1912 if (wakeups != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001913 pw.print(prefix); pw.print(" ");
1914 pw.print(wakeups); pw.println(" wakeup alarms");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001915 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) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001926 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());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001936 apkActivity = true;
1937 }
1938 }
1939 }
1940 if (!apkActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001941 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001942 }
1943 uidActivity = true;
1944 }
1945 }
1946 if (!uidActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001947 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 }
1949 }
1950 }
1951
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001952 static void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001953 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
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001976 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
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002095 /**
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")
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002101 public void dumpLocked(PrintWriter pw) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002102 prepareForDumpLocked();
2103
2104 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
2105
Dianne Hackbornce2ef762010-09-20 11:39:14 -07002106 final HistoryItem rec = new HistoryItem();
2107 if (startIteratingHistoryLocked()) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002108 pw.println("Battery History:");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002109 HistoryPrinter hprinter = new HistoryPrinter();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07002110 while (getNextHistoryLocked(rec)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002111 hprinter.printNextItem(pw, rec, now);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002112 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002113 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();
Dianne Hackbornb5e31652010-09-07 12:13:55 -07002124 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();
Dianne Hackbornb5e31652010-09-07 12:13:55 -07002131 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("");
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002152 }
2153
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002154 pw.println("Statistics since last charge:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155 pw.println(" System starts: " + getStartCount()
2156 + ", currently on battery: " + getIsOnBattery());
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002157 dumpLocked(pw, "", STATS_SINCE_CHARGED, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002158 pw.println("");
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002159 pw.println("Statistics since last unplugged:");
2160 dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 }
2162
2163 @SuppressWarnings("unused")
Dianne Hackborne4a59512010-12-07 11:08:07 -08002164 public void dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002165 prepareForDumpLocked();
2166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 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
Dianne Hackborne4a59512010-12-07 11:08:07 -08002176 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 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002203 if (isUnpluggedOnly) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002204 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002205 }
2206 else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002207 dumpCheckinLocked(pw, STATS_SINCE_CHARGED, -1);
2208 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209 }
2210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211}