blob: e203fd59025827041015a1ae184a5f825a6c8eb4 [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 /**
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700511 * @deprecated use getRadioDataUptime
512 */
513 public long getRadioDataUptimeMs() {
514 return getRadioDataUptime() / 1000;
515 }
516
517 /**
518 * Returns the time that the radio was on for data transfers.
519 * @return the uptime in microseconds while unplugged
520 */
521 public abstract long getRadioDataUptime();
522
523 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 * Returns the current battery realtime in microseconds.
525 *
526 * @param curTime the amount of elapsed realtime in microseconds.
527 */
528 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700529
530 /**
Evan Millar633a1742009-04-02 16:36:33 -0700531 * Returns the battery percentage level at the last time the device was unplugged from power, or
532 * the last time it booted on battery power.
The Android Open Source Project10592532009-03-18 17:39:46 -0700533 */
Evan Millar633a1742009-04-02 16:36:33 -0700534 public abstract int getDischargeStartLevel();
The Android Open Source Project10592532009-03-18 17:39:46 -0700535
536 /**
Evan Millar633a1742009-04-02 16:36:33 -0700537 * Returns the current battery percentage level if we are in a discharge cycle, otherwise
538 * returns the level at the last plug event.
The Android Open Source Project10592532009-03-18 17:39:46 -0700539 */
Evan Millar633a1742009-04-02 16:36:33 -0700540 public abstract int getDischargeCurrentLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541
542 /**
543 * Returns the total, last, or current battery uptime in microseconds.
544 *
545 * @param curTime the elapsed realtime in microseconds.
546 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
547 */
548 public abstract long computeBatteryUptime(long curTime, int which);
549
550 /**
551 * Returns the total, last, or current battery realtime in microseconds.
552 *
553 * @param curTime the current elapsed realtime in microseconds.
554 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
555 */
556 public abstract long computeBatteryRealtime(long curTime, int which);
557
558 /**
559 * Returns the total, last, or current uptime in microseconds.
560 *
561 * @param curTime the current elapsed realtime in microseconds.
562 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
563 */
564 public abstract long computeUptime(long curTime, int which);
565
566 /**
567 * Returns the total, last, or current realtime in microseconds.
568 * *
569 * @param curTime the current elapsed realtime in microseconds.
570 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
571 */
572 public abstract long computeRealtime(long curTime, int which);
Evan Millarc64edde2009-04-18 12:26:32 -0700573
574 public abstract Map<String, ? extends Timer> getKernelWakelockStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700576 private final static void formatTimeRaw(StringBuilder out, long seconds) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 long days = seconds / (60 * 60 * 24);
578 if (days != 0) {
579 out.append(days);
580 out.append("d ");
581 }
582 long used = days * 60 * 60 * 24;
583
584 long hours = (seconds - used) / (60 * 60);
585 if (hours != 0 || used != 0) {
586 out.append(hours);
587 out.append("h ");
588 }
589 used += hours * 60 * 60;
590
591 long mins = (seconds-used) / 60;
592 if (mins != 0 || used != 0) {
593 out.append(mins);
594 out.append("m ");
595 }
596 used += mins * 60;
597
598 if (seconds != 0 || used != 0) {
599 out.append(seconds-used);
600 out.append("s ");
601 }
602 }
603
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700604 private final static void formatTime(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 long sec = time / 100;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700606 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 sb.append((time - (sec * 100)) * 10);
608 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 }
610
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700611 private final static void formatTimeMs(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 long sec = time / 1000;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700613 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 sb.append(time - (sec * 1000));
615 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800616 }
617
618 private final String formatRatioLocked(long num, long den) {
619 if (den == 0L) {
620 return "---%";
621 }
622 float perc = ((float)num) / ((float)den) * 100;
623 mFormatBuilder.setLength(0);
624 mFormatter.format("%.1f%%", perc);
625 return mFormatBuilder.toString();
626 }
627
Evan Millar22ac0432009-03-31 11:33:18 -0700628 private final String formatBytesLocked(long bytes) {
629 mFormatBuilder.setLength(0);
630
631 if (bytes < BYTES_PER_KB) {
632 return bytes + "B";
633 } else if (bytes < BYTES_PER_MB) {
634 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
635 return mFormatBuilder.toString();
636 } else if (bytes < BYTES_PER_GB){
637 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
638 return mFormatBuilder.toString();
639 } else {
640 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
641 return mFormatBuilder.toString();
642 }
643 }
644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645 /**
646 *
647 * @param sb a StringBuilder object.
648 * @param timer a Timer object contining the wakelock times.
649 * @param batteryRealtime the current on-battery time in microseconds.
650 * @param name the name of the wakelock.
651 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
652 * @param linePrefix a String to be prepended to each line of output.
653 * @return the line prefix
654 */
655 private static final String printWakeLock(StringBuilder sb, Timer timer,
656 long batteryRealtime, String name, int which, String linePrefix) {
657
658 if (timer != null) {
659 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -0700660 long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
662
Evan Millarc64edde2009-04-18 12:26:32 -0700663 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 if (totalTimeMillis != 0) {
665 sb.append(linePrefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700666 formatTimeMs(sb, totalTimeMillis);
667 if (name != null) sb.append(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 sb.append(' ');
669 sb.append('(');
670 sb.append(count);
671 sb.append(" times)");
672 return ", ";
673 }
674 }
675 return linePrefix;
676 }
677
678 /**
679 * Checkin version of wakelock printer. Prints simple comma-separated list.
680 *
681 * @param sb a StringBuilder object.
682 * @param timer a Timer object contining the wakelock times.
683 * @param now the current time in microseconds.
684 * @param name the name of the wakelock.
685 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
686 * @param linePrefix a String to be prepended to each line of output.
687 * @return the line prefix
688 */
689 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
Evan Millarc64edde2009-04-18 12:26:32 -0700690 String name, int which, String linePrefix) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 long totalTimeMicros = 0;
692 int count = 0;
693 if (timer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700694 totalTimeMicros = timer.getTotalTimeLocked(now, which);
695 count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800696 }
697 sb.append(linePrefix);
698 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
699 sb.append(',');
Evan Millarc64edde2009-04-18 12:26:32 -0700700 sb.append(name != null ? name + "," : "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701 sb.append(count);
702 return ",";
703 }
704
705 /**
706 * Dump a comma-separated line of values for terse checkin mode.
707 *
708 * @param pw the PageWriter to dump log to
709 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
710 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
711 * @param args type-dependent data arguments
712 */
713 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
714 Object... args ) {
715 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
716 pw.print(uid); pw.print(',');
717 pw.print(category); pw.print(',');
718 pw.print(type);
719
720 for (Object arg : args) {
721 pw.print(',');
722 pw.print(arg);
723 }
724 pw.print('\n');
725 }
726
727 /**
728 * Checkin server version of dump to produce more compact, computer-readable log.
729 *
730 * NOTE: all times are expressed in 'ms'.
731 * @param fd
732 * @param pw
733 * @param which
734 */
735 private final void dumpCheckinLocked(PrintWriter pw, int which) {
736 final long rawUptime = SystemClock.uptimeMillis() * 1000;
737 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
738 final long batteryUptime = getBatteryUptime(rawUptime);
739 final long batteryRealtime = getBatteryRealtime(rawRealtime);
740 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
741 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
742 final long totalRealtime = computeRealtime(rawRealtime, which);
743 final long totalUptime = computeUptime(rawUptime, which);
744 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
745 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700746 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700747 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700748 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749
750 StringBuilder sb = new StringBuilder(128);
751
Evan Millar22ac0432009-03-31 11:33:18 -0700752 SparseArray<? extends Uid> uidStats = getUidStats();
753 final int NU = uidStats.size();
754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 String category = STAT_NAMES[which];
756
757 // Dump "battery" stat
758 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
759 which == STATS_TOTAL ? getStartCount() : "N/A",
Dianne Hackborn617f8772009-03-31 15:04:46 -0700760 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
761 totalRealtime / 1000, totalUptime / 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762
Evan Millar22ac0432009-03-31 11:33:18 -0700763 // Calculate total network and wakelock times across all uids.
764 long rxTotal = 0;
765 long txTotal = 0;
766 long fullWakeLockTimeTotal = 0;
767 long partialWakeLockTimeTotal = 0;
768
769 for (int iu = 0; iu < NU; iu++) {
770 Uid u = uidStats.valueAt(iu);
771 rxTotal += u.getTcpBytesReceived(which);
772 txTotal += u.getTcpBytesSent(which);
773
774 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
775 if (wakelocks.size() > 0) {
776 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
777 : wakelocks.entrySet()) {
778 Uid.Wakelock wl = ent.getValue();
779
780 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
781 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700782 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
Evan Millar22ac0432009-03-31 11:33:18 -0700783 }
784
785 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
786 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700787 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -0700788 batteryRealtime, which);
789 }
790 }
791 }
792 }
793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 // Dump misc stats
795 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700796 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
Evan Millar22ac0432009-03-31 11:33:18 -0700797 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal,
Dianne Hackborn617f8772009-03-31 15:04:46 -0700798 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
799 getInputEventCount(which));
800
801 // Dump screen brightness stats
802 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
803 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
804 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
805 }
806 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
The Android Open Source Project10592532009-03-18 17:39:46 -0700807
Dianne Hackborn627bba72009-03-24 22:32:56 -0700808 // Dump signal strength stats
Dianne Hackborn617f8772009-03-31 15:04:46 -0700809 args = new Object[NUM_SIGNAL_STRENGTH_BINS];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700810 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
811 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
812 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700813 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
814 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
815 args[i] = getPhoneSignalStrengthCount(i, which);
816 }
817 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700818
819 // Dump network type stats
820 args = new Object[NUM_DATA_CONNECTION_TYPES];
821 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
822 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
823 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700824 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
825 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
826 args[i] = getPhoneDataConnectionCount(i, which);
827 }
828 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700829
The Android Open Source Project10592532009-03-18 17:39:46 -0700830 if (which == STATS_UNPLUGGED) {
Evan Millare84de8d2009-04-02 22:16:12 -0700831 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
Evan Millar633a1742009-04-02 16:36:33 -0700832 getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -0700833 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834
Evan Millarc64edde2009-04-18 12:26:32 -0700835 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
836 if (kernelWakelocks.size() > 0) {
837 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
838 sb.setLength(0);
839 printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
840
841 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
842 sb.toString());
843 }
844 }
845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 for (int iu = 0; iu < NU; iu++) {
847 final int uid = uidStats.keyAt(iu);
848 Uid u = uidStats.valueAt(iu);
849 // Dump Network stats per uid, if any
850 long rx = u.getTcpBytesReceived(which);
851 long tx = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700852 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
853 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700854 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800856 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -0700857
Dianne Hackborn617f8772009-03-31 15:04:46 -0700858 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
859 || wifiTurnedOnTime != 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700860 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
Dianne Hackborn617f8772009-03-31 15:04:46 -0700861 fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863
Dianne Hackborn617f8772009-03-31 15:04:46 -0700864 if (u.hasUserActivity()) {
865 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
866 boolean hasData = false;
867 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
868 int val = u.getUserActivityCount(i, which);
869 args[i] = val;
870 if (val != 0) hasData = true;
871 }
872 if (hasData) {
873 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args);
874 }
875 }
876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
878 if (wakelocks.size() > 0) {
879 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
880 : wakelocks.entrySet()) {
881 Uid.Wakelock wl = ent.getValue();
882 String linePrefix = "";
883 sb.setLength(0);
Evan Millarc64edde2009-04-18 12:26:32 -0700884 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
885 batteryRealtime, "f", which, linePrefix);
886 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
887 batteryRealtime, "p", which, linePrefix);
888 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
889 batteryRealtime, "w", which, linePrefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890
891 // Only log if we had at lease one wakelock...
892 if (sb.length() > 0) {
893 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
894 }
895 }
896 }
897
898 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
899 if (sensors.size() > 0) {
900 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
901 : sensors.entrySet()) {
902 Uid.Sensor se = ent.getValue();
903 int sensorNumber = ent.getKey();
904 Timer timer = se.getSensorTime();
905 if (timer != null) {
906 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -0700907 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
908 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 if (totalTime != 0) {
910 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
911 }
912 }
913 }
914 }
915
916 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
917 if (processStats.size() > 0) {
918 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
919 : processStats.entrySet()) {
920 Uid.Proc ps = ent.getValue();
921
922 long userTime = ps.getUserTime(which);
923 long systemTime = ps.getSystemTime(which);
924 int starts = ps.getStarts(which);
925
926 if (userTime != 0 || systemTime != 0 || starts != 0) {
927 dumpLine(pw, uid, category, PROCESS_DATA,
928 ent.getKey(), // proc
929 userTime * 10, // cpu time in ms
930 systemTime * 10, // user time in ms
931 starts); // process starts
932 }
933 }
934 }
935
936 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
937 if (packageStats.size() > 0) {
938 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
939 : packageStats.entrySet()) {
940
941 Uid.Pkg ps = ent.getValue();
942 int wakeups = ps.getWakeups(which);
943 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
944 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
945 : serviceStats.entrySet()) {
946 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
947 long startTime = ss.getStartTime(batteryUptime, which);
948 int starts = ss.getStarts(which);
949 int launches = ss.getLaunches(which);
950 if (startTime != 0 || starts != 0 || launches != 0) {
951 dumpLine(pw, uid, category, APK_DATA,
952 wakeups, // wakeup alarms
953 ent.getKey(), // Apk
954 sent.getKey(), // service
955 startTime / 1000, // time spent started, in ms
956 starts,
957 launches);
958 }
959 }
960 }
961 }
962 }
963 }
964
965 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700966 private final void dumpLocked(PrintWriter pw, String prefix, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 final long rawUptime = SystemClock.uptimeMillis() * 1000;
968 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
969 final long batteryUptime = getBatteryUptime(rawUptime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700970 final long batteryRealtime = getBatteryRealtime(rawRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971
972 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
973 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
974 final long totalRealtime = computeRealtime(rawRealtime, which);
975 final long totalUptime = computeUptime(rawUptime, which);
976
977 StringBuilder sb = new StringBuilder(128);
Evan Millar22ac0432009-03-31 11:33:18 -0700978
979 SparseArray<? extends Uid> uidStats = getUidStats();
980 final int NU = uidStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700982 sb.setLength(0);
983 sb.append(prefix);
984 sb.append(" Time on battery: ");
985 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
986 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
987 sb.append(") realtime, ");
988 formatTimeMs(sb, whichBatteryUptime / 1000);
989 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
990 sb.append(") uptime");
991 pw.println(sb.toString());
992 sb.setLength(0);
993 sb.append(prefix);
994 sb.append(" Total run time: ");
995 formatTimeMs(sb, totalRealtime / 1000);
996 sb.append("realtime, ");
997 formatTimeMs(sb, totalUptime / 1000);
998 sb.append("uptime, ");
999 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000
The Android Open Source Project10592532009-03-18 17:39:46 -07001001 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
1002 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001003 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001004 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
1005 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001006 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001007 sb.append(prefix);
1008 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
1009 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
1010 sb.append("), Input events: "); sb.append(getInputEventCount(which));
1011 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
1012 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
1013 sb.append(")");
1014 pw.println(sb.toString());
1015 sb.setLength(0);
1016 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001017 sb.append(" Screen brightnesses: ");
1018 boolean didOne = false;
1019 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1020 final long time = getScreenBrightnessTime(i, batteryRealtime, which);
1021 if (time == 0) {
1022 continue;
1023 }
1024 if (didOne) sb.append(", ");
1025 didOne = true;
1026 sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
1027 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001028 formatTimeMs(sb, time/1000);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001029 sb.append("(");
1030 sb.append(formatRatioLocked(time, screenOnTime));
1031 sb.append(")");
1032 }
1033 if (!didOne) sb.append("No activity");
1034 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001035
Evan Millar22ac0432009-03-31 11:33:18 -07001036 // Calculate total network and wakelock times across all uids.
1037 long rxTotal = 0;
1038 long txTotal = 0;
1039 long fullWakeLockTimeTotalMicros = 0;
1040 long partialWakeLockTimeTotalMicros = 0;
1041
Evan Millarc64edde2009-04-18 12:26:32 -07001042 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1043 if (kernelWakelocks.size() > 0) {
1044 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1045
1046 String linePrefix = ": ";
1047 sb.setLength(0);
1048 sb.append(prefix);
1049 sb.append(" Kernel Wake lock ");
1050 sb.append(ent.getKey());
1051 linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
1052 linePrefix);
1053 if (!linePrefix.equals(": ")) {
1054 sb.append(" realtime");
1055 } else {
1056 sb.append(": (nothing executed)");
1057 }
1058 pw.println(sb.toString());
1059 }
1060 }
1061
Evan Millar22ac0432009-03-31 11:33:18 -07001062 for (int iu = 0; iu < NU; iu++) {
1063 Uid u = uidStats.valueAt(iu);
1064 rxTotal += u.getTcpBytesReceived(which);
1065 txTotal += u.getTcpBytesSent(which);
1066
1067 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1068 if (wakelocks.size() > 0) {
1069 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1070 : wakelocks.entrySet()) {
1071 Uid.Wakelock wl = ent.getValue();
1072
1073 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1074 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001075 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001076 batteryRealtime, which);
1077 }
1078
1079 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1080 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001081 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001082 batteryRealtime, which);
1083 }
1084 }
1085 }
1086 }
1087
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001088 pw.print(prefix);
1089 pw.print(" Total received: "); pw.print(formatBytesLocked(rxTotal));
1090 pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal));
1091 sb.setLength(0);
1092 sb.append(prefix);
1093 sb.append(" Total full wakelock time: "); formatTimeMs(sb,
1094 (fullWakeLockTimeTotalMicros + 500) / 1000);
1095 sb.append(", Total partial waklock time: "); formatTimeMs(sb,
1096 (partialWakeLockTimeTotalMicros + 500) / 1000);
1097 pw.println(sb.toString());
Evan Millar22ac0432009-03-31 11:33:18 -07001098
Dianne Hackborn627bba72009-03-24 22:32:56 -07001099 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001100 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001101 sb.append(" Signal levels: ");
1102 didOne = false;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001103 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
1104 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
1105 if (time == 0) {
1106 continue;
1107 }
1108 if (didOne) sb.append(", ");
1109 didOne = true;
1110 sb.append(SIGNAL_STRENGTH_NAMES[i]);
1111 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001112 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001113 sb.append("(");
1114 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001115 sb.append(") ");
1116 sb.append(getPhoneSignalStrengthCount(i, which));
1117 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001118 }
1119 if (!didOne) sb.append("No activity");
1120 pw.println(sb.toString());
1121
1122 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001123 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001124 sb.append(" Radio types: ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001125 didOne = false;
1126 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1127 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
1128 if (time == 0) {
1129 continue;
1130 }
1131 if (didOne) sb.append(", ");
1132 didOne = true;
1133 sb.append(DATA_CONNECTION_NAMES[i]);
1134 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001135 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001136 sb.append("(");
1137 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001138 sb.append(") ");
1139 sb.append(getPhoneDataConnectionCount(i, which));
1140 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001141 }
1142 if (!didOne) sb.append("No activity");
1143 pw.println(sb.toString());
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001144
1145 sb.setLength(0);
1146 sb.append(prefix);
1147 sb.append(" Radio data uptime when unplugged: ");
1148 sb.append(getRadioDataUptime() / 1000);
1149 sb.append(" ms");
1150 pw.println(sb.toString());
1151
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001152 sb.setLength(0);
1153 sb.append(prefix);
1154 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
1155 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
1156 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
1157 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
1158 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
1159 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
1160 sb.append(")");
1161 pw.println(sb.toString());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001162
The Android Open Source Project10592532009-03-18 17:39:46 -07001163 pw.println(" ");
1164
1165 if (which == STATS_UNPLUGGED) {
1166 if (getIsOnBattery()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001167 pw.print(prefix); pw.println(" Device is currently unplugged");
1168 pw.print(prefix); pw.print(" Discharge cycle start level: ");
1169 pw.println(getDischargeStartLevel());
1170 pw.print(prefix); pw.print(" Discharge cycle current level: ");
1171 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001172 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001173 pw.print(prefix); pw.println(" Device is currently plugged into power");
1174 pw.print(prefix); pw.print(" Last discharge cycle start level: ");
1175 pw.println(getDischargeStartLevel());
1176 pw.print(prefix); pw.print(" Last discharge cycle end level: ");
1177 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001178 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001179 pw.println(" ");
The Android Open Source Project10592532009-03-18 17:39:46 -07001180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001181
Evan Millar22ac0432009-03-31 11:33:18 -07001182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001183 for (int iu=0; iu<NU; iu++) {
1184 final int uid = uidStats.keyAt(iu);
1185 Uid u = uidStats.valueAt(iu);
1186 pw.println(prefix + " #" + uid + ":");
1187 boolean uidActivity = false;
1188
1189 long tcpReceived = u.getTcpBytesReceived(which);
1190 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001191 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1192 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001193 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001195 if (tcpReceived != 0 || tcpSent != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001196 pw.print(prefix); pw.print(" Network: ");
1197 pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, ");
1198 pw.print(formatBytesLocked(tcpSent)); pw.println(" sent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001200
1201 if (u.hasUserActivity()) {
1202 boolean hasData = false;
1203 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1204 int val = u.getUserActivityCount(i, which);
1205 if (val != 0) {
1206 if (!hasData) {
1207 sb.setLength(0);
1208 sb.append(" User activity: ");
1209 hasData = true;
1210 } else {
1211 sb.append(", ");
1212 }
1213 sb.append(val);
1214 sb.append(" ");
1215 sb.append(Uid.USER_ACTIVITY_TYPES[i]);
1216 }
1217 }
1218 if (hasData) {
1219 pw.println(sb.toString());
1220 }
1221 }
1222
1223 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
1224 || wifiTurnedOnTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001225 sb.setLength(0);
1226 sb.append(prefix); sb.append(" Turned Wifi On: ");
1227 formatTimeMs(sb, wifiTurnedOnTime / 1000);
1228 sb.append("("); sb.append(formatRatioLocked(wifiTurnedOnTime,
1229 whichBatteryRealtime)); sb.append(")\n");
1230 sb.append(prefix); sb.append(" Full Wifi Lock: ");
1231 formatTimeMs(sb, fullWifiLockOnTime / 1000);
1232 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
1233 whichBatteryRealtime)); sb.append(")\n");
1234 sb.append(prefix); sb.append(" Scan Wifi Lock: ");
1235 formatTimeMs(sb, scanWifiLockOnTime / 1000);
1236 sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime,
1237 whichBatteryRealtime)); sb.append(")");
1238 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001239 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240
1241 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1242 if (wakelocks.size() > 0) {
1243 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1244 : wakelocks.entrySet()) {
1245 Uid.Wakelock wl = ent.getValue();
1246 String linePrefix = ": ";
1247 sb.setLength(0);
1248 sb.append(prefix);
1249 sb.append(" Wake lock ");
1250 sb.append(ent.getKey());
1251 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
1252 "full", which, linePrefix);
1253 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
1254 "partial", which, linePrefix);
1255 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
1256 "window", which, linePrefix);
1257 if (!linePrefix.equals(": ")) {
1258 sb.append(" realtime");
1259 } else {
1260 sb.append(": (nothing executed)");
1261 }
1262 pw.println(sb.toString());
1263 uidActivity = true;
1264 }
1265 }
1266
1267 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1268 if (sensors.size() > 0) {
1269 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1270 : sensors.entrySet()) {
1271 Uid.Sensor se = ent.getValue();
1272 int sensorNumber = ent.getKey();
1273 sb.setLength(0);
1274 sb.append(prefix);
1275 sb.append(" Sensor ");
1276 int handle = se.getHandle();
1277 if (handle == Uid.Sensor.GPS) {
1278 sb.append("GPS");
1279 } else {
1280 sb.append(handle);
1281 }
1282 sb.append(": ");
1283
1284 Timer timer = se.getSensorTime();
1285 if (timer != null) {
1286 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -07001287 long totalTime = (timer.getTotalTimeLocked(
1288 batteryRealtime, which) + 500) / 1000;
1289 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 //timer.logState();
1291 if (totalTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001292 formatTimeMs(sb, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 sb.append("realtime (");
1294 sb.append(count);
1295 sb.append(" times)");
1296 } else {
1297 sb.append("(not used)");
1298 }
1299 } else {
1300 sb.append("(not used)");
1301 }
1302
1303 pw.println(sb.toString());
1304 uidActivity = true;
1305 }
1306 }
1307
1308 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1309 if (processStats.size() > 0) {
1310 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1311 : processStats.entrySet()) {
1312 Uid.Proc ps = ent.getValue();
1313 long userTime;
1314 long systemTime;
1315 int starts;
1316
1317 userTime = ps.getUserTime(which);
1318 systemTime = ps.getSystemTime(which);
1319 starts = ps.getStarts(which);
1320
1321 if (userTime != 0 || systemTime != 0 || starts != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001322 sb.setLength(0);
1323 sb.append(prefix); sb.append(" Proc ");
1324 sb.append(ent.getKey()); sb.append(":\n");
1325 sb.append(prefix); sb.append(" CPU: ");
1326 formatTime(sb, userTime); sb.append("usr + ");
1327 formatTime(sb, systemTime); sb.append("krn\n");
1328 sb.append(prefix); sb.append(" "); sb.append(starts);
1329 sb.append(" proc starts");
1330 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 uidActivity = true;
1332 }
1333 }
1334 }
1335
1336 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1337 if (packageStats.size() > 0) {
1338 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1339 : packageStats.entrySet()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001340 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341 boolean apkActivity = false;
1342 Uid.Pkg ps = ent.getValue();
1343 int wakeups = ps.getWakeups(which);
1344 if (wakeups != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001345 pw.print(prefix); pw.print(" ");
1346 pw.print(wakeups); pw.println(" wakeup alarms");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 apkActivity = true;
1348 }
1349 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1350 if (serviceStats.size() > 0) {
1351 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1352 : serviceStats.entrySet()) {
1353 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1354 long startTime = ss.getStartTime(batteryUptime, which);
1355 int starts = ss.getStarts(which);
1356 int launches = ss.getLaunches(which);
1357 if (startTime != 0 || starts != 0 || launches != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001358 sb.setLength(0);
1359 sb.append(prefix); sb.append(" Service ");
1360 sb.append(sent.getKey()); sb.append(":\n");
1361 sb.append(prefix); sb.append(" Created for: ");
1362 formatTimeMs(sb, startTime / 1000);
1363 sb.append(" uptime\n");
1364 sb.append(prefix); sb.append(" Starts: ");
1365 sb.append(starts);
1366 sb.append(", launches: "); sb.append(launches);
1367 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 apkActivity = true;
1369 }
1370 }
1371 }
1372 if (!apkActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001373 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 }
1375 uidActivity = true;
1376 }
1377 }
1378 if (!uidActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001379 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 }
1381 }
1382 }
1383
1384 /**
1385 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
1386 *
1387 * @param pw a Printer to receive the dump output.
1388 */
1389 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001390 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 pw.println("Total Statistics (Current and Historic):");
1392 pw.println(" System starts: " + getStartCount()
1393 + ", currently on battery: " + getIsOnBattery());
1394 dumpLocked(pw, "", STATS_TOTAL);
1395 pw.println("");
1396 pw.println("Last Run Statistics (Previous run of system):");
1397 dumpLocked(pw, "", STATS_LAST);
1398 pw.println("");
1399 pw.println("Current Battery Statistics (Currently running system):");
1400 dumpLocked(pw, "", STATS_CURRENT);
1401 pw.println("");
1402 pw.println("Unplugged Statistics (Since last unplugged from power):");
1403 dumpLocked(pw, "", STATS_UNPLUGGED);
1404 }
1405
1406 @SuppressWarnings("unused")
1407 public void dumpCheckinLocked(PrintWriter pw, String[] args) {
1408 boolean isUnpluggedOnly = false;
1409
1410 for (String arg : args) {
1411 if ("-u".equals(arg)) {
1412 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
1413 isUnpluggedOnly = true;
1414 }
1415 }
1416
1417 if (isUnpluggedOnly) {
1418 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1419 }
1420 else {
1421 dumpCheckinLocked(pw, STATS_TOTAL);
1422 dumpCheckinLocked(pw, STATS_LAST);
1423 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1424 dumpCheckinLocked(pw, STATS_CURRENT);
1425 }
1426 }
1427
1428}