blob: 7590bfef4535559615ba810bdd9f9e28a9f26640 [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;
42
43 /**
44 * Include all of the data in the stats, including previously saved data.
45 */
46 public static final int STATS_TOTAL = 0;
47
48 /**
49 * Include only the last run in the stats.
50 */
51 public static final int STATS_LAST = 1;
52
53 /**
54 * Include only the current run in the stats.
55 */
56 public static final int STATS_CURRENT = 2;
57
58 /**
59 * Include only the run since the last time the device was unplugged in the stats.
60 */
61 public static final int STATS_UNPLUGGED = 3;
62
63 /**
64 * Bump the version on this if the checkin format changes.
65 */
66 private static final int BATTERY_STATS_CHECKIN_VERSION = 1;
67
68 // TODO: Update this list if you add/change any stats above.
69 private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" };
70
71 private static final String APK_DATA = "apk";
72 private static final String PROCESS_DATA = "process";
73 private static final String SENSOR_DATA = "sensor";
74 private static final String WAKELOCK_DATA = "wakelock";
75 private static final String NETWORK_DATA = "network";
76 private static final String BATTERY_DATA = "battery";
77 private static final String MISC_DATA = "misc";
78
79 private final StringBuilder mFormatBuilder = new StringBuilder(8);
80 private final Formatter mFormatter = new Formatter(mFormatBuilder);
81
82 /**
83 * State for keeping track of timing information.
84 */
85 public static abstract class Timer {
86
87 /**
88 * Returns the count associated with this Timer for the
89 * selected type of statistics.
90 *
91 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
92 */
93 public abstract int getCount(int which);
94
95 /**
96 * Returns the total time in microseconds associated with this Timer for the
97 * selected type of statistics.
98 *
99 * @param batteryRealtime system realtime on battery in microseconds
100 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
101 * @return a time in microseconds
102 */
103 public abstract long getTotalTime(long batteryRealtime, int which);
104
105 /**
106 * Temporary for debugging.
107 */
108 public abstract void logState();
109 }
110
111 /**
112 * The statistics associated with a particular uid.
113 */
114 public static abstract class Uid {
115
116 /**
117 * Returns a mapping containing wakelock statistics.
118 *
119 * @return a Map from Strings to Uid.Wakelock objects.
120 */
121 public abstract Map<String, ? extends Wakelock> getWakelockStats();
122
123 /**
124 * The statistics associated with a particular wake lock.
125 */
126 public static abstract class Wakelock {
127 public abstract Timer getWakeTime(int type);
128 }
129
130 /**
131 * Returns a mapping containing sensor statistics.
132 *
133 * @return a Map from Integer sensor ids to Uid.Sensor objects.
134 */
135 public abstract Map<Integer, ? extends Sensor> getSensorStats();
136
137 /**
138 * Returns a mapping containing process statistics.
139 *
140 * @return a Map from Strings to Uid.Proc objects.
141 */
142 public abstract Map<String, ? extends Proc> getProcessStats();
143
144 /**
145 * Returns a mapping containing package statistics.
146 *
147 * @return a Map from Strings to Uid.Pkg objects.
148 */
149 public abstract Map<String, ? extends Pkg> getPackageStats();
150
151 /**
152 * {@hide}
153 */
154 public abstract int getUid();
155
156 /**
157 * {@hide}
158 */
159 public abstract long getTcpBytesReceived(int which);
160
161 /**
162 * {@hide}
163 */
164 public abstract long getTcpBytesSent(int which);
165
166 public static abstract class Sensor {
167 // Magic sensor number for the GPS.
168 public static final int GPS = -10000;
169
170 public abstract int getHandle();
171
172 public abstract Timer getSensorTime();
173 }
174
175 /**
176 * The statistics associated with a particular process.
177 */
178 public static abstract class Proc {
179
180 /**
181 * Returns the total time (in 1/100 sec) spent executing in user code.
182 *
183 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
184 */
185 public abstract long getUserTime(int which);
186
187 /**
188 * Returns the total time (in 1/100 sec) spent executing in system code.
189 *
190 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
191 */
192 public abstract long getSystemTime(int which);
193
194 /**
195 * Returns the number of times the process has been started.
196 *
197 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
198 */
199 public abstract int getStarts(int which);
200 }
201
202 /**
203 * The statistics associated with a particular package.
204 */
205 public static abstract class Pkg {
206
207 /**
208 * Returns the number of times this package has done something that could wake up the
209 * device from sleep.
210 *
211 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
212 */
213 public abstract int getWakeups(int which);
214
215 /**
216 * Returns a mapping containing service statistics.
217 */
218 public abstract Map<String, ? extends Serv> getServiceStats();
219
220 /**
221 * The statistics associated with a particular service.
222 */
223 public abstract class Serv {
224
225 /**
226 * Returns the amount of time spent started.
227 *
228 * @param batteryUptime elapsed uptime on battery in microseconds.
229 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
230 * @return
231 */
232 public abstract long getStartTime(long batteryUptime, int which);
233
234 /**
235 * Returns the total number of times startService() has been called.
236 *
237 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
238 */
239 public abstract int getStarts(int which);
240
241 /**
242 * Returns the total number times the service has been launched.
243 *
244 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
245 */
246 public abstract int getLaunches(int which);
247 }
248 }
249 }
250
251 /**
252 * Returns the number of times the device has been started.
253 */
254 public abstract int getStartCount();
255
256 /**
257 * Returns the time in milliseconds that the screen has been on while the device was
258 * running on battery.
259 *
260 * {@hide}
261 */
262 public abstract long getScreenOnTime(long batteryRealtime, int which);
263
264 /**
265 * Returns the time in milliseconds that the phone has been on while the device was
266 * running on battery.
267 *
268 * {@hide}
269 */
270 public abstract long getPhoneOnTime(long batteryRealtime, int which);
271
272 /**
273 * Return whether we are currently running on battery.
274 */
275 public abstract boolean getIsOnBattery();
276
277 /**
278 * Returns a SparseArray containing the statistics for each uid.
279 */
280 public abstract SparseArray<? extends Uid> getUidStats();
281
282 /**
283 * Returns the current battery uptime in microseconds.
284 *
285 * @param curTime the amount of elapsed realtime in microseconds.
286 */
287 public abstract long getBatteryUptime(long curTime);
288
289 /**
290 * Returns the current battery realtime in microseconds.
291 *
292 * @param curTime the amount of elapsed realtime in microseconds.
293 */
294 public abstract long getBatteryRealtime(long curTime);
295
296 /**
297 * Returns the total, last, or current battery uptime in microseconds.
298 *
299 * @param curTime the elapsed realtime in microseconds.
300 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
301 */
302 public abstract long computeBatteryUptime(long curTime, int which);
303
304 /**
305 * Returns the total, last, or current battery realtime in microseconds.
306 *
307 * @param curTime the current elapsed realtime in microseconds.
308 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
309 */
310 public abstract long computeBatteryRealtime(long curTime, int which);
311
312 /**
313 * Returns the total, last, or current uptime in microseconds.
314 *
315 * @param curTime the current elapsed realtime in microseconds.
316 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
317 */
318 public abstract long computeUptime(long curTime, int which);
319
320 /**
321 * Returns the total, last, or current realtime in microseconds.
322 * *
323 * @param curTime the current elapsed realtime in microseconds.
324 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
325 */
326 public abstract long computeRealtime(long curTime, int which);
327
328 private final static void formatTime(StringBuilder out, long seconds) {
329 long days = seconds / (60 * 60 * 24);
330 if (days != 0) {
331 out.append(days);
332 out.append("d ");
333 }
334 long used = days * 60 * 60 * 24;
335
336 long hours = (seconds - used) / (60 * 60);
337 if (hours != 0 || used != 0) {
338 out.append(hours);
339 out.append("h ");
340 }
341 used += hours * 60 * 60;
342
343 long mins = (seconds-used) / 60;
344 if (mins != 0 || used != 0) {
345 out.append(mins);
346 out.append("m ");
347 }
348 used += mins * 60;
349
350 if (seconds != 0 || used != 0) {
351 out.append(seconds-used);
352 out.append("s ");
353 }
354 }
355
356 private final static String formatTime(long time) {
357 long sec = time / 100;
358 StringBuilder sb = new StringBuilder();
359 formatTime(sb, sec);
360 sb.append((time - (sec * 100)) * 10);
361 sb.append("ms ");
362 return sb.toString();
363 }
364
365 private final static String formatTimeMs(long time) {
366 long sec = time / 1000;
367 StringBuilder sb = new StringBuilder();
368 formatTime(sb, sec);
369 sb.append(time - (sec * 1000));
370 sb.append("ms ");
371 return sb.toString();
372 }
373
374 private final String formatRatioLocked(long num, long den) {
375 if (den == 0L) {
376 return "---%";
377 }
378 float perc = ((float)num) / ((float)den) * 100;
379 mFormatBuilder.setLength(0);
380 mFormatter.format("%.1f%%", perc);
381 return mFormatBuilder.toString();
382 }
383
384 /**
385 *
386 * @param sb a StringBuilder object.
387 * @param timer a Timer object contining the wakelock times.
388 * @param batteryRealtime the current on-battery time in microseconds.
389 * @param name the name of the wakelock.
390 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
391 * @param linePrefix a String to be prepended to each line of output.
392 * @return the line prefix
393 */
394 private static final String printWakeLock(StringBuilder sb, Timer timer,
395 long batteryRealtime, String name, int which, String linePrefix) {
396
397 if (timer != null) {
398 // Convert from microseconds to milliseconds with rounding
399 long totalTimeMicros = timer.getTotalTime(batteryRealtime, which);
400 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
401
402 int count = timer.getCount(which);
403 if (totalTimeMillis != 0) {
404 sb.append(linePrefix);
405 sb.append(formatTimeMs(totalTimeMillis));
406 sb.append(name);
407 sb.append(' ');
408 sb.append('(');
409 sb.append(count);
410 sb.append(" times)");
411 return ", ";
412 }
413 }
414 return linePrefix;
415 }
416
417 /**
418 * Checkin version of wakelock printer. Prints simple comma-separated list.
419 *
420 * @param sb a StringBuilder object.
421 * @param timer a Timer object contining the wakelock times.
422 * @param now the current time in microseconds.
423 * @param name the name of the wakelock.
424 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
425 * @param linePrefix a String to be prepended to each line of output.
426 * @return the line prefix
427 */
428 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
429 String name, int which, String linePrefix) {
430 long totalTimeMicros = 0;
431 int count = 0;
432 if (timer != null) {
433 totalTimeMicros = timer.getTotalTime(now, which);
434 count = timer.getCount(which);
435 }
436 sb.append(linePrefix);
437 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
438 sb.append(',');
439 sb.append(name);
440 sb.append(',');
441 sb.append(count);
442 return ",";
443 }
444
445 /**
446 * Dump a comma-separated line of values for terse checkin mode.
447 *
448 * @param pw the PageWriter to dump log to
449 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
450 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
451 * @param args type-dependent data arguments
452 */
453 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
454 Object... args ) {
455 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
456 pw.print(uid); pw.print(',');
457 pw.print(category); pw.print(',');
458 pw.print(type);
459
460 for (Object arg : args) {
461 pw.print(',');
462 pw.print(arg);
463 }
464 pw.print('\n');
465 }
466
467 /**
468 * Checkin server version of dump to produce more compact, computer-readable log.
469 *
470 * NOTE: all times are expressed in 'ms'.
471 * @param fd
472 * @param pw
473 * @param which
474 */
475 private final void dumpCheckinLocked(PrintWriter pw, int which) {
476 final long rawUptime = SystemClock.uptimeMillis() * 1000;
477 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
478 final long batteryUptime = getBatteryUptime(rawUptime);
479 final long batteryRealtime = getBatteryRealtime(rawRealtime);
480 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
481 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
482 final long totalRealtime = computeRealtime(rawRealtime, which);
483 final long totalUptime = computeUptime(rawUptime, which);
484 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
485 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
486
487 StringBuilder sb = new StringBuilder(128);
488
489 String category = STAT_NAMES[which];
490
491 // Dump "battery" stat
492 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
493 which == STATS_TOTAL ? getStartCount() : "N/A",
494 whichBatteryUptime / 1000, whichBatteryRealtime / 1000,
495 totalUptime / 1000, totalRealtime / 1000);
496
497 // Dump misc stats
498 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
499 screenOnTime / 1000, phoneOnTime / 1000);
500
501 SparseArray<? extends Uid> uidStats = getUidStats();
502 final int NU = uidStats.size();
503 for (int iu = 0; iu < NU; iu++) {
504 final int uid = uidStats.keyAt(iu);
505 Uid u = uidStats.valueAt(iu);
506 // Dump Network stats per uid, if any
507 long rx = u.getTcpBytesReceived(which);
508 long tx = u.getTcpBytesSent(which);
509 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
510
511 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
512 if (wakelocks.size() > 0) {
513 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
514 : wakelocks.entrySet()) {
515 Uid.Wakelock wl = ent.getValue();
516 String linePrefix = "";
517 sb.setLength(0);
518 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
519 "full", which, linePrefix);
520 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
521 "partial", which, linePrefix);
522 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
523 "window", which, linePrefix);
524
525 // Only log if we had at lease one wakelock...
526 if (sb.length() > 0) {
527 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
528 }
529 }
530 }
531
532 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
533 if (sensors.size() > 0) {
534 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
535 : sensors.entrySet()) {
536 Uid.Sensor se = ent.getValue();
537 int sensorNumber = ent.getKey();
538 Timer timer = se.getSensorTime();
539 if (timer != null) {
540 // Convert from microseconds to milliseconds with rounding
541 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
542 int count = timer.getCount(which);
543 if (totalTime != 0) {
544 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
545 }
546 }
547 }
548 }
549
550 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
551 if (processStats.size() > 0) {
552 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
553 : processStats.entrySet()) {
554 Uid.Proc ps = ent.getValue();
555
556 long userTime = ps.getUserTime(which);
557 long systemTime = ps.getSystemTime(which);
558 int starts = ps.getStarts(which);
559
560 if (userTime != 0 || systemTime != 0 || starts != 0) {
561 dumpLine(pw, uid, category, PROCESS_DATA,
562 ent.getKey(), // proc
563 userTime * 10, // cpu time in ms
564 systemTime * 10, // user time in ms
565 starts); // process starts
566 }
567 }
568 }
569
570 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
571 if (packageStats.size() > 0) {
572 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
573 : packageStats.entrySet()) {
574
575 Uid.Pkg ps = ent.getValue();
576 int wakeups = ps.getWakeups(which);
577 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
578 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
579 : serviceStats.entrySet()) {
580 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
581 long startTime = ss.getStartTime(batteryUptime, which);
582 int starts = ss.getStarts(which);
583 int launches = ss.getLaunches(which);
584 if (startTime != 0 || starts != 0 || launches != 0) {
585 dumpLine(pw, uid, category, APK_DATA,
586 wakeups, // wakeup alarms
587 ent.getKey(), // Apk
588 sent.getKey(), // service
589 startTime / 1000, // time spent started, in ms
590 starts,
591 launches);
592 }
593 }
594 }
595 }
596 }
597 }
598
599 @SuppressWarnings("unused")
600 private final void dumpLocked(Printer pw, String prefix, int which) {
601 final long rawUptime = SystemClock.uptimeMillis() * 1000;
602 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
603 final long batteryUptime = getBatteryUptime(rawUptime);
604 final long batteryRealtime = getBatteryUptime(rawRealtime);
605
606 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
607 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
608 final long totalRealtime = computeRealtime(rawRealtime, which);
609 final long totalUptime = computeUptime(rawUptime, which);
610
611 StringBuilder sb = new StringBuilder(128);
612
613 pw.println(prefix
614 + " Time on battery: " + formatTimeMs(whichBatteryUptime / 1000)
615 + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime)
616 + ") uptime, "
617 + formatTimeMs(whichBatteryRealtime / 1000) + "("
618 + formatRatioLocked(whichBatteryRealtime, totalRealtime)
619 + ") realtime");
620 pw.println(prefix
621 + " Total: "
622 + formatTimeMs(totalUptime / 1000)
623 + "uptime, "
624 + formatTimeMs(totalRealtime / 1000)
625 + "realtime");
626
627 long screenOnTime = getScreenOnTime(batteryRealtime, which);
628 long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
629 pw.println(prefix
630 + " Time with screen on: " + formatTimeMs(screenOnTime / 1000)
631 + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime)
632 + "), time with phone on: " + formatTimeMs(phoneOnTime / 1000)
633 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime) + ")");
634
635 pw.println(" ");
636
637 SparseArray<? extends Uid> uidStats = getUidStats();
638 final int NU = uidStats.size();
639 for (int iu=0; iu<NU; iu++) {
640 final int uid = uidStats.keyAt(iu);
641 Uid u = uidStats.valueAt(iu);
642 pw.println(prefix + " #" + uid + ":");
643 boolean uidActivity = false;
644
645 long tcpReceived = u.getTcpBytesReceived(which);
646 long tcpSent = u.getTcpBytesSent(which);
647 if (tcpReceived != 0 || tcpSent != 0) {
648 pw.println(prefix + " Network: " + tcpReceived + " bytes received, "
649 + tcpSent + " bytes sent");
650 }
651
652 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
653 if (wakelocks.size() > 0) {
654 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
655 : wakelocks.entrySet()) {
656 Uid.Wakelock wl = ent.getValue();
657 String linePrefix = ": ";
658 sb.setLength(0);
659 sb.append(prefix);
660 sb.append(" Wake lock ");
661 sb.append(ent.getKey());
662 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
663 "full", which, linePrefix);
664 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
665 "partial", which, linePrefix);
666 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
667 "window", which, linePrefix);
668 if (!linePrefix.equals(": ")) {
669 sb.append(" realtime");
670 } else {
671 sb.append(": (nothing executed)");
672 }
673 pw.println(sb.toString());
674 uidActivity = true;
675 }
676 }
677
678 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
679 if (sensors.size() > 0) {
680 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
681 : sensors.entrySet()) {
682 Uid.Sensor se = ent.getValue();
683 int sensorNumber = ent.getKey();
684 sb.setLength(0);
685 sb.append(prefix);
686 sb.append(" Sensor ");
687 int handle = se.getHandle();
688 if (handle == Uid.Sensor.GPS) {
689 sb.append("GPS");
690 } else {
691 sb.append(handle);
692 }
693 sb.append(": ");
694
695 Timer timer = se.getSensorTime();
696 if (timer != null) {
697 // Convert from microseconds to milliseconds with rounding
698 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
699 int count = timer.getCount(which);
700 //timer.logState();
701 if (totalTime != 0) {
702 sb.append(formatTimeMs(totalTime));
703 sb.append("realtime (");
704 sb.append(count);
705 sb.append(" times)");
706 } else {
707 sb.append("(not used)");
708 }
709 } else {
710 sb.append("(not used)");
711 }
712
713 pw.println(sb.toString());
714 uidActivity = true;
715 }
716 }
717
718 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
719 if (processStats.size() > 0) {
720 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
721 : processStats.entrySet()) {
722 Uid.Proc ps = ent.getValue();
723 long userTime;
724 long systemTime;
725 int starts;
726
727 userTime = ps.getUserTime(which);
728 systemTime = ps.getSystemTime(which);
729 starts = ps.getStarts(which);
730
731 if (userTime != 0 || systemTime != 0 || starts != 0) {
732 pw.println(prefix + " Proc " + ent.getKey() + ":");
733 pw.println(prefix + " CPU: " + formatTime(userTime) + "user + "
734 + formatTime(systemTime) + "kernel");
735 pw.println(prefix + " " + starts + " process starts");
736 uidActivity = true;
737 }
738 }
739 }
740
741 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
742 if (packageStats.size() > 0) {
743 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
744 : packageStats.entrySet()) {
745 pw.println(prefix + " Apk " + ent.getKey() + ":");
746 boolean apkActivity = false;
747 Uid.Pkg ps = ent.getValue();
748 int wakeups = ps.getWakeups(which);
749 if (wakeups != 0) {
750 pw.println(prefix + " " + wakeups + " wakeup alarms");
751 apkActivity = true;
752 }
753 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
754 if (serviceStats.size() > 0) {
755 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
756 : serviceStats.entrySet()) {
757 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
758 long startTime = ss.getStartTime(batteryUptime, which);
759 int starts = ss.getStarts(which);
760 int launches = ss.getLaunches(which);
761 if (startTime != 0 || starts != 0 || launches != 0) {
762 pw.println(prefix + " Service " + sent.getKey() + ":");
763 pw.println(prefix + " Created for: "
764 + formatTimeMs(startTime / 1000)
765 + " uptime");
766 pw.println(prefix + " Starts: " + starts
767 + ", launches: " + launches);
768 apkActivity = true;
769 }
770 }
771 }
772 if (!apkActivity) {
773 pw.println(prefix + " (nothing executed)");
774 }
775 uidActivity = true;
776 }
777 }
778 if (!uidActivity) {
779 pw.println(prefix + " (nothing executed)");
780 }
781 }
782 }
783
784 /**
785 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
786 *
787 * @param pw a Printer to receive the dump output.
788 */
789 @SuppressWarnings("unused")
790 public void dumpLocked(Printer pw) {
791 pw.println("Total Statistics (Current and Historic):");
792 pw.println(" System starts: " + getStartCount()
793 + ", currently on battery: " + getIsOnBattery());
794 dumpLocked(pw, "", STATS_TOTAL);
795 pw.println("");
796 pw.println("Last Run Statistics (Previous run of system):");
797 dumpLocked(pw, "", STATS_LAST);
798 pw.println("");
799 pw.println("Current Battery Statistics (Currently running system):");
800 dumpLocked(pw, "", STATS_CURRENT);
801 pw.println("");
802 pw.println("Unplugged Statistics (Since last unplugged from power):");
803 dumpLocked(pw, "", STATS_UNPLUGGED);
804 }
805
806 @SuppressWarnings("unused")
807 public void dumpCheckinLocked(PrintWriter pw, String[] args) {
808 boolean isUnpluggedOnly = false;
809
810 for (String arg : args) {
811 if ("-u".equals(arg)) {
812 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
813 isUnpluggedOnly = true;
814 }
815 }
816
817 if (isUnpluggedOnly) {
818 dumpCheckinLocked(pw, STATS_UNPLUGGED);
819 }
820 else {
821 dumpCheckinLocked(pw, STATS_TOTAL);
822 dumpCheckinLocked(pw, STATS_LAST);
823 dumpCheckinLocked(pw, STATS_UNPLUGGED);
824 dumpCheckinLocked(pw, STATS_CURRENT);
825 }
826 }
827
828}