blob: 528def5c401182c4e5c934dd6f0390af18d924f7 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001package android.os;
2
3import java.io.PrintWriter;
4import java.util.Formatter;
5import java.util.Map;
6
7import android.util.Log;
8import android.util.Printer;
9import android.util.SparseArray;
10
11/**
12 * A class providing access to battery usage statistics, including information on
13 * wakelocks, processes, packages, and services. All times are represented in microseconds
14 * except where indicated otherwise.
15 * @hide
16 */
17public abstract class BatteryStats implements Parcelable {
18
19 private static final boolean LOCAL_LOGV = false;
20
21 /**
22 * A constant indicating a partial wake lock timer.
23 */
24 public static final int WAKE_TYPE_PARTIAL = 0;
25
26 /**
27 * A constant indicating a full wake lock timer.
28 */
29 public static final int WAKE_TYPE_FULL = 1;
30
31 /**
32 * A constant indicating a window wake lock timer.
33 */
34 public static final int WAKE_TYPE_WINDOW = 2;
35
36 /**
37 * A constant indicating a sensor timer.
38 *
39 * {@hide}
40 */
41 public static final int SENSOR = 3;
The Android Open Source Project10592532009-03-18 17:39:46 -070042
43 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -070044 * A constant indicating a a wifi turn on timer
45 *
46 * {@hide}
47 */
48 public static final int WIFI_TURNED_ON = 4;
49
50 /**
The Android Open Source Project10592532009-03-18 17:39:46 -070051 * A constant indicating a full wifi lock timer
52 *
53 * {@hide}
54 */
Dianne Hackborn617f8772009-03-31 15:04:46 -070055 public static final int FULL_WIFI_LOCK = 5;
The Android Open Source Project10592532009-03-18 17:39:46 -070056
57 /**
58 * A constant indicating a scan wifi lock timer
59 *
60 * {@hide}
61 */
Dianne Hackborn617f8772009-03-31 15:04:46 -070062 public static final int SCAN_WIFI_LOCK = 6;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063
Robert Greenwalt5347bd42009-05-13 15:10:16 -070064 /**
65 * A constant indicating a wifi multicast timer
66 *
67 * {@hide}
68 */
69 public static final int WIFI_MULTICAST_ENABLED = 7;
70
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -070072 * A constant indicating an audio turn on timer
73 *
74 * {@hide}
75 */
76 public static final int AUDIO_TURNED_ON = 7;
77
78 /**
79 * A constant indicating a video turn on timer
80 *
81 * {@hide}
82 */
83 public static final int VIDEO_TURNED_ON = 8;
84
85 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 * Include all of the data in the stats, including previously saved data.
87 */
88 public static final int STATS_TOTAL = 0;
89
90 /**
91 * Include only the last run in the stats.
92 */
93 public static final int STATS_LAST = 1;
94
95 /**
96 * Include only the current run in the stats.
97 */
98 public static final int STATS_CURRENT = 2;
99
100 /**
101 * Include only the run since the last time the device was unplugged in the stats.
102 */
103 public static final int STATS_UNPLUGGED = 3;
Evan Millare84de8d2009-04-02 22:16:12 -0700104
105 // NOTE: Update this list if you add/change any stats above.
106 // These characters are supposed to represent "total", "last", "current",
107 // and "unplugged". They were shortened for effeciency sake.
108 private static final String[] STAT_NAMES = { "t", "l", "c", "u" };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109
110 /**
111 * Bump the version on this if the checkin format changes.
112 */
Evan Millarc64edde2009-04-18 12:26:32 -0700113 private static final int BATTERY_STATS_CHECKIN_VERSION = 5;
Evan Millar22ac0432009-03-31 11:33:18 -0700114
115 private static final long BYTES_PER_KB = 1024;
116 private static final long BYTES_PER_MB = 1048576; // 1024^2
117 private static final long BYTES_PER_GB = 1073741824; //1024^3
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119
120 private static final String APK_DATA = "apk";
Evan Millare84de8d2009-04-02 22:16:12 -0700121 private static final String PROCESS_DATA = "pr";
122 private static final String SENSOR_DATA = "sr";
123 private static final String WAKELOCK_DATA = "wl";
Evan Millarc64edde2009-04-18 12:26:32 -0700124 private static final String KERNEL_WAKELOCK_DATA = "kwl";
Evan Millare84de8d2009-04-02 22:16:12 -0700125 private static final String NETWORK_DATA = "nt";
126 private static final String USER_ACTIVITY_DATA = "ua";
127 private static final String BATTERY_DATA = "bt";
128 private static final String BATTERY_LEVEL_DATA = "lv";
129 private static final String WIFI_LOCK_DATA = "wfl";
130 private static final String MISC_DATA = "m";
131 private static final String SCREEN_BRIGHTNESS_DATA = "br";
132 private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
133 private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
134 private static final String DATA_CONNECTION_TIME_DATA = "dct";
135 private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700137 private final StringBuilder mFormatBuilder = new StringBuilder(32);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 private final Formatter mFormatter = new Formatter(mFormatBuilder);
139
140 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700141 * State for keeping track of counting information.
142 */
143 public static abstract class Counter {
144
145 /**
146 * Returns the count associated with this Counter for the
147 * selected type of statistics.
148 *
149 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
150 */
Evan Millarc64edde2009-04-18 12:26:32 -0700151 public abstract int getCountLocked(int which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700152
153 /**
154 * Temporary for debugging.
155 */
156 public abstract void logState(Printer pw, String prefix);
157 }
158
159 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 * State for keeping track of timing information.
161 */
162 public static abstract class Timer {
163
164 /**
165 * Returns the count associated with this Timer for the
166 * selected type of statistics.
167 *
168 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
169 */
Evan Millarc64edde2009-04-18 12:26:32 -0700170 public abstract int getCountLocked(int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171
172 /**
173 * Returns the total time in microseconds associated with this Timer for the
174 * selected type of statistics.
175 *
176 * @param batteryRealtime system realtime on battery in microseconds
177 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
178 * @return a time in microseconds
179 */
Evan Millarc64edde2009-04-18 12:26:32 -0700180 public abstract long getTotalTimeLocked(long batteryRealtime, int which);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 /**
183 * Temporary for debugging.
184 */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700185 public abstract void logState(Printer pw, String prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 }
187
188 /**
189 * The statistics associated with a particular uid.
190 */
191 public static abstract class Uid {
192
193 /**
194 * Returns a mapping containing wakelock statistics.
195 *
196 * @return a Map from Strings to Uid.Wakelock objects.
197 */
198 public abstract Map<String, ? extends Wakelock> getWakelockStats();
199
200 /**
201 * The statistics associated with a particular wake lock.
202 */
203 public static abstract class Wakelock {
204 public abstract Timer getWakeTime(int type);
205 }
206
207 /**
208 * Returns a mapping containing sensor statistics.
209 *
210 * @return a Map from Integer sensor ids to Uid.Sensor objects.
211 */
212 public abstract Map<Integer, ? extends Sensor> getSensorStats();
213
214 /**
215 * Returns a mapping containing process statistics.
216 *
217 * @return a Map from Strings to Uid.Proc objects.
218 */
219 public abstract Map<String, ? extends Proc> getProcessStats();
220
221 /**
222 * Returns a mapping containing package statistics.
223 *
224 * @return a Map from Strings to Uid.Pkg objects.
225 */
226 public abstract Map<String, ? extends Pkg> getPackageStats();
227
228 /**
229 * {@hide}
230 */
231 public abstract int getUid();
232
233 /**
234 * {@hide}
235 */
236 public abstract long getTcpBytesReceived(int which);
237
238 /**
239 * {@hide}
240 */
241 public abstract long getTcpBytesSent(int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700242
Dianne Hackborn617f8772009-03-31 15:04:46 -0700243 public abstract void noteWifiTurnedOnLocked();
244 public abstract void noteWifiTurnedOffLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700245 public abstract void noteFullWifiLockAcquiredLocked();
246 public abstract void noteFullWifiLockReleasedLocked();
247 public abstract void noteScanWifiLockAcquiredLocked();
248 public abstract void noteScanWifiLockReleasedLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700249 public abstract void noteWifiMulticastEnabledLocked();
250 public abstract void noteWifiMulticastDisabledLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700251 public abstract void noteAudioTurnedOnLocked();
252 public abstract void noteAudioTurnedOffLocked();
253 public abstract void noteVideoTurnedOnLocked();
254 public abstract void noteVideoTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700255 public abstract long getWifiTurnedOnTime(long batteryRealtime, int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700256 public abstract long getFullWifiLockTime(long batteryRealtime, int which);
257 public abstract long getScanWifiLockTime(long batteryRealtime, int which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700258 public abstract long getWifiMulticastTime(long batteryRealtime,
259 int which);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700260 public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
261 public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262
Dianne Hackborn617f8772009-03-31 15:04:46 -0700263 /**
264 * Note that these must match the constants in android.os.LocalPowerManager.
265 */
266 static final String[] USER_ACTIVITY_TYPES = {
267 "other", "cheek", "touch", "long_touch", "touch_up", "button", "unknown"
268 };
269
270 public static final int NUM_USER_ACTIVITY_TYPES = 7;
271
272 public abstract void noteUserActivityLocked(int type);
273 public abstract boolean hasUserActivity();
274 public abstract int getUserActivityCount(int type, int which);
275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 public static abstract class Sensor {
277 // Magic sensor number for the GPS.
278 public static final int GPS = -10000;
279
280 public abstract int getHandle();
281
282 public abstract Timer getSensorTime();
283 }
284
285 /**
286 * The statistics associated with a particular process.
287 */
288 public static abstract class Proc {
289
290 /**
291 * Returns the total time (in 1/100 sec) spent executing in user code.
292 *
293 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
294 */
295 public abstract long getUserTime(int which);
296
297 /**
298 * Returns the total time (in 1/100 sec) spent executing in system code.
299 *
300 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
301 */
302 public abstract long getSystemTime(int which);
303
304 /**
305 * Returns the number of times the process has been started.
306 *
307 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
308 */
309 public abstract int getStarts(int which);
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700310
311 /**
312 * Returns the cpu time spent in microseconds while the process was in the foreground.
313 * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
314 * @return foreground cpu time in microseconds
315 */
316 public abstract long getForegroundTime(int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 }
318
319 /**
320 * The statistics associated with a particular package.
321 */
322 public static abstract class Pkg {
323
324 /**
325 * Returns the number of times this package has done something that could wake up the
326 * device from sleep.
327 *
328 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
329 */
330 public abstract int getWakeups(int which);
331
332 /**
333 * Returns a mapping containing service statistics.
334 */
335 public abstract Map<String, ? extends Serv> getServiceStats();
336
337 /**
338 * The statistics associated with a particular service.
339 */
340 public abstract class Serv {
341
342 /**
343 * Returns the amount of time spent started.
344 *
345 * @param batteryUptime elapsed uptime on battery in microseconds.
346 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
347 * @return
348 */
349 public abstract long getStartTime(long batteryUptime, int which);
350
351 /**
352 * Returns the total number of times startService() has been called.
353 *
354 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
355 */
356 public abstract int getStarts(int which);
357
358 /**
359 * Returns the total number times the service has been launched.
360 *
361 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
362 */
363 public abstract int getLaunches(int which);
364 }
365 }
366 }
367
368 /**
369 * Returns the number of times the device has been started.
370 */
371 public abstract int getStartCount();
372
373 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700374 * 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 -0800375 * running on battery.
376 *
377 * {@hide}
378 */
379 public abstract long getScreenOnTime(long batteryRealtime, int which);
380
Dianne Hackborn617f8772009-03-31 15:04:46 -0700381 public static final int SCREEN_BRIGHTNESS_DARK = 0;
382 public static final int SCREEN_BRIGHTNESS_DIM = 1;
383 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
384 public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
385 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
386
387 static final String[] SCREEN_BRIGHTNESS_NAMES = {
388 "dark", "dim", "medium", "light", "bright"
389 };
390
391 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
392
393 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700394 * Returns the time in microseconds that the screen has been on with
Dianne Hackborn617f8772009-03-31 15:04:46 -0700395 * the given brightness
396 *
397 * {@hide}
398 */
399 public abstract long getScreenBrightnessTime(int brightnessBin,
400 long batteryRealtime, int which);
401
402 public abstract int getInputEventCount(int which);
403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700405 * 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 -0800406 * running on battery.
407 *
408 * {@hide}
409 */
410 public abstract long getPhoneOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700411
Dianne Hackborn627bba72009-03-24 22:32:56 -0700412 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
413 public static final int SIGNAL_STRENGTH_POOR = 1;
414 public static final int SIGNAL_STRENGTH_MODERATE = 2;
415 public static final int SIGNAL_STRENGTH_GOOD = 3;
416 public static final int SIGNAL_STRENGTH_GREAT = 4;
417
418 static final String[] SIGNAL_STRENGTH_NAMES = {
419 "none", "poor", "moderate", "good", "great"
420 };
421
422 public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
423
424 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700425 * Returns the time in microseconds that the phone has been running with
Dianne Hackborn627bba72009-03-24 22:32:56 -0700426 * the given signal strength.
427 *
428 * {@hide}
429 */
430 public abstract long getPhoneSignalStrengthTime(int strengthBin,
431 long batteryRealtime, int which);
432
Dianne Hackborn617f8772009-03-31 15:04:46 -0700433 /**
434 * Returns the number of times the phone has entered the given signal strength.
435 *
436 * {@hide}
437 */
438 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
439
Dianne Hackborn627bba72009-03-24 22:32:56 -0700440 public static final int DATA_CONNECTION_NONE = 0;
441 public static final int DATA_CONNECTION_GPRS = 1;
442 public static final int DATA_CONNECTION_EDGE = 2;
443 public static final int DATA_CONNECTION_UMTS = 3;
444 public static final int DATA_CONNECTION_OTHER = 4;
445
446 static final String[] DATA_CONNECTION_NAMES = {
447 "none", "gprs", "edge", "umts", "other"
448 };
449
450 public static final int NUM_DATA_CONNECTION_TYPES = 5;
451
452 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700453 * Returns the time in microseconds that the phone has been running with
Dianne Hackborn627bba72009-03-24 22:32:56 -0700454 * the given data connection.
455 *
456 * {@hide}
457 */
458 public abstract long getPhoneDataConnectionTime(int dataType,
459 long batteryRealtime, int which);
460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700462 * Returns the number of times the phone has entered the given data
463 * connection type.
464 *
465 * {@hide}
466 */
467 public abstract int getPhoneDataConnectionCount(int dataType, int which);
468
469 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700470 * Returns the time in microseconds that wifi has been on while the device was
The Android Open Source Project10592532009-03-18 17:39:46 -0700471 * running on battery.
472 *
473 * {@hide}
474 */
475 public abstract long getWifiOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700476
477 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700478 * Returns the time in microseconds that wifi has been on and the driver has
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700479 * been in the running state while the device was running on battery.
480 *
481 * {@hide}
482 */
483 public abstract long getWifiRunningTime(long batteryRealtime, int which);
484
The Android Open Source Project10592532009-03-18 17:39:46 -0700485 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700486 * Returns the time in microseconds that bluetooth has been on while the device was
The Android Open Source Project10592532009-03-18 17:39:46 -0700487 * running on battery.
488 *
489 * {@hide}
490 */
491 public abstract long getBluetoothOnTime(long batteryRealtime, int which);
492
493 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 * Return whether we are currently running on battery.
495 */
496 public abstract boolean getIsOnBattery();
497
498 /**
499 * Returns a SparseArray containing the statistics for each uid.
500 */
501 public abstract SparseArray<? extends Uid> getUidStats();
502
503 /**
504 * Returns the current battery uptime in microseconds.
505 *
506 * @param curTime the amount of elapsed realtime in microseconds.
507 */
508 public abstract long getBatteryUptime(long curTime);
509
510 /**
511 * Returns the current battery realtime in microseconds.
512 *
513 * @param curTime the amount of elapsed realtime in microseconds.
514 */
515 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700516
517 /**
Evan Millar633a1742009-04-02 16:36:33 -0700518 * Returns the battery percentage level at the last time the device was unplugged from power, or
519 * the last time it booted on battery power.
The Android Open Source Project10592532009-03-18 17:39:46 -0700520 */
Evan Millar633a1742009-04-02 16:36:33 -0700521 public abstract int getDischargeStartLevel();
The Android Open Source Project10592532009-03-18 17:39:46 -0700522
523 /**
Evan Millar633a1742009-04-02 16:36:33 -0700524 * Returns the current battery percentage level if we are in a discharge cycle, otherwise
525 * returns the level at the last plug event.
The Android Open Source Project10592532009-03-18 17:39:46 -0700526 */
Evan Millar633a1742009-04-02 16:36:33 -0700527 public abstract int getDischargeCurrentLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528
529 /**
530 * Returns the total, last, or current battery uptime in microseconds.
531 *
532 * @param curTime the elapsed realtime in microseconds.
533 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
534 */
535 public abstract long computeBatteryUptime(long curTime, int which);
536
537 /**
538 * Returns the total, last, or current battery realtime in microseconds.
539 *
540 * @param curTime the current elapsed realtime in microseconds.
541 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
542 */
543 public abstract long computeBatteryRealtime(long curTime, int which);
544
545 /**
546 * Returns the total, last, or current uptime in microseconds.
547 *
548 * @param curTime the current elapsed realtime in microseconds.
549 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
550 */
551 public abstract long computeUptime(long curTime, int which);
552
553 /**
554 * Returns the total, last, or current realtime in microseconds.
555 * *
556 * @param curTime the current elapsed realtime in microseconds.
557 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
558 */
559 public abstract long computeRealtime(long curTime, int which);
Evan Millarc64edde2009-04-18 12:26:32 -0700560
561 public abstract Map<String, ? extends Timer> getKernelWakelockStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700563 private final static void formatTimeRaw(StringBuilder out, long seconds) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 long days = seconds / (60 * 60 * 24);
565 if (days != 0) {
566 out.append(days);
567 out.append("d ");
568 }
569 long used = days * 60 * 60 * 24;
570
571 long hours = (seconds - used) / (60 * 60);
572 if (hours != 0 || used != 0) {
573 out.append(hours);
574 out.append("h ");
575 }
576 used += hours * 60 * 60;
577
578 long mins = (seconds-used) / 60;
579 if (mins != 0 || used != 0) {
580 out.append(mins);
581 out.append("m ");
582 }
583 used += mins * 60;
584
585 if (seconds != 0 || used != 0) {
586 out.append(seconds-used);
587 out.append("s ");
588 }
589 }
590
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700591 private final static void formatTime(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 long sec = time / 100;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700593 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 sb.append((time - (sec * 100)) * 10);
595 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 }
597
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700598 private final static void formatTimeMs(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 long sec = time / 1000;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700600 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 sb.append(time - (sec * 1000));
602 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 }
604
605 private final String formatRatioLocked(long num, long den) {
606 if (den == 0L) {
607 return "---%";
608 }
609 float perc = ((float)num) / ((float)den) * 100;
610 mFormatBuilder.setLength(0);
611 mFormatter.format("%.1f%%", perc);
612 return mFormatBuilder.toString();
613 }
614
Evan Millar22ac0432009-03-31 11:33:18 -0700615 private final String formatBytesLocked(long bytes) {
616 mFormatBuilder.setLength(0);
617
618 if (bytes < BYTES_PER_KB) {
619 return bytes + "B";
620 } else if (bytes < BYTES_PER_MB) {
621 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
622 return mFormatBuilder.toString();
623 } else if (bytes < BYTES_PER_GB){
624 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
625 return mFormatBuilder.toString();
626 } else {
627 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
628 return mFormatBuilder.toString();
629 }
630 }
631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800632 /**
633 *
634 * @param sb a StringBuilder object.
635 * @param timer a Timer object contining the wakelock times.
636 * @param batteryRealtime the current on-battery time in microseconds.
637 * @param name the name of the wakelock.
638 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
639 * @param linePrefix a String to be prepended to each line of output.
640 * @return the line prefix
641 */
642 private static final String printWakeLock(StringBuilder sb, Timer timer,
643 long batteryRealtime, String name, int which, String linePrefix) {
644
645 if (timer != null) {
646 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -0700647 long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
649
Evan Millarc64edde2009-04-18 12:26:32 -0700650 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 if (totalTimeMillis != 0) {
652 sb.append(linePrefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700653 formatTimeMs(sb, totalTimeMillis);
654 if (name != null) sb.append(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655 sb.append(' ');
656 sb.append('(');
657 sb.append(count);
658 sb.append(" times)");
659 return ", ";
660 }
661 }
662 return linePrefix;
663 }
664
665 /**
666 * Checkin version of wakelock printer. Prints simple comma-separated list.
667 *
668 * @param sb a StringBuilder object.
669 * @param timer a Timer object contining the wakelock times.
670 * @param now the current time in microseconds.
671 * @param name the name of the wakelock.
672 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
673 * @param linePrefix a String to be prepended to each line of output.
674 * @return the line prefix
675 */
676 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
Evan Millarc64edde2009-04-18 12:26:32 -0700677 String name, int which, String linePrefix) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 long totalTimeMicros = 0;
679 int count = 0;
680 if (timer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700681 totalTimeMicros = timer.getTotalTimeLocked(now, which);
682 count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800683 }
684 sb.append(linePrefix);
685 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
686 sb.append(',');
Evan Millarc64edde2009-04-18 12:26:32 -0700687 sb.append(name != null ? name + "," : "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800688 sb.append(count);
689 return ",";
690 }
691
692 /**
693 * Dump a comma-separated line of values for terse checkin mode.
694 *
695 * @param pw the PageWriter to dump log to
696 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
697 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
698 * @param args type-dependent data arguments
699 */
700 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
701 Object... args ) {
702 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
703 pw.print(uid); pw.print(',');
704 pw.print(category); pw.print(',');
705 pw.print(type);
706
707 for (Object arg : args) {
708 pw.print(',');
709 pw.print(arg);
710 }
711 pw.print('\n');
712 }
713
714 /**
715 * Checkin server version of dump to produce more compact, computer-readable log.
716 *
717 * NOTE: all times are expressed in 'ms'.
718 * @param fd
719 * @param pw
720 * @param which
721 */
722 private final void dumpCheckinLocked(PrintWriter pw, int which) {
723 final long rawUptime = SystemClock.uptimeMillis() * 1000;
724 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
725 final long batteryUptime = getBatteryUptime(rawUptime);
726 final long batteryRealtime = getBatteryRealtime(rawRealtime);
727 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
728 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
729 final long totalRealtime = computeRealtime(rawRealtime, which);
730 final long totalUptime = computeUptime(rawUptime, which);
731 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
732 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700733 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700734 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700735 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736
737 StringBuilder sb = new StringBuilder(128);
738
Evan Millar22ac0432009-03-31 11:33:18 -0700739 SparseArray<? extends Uid> uidStats = getUidStats();
740 final int NU = uidStats.size();
741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800742 String category = STAT_NAMES[which];
743
744 // Dump "battery" stat
745 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
746 which == STATS_TOTAL ? getStartCount() : "N/A",
Dianne Hackborn617f8772009-03-31 15:04:46 -0700747 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
748 totalRealtime / 1000, totalUptime / 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749
Evan Millar22ac0432009-03-31 11:33:18 -0700750 // Calculate total network and wakelock times across all uids.
751 long rxTotal = 0;
752 long txTotal = 0;
753 long fullWakeLockTimeTotal = 0;
754 long partialWakeLockTimeTotal = 0;
755
756 for (int iu = 0; iu < NU; iu++) {
757 Uid u = uidStats.valueAt(iu);
758 rxTotal += u.getTcpBytesReceived(which);
759 txTotal += u.getTcpBytesSent(which);
760
761 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
762 if (wakelocks.size() > 0) {
763 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
764 : wakelocks.entrySet()) {
765 Uid.Wakelock wl = ent.getValue();
766
767 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
768 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700769 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
Evan Millar22ac0432009-03-31 11:33:18 -0700770 }
771
772 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
773 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700774 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -0700775 batteryRealtime, which);
776 }
777 }
778 }
779 }
780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 // Dump misc stats
782 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700783 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
Evan Millar22ac0432009-03-31 11:33:18 -0700784 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal,
Dianne Hackborn617f8772009-03-31 15:04:46 -0700785 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
786 getInputEventCount(which));
787
788 // Dump screen brightness stats
789 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
790 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
791 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
792 }
793 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
The Android Open Source Project10592532009-03-18 17:39:46 -0700794
Dianne Hackborn627bba72009-03-24 22:32:56 -0700795 // Dump signal strength stats
Dianne Hackborn617f8772009-03-31 15:04:46 -0700796 args = new Object[NUM_SIGNAL_STRENGTH_BINS];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700797 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
798 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
799 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700800 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
801 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
802 args[i] = getPhoneSignalStrengthCount(i, which);
803 }
804 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700805
806 // Dump network type stats
807 args = new Object[NUM_DATA_CONNECTION_TYPES];
808 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
809 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
810 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700811 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
812 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
813 args[i] = getPhoneDataConnectionCount(i, which);
814 }
815 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700816
The Android Open Source Project10592532009-03-18 17:39:46 -0700817 if (which == STATS_UNPLUGGED) {
Evan Millare84de8d2009-04-02 22:16:12 -0700818 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
Evan Millar633a1742009-04-02 16:36:33 -0700819 getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -0700820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821
Evan Millarc64edde2009-04-18 12:26:32 -0700822 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
823 if (kernelWakelocks.size() > 0) {
824 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
825 sb.setLength(0);
826 printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
827
828 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
829 sb.toString());
830 }
831 }
832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 for (int iu = 0; iu < NU; iu++) {
834 final int uid = uidStats.keyAt(iu);
835 Uid u = uidStats.valueAt(iu);
836 // Dump Network stats per uid, if any
837 long rx = u.getTcpBytesReceived(which);
838 long tx = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700839 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
840 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700841 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -0700844
Dianne Hackborn617f8772009-03-31 15:04:46 -0700845 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
846 || wifiTurnedOnTime != 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700847 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
Dianne Hackborn617f8772009-03-31 15:04:46 -0700848 fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850
Dianne Hackborn617f8772009-03-31 15:04:46 -0700851 if (u.hasUserActivity()) {
852 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
853 boolean hasData = false;
854 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
855 int val = u.getUserActivityCount(i, which);
856 args[i] = val;
857 if (val != 0) hasData = true;
858 }
859 if (hasData) {
860 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args);
861 }
862 }
863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
865 if (wakelocks.size() > 0) {
866 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
867 : wakelocks.entrySet()) {
868 Uid.Wakelock wl = ent.getValue();
869 String linePrefix = "";
870 sb.setLength(0);
Evan Millarc64edde2009-04-18 12:26:32 -0700871 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
872 batteryRealtime, "f", which, linePrefix);
873 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
874 batteryRealtime, "p", which, linePrefix);
875 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
876 batteryRealtime, "w", which, linePrefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877
878 // Only log if we had at lease one wakelock...
879 if (sb.length() > 0) {
880 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
881 }
882 }
883 }
884
885 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
886 if (sensors.size() > 0) {
887 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
888 : sensors.entrySet()) {
889 Uid.Sensor se = ent.getValue();
890 int sensorNumber = ent.getKey();
891 Timer timer = se.getSensorTime();
892 if (timer != null) {
893 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -0700894 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
895 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 if (totalTime != 0) {
897 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
898 }
899 }
900 }
901 }
902
903 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
904 if (processStats.size() > 0) {
905 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
906 : processStats.entrySet()) {
907 Uid.Proc ps = ent.getValue();
908
909 long userTime = ps.getUserTime(which);
910 long systemTime = ps.getSystemTime(which);
911 int starts = ps.getStarts(which);
912
913 if (userTime != 0 || systemTime != 0 || starts != 0) {
914 dumpLine(pw, uid, category, PROCESS_DATA,
915 ent.getKey(), // proc
916 userTime * 10, // cpu time in ms
917 systemTime * 10, // user time in ms
918 starts); // process starts
919 }
920 }
921 }
922
923 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
924 if (packageStats.size() > 0) {
925 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
926 : packageStats.entrySet()) {
927
928 Uid.Pkg ps = ent.getValue();
929 int wakeups = ps.getWakeups(which);
930 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
931 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
932 : serviceStats.entrySet()) {
933 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
934 long startTime = ss.getStartTime(batteryUptime, which);
935 int starts = ss.getStarts(which);
936 int launches = ss.getLaunches(which);
937 if (startTime != 0 || starts != 0 || launches != 0) {
938 dumpLine(pw, uid, category, APK_DATA,
939 wakeups, // wakeup alarms
940 ent.getKey(), // Apk
941 sent.getKey(), // service
942 startTime / 1000, // time spent started, in ms
943 starts,
944 launches);
945 }
946 }
947 }
948 }
949 }
950 }
951
952 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700953 private final void dumpLocked(PrintWriter pw, String prefix, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 final long rawUptime = SystemClock.uptimeMillis() * 1000;
955 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
956 final long batteryUptime = getBatteryUptime(rawUptime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700957 final long batteryRealtime = getBatteryRealtime(rawRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958
959 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
960 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
961 final long totalRealtime = computeRealtime(rawRealtime, which);
962 final long totalUptime = computeUptime(rawUptime, which);
963
964 StringBuilder sb = new StringBuilder(128);
Evan Millar22ac0432009-03-31 11:33:18 -0700965
966 SparseArray<? extends Uid> uidStats = getUidStats();
967 final int NU = uidStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700969 sb.setLength(0);
970 sb.append(prefix);
971 sb.append(" Time on battery: ");
972 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
973 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
974 sb.append(") realtime, ");
975 formatTimeMs(sb, whichBatteryUptime / 1000);
976 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
977 sb.append(") uptime");
978 pw.println(sb.toString());
979 sb.setLength(0);
980 sb.append(prefix);
981 sb.append(" Total run time: ");
982 formatTimeMs(sb, totalRealtime / 1000);
983 sb.append("realtime, ");
984 formatTimeMs(sb, totalUptime / 1000);
985 sb.append("uptime, ");
986 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987
The Android Open Source Project10592532009-03-18 17:39:46 -0700988 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
989 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700990 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700991 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
992 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700993 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700994 sb.append(prefix);
995 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
996 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
997 sb.append("), Input events: "); sb.append(getInputEventCount(which));
998 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
999 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
1000 sb.append(")");
1001 pw.println(sb.toString());
1002 sb.setLength(0);
1003 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001004 sb.append(" Screen brightnesses: ");
1005 boolean didOne = false;
1006 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1007 final long time = getScreenBrightnessTime(i, batteryRealtime, which);
1008 if (time == 0) {
1009 continue;
1010 }
1011 if (didOne) sb.append(", ");
1012 didOne = true;
1013 sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
1014 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001015 formatTimeMs(sb, time/1000);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001016 sb.append("(");
1017 sb.append(formatRatioLocked(time, screenOnTime));
1018 sb.append(")");
1019 }
1020 if (!didOne) sb.append("No activity");
1021 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001022
Evan Millar22ac0432009-03-31 11:33:18 -07001023 // Calculate total network and wakelock times across all uids.
1024 long rxTotal = 0;
1025 long txTotal = 0;
1026 long fullWakeLockTimeTotalMicros = 0;
1027 long partialWakeLockTimeTotalMicros = 0;
1028
Evan Millarc64edde2009-04-18 12:26:32 -07001029 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1030 if (kernelWakelocks.size() > 0) {
1031 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1032
1033 String linePrefix = ": ";
1034 sb.setLength(0);
1035 sb.append(prefix);
1036 sb.append(" Kernel Wake lock ");
1037 sb.append(ent.getKey());
1038 linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
1039 linePrefix);
1040 if (!linePrefix.equals(": ")) {
1041 sb.append(" realtime");
1042 } else {
1043 sb.append(": (nothing executed)");
1044 }
1045 pw.println(sb.toString());
1046 }
1047 }
1048
Evan Millar22ac0432009-03-31 11:33:18 -07001049 for (int iu = 0; iu < NU; iu++) {
1050 Uid u = uidStats.valueAt(iu);
1051 rxTotal += u.getTcpBytesReceived(which);
1052 txTotal += u.getTcpBytesSent(which);
1053
1054 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1055 if (wakelocks.size() > 0) {
1056 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1057 : wakelocks.entrySet()) {
1058 Uid.Wakelock wl = ent.getValue();
1059
1060 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1061 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001062 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001063 batteryRealtime, which);
1064 }
1065
1066 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1067 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001068 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001069 batteryRealtime, which);
1070 }
1071 }
1072 }
1073 }
1074
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001075 pw.print(prefix);
1076 pw.print(" Total received: "); pw.print(formatBytesLocked(rxTotal));
1077 pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal));
1078 sb.setLength(0);
1079 sb.append(prefix);
1080 sb.append(" Total full wakelock time: "); formatTimeMs(sb,
1081 (fullWakeLockTimeTotalMicros + 500) / 1000);
1082 sb.append(", Total partial waklock time: "); formatTimeMs(sb,
1083 (partialWakeLockTimeTotalMicros + 500) / 1000);
1084 pw.println(sb.toString());
Evan Millar22ac0432009-03-31 11:33:18 -07001085
Dianne Hackborn627bba72009-03-24 22:32:56 -07001086 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001087 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001088 sb.append(" Signal levels: ");
1089 didOne = false;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001090 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
1091 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
1092 if (time == 0) {
1093 continue;
1094 }
1095 if (didOne) sb.append(", ");
1096 didOne = true;
1097 sb.append(SIGNAL_STRENGTH_NAMES[i]);
1098 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001099 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001100 sb.append("(");
1101 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001102 sb.append(") ");
1103 sb.append(getPhoneSignalStrengthCount(i, which));
1104 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001105 }
1106 if (!didOne) sb.append("No activity");
1107 pw.println(sb.toString());
1108
1109 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001110 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001111 sb.append(" Radio types: ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001112 didOne = false;
1113 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1114 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
1115 if (time == 0) {
1116 continue;
1117 }
1118 if (didOne) sb.append(", ");
1119 didOne = true;
1120 sb.append(DATA_CONNECTION_NAMES[i]);
1121 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001122 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001123 sb.append("(");
1124 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001125 sb.append(") ");
1126 sb.append(getPhoneDataConnectionCount(i, which));
1127 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001128 }
1129 if (!didOne) sb.append("No activity");
1130 pw.println(sb.toString());
1131
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001132 sb.setLength(0);
1133 sb.append(prefix);
1134 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
1135 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
1136 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
1137 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
1138 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
1139 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
1140 sb.append(")");
1141 pw.println(sb.toString());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001142
The Android Open Source Project10592532009-03-18 17:39:46 -07001143 pw.println(" ");
1144
1145 if (which == STATS_UNPLUGGED) {
1146 if (getIsOnBattery()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001147 pw.print(prefix); pw.println(" Device is currently unplugged");
1148 pw.print(prefix); pw.print(" Discharge cycle start level: ");
1149 pw.println(getDischargeStartLevel());
1150 pw.print(prefix); pw.print(" Discharge cycle current level: ");
1151 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001152 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001153 pw.print(prefix); pw.println(" Device is currently plugged into power");
1154 pw.print(prefix); pw.print(" Last discharge cycle start level: ");
1155 pw.println(getDischargeStartLevel());
1156 pw.print(prefix); pw.print(" Last discharge cycle end level: ");
1157 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001158 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001159 pw.println(" ");
The Android Open Source Project10592532009-03-18 17:39:46 -07001160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001161
Evan Millar22ac0432009-03-31 11:33:18 -07001162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001163 for (int iu=0; iu<NU; iu++) {
1164 final int uid = uidStats.keyAt(iu);
1165 Uid u = uidStats.valueAt(iu);
1166 pw.println(prefix + " #" + uid + ":");
1167 boolean uidActivity = false;
1168
1169 long tcpReceived = u.getTcpBytesReceived(which);
1170 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001171 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1172 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001173 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 if (tcpReceived != 0 || tcpSent != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001176 pw.print(prefix); pw.print(" Network: ");
1177 pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, ");
1178 pw.print(formatBytesLocked(tcpSent)); pw.println(" sent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001179 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001180
1181 if (u.hasUserActivity()) {
1182 boolean hasData = false;
1183 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1184 int val = u.getUserActivityCount(i, which);
1185 if (val != 0) {
1186 if (!hasData) {
1187 sb.setLength(0);
1188 sb.append(" User activity: ");
1189 hasData = true;
1190 } else {
1191 sb.append(", ");
1192 }
1193 sb.append(val);
1194 sb.append(" ");
1195 sb.append(Uid.USER_ACTIVITY_TYPES[i]);
1196 }
1197 }
1198 if (hasData) {
1199 pw.println(sb.toString());
1200 }
1201 }
1202
1203 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
1204 || wifiTurnedOnTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001205 sb.setLength(0);
1206 sb.append(prefix); sb.append(" Turned Wifi On: ");
1207 formatTimeMs(sb, wifiTurnedOnTime / 1000);
1208 sb.append("("); sb.append(formatRatioLocked(wifiTurnedOnTime,
1209 whichBatteryRealtime)); sb.append(")\n");
1210 sb.append(prefix); sb.append(" Full Wifi Lock: ");
1211 formatTimeMs(sb, fullWifiLockOnTime / 1000);
1212 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
1213 whichBatteryRealtime)); sb.append(")\n");
1214 sb.append(prefix); sb.append(" Scan Wifi Lock: ");
1215 formatTimeMs(sb, scanWifiLockOnTime / 1000);
1216 sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime,
1217 whichBatteryRealtime)); sb.append(")");
1218 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220
1221 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1222 if (wakelocks.size() > 0) {
1223 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1224 : wakelocks.entrySet()) {
1225 Uid.Wakelock wl = ent.getValue();
1226 String linePrefix = ": ";
1227 sb.setLength(0);
1228 sb.append(prefix);
1229 sb.append(" Wake lock ");
1230 sb.append(ent.getKey());
1231 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
1232 "full", which, linePrefix);
1233 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
1234 "partial", which, linePrefix);
1235 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
1236 "window", which, linePrefix);
1237 if (!linePrefix.equals(": ")) {
1238 sb.append(" realtime");
1239 } else {
1240 sb.append(": (nothing executed)");
1241 }
1242 pw.println(sb.toString());
1243 uidActivity = true;
1244 }
1245 }
1246
1247 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1248 if (sensors.size() > 0) {
1249 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1250 : sensors.entrySet()) {
1251 Uid.Sensor se = ent.getValue();
1252 int sensorNumber = ent.getKey();
1253 sb.setLength(0);
1254 sb.append(prefix);
1255 sb.append(" Sensor ");
1256 int handle = se.getHandle();
1257 if (handle == Uid.Sensor.GPS) {
1258 sb.append("GPS");
1259 } else {
1260 sb.append(handle);
1261 }
1262 sb.append(": ");
1263
1264 Timer timer = se.getSensorTime();
1265 if (timer != null) {
1266 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -07001267 long totalTime = (timer.getTotalTimeLocked(
1268 batteryRealtime, which) + 500) / 1000;
1269 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 //timer.logState();
1271 if (totalTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001272 formatTimeMs(sb, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001273 sb.append("realtime (");
1274 sb.append(count);
1275 sb.append(" times)");
1276 } else {
1277 sb.append("(not used)");
1278 }
1279 } else {
1280 sb.append("(not used)");
1281 }
1282
1283 pw.println(sb.toString());
1284 uidActivity = true;
1285 }
1286 }
1287
1288 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1289 if (processStats.size() > 0) {
1290 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1291 : processStats.entrySet()) {
1292 Uid.Proc ps = ent.getValue();
1293 long userTime;
1294 long systemTime;
1295 int starts;
1296
1297 userTime = ps.getUserTime(which);
1298 systemTime = ps.getSystemTime(which);
1299 starts = ps.getStarts(which);
1300
1301 if (userTime != 0 || systemTime != 0 || starts != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001302 sb.setLength(0);
1303 sb.append(prefix); sb.append(" Proc ");
1304 sb.append(ent.getKey()); sb.append(":\n");
1305 sb.append(prefix); sb.append(" CPU: ");
1306 formatTime(sb, userTime); sb.append("usr + ");
1307 formatTime(sb, systemTime); sb.append("krn\n");
1308 sb.append(prefix); sb.append(" "); sb.append(starts);
1309 sb.append(" proc starts");
1310 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 uidActivity = true;
1312 }
1313 }
1314 }
1315
1316 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1317 if (packageStats.size() > 0) {
1318 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1319 : packageStats.entrySet()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001320 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 boolean apkActivity = false;
1322 Uid.Pkg ps = ent.getValue();
1323 int wakeups = ps.getWakeups(which);
1324 if (wakeups != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001325 pw.print(prefix); pw.print(" ");
1326 pw.print(wakeups); pw.println(" wakeup alarms");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327 apkActivity = true;
1328 }
1329 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1330 if (serviceStats.size() > 0) {
1331 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1332 : serviceStats.entrySet()) {
1333 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1334 long startTime = ss.getStartTime(batteryUptime, which);
1335 int starts = ss.getStarts(which);
1336 int launches = ss.getLaunches(which);
1337 if (startTime != 0 || starts != 0 || launches != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001338 sb.setLength(0);
1339 sb.append(prefix); sb.append(" Service ");
1340 sb.append(sent.getKey()); sb.append(":\n");
1341 sb.append(prefix); sb.append(" Created for: ");
1342 formatTimeMs(sb, startTime / 1000);
1343 sb.append(" uptime\n");
1344 sb.append(prefix); sb.append(" Starts: ");
1345 sb.append(starts);
1346 sb.append(", launches: "); sb.append(launches);
1347 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 apkActivity = true;
1349 }
1350 }
1351 }
1352 if (!apkActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001353 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001354 }
1355 uidActivity = true;
1356 }
1357 }
1358 if (!uidActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001359 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 }
1361 }
1362 }
1363
1364 /**
1365 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
1366 *
1367 * @param pw a Printer to receive the dump output.
1368 */
1369 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001370 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001371 pw.println("Total Statistics (Current and Historic):");
1372 pw.println(" System starts: " + getStartCount()
1373 + ", currently on battery: " + getIsOnBattery());
1374 dumpLocked(pw, "", STATS_TOTAL);
1375 pw.println("");
1376 pw.println("Last Run Statistics (Previous run of system):");
1377 dumpLocked(pw, "", STATS_LAST);
1378 pw.println("");
1379 pw.println("Current Battery Statistics (Currently running system):");
1380 dumpLocked(pw, "", STATS_CURRENT);
1381 pw.println("");
1382 pw.println("Unplugged Statistics (Since last unplugged from power):");
1383 dumpLocked(pw, "", STATS_UNPLUGGED);
1384 }
1385
1386 @SuppressWarnings("unused")
1387 public void dumpCheckinLocked(PrintWriter pw, String[] args) {
1388 boolean isUnpluggedOnly = false;
1389
1390 for (String arg : args) {
1391 if ("-u".equals(arg)) {
1392 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
1393 isUnpluggedOnly = true;
1394 }
1395 }
1396
1397 if (isUnpluggedOnly) {
1398 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1399 }
1400 else {
1401 dumpCheckinLocked(pw, STATS_TOTAL);
1402 dumpCheckinLocked(pw, STATS_LAST);
1403 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1404 dumpCheckinLocked(pw, STATS_CURRENT);
1405 }
1406 }
1407
1408}