blob: c72b8286dbfd5072e0a8315c595c6e3fee24c6f9 [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 /**
44 * A constant indicating a full wifi lock timer
45 *
46 * {@hide}
47 */
48 public static final int FULL_WIFI_LOCK = 4;
49
50 /**
51 * A constant indicating a scan wifi lock timer
52 *
53 * {@hide}
54 */
55 public static final int SCAN_WIFI_LOCK = 5;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056
57 /**
58 * Include all of the data in the stats, including previously saved data.
59 */
60 public static final int STATS_TOTAL = 0;
61
62 /**
63 * Include only the last run in the stats.
64 */
65 public static final int STATS_LAST = 1;
66
67 /**
68 * Include only the current run in the stats.
69 */
70 public static final int STATS_CURRENT = 2;
71
72 /**
73 * Include only the run since the last time the device was unplugged in the stats.
74 */
75 public static final int STATS_UNPLUGGED = 3;
76
77 /**
78 * Bump the version on this if the checkin format changes.
79 */
80 private static final int BATTERY_STATS_CHECKIN_VERSION = 1;
81
82 // TODO: Update this list if you add/change any stats above.
83 private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" };
84
85 private static final String APK_DATA = "apk";
86 private static final String PROCESS_DATA = "process";
87 private static final String SENSOR_DATA = "sensor";
88 private static final String WAKELOCK_DATA = "wakelock";
89 private static final String NETWORK_DATA = "network";
90 private static final String BATTERY_DATA = "battery";
The Android Open Source Project10592532009-03-18 17:39:46 -070091 private static final String WIFI_LOCK_DATA = "wifilock";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 private static final String MISC_DATA = "misc";
Dianne Hackborn627bba72009-03-24 22:32:56 -070093 private static final String SIGNAL_STRENGTH_DATA = "signal";
94 private static final String DATA_CONNECTION_DATA = "dataconn";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095
96 private final StringBuilder mFormatBuilder = new StringBuilder(8);
97 private final Formatter mFormatter = new Formatter(mFormatBuilder);
98
99 /**
100 * State for keeping track of timing information.
101 */
102 public static abstract class Timer {
103
104 /**
105 * Returns the count associated with this Timer for the
106 * selected type of statistics.
107 *
108 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
109 */
110 public abstract int getCount(int which);
111
112 /**
113 * Returns the total time in microseconds associated with this Timer for the
114 * selected type of statistics.
115 *
116 * @param batteryRealtime system realtime on battery in microseconds
117 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
118 * @return a time in microseconds
119 */
120 public abstract long getTotalTime(long batteryRealtime, int which);
121
122 /**
123 * Temporary for debugging.
124 */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700125 public abstract void logState(Printer pw, String prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 }
127
128 /**
129 * The statistics associated with a particular uid.
130 */
131 public static abstract class Uid {
132
133 /**
134 * Returns a mapping containing wakelock statistics.
135 *
136 * @return a Map from Strings to Uid.Wakelock objects.
137 */
138 public abstract Map<String, ? extends Wakelock> getWakelockStats();
139
140 /**
141 * The statistics associated with a particular wake lock.
142 */
143 public static abstract class Wakelock {
144 public abstract Timer getWakeTime(int type);
145 }
146
147 /**
148 * Returns a mapping containing sensor statistics.
149 *
150 * @return a Map from Integer sensor ids to Uid.Sensor objects.
151 */
152 public abstract Map<Integer, ? extends Sensor> getSensorStats();
153
154 /**
155 * Returns a mapping containing process statistics.
156 *
157 * @return a Map from Strings to Uid.Proc objects.
158 */
159 public abstract Map<String, ? extends Proc> getProcessStats();
160
161 /**
162 * Returns a mapping containing package statistics.
163 *
164 * @return a Map from Strings to Uid.Pkg objects.
165 */
166 public abstract Map<String, ? extends Pkg> getPackageStats();
167
168 /**
169 * {@hide}
170 */
171 public abstract int getUid();
172
173 /**
174 * {@hide}
175 */
176 public abstract long getTcpBytesReceived(int which);
177
178 /**
179 * {@hide}
180 */
181 public abstract long getTcpBytesSent(int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700182
183 public abstract void noteFullWifiLockAcquiredLocked();
184 public abstract void noteFullWifiLockReleasedLocked();
185 public abstract void noteScanWifiLockAcquiredLocked();
186 public abstract void noteScanWifiLockReleasedLocked();
187 public abstract long getFullWifiLockTime(long batteryRealtime, int which);
188 public abstract long getScanWifiLockTime(long batteryRealtime, int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189
190 public static abstract class Sensor {
191 // Magic sensor number for the GPS.
192 public static final int GPS = -10000;
193
194 public abstract int getHandle();
195
196 public abstract Timer getSensorTime();
197 }
198
199 /**
200 * The statistics associated with a particular process.
201 */
202 public static abstract class Proc {
203
204 /**
205 * Returns the total time (in 1/100 sec) spent executing in user code.
206 *
207 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
208 */
209 public abstract long getUserTime(int which);
210
211 /**
212 * Returns the total time (in 1/100 sec) spent executing in system code.
213 *
214 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
215 */
216 public abstract long getSystemTime(int which);
217
218 /**
219 * Returns the number of times the process has been started.
220 *
221 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
222 */
223 public abstract int getStarts(int which);
224 }
225
226 /**
227 * The statistics associated with a particular package.
228 */
229 public static abstract class Pkg {
230
231 /**
232 * Returns the number of times this package has done something that could wake up the
233 * device from sleep.
234 *
235 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
236 */
237 public abstract int getWakeups(int which);
238
239 /**
240 * Returns a mapping containing service statistics.
241 */
242 public abstract Map<String, ? extends Serv> getServiceStats();
243
244 /**
245 * The statistics associated with a particular service.
246 */
247 public abstract class Serv {
248
249 /**
250 * Returns the amount of time spent started.
251 *
252 * @param batteryUptime elapsed uptime on battery in microseconds.
253 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
254 * @return
255 */
256 public abstract long getStartTime(long batteryUptime, int which);
257
258 /**
259 * Returns the total number of times startService() has been called.
260 *
261 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
262 */
263 public abstract int getStarts(int which);
264
265 /**
266 * Returns the total number times the service has been launched.
267 *
268 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
269 */
270 public abstract int getLaunches(int which);
271 }
272 }
273 }
274
275 /**
276 * Returns the number of times the device has been started.
277 */
278 public abstract int getStartCount();
279
280 /**
281 * Returns the time in milliseconds that the screen has been on while the device was
282 * running on battery.
283 *
284 * {@hide}
285 */
286 public abstract long getScreenOnTime(long batteryRealtime, int which);
287
288 /**
289 * Returns the time in milliseconds that the phone has been on while the device was
290 * running on battery.
291 *
292 * {@hide}
293 */
294 public abstract long getPhoneOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700295
Dianne Hackborn627bba72009-03-24 22:32:56 -0700296 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
297 public static final int SIGNAL_STRENGTH_POOR = 1;
298 public static final int SIGNAL_STRENGTH_MODERATE = 2;
299 public static final int SIGNAL_STRENGTH_GOOD = 3;
300 public static final int SIGNAL_STRENGTH_GREAT = 4;
301
302 static final String[] SIGNAL_STRENGTH_NAMES = {
303 "none", "poor", "moderate", "good", "great"
304 };
305
306 public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
307
308 /**
309 * Returns the time in milliseconds that the phone has been running with
310 * the given signal strength.
311 *
312 * {@hide}
313 */
314 public abstract long getPhoneSignalStrengthTime(int strengthBin,
315 long batteryRealtime, int which);
316
317 public static final int DATA_CONNECTION_NONE = 0;
318 public static final int DATA_CONNECTION_GPRS = 1;
319 public static final int DATA_CONNECTION_EDGE = 2;
320 public static final int DATA_CONNECTION_UMTS = 3;
321 public static final int DATA_CONNECTION_OTHER = 4;
322
323 static final String[] DATA_CONNECTION_NAMES = {
324 "none", "gprs", "edge", "umts", "other"
325 };
326
327 public static final int NUM_DATA_CONNECTION_TYPES = 5;
328
329 /**
330 * Returns the time in milliseconds that the phone has been running with
331 * the given data connection.
332 *
333 * {@hide}
334 */
335 public abstract long getPhoneDataConnectionTime(int dataType,
336 long batteryRealtime, int which);
337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 /**
The Android Open Source Project10592532009-03-18 17:39:46 -0700339 * Returns the time in milliseconds that wifi has been on while the device was
340 * running on battery.
341 *
342 * {@hide}
343 */
344 public abstract long getWifiOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700345
346 /**
347 * Returns the time in milliseconds that wifi has been on and the driver has
348 * been in the running state while the device was running on battery.
349 *
350 * {@hide}
351 */
352 public abstract long getWifiRunningTime(long batteryRealtime, int which);
353
The Android Open Source Project10592532009-03-18 17:39:46 -0700354 /**
355 * Returns the time in milliseconds that bluetooth has been on while the device was
356 * running on battery.
357 *
358 * {@hide}
359 */
360 public abstract long getBluetoothOnTime(long batteryRealtime, int which);
361
362 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 * Return whether we are currently running on battery.
364 */
365 public abstract boolean getIsOnBattery();
366
367 /**
368 * Returns a SparseArray containing the statistics for each uid.
369 */
370 public abstract SparseArray<? extends Uid> getUidStats();
371
372 /**
373 * Returns the current battery uptime in microseconds.
374 *
375 * @param curTime the amount of elapsed realtime in microseconds.
376 */
377 public abstract long getBatteryUptime(long curTime);
378
379 /**
380 * Returns the current battery realtime in microseconds.
381 *
382 * @param curTime the amount of elapsed realtime in microseconds.
383 */
384 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700385
386 /**
387 * Returns the battery percentage level at the last time the device was unplugged from power,
388 * or the last time it was booted while unplugged.
389 */
390 public abstract int getUnpluggedStartLevel();
391
392 /**
393 * Returns the battery percentage level at the last time the device was plugged into power.
394 */
395 public abstract int getPluggedStartLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396
397 /**
398 * Returns the total, last, or current battery uptime in microseconds.
399 *
400 * @param curTime the elapsed realtime in microseconds.
401 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
402 */
403 public abstract long computeBatteryUptime(long curTime, int which);
404
405 /**
406 * Returns the total, last, or current battery realtime in microseconds.
407 *
408 * @param curTime the current elapsed realtime in microseconds.
409 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
410 */
411 public abstract long computeBatteryRealtime(long curTime, int which);
412
413 /**
414 * Returns the total, last, or current uptime in microseconds.
415 *
416 * @param curTime the current elapsed realtime in microseconds.
417 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
418 */
419 public abstract long computeUptime(long curTime, int which);
420
421 /**
422 * Returns the total, last, or current realtime in microseconds.
423 * *
424 * @param curTime the current elapsed realtime in microseconds.
425 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
426 */
427 public abstract long computeRealtime(long curTime, int which);
428
429 private final static void formatTime(StringBuilder out, long seconds) {
430 long days = seconds / (60 * 60 * 24);
431 if (days != 0) {
432 out.append(days);
433 out.append("d ");
434 }
435 long used = days * 60 * 60 * 24;
436
437 long hours = (seconds - used) / (60 * 60);
438 if (hours != 0 || used != 0) {
439 out.append(hours);
440 out.append("h ");
441 }
442 used += hours * 60 * 60;
443
444 long mins = (seconds-used) / 60;
445 if (mins != 0 || used != 0) {
446 out.append(mins);
447 out.append("m ");
448 }
449 used += mins * 60;
450
451 if (seconds != 0 || used != 0) {
452 out.append(seconds-used);
453 out.append("s ");
454 }
455 }
456
457 private final static String formatTime(long time) {
458 long sec = time / 100;
459 StringBuilder sb = new StringBuilder();
460 formatTime(sb, sec);
461 sb.append((time - (sec * 100)) * 10);
462 sb.append("ms ");
463 return sb.toString();
464 }
465
466 private final static String formatTimeMs(long time) {
467 long sec = time / 1000;
468 StringBuilder sb = new StringBuilder();
469 formatTime(sb, sec);
470 sb.append(time - (sec * 1000));
471 sb.append("ms ");
472 return sb.toString();
473 }
474
475 private final String formatRatioLocked(long num, long den) {
476 if (den == 0L) {
477 return "---%";
478 }
479 float perc = ((float)num) / ((float)den) * 100;
480 mFormatBuilder.setLength(0);
481 mFormatter.format("%.1f%%", perc);
482 return mFormatBuilder.toString();
483 }
484
485 /**
486 *
487 * @param sb a StringBuilder object.
488 * @param timer a Timer object contining the wakelock times.
489 * @param batteryRealtime the current on-battery time in microseconds.
490 * @param name the name of the wakelock.
491 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
492 * @param linePrefix a String to be prepended to each line of output.
493 * @return the line prefix
494 */
495 private static final String printWakeLock(StringBuilder sb, Timer timer,
496 long batteryRealtime, String name, int which, String linePrefix) {
497
498 if (timer != null) {
499 // Convert from microseconds to milliseconds with rounding
500 long totalTimeMicros = timer.getTotalTime(batteryRealtime, which);
501 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
502
503 int count = timer.getCount(which);
504 if (totalTimeMillis != 0) {
505 sb.append(linePrefix);
506 sb.append(formatTimeMs(totalTimeMillis));
507 sb.append(name);
508 sb.append(' ');
509 sb.append('(');
510 sb.append(count);
511 sb.append(" times)");
512 return ", ";
513 }
514 }
515 return linePrefix;
516 }
517
518 /**
519 * Checkin version of wakelock printer. Prints simple comma-separated list.
520 *
521 * @param sb a StringBuilder object.
522 * @param timer a Timer object contining the wakelock times.
523 * @param now the current time in microseconds.
524 * @param name the name of the wakelock.
525 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
526 * @param linePrefix a String to be prepended to each line of output.
527 * @return the line prefix
528 */
529 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
530 String name, int which, String linePrefix) {
531 long totalTimeMicros = 0;
532 int count = 0;
533 if (timer != null) {
534 totalTimeMicros = timer.getTotalTime(now, which);
535 count = timer.getCount(which);
536 }
537 sb.append(linePrefix);
538 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
539 sb.append(',');
540 sb.append(name);
541 sb.append(',');
542 sb.append(count);
543 return ",";
544 }
545
546 /**
547 * Dump a comma-separated line of values for terse checkin mode.
548 *
549 * @param pw the PageWriter to dump log to
550 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
551 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
552 * @param args type-dependent data arguments
553 */
554 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
555 Object... args ) {
556 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
557 pw.print(uid); pw.print(',');
558 pw.print(category); pw.print(',');
559 pw.print(type);
560
561 for (Object arg : args) {
562 pw.print(',');
563 pw.print(arg);
564 }
565 pw.print('\n');
566 }
567
568 /**
569 * Checkin server version of dump to produce more compact, computer-readable log.
570 *
571 * NOTE: all times are expressed in 'ms'.
572 * @param fd
573 * @param pw
574 * @param which
575 */
576 private final void dumpCheckinLocked(PrintWriter pw, int which) {
577 final long rawUptime = SystemClock.uptimeMillis() * 1000;
578 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
579 final long batteryUptime = getBatteryUptime(rawUptime);
580 final long batteryRealtime = getBatteryRealtime(rawRealtime);
581 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
582 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
583 final long totalRealtime = computeRealtime(rawRealtime, which);
584 final long totalUptime = computeUptime(rawUptime, which);
585 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
586 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700587 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700588 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700589 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590
591 StringBuilder sb = new StringBuilder(128);
592
593 String category = STAT_NAMES[which];
594
595 // Dump "battery" stat
596 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
597 which == STATS_TOTAL ? getStartCount() : "N/A",
598 whichBatteryUptime / 1000, whichBatteryRealtime / 1000,
599 totalUptime / 1000, totalRealtime / 1000);
600
601 // Dump misc stats
602 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700603 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
604 wifiRunningTime / 1000, bluetoothOnTime / 1000);
The Android Open Source Project10592532009-03-18 17:39:46 -0700605
Dianne Hackborn627bba72009-03-24 22:32:56 -0700606 // Dump signal strength stats
607 Object[] args = new Object[NUM_SIGNAL_STRENGTH_BINS];
608 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
609 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
610 }
611 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_DATA, args);
612
613 // Dump network type stats
614 args = new Object[NUM_DATA_CONNECTION_TYPES];
615 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
616 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
617 }
618 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_DATA, args);
619
The Android Open Source Project10592532009-03-18 17:39:46 -0700620 if (which == STATS_UNPLUGGED) {
621 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, getUnpluggedStartLevel(),
622 getPluggedStartLevel());
623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624
625 SparseArray<? extends Uid> uidStats = getUidStats();
626 final int NU = uidStats.size();
627 for (int iu = 0; iu < NU; iu++) {
628 final int uid = uidStats.keyAt(iu);
629 Uid u = uidStats.valueAt(iu);
630 // Dump Network stats per uid, if any
631 long rx = u.getTcpBytesReceived(which);
632 long tx = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700633 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
634 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -0700637
638 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) {
639 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
640 fullWifiLockOnTime, scanWifiLockOnTime);
641 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800642
643 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
644 if (wakelocks.size() > 0) {
645 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
646 : wakelocks.entrySet()) {
647 Uid.Wakelock wl = ent.getValue();
648 String linePrefix = "";
649 sb.setLength(0);
650 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
651 "full", which, linePrefix);
652 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
653 "partial", which, linePrefix);
654 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
655 "window", which, linePrefix);
656
657 // Only log if we had at lease one wakelock...
658 if (sb.length() > 0) {
659 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
660 }
661 }
662 }
663
664 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
665 if (sensors.size() > 0) {
666 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
667 : sensors.entrySet()) {
668 Uid.Sensor se = ent.getValue();
669 int sensorNumber = ent.getKey();
670 Timer timer = se.getSensorTime();
671 if (timer != null) {
672 // Convert from microseconds to milliseconds with rounding
673 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
674 int count = timer.getCount(which);
675 if (totalTime != 0) {
676 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
677 }
678 }
679 }
680 }
681
682 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
683 if (processStats.size() > 0) {
684 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
685 : processStats.entrySet()) {
686 Uid.Proc ps = ent.getValue();
687
688 long userTime = ps.getUserTime(which);
689 long systemTime = ps.getSystemTime(which);
690 int starts = ps.getStarts(which);
691
692 if (userTime != 0 || systemTime != 0 || starts != 0) {
693 dumpLine(pw, uid, category, PROCESS_DATA,
694 ent.getKey(), // proc
695 userTime * 10, // cpu time in ms
696 systemTime * 10, // user time in ms
697 starts); // process starts
698 }
699 }
700 }
701
702 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
703 if (packageStats.size() > 0) {
704 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
705 : packageStats.entrySet()) {
706
707 Uid.Pkg ps = ent.getValue();
708 int wakeups = ps.getWakeups(which);
709 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
710 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
711 : serviceStats.entrySet()) {
712 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
713 long startTime = ss.getStartTime(batteryUptime, which);
714 int starts = ss.getStarts(which);
715 int launches = ss.getLaunches(which);
716 if (startTime != 0 || starts != 0 || launches != 0) {
717 dumpLine(pw, uid, category, APK_DATA,
718 wakeups, // wakeup alarms
719 ent.getKey(), // Apk
720 sent.getKey(), // service
721 startTime / 1000, // time spent started, in ms
722 starts,
723 launches);
724 }
725 }
726 }
727 }
728 }
729 }
730
731 @SuppressWarnings("unused")
732 private final void dumpLocked(Printer pw, String prefix, int which) {
733 final long rawUptime = SystemClock.uptimeMillis() * 1000;
734 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
735 final long batteryUptime = getBatteryUptime(rawUptime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700736 final long batteryRealtime = getBatteryRealtime(rawRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737
738 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
739 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
740 final long totalRealtime = computeRealtime(rawRealtime, which);
741 final long totalUptime = computeUptime(rawUptime, which);
742
743 StringBuilder sb = new StringBuilder(128);
744
745 pw.println(prefix
746 + " Time on battery: " + formatTimeMs(whichBatteryUptime / 1000)
747 + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime)
748 + ") uptime, "
749 + formatTimeMs(whichBatteryRealtime / 1000) + "("
750 + formatRatioLocked(whichBatteryRealtime, totalRealtime)
751 + ") realtime");
752 pw.println(prefix
753 + " Total: "
754 + formatTimeMs(totalUptime / 1000)
755 + "uptime, "
756 + formatTimeMs(totalRealtime / 1000)
757 + "realtime");
758
The Android Open Source Project10592532009-03-18 17:39:46 -0700759 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
760 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700761 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700762 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
763 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764 pw.println(prefix
Dianne Hackborn627bba72009-03-24 22:32:56 -0700765 + " Screen on: " + formatTimeMs(screenOnTime / 1000)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800766 + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime)
Dianne Hackborn627bba72009-03-24 22:32:56 -0700767 + "), Phone on: " + formatTimeMs(phoneOnTime / 1000)
768 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime));
769 pw.println(prefix
770 + " Wifi on: " + formatTimeMs(wifiOnTime / 1000)
The Android Open Source Project10592532009-03-18 17:39:46 -0700771 + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime)
Dianne Hackborn627bba72009-03-24 22:32:56 -0700772 + "), Wifi running: " + formatTimeMs(wifiRunningTime / 1000)
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700773 + "(" + formatRatioLocked(wifiRunningTime, whichBatteryRealtime)
Dianne Hackborn627bba72009-03-24 22:32:56 -0700774 + "), Bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000)
The Android Open Source Project10592532009-03-18 17:39:46 -0700775 + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")");
776
Dianne Hackborn627bba72009-03-24 22:32:56 -0700777 sb.setLength(0);
778 sb.append(" Signal strengths: ");
779 boolean didOne = false;
780 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
781 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
782 if (time == 0) {
783 continue;
784 }
785 if (didOne) sb.append(", ");
786 didOne = true;
787 sb.append(SIGNAL_STRENGTH_NAMES[i]);
788 sb.append(" ");
789 sb.append(formatTimeMs(time/1000));
790 sb.append("(");
791 sb.append(formatRatioLocked(time, whichBatteryRealtime));
792 sb.append(")");
793 }
794 if (!didOne) sb.append("No activity");
795 pw.println(sb.toString());
796
797 sb.setLength(0);
798 sb.append(" Data types: ");
799 didOne = false;
800 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
801 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
802 if (time == 0) {
803 continue;
804 }
805 if (didOne) sb.append(", ");
806 didOne = true;
807 sb.append(DATA_CONNECTION_NAMES[i]);
808 sb.append(" ");
809 sb.append(formatTimeMs(time/1000));
810 sb.append("(");
811 sb.append(formatRatioLocked(time, whichBatteryRealtime));
812 sb.append(")");
813 }
814 if (!didOne) sb.append("No activity");
815 pw.println(sb.toString());
816
The Android Open Source Project10592532009-03-18 17:39:46 -0700817 pw.println(" ");
818
819 if (which == STATS_UNPLUGGED) {
820 if (getIsOnBattery()) {
821 pw.println(prefix + " Device is currently unplugged");
822 pw.println(prefix + " Discharge cycle start level: " +
823 getUnpluggedStartLevel());
824 } else {
825 pw.println(prefix + " Device is currently plugged into power");
826 pw.println(prefix + " Last discharge cycle start level: " +
827 getUnpluggedStartLevel());
828 pw.println(prefix + " Last discharge cycle end level: " +
829 getPluggedStartLevel());
830 }
831 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832
833 pw.println(" ");
834
835 SparseArray<? extends Uid> uidStats = getUidStats();
836 final int NU = uidStats.size();
837 for (int iu=0; iu<NU; iu++) {
838 final int uid = uidStats.keyAt(iu);
839 Uid u = uidStats.valueAt(iu);
840 pw.println(prefix + " #" + uid + ":");
841 boolean uidActivity = false;
842
843 long tcpReceived = u.getTcpBytesReceived(which);
844 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700845 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
846 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800848 if (tcpReceived != 0 || tcpSent != 0) {
849 pw.println(prefix + " Network: " + tcpReceived + " bytes received, "
850 + tcpSent + " bytes sent");
851 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700852 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) {
853 pw.println(prefix + " Full Wifi Lock Time: "
854 + formatTime(fullWifiLockOnTime / 1000)
855 + "(" + formatRatioLocked(fullWifiLockOnTime,
856 whichBatteryRealtime)+ ")");
857 pw.println(prefix + " Scan Wifi Lock Time: "
858 + formatTime(scanWifiLockOnTime / 1000)
859 + "(" + formatRatioLocked(scanWifiLockOnTime,
860 whichBatteryRealtime)+ ")");
861 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862
863 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
864 if (wakelocks.size() > 0) {
865 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
866 : wakelocks.entrySet()) {
867 Uid.Wakelock wl = ent.getValue();
868 String linePrefix = ": ";
869 sb.setLength(0);
870 sb.append(prefix);
871 sb.append(" Wake lock ");
872 sb.append(ent.getKey());
873 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
874 "full", which, linePrefix);
875 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
876 "partial", which, linePrefix);
877 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
878 "window", which, linePrefix);
879 if (!linePrefix.equals(": ")) {
880 sb.append(" realtime");
881 } else {
882 sb.append(": (nothing executed)");
883 }
884 pw.println(sb.toString());
885 uidActivity = true;
886 }
887 }
888
889 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
890 if (sensors.size() > 0) {
891 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
892 : sensors.entrySet()) {
893 Uid.Sensor se = ent.getValue();
894 int sensorNumber = ent.getKey();
895 sb.setLength(0);
896 sb.append(prefix);
897 sb.append(" Sensor ");
898 int handle = se.getHandle();
899 if (handle == Uid.Sensor.GPS) {
900 sb.append("GPS");
901 } else {
902 sb.append(handle);
903 }
904 sb.append(": ");
905
906 Timer timer = se.getSensorTime();
907 if (timer != null) {
908 // Convert from microseconds to milliseconds with rounding
909 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
910 int count = timer.getCount(which);
911 //timer.logState();
912 if (totalTime != 0) {
913 sb.append(formatTimeMs(totalTime));
914 sb.append("realtime (");
915 sb.append(count);
916 sb.append(" times)");
917 } else {
918 sb.append("(not used)");
919 }
920 } else {
921 sb.append("(not used)");
922 }
923
924 pw.println(sb.toString());
925 uidActivity = true;
926 }
927 }
928
929 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
930 if (processStats.size() > 0) {
931 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
932 : processStats.entrySet()) {
933 Uid.Proc ps = ent.getValue();
934 long userTime;
935 long systemTime;
936 int starts;
937
938 userTime = ps.getUserTime(which);
939 systemTime = ps.getSystemTime(which);
940 starts = ps.getStarts(which);
941
942 if (userTime != 0 || systemTime != 0 || starts != 0) {
943 pw.println(prefix + " Proc " + ent.getKey() + ":");
944 pw.println(prefix + " CPU: " + formatTime(userTime) + "user + "
945 + formatTime(systemTime) + "kernel");
946 pw.println(prefix + " " + starts + " process starts");
947 uidActivity = true;
948 }
949 }
950 }
951
952 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
953 if (packageStats.size() > 0) {
954 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
955 : packageStats.entrySet()) {
956 pw.println(prefix + " Apk " + ent.getKey() + ":");
957 boolean apkActivity = false;
958 Uid.Pkg ps = ent.getValue();
959 int wakeups = ps.getWakeups(which);
960 if (wakeups != 0) {
961 pw.println(prefix + " " + wakeups + " wakeup alarms");
962 apkActivity = true;
963 }
964 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
965 if (serviceStats.size() > 0) {
966 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
967 : serviceStats.entrySet()) {
968 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
969 long startTime = ss.getStartTime(batteryUptime, which);
970 int starts = ss.getStarts(which);
971 int launches = ss.getLaunches(which);
972 if (startTime != 0 || starts != 0 || launches != 0) {
973 pw.println(prefix + " Service " + sent.getKey() + ":");
974 pw.println(prefix + " Created for: "
975 + formatTimeMs(startTime / 1000)
976 + " uptime");
977 pw.println(prefix + " Starts: " + starts
978 + ", launches: " + launches);
979 apkActivity = true;
980 }
981 }
982 }
983 if (!apkActivity) {
984 pw.println(prefix + " (nothing executed)");
985 }
986 uidActivity = true;
987 }
988 }
989 if (!uidActivity) {
990 pw.println(prefix + " (nothing executed)");
991 }
992 }
993 }
994
995 /**
996 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
997 *
998 * @param pw a Printer to receive the dump output.
999 */
1000 @SuppressWarnings("unused")
1001 public void dumpLocked(Printer pw) {
1002 pw.println("Total Statistics (Current and Historic):");
1003 pw.println(" System starts: " + getStartCount()
1004 + ", currently on battery: " + getIsOnBattery());
1005 dumpLocked(pw, "", STATS_TOTAL);
1006 pw.println("");
1007 pw.println("Last Run Statistics (Previous run of system):");
1008 dumpLocked(pw, "", STATS_LAST);
1009 pw.println("");
1010 pw.println("Current Battery Statistics (Currently running system):");
1011 dumpLocked(pw, "", STATS_CURRENT);
1012 pw.println("");
1013 pw.println("Unplugged Statistics (Since last unplugged from power):");
1014 dumpLocked(pw, "", STATS_UNPLUGGED);
1015 }
1016
1017 @SuppressWarnings("unused")
1018 public void dumpCheckinLocked(PrintWriter pw, String[] args) {
1019 boolean isUnpluggedOnly = false;
1020
1021 for (String arg : args) {
1022 if ("-u".equals(arg)) {
1023 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
1024 isUnpluggedOnly = true;
1025 }
1026 }
1027
1028 if (isUnpluggedOnly) {
1029 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1030 }
1031 else {
1032 dumpCheckinLocked(pw, STATS_TOTAL);
1033 dumpCheckinLocked(pw, STATS_LAST);
1034 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1035 dumpCheckinLocked(pw, STATS_CURRENT);
1036 }
1037 }
1038
1039}