blob: 76c74df27838ae2fa075ee7d9be4c26745675ccb [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);
295
296 /**
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);
303
304 /**
305 * Returns the time in milliseconds that bluetooth has been on while the device was
306 * running on battery.
307 *
308 * {@hide}
309 */
310 public abstract long getBluetoothOnTime(long batteryRealtime, int which);
311
312 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 * Return whether we are currently running on battery.
314 */
315 public abstract boolean getIsOnBattery();
316
317 /**
318 * Returns a SparseArray containing the statistics for each uid.
319 */
320 public abstract SparseArray<? extends Uid> getUidStats();
321
322 /**
323 * Returns the current battery uptime in microseconds.
324 *
325 * @param curTime the amount of elapsed realtime in microseconds.
326 */
327 public abstract long getBatteryUptime(long curTime);
328
329 /**
330 * Returns the current battery realtime in microseconds.
331 *
332 * @param curTime the amount of elapsed realtime in microseconds.
333 */
334 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700335
336 /**
337 * Returns the battery percentage level at the last time the device was unplugged from power,
338 * or the last time it was booted while unplugged.
339 */
340 public abstract int getUnpluggedStartLevel();
341
342 /**
343 * Returns the battery percentage level at the last time the device was plugged into power.
344 */
345 public abstract int getPluggedStartLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346
347 /**
348 * Returns the total, last, or current battery uptime in microseconds.
349 *
350 * @param curTime the elapsed realtime in microseconds.
351 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
352 */
353 public abstract long computeBatteryUptime(long curTime, int which);
354
355 /**
356 * Returns the total, last, or current battery realtime in microseconds.
357 *
358 * @param curTime the current elapsed realtime in microseconds.
359 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
360 */
361 public abstract long computeBatteryRealtime(long curTime, int which);
362
363 /**
364 * Returns the total, last, or current uptime 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 computeUptime(long curTime, int which);
370
371 /**
372 * Returns the total, last, or current realtime 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 computeRealtime(long curTime, int which);
378
379 private final static void formatTime(StringBuilder out, long seconds) {
380 long days = seconds / (60 * 60 * 24);
381 if (days != 0) {
382 out.append(days);
383 out.append("d ");
384 }
385 long used = days * 60 * 60 * 24;
386
387 long hours = (seconds - used) / (60 * 60);
388 if (hours != 0 || used != 0) {
389 out.append(hours);
390 out.append("h ");
391 }
392 used += hours * 60 * 60;
393
394 long mins = (seconds-used) / 60;
395 if (mins != 0 || used != 0) {
396 out.append(mins);
397 out.append("m ");
398 }
399 used += mins * 60;
400
401 if (seconds != 0 || used != 0) {
402 out.append(seconds-used);
403 out.append("s ");
404 }
405 }
406
407 private final static String formatTime(long time) {
408 long sec = time / 100;
409 StringBuilder sb = new StringBuilder();
410 formatTime(sb, sec);
411 sb.append((time - (sec * 100)) * 10);
412 sb.append("ms ");
413 return sb.toString();
414 }
415
416 private final static String formatTimeMs(long time) {
417 long sec = time / 1000;
418 StringBuilder sb = new StringBuilder();
419 formatTime(sb, sec);
420 sb.append(time - (sec * 1000));
421 sb.append("ms ");
422 return sb.toString();
423 }
424
425 private final String formatRatioLocked(long num, long den) {
426 if (den == 0L) {
427 return "---%";
428 }
429 float perc = ((float)num) / ((float)den) * 100;
430 mFormatBuilder.setLength(0);
431 mFormatter.format("%.1f%%", perc);
432 return mFormatBuilder.toString();
433 }
434
435 /**
436 *
437 * @param sb a StringBuilder object.
438 * @param timer a Timer object contining the wakelock times.
439 * @param batteryRealtime the current on-battery time in microseconds.
440 * @param name the name of the wakelock.
441 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
442 * @param linePrefix a String to be prepended to each line of output.
443 * @return the line prefix
444 */
445 private static final String printWakeLock(StringBuilder sb, Timer timer,
446 long batteryRealtime, String name, int which, String linePrefix) {
447
448 if (timer != null) {
449 // Convert from microseconds to milliseconds with rounding
450 long totalTimeMicros = timer.getTotalTime(batteryRealtime, which);
451 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
452
453 int count = timer.getCount(which);
454 if (totalTimeMillis != 0) {
455 sb.append(linePrefix);
456 sb.append(formatTimeMs(totalTimeMillis));
457 sb.append(name);
458 sb.append(' ');
459 sb.append('(');
460 sb.append(count);
461 sb.append(" times)");
462 return ", ";
463 }
464 }
465 return linePrefix;
466 }
467
468 /**
469 * Checkin version of wakelock printer. Prints simple comma-separated list.
470 *
471 * @param sb a StringBuilder object.
472 * @param timer a Timer object contining the wakelock times.
473 * @param now the current time in microseconds.
474 * @param name the name of the wakelock.
475 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
476 * @param linePrefix a String to be prepended to each line of output.
477 * @return the line prefix
478 */
479 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
480 String name, int which, String linePrefix) {
481 long totalTimeMicros = 0;
482 int count = 0;
483 if (timer != null) {
484 totalTimeMicros = timer.getTotalTime(now, which);
485 count = timer.getCount(which);
486 }
487 sb.append(linePrefix);
488 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
489 sb.append(',');
490 sb.append(name);
491 sb.append(',');
492 sb.append(count);
493 return ",";
494 }
495
496 /**
497 * Dump a comma-separated line of values for terse checkin mode.
498 *
499 * @param pw the PageWriter to dump log to
500 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
501 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
502 * @param args type-dependent data arguments
503 */
504 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
505 Object... args ) {
506 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
507 pw.print(uid); pw.print(',');
508 pw.print(category); pw.print(',');
509 pw.print(type);
510
511 for (Object arg : args) {
512 pw.print(',');
513 pw.print(arg);
514 }
515 pw.print('\n');
516 }
517
518 /**
519 * Checkin server version of dump to produce more compact, computer-readable log.
520 *
521 * NOTE: all times are expressed in 'ms'.
522 * @param fd
523 * @param pw
524 * @param which
525 */
526 private final void dumpCheckinLocked(PrintWriter pw, int which) {
527 final long rawUptime = SystemClock.uptimeMillis() * 1000;
528 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
529 final long batteryUptime = getBatteryUptime(rawUptime);
530 final long batteryRealtime = getBatteryRealtime(rawRealtime);
531 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
532 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
533 final long totalRealtime = computeRealtime(rawRealtime, which);
534 final long totalUptime = computeUptime(rawUptime, which);
535 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
536 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700537 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
538 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800539
540 StringBuilder sb = new StringBuilder(128);
541
542 String category = STAT_NAMES[which];
543
544 // Dump "battery" stat
545 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
546 which == STATS_TOTAL ? getStartCount() : "N/A",
547 whichBatteryUptime / 1000, whichBatteryRealtime / 1000,
548 totalUptime / 1000, totalRealtime / 1000);
549
550 // Dump misc stats
551 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
The Android Open Source Project10592532009-03-18 17:39:46 -0700552 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, bluetoothOnTime / 1000);
553
554 if (which == STATS_UNPLUGGED) {
555 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, getUnpluggedStartLevel(),
556 getPluggedStartLevel());
557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558
559 SparseArray<? extends Uid> uidStats = getUidStats();
560 final int NU = uidStats.size();
561 for (int iu = 0; iu < NU; iu++) {
562 final int uid = uidStats.keyAt(iu);
563 Uid u = uidStats.valueAt(iu);
564 // Dump Network stats per uid, if any
565 long rx = u.getTcpBytesReceived(which);
566 long tx = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700567 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
568 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -0700571
572 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) {
573 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
574 fullWifiLockOnTime, scanWifiLockOnTime);
575 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576
577 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
578 if (wakelocks.size() > 0) {
579 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
580 : wakelocks.entrySet()) {
581 Uid.Wakelock wl = ent.getValue();
582 String linePrefix = "";
583 sb.setLength(0);
584 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
585 "full", which, linePrefix);
586 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
587 "partial", which, linePrefix);
588 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
589 "window", which, linePrefix);
590
591 // Only log if we had at lease one wakelock...
592 if (sb.length() > 0) {
593 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
594 }
595 }
596 }
597
598 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
599 if (sensors.size() > 0) {
600 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
601 : sensors.entrySet()) {
602 Uid.Sensor se = ent.getValue();
603 int sensorNumber = ent.getKey();
604 Timer timer = se.getSensorTime();
605 if (timer != null) {
606 // Convert from microseconds to milliseconds with rounding
607 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
608 int count = timer.getCount(which);
609 if (totalTime != 0) {
610 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
611 }
612 }
613 }
614 }
615
616 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
617 if (processStats.size() > 0) {
618 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
619 : processStats.entrySet()) {
620 Uid.Proc ps = ent.getValue();
621
622 long userTime = ps.getUserTime(which);
623 long systemTime = ps.getSystemTime(which);
624 int starts = ps.getStarts(which);
625
626 if (userTime != 0 || systemTime != 0 || starts != 0) {
627 dumpLine(pw, uid, category, PROCESS_DATA,
628 ent.getKey(), // proc
629 userTime * 10, // cpu time in ms
630 systemTime * 10, // user time in ms
631 starts); // process starts
632 }
633 }
634 }
635
636 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
637 if (packageStats.size() > 0) {
638 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
639 : packageStats.entrySet()) {
640
641 Uid.Pkg ps = ent.getValue();
642 int wakeups = ps.getWakeups(which);
643 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
644 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
645 : serviceStats.entrySet()) {
646 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
647 long startTime = ss.getStartTime(batteryUptime, which);
648 int starts = ss.getStarts(which);
649 int launches = ss.getLaunches(which);
650 if (startTime != 0 || starts != 0 || launches != 0) {
651 dumpLine(pw, uid, category, APK_DATA,
652 wakeups, // wakeup alarms
653 ent.getKey(), // Apk
654 sent.getKey(), // service
655 startTime / 1000, // time spent started, in ms
656 starts,
657 launches);
658 }
659 }
660 }
661 }
662 }
663 }
664
665 @SuppressWarnings("unused")
666 private final void dumpLocked(Printer pw, String prefix, int which) {
667 final long rawUptime = SystemClock.uptimeMillis() * 1000;
668 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
669 final long batteryUptime = getBatteryUptime(rawUptime);
670 final long batteryRealtime = getBatteryUptime(rawRealtime);
671
672 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
673 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
674 final long totalRealtime = computeRealtime(rawRealtime, which);
675 final long totalUptime = computeUptime(rawUptime, which);
676
677 StringBuilder sb = new StringBuilder(128);
678
679 pw.println(prefix
680 + " Time on battery: " + formatTimeMs(whichBatteryUptime / 1000)
681 + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime)
682 + ") uptime, "
683 + formatTimeMs(whichBatteryRealtime / 1000) + "("
684 + formatRatioLocked(whichBatteryRealtime, totalRealtime)
685 + ") realtime");
686 pw.println(prefix
687 + " Total: "
688 + formatTimeMs(totalUptime / 1000)
689 + "uptime, "
690 + formatTimeMs(totalRealtime / 1000)
691 + "realtime");
692
The Android Open Source Project10592532009-03-18 17:39:46 -0700693 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
694 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
695 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
696 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800697 pw.println(prefix
698 + " Time with screen on: " + formatTimeMs(screenOnTime / 1000)
699 + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime)
700 + "), time with phone on: " + formatTimeMs(phoneOnTime / 1000)
The Android Open Source Project10592532009-03-18 17:39:46 -0700701 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime)
702 + "), time with wifi on: " + formatTimeMs(wifiOnTime / 1000)
703 + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime)
704 + "), time with bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000)
705 + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")");
706
707 pw.println(" ");
708
709 if (which == STATS_UNPLUGGED) {
710 if (getIsOnBattery()) {
711 pw.println(prefix + " Device is currently unplugged");
712 pw.println(prefix + " Discharge cycle start level: " +
713 getUnpluggedStartLevel());
714 } else {
715 pw.println(prefix + " Device is currently plugged into power");
716 pw.println(prefix + " Last discharge cycle start level: " +
717 getUnpluggedStartLevel());
718 pw.println(prefix + " Last discharge cycle end level: " +
719 getPluggedStartLevel());
720 }
721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722
723 pw.println(" ");
724
725 SparseArray<? extends Uid> uidStats = getUidStats();
726 final int NU = uidStats.size();
727 for (int iu=0; iu<NU; iu++) {
728 final int uid = uidStats.keyAt(iu);
729 Uid u = uidStats.valueAt(iu);
730 pw.println(prefix + " #" + uid + ":");
731 boolean uidActivity = false;
732
733 long tcpReceived = u.getTcpBytesReceived(which);
734 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700735 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
736 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 if (tcpReceived != 0 || tcpSent != 0) {
739 pw.println(prefix + " Network: " + tcpReceived + " bytes received, "
740 + tcpSent + " bytes sent");
741 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700742 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) {
743 pw.println(prefix + " Full Wifi Lock Time: "
744 + formatTime(fullWifiLockOnTime / 1000)
745 + "(" + formatRatioLocked(fullWifiLockOnTime,
746 whichBatteryRealtime)+ ")");
747 pw.println(prefix + " Scan Wifi Lock Time: "
748 + formatTime(scanWifiLockOnTime / 1000)
749 + "(" + formatRatioLocked(scanWifiLockOnTime,
750 whichBatteryRealtime)+ ")");
751 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752
753 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
754 if (wakelocks.size() > 0) {
755 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
756 : wakelocks.entrySet()) {
757 Uid.Wakelock wl = ent.getValue();
758 String linePrefix = ": ";
759 sb.setLength(0);
760 sb.append(prefix);
761 sb.append(" Wake lock ");
762 sb.append(ent.getKey());
763 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
764 "full", which, linePrefix);
765 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
766 "partial", which, linePrefix);
767 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
768 "window", which, linePrefix);
769 if (!linePrefix.equals(": ")) {
770 sb.append(" realtime");
771 } else {
772 sb.append(": (nothing executed)");
773 }
774 pw.println(sb.toString());
775 uidActivity = true;
776 }
777 }
778
779 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
780 if (sensors.size() > 0) {
781 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
782 : sensors.entrySet()) {
783 Uid.Sensor se = ent.getValue();
784 int sensorNumber = ent.getKey();
785 sb.setLength(0);
786 sb.append(prefix);
787 sb.append(" Sensor ");
788 int handle = se.getHandle();
789 if (handle == Uid.Sensor.GPS) {
790 sb.append("GPS");
791 } else {
792 sb.append(handle);
793 }
794 sb.append(": ");
795
796 Timer timer = se.getSensorTime();
797 if (timer != null) {
798 // Convert from microseconds to milliseconds with rounding
799 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
800 int count = timer.getCount(which);
801 //timer.logState();
802 if (totalTime != 0) {
803 sb.append(formatTimeMs(totalTime));
804 sb.append("realtime (");
805 sb.append(count);
806 sb.append(" times)");
807 } else {
808 sb.append("(not used)");
809 }
810 } else {
811 sb.append("(not used)");
812 }
813
814 pw.println(sb.toString());
815 uidActivity = true;
816 }
817 }
818
819 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
820 if (processStats.size() > 0) {
821 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
822 : processStats.entrySet()) {
823 Uid.Proc ps = ent.getValue();
824 long userTime;
825 long systemTime;
826 int starts;
827
828 userTime = ps.getUserTime(which);
829 systemTime = ps.getSystemTime(which);
830 starts = ps.getStarts(which);
831
832 if (userTime != 0 || systemTime != 0 || starts != 0) {
833 pw.println(prefix + " Proc " + ent.getKey() + ":");
834 pw.println(prefix + " CPU: " + formatTime(userTime) + "user + "
835 + formatTime(systemTime) + "kernel");
836 pw.println(prefix + " " + starts + " process starts");
837 uidActivity = true;
838 }
839 }
840 }
841
842 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
843 if (packageStats.size() > 0) {
844 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
845 : packageStats.entrySet()) {
846 pw.println(prefix + " Apk " + ent.getKey() + ":");
847 boolean apkActivity = false;
848 Uid.Pkg ps = ent.getValue();
849 int wakeups = ps.getWakeups(which);
850 if (wakeups != 0) {
851 pw.println(prefix + " " + wakeups + " wakeup alarms");
852 apkActivity = true;
853 }
854 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
855 if (serviceStats.size() > 0) {
856 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
857 : serviceStats.entrySet()) {
858 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
859 long startTime = ss.getStartTime(batteryUptime, which);
860 int starts = ss.getStarts(which);
861 int launches = ss.getLaunches(which);
862 if (startTime != 0 || starts != 0 || launches != 0) {
863 pw.println(prefix + " Service " + sent.getKey() + ":");
864 pw.println(prefix + " Created for: "
865 + formatTimeMs(startTime / 1000)
866 + " uptime");
867 pw.println(prefix + " Starts: " + starts
868 + ", launches: " + launches);
869 apkActivity = true;
870 }
871 }
872 }
873 if (!apkActivity) {
874 pw.println(prefix + " (nothing executed)");
875 }
876 uidActivity = true;
877 }
878 }
879 if (!uidActivity) {
880 pw.println(prefix + " (nothing executed)");
881 }
882 }
883 }
884
885 /**
886 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
887 *
888 * @param pw a Printer to receive the dump output.
889 */
890 @SuppressWarnings("unused")
891 public void dumpLocked(Printer pw) {
892 pw.println("Total Statistics (Current and Historic):");
893 pw.println(" System starts: " + getStartCount()
894 + ", currently on battery: " + getIsOnBattery());
895 dumpLocked(pw, "", STATS_TOTAL);
896 pw.println("");
897 pw.println("Last Run Statistics (Previous run of system):");
898 dumpLocked(pw, "", STATS_LAST);
899 pw.println("");
900 pw.println("Current Battery Statistics (Currently running system):");
901 dumpLocked(pw, "", STATS_CURRENT);
902 pw.println("");
903 pw.println("Unplugged Statistics (Since last unplugged from power):");
904 dumpLocked(pw, "", STATS_UNPLUGGED);
905 }
906
907 @SuppressWarnings("unused")
908 public void dumpCheckinLocked(PrintWriter pw, String[] args) {
909 boolean isUnpluggedOnly = false;
910
911 for (String arg : args) {
912 if ("-u".equals(arg)) {
913 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
914 isUnpluggedOnly = true;
915 }
916 }
917
918 if (isUnpluggedOnly) {
919 dumpCheckinLocked(pw, STATS_UNPLUGGED);
920 }
921 else {
922 dumpCheckinLocked(pw, STATS_TOTAL);
923 dumpCheckinLocked(pw, STATS_LAST);
924 dumpCheckinLocked(pw, STATS_UNPLUGGED);
925 dumpCheckinLocked(pw, STATS_CURRENT);
926 }
927 }
928
929}