blob: d492b6ae2c692e8a554cc8569a57235428e55c08 [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
The Android Open Source Project10592532009-03-18 17:39:46 -07007import com.android.internal.os.BatteryStatsImpl.Timer;
8
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009import android.util.Log;
10import android.util.Printer;
11import android.util.SparseArray;
12
13/**
14 * A class providing access to battery usage statistics, including information on
15 * wakelocks, processes, packages, and services. All times are represented in microseconds
16 * except where indicated otherwise.
17 * @hide
18 */
19public abstract class BatteryStats implements Parcelable {
20
21 private static final boolean LOCAL_LOGV = false;
22
23 /**
24 * A constant indicating a partial wake lock timer.
25 */
26 public static final int WAKE_TYPE_PARTIAL = 0;
27
28 /**
29 * A constant indicating a full wake lock timer.
30 */
31 public static final int WAKE_TYPE_FULL = 1;
32
33 /**
34 * A constant indicating a window wake lock timer.
35 */
36 public static final int WAKE_TYPE_WINDOW = 2;
37
38 /**
39 * A constant indicating a sensor timer.
40 *
41 * {@hide}
42 */
43 public static final int SENSOR = 3;
The Android Open Source Project10592532009-03-18 17:39:46 -070044
45 /**
46 * A constant indicating a full wifi lock timer
47 *
48 * {@hide}
49 */
50 public static final int FULL_WIFI_LOCK = 4;
51
52 /**
53 * A constant indicating a scan wifi lock timer
54 *
55 * {@hide}
56 */
57 public static final int SCAN_WIFI_LOCK = 5;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
59 /**
60 * Include all of the data in the stats, including previously saved data.
61 */
62 public static final int STATS_TOTAL = 0;
63
64 /**
65 * Include only the last run in the stats.
66 */
67 public static final int STATS_LAST = 1;
68
69 /**
70 * Include only the current run in the stats.
71 */
72 public static final int STATS_CURRENT = 2;
73
74 /**
75 * Include only the run since the last time the device was unplugged in the stats.
76 */
77 public static final int STATS_UNPLUGGED = 3;
78
79 /**
80 * Bump the version on this if the checkin format changes.
81 */
82 private static final int BATTERY_STATS_CHECKIN_VERSION = 1;
83
84 // TODO: Update this list if you add/change any stats above.
85 private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" };
86
87 private static final String APK_DATA = "apk";
88 private static final String PROCESS_DATA = "process";
89 private static final String SENSOR_DATA = "sensor";
90 private static final String WAKELOCK_DATA = "wakelock";
91 private static final String NETWORK_DATA = "network";
92 private static final String BATTERY_DATA = "battery";
The Android Open Source Project10592532009-03-18 17:39:46 -070093 private static final String WIFI_LOCK_DATA = "wifilock";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 private static final String MISC_DATA = "misc";
95
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 */
125 public abstract void logState();
126 }
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 /**
The Android Open Source Project10592532009-03-18 17:39:46 -0700297 * Returns the time in milliseconds that wifi has been on while the device was
298 * running on battery.
299 *
300 * {@hide}
301 */
302 public abstract long getWifiOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700303
304 /**
305 * Returns the time in milliseconds that wifi has been on and the driver has
306 * been in the running state while the device was running on battery.
307 *
308 * {@hide}
309 */
310 public abstract long getWifiRunningTime(long batteryRealtime, int which);
311
The Android Open Source Project10592532009-03-18 17:39:46 -0700312 /**
313 * Returns the time in milliseconds that bluetooth has been on while the device was
314 * running on battery.
315 *
316 * {@hide}
317 */
318 public abstract long getBluetoothOnTime(long batteryRealtime, int which);
319
320 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 * Return whether we are currently running on battery.
322 */
323 public abstract boolean getIsOnBattery();
324
325 /**
326 * Returns a SparseArray containing the statistics for each uid.
327 */
328 public abstract SparseArray<? extends Uid> getUidStats();
329
330 /**
331 * Returns the current battery uptime in microseconds.
332 *
333 * @param curTime the amount of elapsed realtime in microseconds.
334 */
335 public abstract long getBatteryUptime(long curTime);
336
337 /**
338 * Returns the current battery realtime in microseconds.
339 *
340 * @param curTime the amount of elapsed realtime in microseconds.
341 */
342 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700343
344 /**
345 * Returns the battery percentage level at the last time the device was unplugged from power,
346 * or the last time it was booted while unplugged.
347 */
348 public abstract int getUnpluggedStartLevel();
349
350 /**
351 * Returns the battery percentage level at the last time the device was plugged into power.
352 */
353 public abstract int getPluggedStartLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354
355 /**
356 * Returns the total, last, or current battery uptime in microseconds.
357 *
358 * @param curTime the elapsed realtime in microseconds.
359 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
360 */
361 public abstract long computeBatteryUptime(long curTime, int which);
362
363 /**
364 * Returns the total, last, or current battery realtime in microseconds.
365 *
366 * @param curTime the current elapsed realtime in microseconds.
367 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
368 */
369 public abstract long computeBatteryRealtime(long curTime, int which);
370
371 /**
372 * Returns the total, last, or current uptime in microseconds.
373 *
374 * @param curTime the current elapsed realtime in microseconds.
375 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
376 */
377 public abstract long computeUptime(long curTime, int which);
378
379 /**
380 * Returns the total, last, or current realtime in microseconds.
381 * *
382 * @param curTime the current elapsed realtime in microseconds.
383 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
384 */
385 public abstract long computeRealtime(long curTime, int which);
386
387 private final static void formatTime(StringBuilder out, long seconds) {
388 long days = seconds / (60 * 60 * 24);
389 if (days != 0) {
390 out.append(days);
391 out.append("d ");
392 }
393 long used = days * 60 * 60 * 24;
394
395 long hours = (seconds - used) / (60 * 60);
396 if (hours != 0 || used != 0) {
397 out.append(hours);
398 out.append("h ");
399 }
400 used += hours * 60 * 60;
401
402 long mins = (seconds-used) / 60;
403 if (mins != 0 || used != 0) {
404 out.append(mins);
405 out.append("m ");
406 }
407 used += mins * 60;
408
409 if (seconds != 0 || used != 0) {
410 out.append(seconds-used);
411 out.append("s ");
412 }
413 }
414
415 private final static String formatTime(long time) {
416 long sec = time / 100;
417 StringBuilder sb = new StringBuilder();
418 formatTime(sb, sec);
419 sb.append((time - (sec * 100)) * 10);
420 sb.append("ms ");
421 return sb.toString();
422 }
423
424 private final static String formatTimeMs(long time) {
425 long sec = time / 1000;
426 StringBuilder sb = new StringBuilder();
427 formatTime(sb, sec);
428 sb.append(time - (sec * 1000));
429 sb.append("ms ");
430 return sb.toString();
431 }
432
433 private final String formatRatioLocked(long num, long den) {
434 if (den == 0L) {
435 return "---%";
436 }
437 float perc = ((float)num) / ((float)den) * 100;
438 mFormatBuilder.setLength(0);
439 mFormatter.format("%.1f%%", perc);
440 return mFormatBuilder.toString();
441 }
442
443 /**
444 *
445 * @param sb a StringBuilder object.
446 * @param timer a Timer object contining the wakelock times.
447 * @param batteryRealtime the current on-battery time in microseconds.
448 * @param name the name of the wakelock.
449 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
450 * @param linePrefix a String to be prepended to each line of output.
451 * @return the line prefix
452 */
453 private static final String printWakeLock(StringBuilder sb, Timer timer,
454 long batteryRealtime, String name, int which, String linePrefix) {
455
456 if (timer != null) {
457 // Convert from microseconds to milliseconds with rounding
458 long totalTimeMicros = timer.getTotalTime(batteryRealtime, which);
459 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
460
461 int count = timer.getCount(which);
462 if (totalTimeMillis != 0) {
463 sb.append(linePrefix);
464 sb.append(formatTimeMs(totalTimeMillis));
465 sb.append(name);
466 sb.append(' ');
467 sb.append('(');
468 sb.append(count);
469 sb.append(" times)");
470 return ", ";
471 }
472 }
473 return linePrefix;
474 }
475
476 /**
477 * Checkin version of wakelock printer. Prints simple comma-separated list.
478 *
479 * @param sb a StringBuilder object.
480 * @param timer a Timer object contining the wakelock times.
481 * @param now the current time in microseconds.
482 * @param name the name of the wakelock.
483 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
484 * @param linePrefix a String to be prepended to each line of output.
485 * @return the line prefix
486 */
487 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
488 String name, int which, String linePrefix) {
489 long totalTimeMicros = 0;
490 int count = 0;
491 if (timer != null) {
492 totalTimeMicros = timer.getTotalTime(now, which);
493 count = timer.getCount(which);
494 }
495 sb.append(linePrefix);
496 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
497 sb.append(',');
498 sb.append(name);
499 sb.append(',');
500 sb.append(count);
501 return ",";
502 }
503
504 /**
505 * Dump a comma-separated line of values for terse checkin mode.
506 *
507 * @param pw the PageWriter to dump log to
508 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
509 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
510 * @param args type-dependent data arguments
511 */
512 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
513 Object... args ) {
514 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
515 pw.print(uid); pw.print(',');
516 pw.print(category); pw.print(',');
517 pw.print(type);
518
519 for (Object arg : args) {
520 pw.print(',');
521 pw.print(arg);
522 }
523 pw.print('\n');
524 }
525
526 /**
527 * Checkin server version of dump to produce more compact, computer-readable log.
528 *
529 * NOTE: all times are expressed in 'ms'.
530 * @param fd
531 * @param pw
532 * @param which
533 */
534 private final void dumpCheckinLocked(PrintWriter pw, int which) {
535 final long rawUptime = SystemClock.uptimeMillis() * 1000;
536 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
537 final long batteryUptime = getBatteryUptime(rawUptime);
538 final long batteryRealtime = getBatteryRealtime(rawRealtime);
539 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
540 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
541 final long totalRealtime = computeRealtime(rawRealtime, which);
542 final long totalUptime = computeUptime(rawUptime, which);
543 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
544 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700545 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700546 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700547 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548
549 StringBuilder sb = new StringBuilder(128);
550
551 String category = STAT_NAMES[which];
552
553 // Dump "battery" stat
554 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
555 which == STATS_TOTAL ? getStartCount() : "N/A",
556 whichBatteryUptime / 1000, whichBatteryRealtime / 1000,
557 totalUptime / 1000, totalRealtime / 1000);
558
559 // Dump misc stats
560 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700561 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
562 wifiRunningTime / 1000, bluetoothOnTime / 1000);
The Android Open Source Project10592532009-03-18 17:39:46 -0700563
564 if (which == STATS_UNPLUGGED) {
565 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, getUnpluggedStartLevel(),
566 getPluggedStartLevel());
567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568
569 SparseArray<? extends Uid> uidStats = getUidStats();
570 final int NU = uidStats.size();
571 for (int iu = 0; iu < NU; iu++) {
572 final int uid = uidStats.keyAt(iu);
573 Uid u = uidStats.valueAt(iu);
574 // Dump Network stats per uid, if any
575 long rx = u.getTcpBytesReceived(which);
576 long tx = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700577 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
578 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -0700581
582 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) {
583 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
584 fullWifiLockOnTime, scanWifiLockOnTime);
585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586
587 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
588 if (wakelocks.size() > 0) {
589 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
590 : wakelocks.entrySet()) {
591 Uid.Wakelock wl = ent.getValue();
592 String linePrefix = "";
593 sb.setLength(0);
594 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
595 "full", which, linePrefix);
596 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
597 "partial", which, linePrefix);
598 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
599 "window", which, linePrefix);
600
601 // Only log if we had at lease one wakelock...
602 if (sb.length() > 0) {
603 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
604 }
605 }
606 }
607
608 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
609 if (sensors.size() > 0) {
610 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
611 : sensors.entrySet()) {
612 Uid.Sensor se = ent.getValue();
613 int sensorNumber = ent.getKey();
614 Timer timer = se.getSensorTime();
615 if (timer != null) {
616 // Convert from microseconds to milliseconds with rounding
617 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
618 int count = timer.getCount(which);
619 if (totalTime != 0) {
620 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
621 }
622 }
623 }
624 }
625
626 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
627 if (processStats.size() > 0) {
628 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
629 : processStats.entrySet()) {
630 Uid.Proc ps = ent.getValue();
631
632 long userTime = ps.getUserTime(which);
633 long systemTime = ps.getSystemTime(which);
634 int starts = ps.getStarts(which);
635
636 if (userTime != 0 || systemTime != 0 || starts != 0) {
637 dumpLine(pw, uid, category, PROCESS_DATA,
638 ent.getKey(), // proc
639 userTime * 10, // cpu time in ms
640 systemTime * 10, // user time in ms
641 starts); // process starts
642 }
643 }
644 }
645
646 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
647 if (packageStats.size() > 0) {
648 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
649 : packageStats.entrySet()) {
650
651 Uid.Pkg ps = ent.getValue();
652 int wakeups = ps.getWakeups(which);
653 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
654 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
655 : serviceStats.entrySet()) {
656 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
657 long startTime = ss.getStartTime(batteryUptime, which);
658 int starts = ss.getStarts(which);
659 int launches = ss.getLaunches(which);
660 if (startTime != 0 || starts != 0 || launches != 0) {
661 dumpLine(pw, uid, category, APK_DATA,
662 wakeups, // wakeup alarms
663 ent.getKey(), // Apk
664 sent.getKey(), // service
665 startTime / 1000, // time spent started, in ms
666 starts,
667 launches);
668 }
669 }
670 }
671 }
672 }
673 }
674
675 @SuppressWarnings("unused")
676 private final void dumpLocked(Printer pw, String prefix, int which) {
677 final long rawUptime = SystemClock.uptimeMillis() * 1000;
678 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
679 final long batteryUptime = getBatteryUptime(rawUptime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700680 final long batteryRealtime = getBatteryRealtime(rawRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681
682 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
683 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
684 final long totalRealtime = computeRealtime(rawRealtime, which);
685 final long totalUptime = computeUptime(rawUptime, which);
686
687 StringBuilder sb = new StringBuilder(128);
688
689 pw.println(prefix
690 + " Time on battery: " + formatTimeMs(whichBatteryUptime / 1000)
691 + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime)
692 + ") uptime, "
693 + formatTimeMs(whichBatteryRealtime / 1000) + "("
694 + formatRatioLocked(whichBatteryRealtime, totalRealtime)
695 + ") realtime");
696 pw.println(prefix
697 + " Total: "
698 + formatTimeMs(totalUptime / 1000)
699 + "uptime, "
700 + formatTimeMs(totalRealtime / 1000)
701 + "realtime");
702
The Android Open Source Project10592532009-03-18 17:39:46 -0700703 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
704 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700705 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700706 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
707 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 pw.println(prefix
709 + " Time with screen on: " + formatTimeMs(screenOnTime / 1000)
710 + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime)
711 + "), time with phone on: " + formatTimeMs(phoneOnTime / 1000)
The Android Open Source Project10592532009-03-18 17:39:46 -0700712 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime)
713 + "), time with wifi on: " + formatTimeMs(wifiOnTime / 1000)
714 + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime)
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700715 + "), time with wifi running: " + formatTimeMs(wifiRunningTime / 1000)
716 + "(" + formatRatioLocked(wifiRunningTime, whichBatteryRealtime)
The Android Open Source Project10592532009-03-18 17:39:46 -0700717 + "), time with bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000)
718 + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")");
719
720 pw.println(" ");
721
722 if (which == STATS_UNPLUGGED) {
723 if (getIsOnBattery()) {
724 pw.println(prefix + " Device is currently unplugged");
725 pw.println(prefix + " Discharge cycle start level: " +
726 getUnpluggedStartLevel());
727 } else {
728 pw.println(prefix + " Device is currently plugged into power");
729 pw.println(prefix + " Last discharge cycle start level: " +
730 getUnpluggedStartLevel());
731 pw.println(prefix + " Last discharge cycle end level: " +
732 getPluggedStartLevel());
733 }
734 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735
736 pw.println(" ");
737
738 SparseArray<? extends Uid> uidStats = getUidStats();
739 final int NU = uidStats.size();
740 for (int iu=0; iu<NU; iu++) {
741 final int uid = uidStats.keyAt(iu);
742 Uid u = uidStats.valueAt(iu);
743 pw.println(prefix + " #" + uid + ":");
744 boolean uidActivity = false;
745
746 long tcpReceived = u.getTcpBytesReceived(which);
747 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700748 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
749 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800751 if (tcpReceived != 0 || tcpSent != 0) {
752 pw.println(prefix + " Network: " + tcpReceived + " bytes received, "
753 + tcpSent + " bytes sent");
754 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700755 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) {
756 pw.println(prefix + " Full Wifi Lock Time: "
757 + formatTime(fullWifiLockOnTime / 1000)
758 + "(" + formatRatioLocked(fullWifiLockOnTime,
759 whichBatteryRealtime)+ ")");
760 pw.println(prefix + " Scan Wifi Lock Time: "
761 + formatTime(scanWifiLockOnTime / 1000)
762 + "(" + formatRatioLocked(scanWifiLockOnTime,
763 whichBatteryRealtime)+ ")");
764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765
766 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
767 if (wakelocks.size() > 0) {
768 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
769 : wakelocks.entrySet()) {
770 Uid.Wakelock wl = ent.getValue();
771 String linePrefix = ": ";
772 sb.setLength(0);
773 sb.append(prefix);
774 sb.append(" Wake lock ");
775 sb.append(ent.getKey());
776 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
777 "full", which, linePrefix);
778 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
779 "partial", which, linePrefix);
780 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
781 "window", which, linePrefix);
782 if (!linePrefix.equals(": ")) {
783 sb.append(" realtime");
784 } else {
785 sb.append(": (nothing executed)");
786 }
787 pw.println(sb.toString());
788 uidActivity = true;
789 }
790 }
791
792 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
793 if (sensors.size() > 0) {
794 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
795 : sensors.entrySet()) {
796 Uid.Sensor se = ent.getValue();
797 int sensorNumber = ent.getKey();
798 sb.setLength(0);
799 sb.append(prefix);
800 sb.append(" Sensor ");
801 int handle = se.getHandle();
802 if (handle == Uid.Sensor.GPS) {
803 sb.append("GPS");
804 } else {
805 sb.append(handle);
806 }
807 sb.append(": ");
808
809 Timer timer = se.getSensorTime();
810 if (timer != null) {
811 // Convert from microseconds to milliseconds with rounding
812 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
813 int count = timer.getCount(which);
814 //timer.logState();
815 if (totalTime != 0) {
816 sb.append(formatTimeMs(totalTime));
817 sb.append("realtime (");
818 sb.append(count);
819 sb.append(" times)");
820 } else {
821 sb.append("(not used)");
822 }
823 } else {
824 sb.append("(not used)");
825 }
826
827 pw.println(sb.toString());
828 uidActivity = true;
829 }
830 }
831
832 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
833 if (processStats.size() > 0) {
834 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
835 : processStats.entrySet()) {
836 Uid.Proc ps = ent.getValue();
837 long userTime;
838 long systemTime;
839 int starts;
840
841 userTime = ps.getUserTime(which);
842 systemTime = ps.getSystemTime(which);
843 starts = ps.getStarts(which);
844
845 if (userTime != 0 || systemTime != 0 || starts != 0) {
846 pw.println(prefix + " Proc " + ent.getKey() + ":");
847 pw.println(prefix + " CPU: " + formatTime(userTime) + "user + "
848 + formatTime(systemTime) + "kernel");
849 pw.println(prefix + " " + starts + " process starts");
850 uidActivity = true;
851 }
852 }
853 }
854
855 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
856 if (packageStats.size() > 0) {
857 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
858 : packageStats.entrySet()) {
859 pw.println(prefix + " Apk " + ent.getKey() + ":");
860 boolean apkActivity = false;
861 Uid.Pkg ps = ent.getValue();
862 int wakeups = ps.getWakeups(which);
863 if (wakeups != 0) {
864 pw.println(prefix + " " + wakeups + " wakeup alarms");
865 apkActivity = true;
866 }
867 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
868 if (serviceStats.size() > 0) {
869 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
870 : serviceStats.entrySet()) {
871 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
872 long startTime = ss.getStartTime(batteryUptime, which);
873 int starts = ss.getStarts(which);
874 int launches = ss.getLaunches(which);
875 if (startTime != 0 || starts != 0 || launches != 0) {
876 pw.println(prefix + " Service " + sent.getKey() + ":");
877 pw.println(prefix + " Created for: "
878 + formatTimeMs(startTime / 1000)
879 + " uptime");
880 pw.println(prefix + " Starts: " + starts
881 + ", launches: " + launches);
882 apkActivity = true;
883 }
884 }
885 }
886 if (!apkActivity) {
887 pw.println(prefix + " (nothing executed)");
888 }
889 uidActivity = true;
890 }
891 }
892 if (!uidActivity) {
893 pw.println(prefix + " (nothing executed)");
894 }
895 }
896 }
897
898 /**
899 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
900 *
901 * @param pw a Printer to receive the dump output.
902 */
903 @SuppressWarnings("unused")
904 public void dumpLocked(Printer pw) {
905 pw.println("Total Statistics (Current and Historic):");
906 pw.println(" System starts: " + getStartCount()
907 + ", currently on battery: " + getIsOnBattery());
908 dumpLocked(pw, "", STATS_TOTAL);
909 pw.println("");
910 pw.println("Last Run Statistics (Previous run of system):");
911 dumpLocked(pw, "", STATS_LAST);
912 pw.println("");
913 pw.println("Current Battery Statistics (Currently running system):");
914 dumpLocked(pw, "", STATS_CURRENT);
915 pw.println("");
916 pw.println("Unplugged Statistics (Since last unplugged from power):");
917 dumpLocked(pw, "", STATS_UNPLUGGED);
918 }
919
920 @SuppressWarnings("unused")
921 public void dumpCheckinLocked(PrintWriter pw, String[] args) {
922 boolean isUnpluggedOnly = false;
923
924 for (String arg : args) {
925 if ("-u".equals(arg)) {
926 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
927 isUnpluggedOnly = true;
928 }
929 }
930
931 if (isUnpluggedOnly) {
932 dumpCheckinLocked(pw, STATS_UNPLUGGED);
933 }
934 else {
935 dumpCheckinLocked(pw, STATS_TOTAL);
936 dumpCheckinLocked(pw, STATS_LAST);
937 dumpCheckinLocked(pw, STATS_UNPLUGGED);
938 dumpCheckinLocked(pw, STATS_CURRENT);
939 }
940 }
941
942}