blob: c747c43b81e7c516b1fd49d33734ba0042577d60 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001package android.os;
2
3import java.io.PrintWriter;
4import java.util.Formatter;
5import java.util.Map;
6
7import android.util.Log;
8import android.util.Printer;
9import android.util.SparseArray;
10
11/**
12 * A class providing access to battery usage statistics, including information on
13 * wakelocks, processes, packages, and services. All times are represented in microseconds
14 * except where indicated otherwise.
15 * @hide
16 */
17public abstract class BatteryStats implements Parcelable {
18
19 private static final boolean LOCAL_LOGV = false;
20
21 /**
22 * A constant indicating a partial wake lock timer.
23 */
24 public static final int WAKE_TYPE_PARTIAL = 0;
25
26 /**
27 * A constant indicating a full wake lock timer.
28 */
29 public static final int WAKE_TYPE_FULL = 1;
30
31 /**
32 * A constant indicating a window wake lock timer.
33 */
34 public static final int WAKE_TYPE_WINDOW = 2;
35
36 /**
37 * A constant indicating a sensor timer.
38 *
39 * {@hide}
40 */
41 public static final int SENSOR = 3;
The Android Open Source Project10592532009-03-18 17:39:46 -070042
43 /**
44 * A constant indicating a full wifi lock timer
45 *
46 * {@hide}
47 */
48 public static final int FULL_WIFI_LOCK = 4;
49
50 /**
51 * A constant indicating a scan wifi lock timer
52 *
53 * {@hide}
54 */
55 public static final int SCAN_WIFI_LOCK = 5;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056
57 /**
58 * Include all of the data in the stats, including previously saved data.
59 */
60 public static final int STATS_TOTAL = 0;
61
62 /**
63 * Include only the last run in the stats.
64 */
65 public static final int STATS_LAST = 1;
66
67 /**
68 * Include only the current run in the stats.
69 */
70 public static final int STATS_CURRENT = 2;
71
72 /**
73 * Include only the run since the last time the device was unplugged in the stats.
74 */
75 public static final int STATS_UNPLUGGED = 3;
76
77 /**
78 * Bump the version on this if the checkin format changes.
79 */
Evan Millar22ac0432009-03-31 11:33:18 -070080 private static final int BATTERY_STATS_CHECKIN_VERSION = 2;
81
82 private static final long BYTES_PER_KB = 1024;
83 private static final long BYTES_PER_MB = 1048576; // 1024^2
84 private static final long BYTES_PER_GB = 1073741824; //1024^3
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085
86 // TODO: Update this list if you add/change any stats above.
87 private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" };
88
89 private static final String APK_DATA = "apk";
90 private static final String PROCESS_DATA = "process";
91 private static final String SENSOR_DATA = "sensor";
92 private static final String WAKELOCK_DATA = "wakelock";
93 private static final String NETWORK_DATA = "network";
94 private static final String BATTERY_DATA = "battery";
The Android Open Source Project10592532009-03-18 17:39:46 -070095 private static final String WIFI_LOCK_DATA = "wifilock";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 private static final String MISC_DATA = "misc";
Dianne Hackborn627bba72009-03-24 22:32:56 -070097 private static final String SIGNAL_STRENGTH_DATA = "signal";
98 private static final String DATA_CONNECTION_DATA = "dataconn";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099
100 private final StringBuilder mFormatBuilder = new StringBuilder(8);
101 private final Formatter mFormatter = new Formatter(mFormatBuilder);
102
103 /**
104 * State for keeping track of timing information.
105 */
106 public static abstract class Timer {
107
108 /**
109 * Returns the count associated with this Timer for the
110 * selected type of statistics.
111 *
112 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
113 */
114 public abstract int getCount(int which);
115
116 /**
117 * Returns the total time in microseconds associated with this Timer for the
118 * selected type of statistics.
119 *
120 * @param batteryRealtime system realtime on battery in microseconds
121 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
122 * @return a time in microseconds
123 */
124 public abstract long getTotalTime(long batteryRealtime, int which);
125
126 /**
127 * Temporary for debugging.
128 */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700129 public abstract void logState(Printer pw, String prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 }
131
132 /**
133 * The statistics associated with a particular uid.
134 */
135 public static abstract class Uid {
136
137 /**
138 * Returns a mapping containing wakelock statistics.
139 *
140 * @return a Map from Strings to Uid.Wakelock objects.
141 */
142 public abstract Map<String, ? extends Wakelock> getWakelockStats();
143
144 /**
145 * The statistics associated with a particular wake lock.
146 */
147 public static abstract class Wakelock {
148 public abstract Timer getWakeTime(int type);
149 }
150
151 /**
152 * Returns a mapping containing sensor statistics.
153 *
154 * @return a Map from Integer sensor ids to Uid.Sensor objects.
155 */
156 public abstract Map<Integer, ? extends Sensor> getSensorStats();
157
158 /**
159 * Returns a mapping containing process statistics.
160 *
161 * @return a Map from Strings to Uid.Proc objects.
162 */
163 public abstract Map<String, ? extends Proc> getProcessStats();
164
165 /**
166 * Returns a mapping containing package statistics.
167 *
168 * @return a Map from Strings to Uid.Pkg objects.
169 */
170 public abstract Map<String, ? extends Pkg> getPackageStats();
171
172 /**
173 * {@hide}
174 */
175 public abstract int getUid();
176
177 /**
178 * {@hide}
179 */
180 public abstract long getTcpBytesReceived(int which);
181
182 /**
183 * {@hide}
184 */
185 public abstract long getTcpBytesSent(int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700186
187 public abstract void noteFullWifiLockAcquiredLocked();
188 public abstract void noteFullWifiLockReleasedLocked();
189 public abstract void noteScanWifiLockAcquiredLocked();
190 public abstract void noteScanWifiLockReleasedLocked();
191 public abstract long getFullWifiLockTime(long batteryRealtime, int which);
192 public abstract long getScanWifiLockTime(long batteryRealtime, int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
194 public static abstract class Sensor {
195 // Magic sensor number for the GPS.
196 public static final int GPS = -10000;
197
198 public abstract int getHandle();
199
200 public abstract Timer getSensorTime();
201 }
202
203 /**
204 * The statistics associated with a particular process.
205 */
206 public static abstract class Proc {
207
208 /**
209 * Returns the total time (in 1/100 sec) spent executing in user code.
210 *
211 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
212 */
213 public abstract long getUserTime(int which);
214
215 /**
216 * Returns the total time (in 1/100 sec) spent executing in system code.
217 *
218 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
219 */
220 public abstract long getSystemTime(int which);
221
222 /**
223 * Returns the number of times the process has been started.
224 *
225 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
226 */
227 public abstract int getStarts(int which);
228 }
229
230 /**
231 * The statistics associated with a particular package.
232 */
233 public static abstract class Pkg {
234
235 /**
236 * Returns the number of times this package has done something that could wake up the
237 * device from sleep.
238 *
239 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
240 */
241 public abstract int getWakeups(int which);
242
243 /**
244 * Returns a mapping containing service statistics.
245 */
246 public abstract Map<String, ? extends Serv> getServiceStats();
247
248 /**
249 * The statistics associated with a particular service.
250 */
251 public abstract class Serv {
252
253 /**
254 * Returns the amount of time spent started.
255 *
256 * @param batteryUptime elapsed uptime on battery in microseconds.
257 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
258 * @return
259 */
260 public abstract long getStartTime(long batteryUptime, int which);
261
262 /**
263 * Returns the total number of times startService() has been called.
264 *
265 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
266 */
267 public abstract int getStarts(int which);
268
269 /**
270 * Returns the total number times the service has been launched.
271 *
272 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
273 */
274 public abstract int getLaunches(int which);
275 }
276 }
277 }
278
279 /**
280 * Returns the number of times the device has been started.
281 */
282 public abstract int getStartCount();
283
284 /**
285 * Returns the time in milliseconds that the screen has been on while the device was
286 * running on battery.
287 *
288 * {@hide}
289 */
290 public abstract long getScreenOnTime(long batteryRealtime, int which);
291
292 /**
293 * Returns the time in milliseconds that the phone has been on while the device was
294 * running on battery.
295 *
296 * {@hide}
297 */
298 public abstract long getPhoneOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700299
Dianne Hackborn627bba72009-03-24 22:32:56 -0700300 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
301 public static final int SIGNAL_STRENGTH_POOR = 1;
302 public static final int SIGNAL_STRENGTH_MODERATE = 2;
303 public static final int SIGNAL_STRENGTH_GOOD = 3;
304 public static final int SIGNAL_STRENGTH_GREAT = 4;
305
306 static final String[] SIGNAL_STRENGTH_NAMES = {
307 "none", "poor", "moderate", "good", "great"
308 };
309
310 public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
311
312 /**
313 * Returns the time in milliseconds that the phone has been running with
314 * the given signal strength.
315 *
316 * {@hide}
317 */
318 public abstract long getPhoneSignalStrengthTime(int strengthBin,
319 long batteryRealtime, int which);
320
321 public static final int DATA_CONNECTION_NONE = 0;
322 public static final int DATA_CONNECTION_GPRS = 1;
323 public static final int DATA_CONNECTION_EDGE = 2;
324 public static final int DATA_CONNECTION_UMTS = 3;
325 public static final int DATA_CONNECTION_OTHER = 4;
326
327 static final String[] DATA_CONNECTION_NAMES = {
328 "none", "gprs", "edge", "umts", "other"
329 };
330
331 public static final int NUM_DATA_CONNECTION_TYPES = 5;
332
333 /**
334 * Returns the time in milliseconds that the phone has been running with
335 * the given data connection.
336 *
337 * {@hide}
338 */
339 public abstract long getPhoneDataConnectionTime(int dataType,
340 long batteryRealtime, int which);
341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 /**
The Android Open Source Project10592532009-03-18 17:39:46 -0700343 * Returns the time in milliseconds that wifi has been on while the device was
344 * running on battery.
345 *
346 * {@hide}
347 */
348 public abstract long getWifiOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700349
350 /**
351 * Returns the time in milliseconds that wifi has been on and the driver has
352 * been in the running state while the device was running on battery.
353 *
354 * {@hide}
355 */
356 public abstract long getWifiRunningTime(long batteryRealtime, int which);
357
The Android Open Source Project10592532009-03-18 17:39:46 -0700358 /**
359 * Returns the time in milliseconds that bluetooth has been on while the device was
360 * running on battery.
361 *
362 * {@hide}
363 */
364 public abstract long getBluetoothOnTime(long batteryRealtime, int which);
365
366 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 * Return whether we are currently running on battery.
368 */
369 public abstract boolean getIsOnBattery();
370
371 /**
372 * Returns a SparseArray containing the statistics for each uid.
373 */
374 public abstract SparseArray<? extends Uid> getUidStats();
375
376 /**
377 * Returns the current battery uptime in microseconds.
378 *
379 * @param curTime the amount of elapsed realtime in microseconds.
380 */
381 public abstract long getBatteryUptime(long curTime);
382
383 /**
384 * Returns the current battery realtime in microseconds.
385 *
386 * @param curTime the amount of elapsed realtime in microseconds.
387 */
388 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700389
390 /**
391 * Returns the battery percentage level at the last time the device was unplugged from power,
392 * or the last time it was booted while unplugged.
393 */
394 public abstract int getUnpluggedStartLevel();
395
396 /**
397 * Returns the battery percentage level at the last time the device was plugged into power.
398 */
399 public abstract int getPluggedStartLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400
401 /**
402 * Returns the total, last, or current battery uptime in microseconds.
403 *
404 * @param curTime the elapsed realtime in microseconds.
405 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
406 */
407 public abstract long computeBatteryUptime(long curTime, int which);
408
409 /**
410 * Returns the total, last, or current battery realtime in microseconds.
411 *
412 * @param curTime the current elapsed realtime in microseconds.
413 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
414 */
415 public abstract long computeBatteryRealtime(long curTime, int which);
416
417 /**
418 * Returns the total, last, or current uptime in microseconds.
419 *
420 * @param curTime the current elapsed realtime in microseconds.
421 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
422 */
423 public abstract long computeUptime(long curTime, int which);
424
425 /**
426 * Returns the total, last, or current realtime in microseconds.
427 * *
428 * @param curTime the current elapsed realtime in microseconds.
429 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
430 */
431 public abstract long computeRealtime(long curTime, int which);
432
433 private final static void formatTime(StringBuilder out, long seconds) {
434 long days = seconds / (60 * 60 * 24);
435 if (days != 0) {
436 out.append(days);
437 out.append("d ");
438 }
439 long used = days * 60 * 60 * 24;
440
441 long hours = (seconds - used) / (60 * 60);
442 if (hours != 0 || used != 0) {
443 out.append(hours);
444 out.append("h ");
445 }
446 used += hours * 60 * 60;
447
448 long mins = (seconds-used) / 60;
449 if (mins != 0 || used != 0) {
450 out.append(mins);
451 out.append("m ");
452 }
453 used += mins * 60;
454
455 if (seconds != 0 || used != 0) {
456 out.append(seconds-used);
457 out.append("s ");
458 }
459 }
460
461 private final static String formatTime(long time) {
462 long sec = time / 100;
463 StringBuilder sb = new StringBuilder();
464 formatTime(sb, sec);
465 sb.append((time - (sec * 100)) * 10);
466 sb.append("ms ");
467 return sb.toString();
468 }
469
470 private final static String formatTimeMs(long time) {
471 long sec = time / 1000;
472 StringBuilder sb = new StringBuilder();
473 formatTime(sb, sec);
474 sb.append(time - (sec * 1000));
475 sb.append("ms ");
476 return sb.toString();
477 }
478
479 private final String formatRatioLocked(long num, long den) {
480 if (den == 0L) {
481 return "---%";
482 }
483 float perc = ((float)num) / ((float)den) * 100;
484 mFormatBuilder.setLength(0);
485 mFormatter.format("%.1f%%", perc);
486 return mFormatBuilder.toString();
487 }
488
Evan Millar22ac0432009-03-31 11:33:18 -0700489 private final String formatBytesLocked(long bytes) {
490 mFormatBuilder.setLength(0);
491
492 if (bytes < BYTES_PER_KB) {
493 return bytes + "B";
494 } else if (bytes < BYTES_PER_MB) {
495 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
496 return mFormatBuilder.toString();
497 } else if (bytes < BYTES_PER_GB){
498 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
499 return mFormatBuilder.toString();
500 } else {
501 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
502 return mFormatBuilder.toString();
503 }
504 }
505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 /**
507 *
508 * @param sb a StringBuilder object.
509 * @param timer a Timer object contining the wakelock times.
510 * @param batteryRealtime the current on-battery time in microseconds.
511 * @param name the name of the wakelock.
512 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
513 * @param linePrefix a String to be prepended to each line of output.
514 * @return the line prefix
515 */
516 private static final String printWakeLock(StringBuilder sb, Timer timer,
517 long batteryRealtime, String name, int which, String linePrefix) {
518
519 if (timer != null) {
520 // Convert from microseconds to milliseconds with rounding
521 long totalTimeMicros = timer.getTotalTime(batteryRealtime, which);
522 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
523
524 int count = timer.getCount(which);
525 if (totalTimeMillis != 0) {
526 sb.append(linePrefix);
527 sb.append(formatTimeMs(totalTimeMillis));
528 sb.append(name);
529 sb.append(' ');
530 sb.append('(');
531 sb.append(count);
532 sb.append(" times)");
533 return ", ";
534 }
535 }
536 return linePrefix;
537 }
538
539 /**
540 * Checkin version of wakelock printer. Prints simple comma-separated list.
541 *
542 * @param sb a StringBuilder object.
543 * @param timer a Timer object contining the wakelock times.
544 * @param now the current time in microseconds.
545 * @param name the name of the wakelock.
546 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
547 * @param linePrefix a String to be prepended to each line of output.
548 * @return the line prefix
549 */
550 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
551 String name, int which, String linePrefix) {
552 long totalTimeMicros = 0;
553 int count = 0;
554 if (timer != null) {
555 totalTimeMicros = timer.getTotalTime(now, which);
556 count = timer.getCount(which);
557 }
558 sb.append(linePrefix);
559 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
560 sb.append(',');
561 sb.append(name);
562 sb.append(',');
563 sb.append(count);
564 return ",";
565 }
566
567 /**
568 * Dump a comma-separated line of values for terse checkin mode.
569 *
570 * @param pw the PageWriter to dump log to
571 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
572 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
573 * @param args type-dependent data arguments
574 */
575 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
576 Object... args ) {
577 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
578 pw.print(uid); pw.print(',');
579 pw.print(category); pw.print(',');
580 pw.print(type);
581
582 for (Object arg : args) {
583 pw.print(',');
584 pw.print(arg);
585 }
586 pw.print('\n');
587 }
588
589 /**
590 * Checkin server version of dump to produce more compact, computer-readable log.
591 *
592 * NOTE: all times are expressed in 'ms'.
593 * @param fd
594 * @param pw
595 * @param which
596 */
597 private final void dumpCheckinLocked(PrintWriter pw, int which) {
598 final long rawUptime = SystemClock.uptimeMillis() * 1000;
599 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
600 final long batteryUptime = getBatteryUptime(rawUptime);
601 final long batteryRealtime = getBatteryRealtime(rawRealtime);
602 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
603 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
604 final long totalRealtime = computeRealtime(rawRealtime, which);
605 final long totalUptime = computeUptime(rawUptime, which);
606 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
607 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700608 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700609 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700610 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611
612 StringBuilder sb = new StringBuilder(128);
613
Evan Millar22ac0432009-03-31 11:33:18 -0700614 SparseArray<? extends Uid> uidStats = getUidStats();
615 final int NU = uidStats.size();
616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 String category = STAT_NAMES[which];
618
619 // Dump "battery" stat
620 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
621 which == STATS_TOTAL ? getStartCount() : "N/A",
622 whichBatteryUptime / 1000, whichBatteryRealtime / 1000,
623 totalUptime / 1000, totalRealtime / 1000);
624
Evan Millar22ac0432009-03-31 11:33:18 -0700625 // Calculate total network and wakelock times across all uids.
626 long rxTotal = 0;
627 long txTotal = 0;
628 long fullWakeLockTimeTotal = 0;
629 long partialWakeLockTimeTotal = 0;
630
631 for (int iu = 0; iu < NU; iu++) {
632 Uid u = uidStats.valueAt(iu);
633 rxTotal += u.getTcpBytesReceived(which);
634 txTotal += u.getTcpBytesSent(which);
635
636 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
637 if (wakelocks.size() > 0) {
638 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
639 : wakelocks.entrySet()) {
640 Uid.Wakelock wl = ent.getValue();
641
642 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
643 if (fullWakeTimer != null) {
644 fullWakeLockTimeTotal += fullWakeTimer.getTotalTime(batteryRealtime, which);
645 }
646
647 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
648 if (partialWakeTimer != null) {
649 partialWakeLockTimeTotal += partialWakeTimer.getTotalTime(
650 batteryRealtime, which);
651 }
652 }
653 }
654 }
655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 // Dump misc stats
657 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700658 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
Evan Millar22ac0432009-03-31 11:33:18 -0700659 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal,
660 fullWakeLockTimeTotal, partialWakeLockTimeTotal);
The Android Open Source Project10592532009-03-18 17:39:46 -0700661
Dianne Hackborn627bba72009-03-24 22:32:56 -0700662 // Dump signal strength stats
663 Object[] args = new Object[NUM_SIGNAL_STRENGTH_BINS];
664 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
665 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
666 }
667 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_DATA, args);
668
669 // Dump network type stats
670 args = new Object[NUM_DATA_CONNECTION_TYPES];
671 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
672 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
673 }
674 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_DATA, args);
675
The Android Open Source Project10592532009-03-18 17:39:46 -0700676 if (which == STATS_UNPLUGGED) {
677 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, getUnpluggedStartLevel(),
678 getPluggedStartLevel());
679 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681 for (int iu = 0; iu < NU; iu++) {
682 final int uid = uidStats.keyAt(iu);
683 Uid u = uidStats.valueAt(iu);
684 // Dump Network stats per uid, if any
685 long rx = u.getTcpBytesReceived(which);
686 long tx = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700687 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
688 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -0700691
692 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) {
693 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
694 fullWifiLockOnTime, scanWifiLockOnTime);
695 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800696
697 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
698 if (wakelocks.size() > 0) {
699 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
700 : wakelocks.entrySet()) {
701 Uid.Wakelock wl = ent.getValue();
702 String linePrefix = "";
703 sb.setLength(0);
704 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
705 "full", which, linePrefix);
706 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
707 "partial", which, linePrefix);
708 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
709 "window", which, linePrefix);
710
711 // Only log if we had at lease one wakelock...
712 if (sb.length() > 0) {
713 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
714 }
715 }
716 }
717
718 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
719 if (sensors.size() > 0) {
720 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
721 : sensors.entrySet()) {
722 Uid.Sensor se = ent.getValue();
723 int sensorNumber = ent.getKey();
724 Timer timer = se.getSensorTime();
725 if (timer != null) {
726 // Convert from microseconds to milliseconds with rounding
727 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
728 int count = timer.getCount(which);
729 if (totalTime != 0) {
730 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
731 }
732 }
733 }
734 }
735
736 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
737 if (processStats.size() > 0) {
738 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
739 : processStats.entrySet()) {
740 Uid.Proc ps = ent.getValue();
741
742 long userTime = ps.getUserTime(which);
743 long systemTime = ps.getSystemTime(which);
744 int starts = ps.getStarts(which);
745
746 if (userTime != 0 || systemTime != 0 || starts != 0) {
747 dumpLine(pw, uid, category, PROCESS_DATA,
748 ent.getKey(), // proc
749 userTime * 10, // cpu time in ms
750 systemTime * 10, // user time in ms
751 starts); // process starts
752 }
753 }
754 }
755
756 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
757 if (packageStats.size() > 0) {
758 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
759 : packageStats.entrySet()) {
760
761 Uid.Pkg ps = ent.getValue();
762 int wakeups = ps.getWakeups(which);
763 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
764 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
765 : serviceStats.entrySet()) {
766 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
767 long startTime = ss.getStartTime(batteryUptime, which);
768 int starts = ss.getStarts(which);
769 int launches = ss.getLaunches(which);
770 if (startTime != 0 || starts != 0 || launches != 0) {
771 dumpLine(pw, uid, category, APK_DATA,
772 wakeups, // wakeup alarms
773 ent.getKey(), // Apk
774 sent.getKey(), // service
775 startTime / 1000, // time spent started, in ms
776 starts,
777 launches);
778 }
779 }
780 }
781 }
782 }
783 }
784
785 @SuppressWarnings("unused")
786 private final void dumpLocked(Printer pw, String prefix, int which) {
787 final long rawUptime = SystemClock.uptimeMillis() * 1000;
788 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
789 final long batteryUptime = getBatteryUptime(rawUptime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700790 final long batteryRealtime = getBatteryRealtime(rawRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791
792 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
793 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
794 final long totalRealtime = computeRealtime(rawRealtime, which);
795 final long totalUptime = computeUptime(rawUptime, which);
796
797 StringBuilder sb = new StringBuilder(128);
Evan Millar22ac0432009-03-31 11:33:18 -0700798
799 SparseArray<? extends Uid> uidStats = getUidStats();
800 final int NU = uidStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801
802 pw.println(prefix
803 + " Time on battery: " + formatTimeMs(whichBatteryUptime / 1000)
804 + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime)
805 + ") uptime, "
806 + formatTimeMs(whichBatteryRealtime / 1000) + "("
807 + formatRatioLocked(whichBatteryRealtime, totalRealtime)
808 + ") realtime");
809 pw.println(prefix
810 + " Total: "
811 + formatTimeMs(totalUptime / 1000)
812 + "uptime, "
813 + formatTimeMs(totalRealtime / 1000)
814 + "realtime");
815
The Android Open Source Project10592532009-03-18 17:39:46 -0700816 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
817 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700818 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700819 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
820 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 pw.println(prefix
Dianne Hackborn627bba72009-03-24 22:32:56 -0700822 + " Screen on: " + formatTimeMs(screenOnTime / 1000)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime)
Dianne Hackborn627bba72009-03-24 22:32:56 -0700824 + "), Phone on: " + formatTimeMs(phoneOnTime / 1000)
825 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime));
826 pw.println(prefix
827 + " Wifi on: " + formatTimeMs(wifiOnTime / 1000)
The Android Open Source Project10592532009-03-18 17:39:46 -0700828 + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime)
Dianne Hackborn627bba72009-03-24 22:32:56 -0700829 + "), Wifi running: " + formatTimeMs(wifiRunningTime / 1000)
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700830 + "(" + formatRatioLocked(wifiRunningTime, whichBatteryRealtime)
Dianne Hackborn627bba72009-03-24 22:32:56 -0700831 + "), Bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000)
The Android Open Source Project10592532009-03-18 17:39:46 -0700832 + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")");
833
Evan Millar22ac0432009-03-31 11:33:18 -0700834 // Calculate total network and wakelock times across all uids.
835 long rxTotal = 0;
836 long txTotal = 0;
837 long fullWakeLockTimeTotalMicros = 0;
838 long partialWakeLockTimeTotalMicros = 0;
839
840 for (int iu = 0; iu < NU; iu++) {
841 Uid u = uidStats.valueAt(iu);
842 rxTotal += u.getTcpBytesReceived(which);
843 txTotal += u.getTcpBytesSent(which);
844
845 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
846 if (wakelocks.size() > 0) {
847 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
848 : wakelocks.entrySet()) {
849 Uid.Wakelock wl = ent.getValue();
850
851 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
852 if (fullWakeTimer != null) {
853 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTime(
854 batteryRealtime, which);
855 }
856
857 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
858 if (partialWakeTimer != null) {
859 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTime(
860 batteryRealtime, which);
861 }
862 }
863 }
864 }
865
866 pw.println(prefix
867 + " Total received: " + formatBytesLocked(rxTotal)
868 + ", Total sent: " + formatBytesLocked(txTotal));
869 pw.println(prefix
870 + " Total full wakelock time: " + formatTimeMs(
871 (fullWakeLockTimeTotalMicros + 500) / 1000)
872 + ", Total partial waklock time: " + formatTimeMs(
873 (partialWakeLockTimeTotalMicros + 500) / 1000));
874
Dianne Hackborn627bba72009-03-24 22:32:56 -0700875 sb.setLength(0);
876 sb.append(" Signal strengths: ");
877 boolean didOne = false;
878 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
879 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
880 if (time == 0) {
881 continue;
882 }
883 if (didOne) sb.append(", ");
884 didOne = true;
885 sb.append(SIGNAL_STRENGTH_NAMES[i]);
886 sb.append(" ");
887 sb.append(formatTimeMs(time/1000));
888 sb.append("(");
889 sb.append(formatRatioLocked(time, whichBatteryRealtime));
890 sb.append(")");
891 }
892 if (!didOne) sb.append("No activity");
893 pw.println(sb.toString());
894
895 sb.setLength(0);
896 sb.append(" Data types: ");
897 didOne = false;
898 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
899 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
900 if (time == 0) {
901 continue;
902 }
903 if (didOne) sb.append(", ");
904 didOne = true;
905 sb.append(DATA_CONNECTION_NAMES[i]);
906 sb.append(" ");
907 sb.append(formatTimeMs(time/1000));
908 sb.append("(");
909 sb.append(formatRatioLocked(time, whichBatteryRealtime));
910 sb.append(")");
911 }
912 if (!didOne) sb.append("No activity");
913 pw.println(sb.toString());
914
The Android Open Source Project10592532009-03-18 17:39:46 -0700915 pw.println(" ");
916
917 if (which == STATS_UNPLUGGED) {
918 if (getIsOnBattery()) {
919 pw.println(prefix + " Device is currently unplugged");
920 pw.println(prefix + " Discharge cycle start level: " +
921 getUnpluggedStartLevel());
922 } else {
923 pw.println(prefix + " Device is currently plugged into power");
924 pw.println(prefix + " Last discharge cycle start level: " +
925 getUnpluggedStartLevel());
926 pw.println(prefix + " Last discharge cycle end level: " +
927 getPluggedStartLevel());
928 }
929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930
931 pw.println(" ");
932
Evan Millar22ac0432009-03-31 11:33:18 -0700933
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 for (int iu=0; iu<NU; iu++) {
935 final int uid = uidStats.keyAt(iu);
936 Uid u = uidStats.valueAt(iu);
937 pw.println(prefix + " #" + uid + ":");
938 boolean uidActivity = false;
939
940 long tcpReceived = u.getTcpBytesReceived(which);
941 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700942 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
943 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 if (tcpReceived != 0 || tcpSent != 0) {
Evan Millar22ac0432009-03-31 11:33:18 -0700946 pw.println(prefix + " Network: " + formatBytesLocked(tcpReceived) + " received, "
947 + formatBytesLocked(tcpSent) + " sent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700949 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) {
950 pw.println(prefix + " Full Wifi Lock Time: "
Evan Millar2a15f382009-03-27 18:03:56 -0700951 + formatTimeMs(fullWifiLockOnTime / 1000)
The Android Open Source Project10592532009-03-18 17:39:46 -0700952 + "(" + formatRatioLocked(fullWifiLockOnTime,
953 whichBatteryRealtime)+ ")");
954 pw.println(prefix + " Scan Wifi Lock Time: "
Evan Millar2a15f382009-03-27 18:03:56 -0700955 + formatTimeMs(scanWifiLockOnTime / 1000)
The Android Open Source Project10592532009-03-18 17:39:46 -0700956 + "(" + formatRatioLocked(scanWifiLockOnTime,
957 whichBatteryRealtime)+ ")");
958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959
960 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
961 if (wakelocks.size() > 0) {
962 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
963 : wakelocks.entrySet()) {
964 Uid.Wakelock wl = ent.getValue();
965 String linePrefix = ": ";
966 sb.setLength(0);
967 sb.append(prefix);
968 sb.append(" Wake lock ");
969 sb.append(ent.getKey());
970 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
971 "full", which, linePrefix);
972 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
973 "partial", which, linePrefix);
974 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
975 "window", which, linePrefix);
976 if (!linePrefix.equals(": ")) {
977 sb.append(" realtime");
978 } else {
979 sb.append(": (nothing executed)");
980 }
981 pw.println(sb.toString());
982 uidActivity = true;
983 }
984 }
985
986 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
987 if (sensors.size() > 0) {
988 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
989 : sensors.entrySet()) {
990 Uid.Sensor se = ent.getValue();
991 int sensorNumber = ent.getKey();
992 sb.setLength(0);
993 sb.append(prefix);
994 sb.append(" Sensor ");
995 int handle = se.getHandle();
996 if (handle == Uid.Sensor.GPS) {
997 sb.append("GPS");
998 } else {
999 sb.append(handle);
1000 }
1001 sb.append(": ");
1002
1003 Timer timer = se.getSensorTime();
1004 if (timer != null) {
1005 // Convert from microseconds to milliseconds with rounding
1006 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
1007 int count = timer.getCount(which);
1008 //timer.logState();
1009 if (totalTime != 0) {
1010 sb.append(formatTimeMs(totalTime));
1011 sb.append("realtime (");
1012 sb.append(count);
1013 sb.append(" times)");
1014 } else {
1015 sb.append("(not used)");
1016 }
1017 } else {
1018 sb.append("(not used)");
1019 }
1020
1021 pw.println(sb.toString());
1022 uidActivity = true;
1023 }
1024 }
1025
1026 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1027 if (processStats.size() > 0) {
1028 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1029 : processStats.entrySet()) {
1030 Uid.Proc ps = ent.getValue();
1031 long userTime;
1032 long systemTime;
1033 int starts;
1034
1035 userTime = ps.getUserTime(which);
1036 systemTime = ps.getSystemTime(which);
1037 starts = ps.getStarts(which);
1038
1039 if (userTime != 0 || systemTime != 0 || starts != 0) {
1040 pw.println(prefix + " Proc " + ent.getKey() + ":");
1041 pw.println(prefix + " CPU: " + formatTime(userTime) + "user + "
1042 + formatTime(systemTime) + "kernel");
1043 pw.println(prefix + " " + starts + " process starts");
1044 uidActivity = true;
1045 }
1046 }
1047 }
1048
1049 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1050 if (packageStats.size() > 0) {
1051 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1052 : packageStats.entrySet()) {
1053 pw.println(prefix + " Apk " + ent.getKey() + ":");
1054 boolean apkActivity = false;
1055 Uid.Pkg ps = ent.getValue();
1056 int wakeups = ps.getWakeups(which);
1057 if (wakeups != 0) {
1058 pw.println(prefix + " " + wakeups + " wakeup alarms");
1059 apkActivity = true;
1060 }
1061 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1062 if (serviceStats.size() > 0) {
1063 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1064 : serviceStats.entrySet()) {
1065 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1066 long startTime = ss.getStartTime(batteryUptime, which);
1067 int starts = ss.getStarts(which);
1068 int launches = ss.getLaunches(which);
1069 if (startTime != 0 || starts != 0 || launches != 0) {
1070 pw.println(prefix + " Service " + sent.getKey() + ":");
1071 pw.println(prefix + " Created for: "
1072 + formatTimeMs(startTime / 1000)
1073 + " uptime");
1074 pw.println(prefix + " Starts: " + starts
1075 + ", launches: " + launches);
1076 apkActivity = true;
1077 }
1078 }
1079 }
1080 if (!apkActivity) {
1081 pw.println(prefix + " (nothing executed)");
1082 }
1083 uidActivity = true;
1084 }
1085 }
1086 if (!uidActivity) {
1087 pw.println(prefix + " (nothing executed)");
1088 }
1089 }
1090 }
1091
1092 /**
1093 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
1094 *
1095 * @param pw a Printer to receive the dump output.
1096 */
1097 @SuppressWarnings("unused")
1098 public void dumpLocked(Printer pw) {
1099 pw.println("Total Statistics (Current and Historic):");
1100 pw.println(" System starts: " + getStartCount()
1101 + ", currently on battery: " + getIsOnBattery());
1102 dumpLocked(pw, "", STATS_TOTAL);
1103 pw.println("");
1104 pw.println("Last Run Statistics (Previous run of system):");
1105 dumpLocked(pw, "", STATS_LAST);
1106 pw.println("");
1107 pw.println("Current Battery Statistics (Currently running system):");
1108 dumpLocked(pw, "", STATS_CURRENT);
1109 pw.println("");
1110 pw.println("Unplugged Statistics (Since last unplugged from power):");
1111 dumpLocked(pw, "", STATS_UNPLUGGED);
1112 }
1113
1114 @SuppressWarnings("unused")
1115 public void dumpCheckinLocked(PrintWriter pw, String[] args) {
1116 boolean isUnpluggedOnly = false;
1117
1118 for (String arg : args) {
1119 if ("-u".equals(arg)) {
1120 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
1121 isUnpluggedOnly = true;
1122 }
1123 }
1124
1125 if (isUnpluggedOnly) {
1126 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1127 }
1128 else {
1129 dumpCheckinLocked(pw, STATS_TOTAL);
1130 dumpCheckinLocked(pw, STATS_LAST);
1131 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1132 dumpCheckinLocked(pw, STATS_CURRENT);
1133 }
1134 }
1135
1136}