blob: 8a0fd58530b04f0b84dfa394f277494f5ce7ba0b [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 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -070044 * A constant indicating a a wifi turn on timer
45 *
46 * {@hide}
47 */
48 public static final int WIFI_TURNED_ON = 4;
49
50 /**
The Android Open Source Project10592532009-03-18 17:39:46 -070051 * A constant indicating a full wifi lock timer
52 *
53 * {@hide}
54 */
Dianne Hackborn617f8772009-03-31 15:04:46 -070055 public static final int FULL_WIFI_LOCK = 5;
The Android Open Source Project10592532009-03-18 17:39:46 -070056
57 /**
58 * A constant indicating a scan wifi lock timer
59 *
60 * {@hide}
61 */
Dianne Hackborn617f8772009-03-31 15:04:46 -070062 public static final int SCAN_WIFI_LOCK = 6;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063
Robert Greenwalt5347bd42009-05-13 15:10:16 -070064 /**
65 * A constant indicating a wifi multicast timer
66 *
67 * {@hide}
68 */
69 public static final int WIFI_MULTICAST_ENABLED = 7;
70
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 /**
72 * Include all of the data in the stats, including previously saved data.
73 */
74 public static final int STATS_TOTAL = 0;
75
76 /**
77 * Include only the last run in the stats.
78 */
79 public static final int STATS_LAST = 1;
80
81 /**
82 * Include only the current run in the stats.
83 */
84 public static final int STATS_CURRENT = 2;
85
86 /**
87 * Include only the run since the last time the device was unplugged in the stats.
88 */
89 public static final int STATS_UNPLUGGED = 3;
Evan Millare84de8d2009-04-02 22:16:12 -070090
91 // NOTE: Update this list if you add/change any stats above.
92 // These characters are supposed to represent "total", "last", "current",
93 // and "unplugged". They were shortened for effeciency sake.
94 private static final String[] STAT_NAMES = { "t", "l", "c", "u" };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095
96 /**
97 * Bump the version on this if the checkin format changes.
98 */
Evan Millarc64edde2009-04-18 12:26:32 -070099 private static final int BATTERY_STATS_CHECKIN_VERSION = 5;
Evan Millar22ac0432009-03-31 11:33:18 -0700100
101 private static final long BYTES_PER_KB = 1024;
102 private static final long BYTES_PER_MB = 1048576; // 1024^2
103 private static final long BYTES_PER_GB = 1073741824; //1024^3
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105
106 private static final String APK_DATA = "apk";
Evan Millare84de8d2009-04-02 22:16:12 -0700107 private static final String PROCESS_DATA = "pr";
108 private static final String SENSOR_DATA = "sr";
109 private static final String WAKELOCK_DATA = "wl";
Evan Millarc64edde2009-04-18 12:26:32 -0700110 private static final String KERNEL_WAKELOCK_DATA = "kwl";
Evan Millare84de8d2009-04-02 22:16:12 -0700111 private static final String NETWORK_DATA = "nt";
112 private static final String USER_ACTIVITY_DATA = "ua";
113 private static final String BATTERY_DATA = "bt";
114 private static final String BATTERY_LEVEL_DATA = "lv";
115 private static final String WIFI_LOCK_DATA = "wfl";
116 private static final String MISC_DATA = "m";
117 private static final String SCREEN_BRIGHTNESS_DATA = "br";
118 private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
119 private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
120 private static final String DATA_CONNECTION_TIME_DATA = "dct";
121 private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700123 private final StringBuilder mFormatBuilder = new StringBuilder(32);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 private final Formatter mFormatter = new Formatter(mFormatBuilder);
125
126 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700127 * State for keeping track of counting information.
128 */
129 public static abstract class Counter {
130
131 /**
132 * Returns the count associated with this Counter for the
133 * selected type of statistics.
134 *
135 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
136 */
Evan Millarc64edde2009-04-18 12:26:32 -0700137 public abstract int getCountLocked(int which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700138
139 /**
140 * Temporary for debugging.
141 */
142 public abstract void logState(Printer pw, String prefix);
143 }
144
145 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 * State for keeping track of timing information.
147 */
148 public static abstract class Timer {
149
150 /**
151 * Returns the count associated with this Timer for the
152 * selected type of statistics.
153 *
154 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
155 */
Evan Millarc64edde2009-04-18 12:26:32 -0700156 public abstract int getCountLocked(int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157
158 /**
159 * Returns the total time in microseconds associated with this Timer for the
160 * selected type of statistics.
161 *
162 * @param batteryRealtime system realtime on battery in microseconds
163 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
164 * @return a time in microseconds
165 */
Evan Millarc64edde2009-04-18 12:26:32 -0700166 public abstract long getTotalTimeLocked(long batteryRealtime, int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167
168 /**
169 * Temporary for debugging.
170 */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700171 public abstract void logState(Printer pw, String prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 }
173
174 /**
175 * The statistics associated with a particular uid.
176 */
177 public static abstract class Uid {
178
179 /**
180 * Returns a mapping containing wakelock statistics.
181 *
182 * @return a Map from Strings to Uid.Wakelock objects.
183 */
184 public abstract Map<String, ? extends Wakelock> getWakelockStats();
185
186 /**
187 * The statistics associated with a particular wake lock.
188 */
189 public static abstract class Wakelock {
190 public abstract Timer getWakeTime(int type);
191 }
192
193 /**
194 * Returns a mapping containing sensor statistics.
195 *
196 * @return a Map from Integer sensor ids to Uid.Sensor objects.
197 */
198 public abstract Map<Integer, ? extends Sensor> getSensorStats();
199
200 /**
201 * Returns a mapping containing process statistics.
202 *
203 * @return a Map from Strings to Uid.Proc objects.
204 */
205 public abstract Map<String, ? extends Proc> getProcessStats();
206
207 /**
208 * Returns a mapping containing package statistics.
209 *
210 * @return a Map from Strings to Uid.Pkg objects.
211 */
212 public abstract Map<String, ? extends Pkg> getPackageStats();
213
214 /**
215 * {@hide}
216 */
217 public abstract int getUid();
218
219 /**
220 * {@hide}
221 */
222 public abstract long getTcpBytesReceived(int which);
223
224 /**
225 * {@hide}
226 */
227 public abstract long getTcpBytesSent(int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700228
Dianne Hackborn617f8772009-03-31 15:04:46 -0700229 public abstract void noteWifiTurnedOnLocked();
230 public abstract void noteWifiTurnedOffLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700231 public abstract void noteFullWifiLockAcquiredLocked();
232 public abstract void noteFullWifiLockReleasedLocked();
233 public abstract void noteScanWifiLockAcquiredLocked();
234 public abstract void noteScanWifiLockReleasedLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700235 public abstract void noteWifiMulticastEnabledLocked();
236 public abstract void noteWifiMulticastDisabledLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700237 public abstract long getWifiTurnedOnTime(long batteryRealtime, int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700238 public abstract long getFullWifiLockTime(long batteryRealtime, int which);
239 public abstract long getScanWifiLockTime(long batteryRealtime, int which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700240 public abstract long getWifiMulticastTime(long batteryRealtime,
241 int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242
Dianne Hackborn617f8772009-03-31 15:04:46 -0700243 /**
244 * Note that these must match the constants in android.os.LocalPowerManager.
245 */
246 static final String[] USER_ACTIVITY_TYPES = {
247 "other", "cheek", "touch", "long_touch", "touch_up", "button", "unknown"
248 };
249
250 public static final int NUM_USER_ACTIVITY_TYPES = 7;
251
252 public abstract void noteUserActivityLocked(int type);
253 public abstract boolean hasUserActivity();
254 public abstract int getUserActivityCount(int type, int which);
255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 public static abstract class Sensor {
257 // Magic sensor number for the GPS.
258 public static final int GPS = -10000;
259
260 public abstract int getHandle();
261
262 public abstract Timer getSensorTime();
263 }
264
265 /**
266 * The statistics associated with a particular process.
267 */
268 public static abstract class Proc {
269
270 /**
271 * Returns the total time (in 1/100 sec) spent executing in user code.
272 *
273 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
274 */
275 public abstract long getUserTime(int which);
276
277 /**
278 * Returns the total time (in 1/100 sec) spent executing in system code.
279 *
280 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
281 */
282 public abstract long getSystemTime(int which);
283
284 /**
285 * Returns the number of times the process has been started.
286 *
287 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
288 */
289 public abstract int getStarts(int which);
290 }
291
292 /**
293 * The statistics associated with a particular package.
294 */
295 public static abstract class Pkg {
296
297 /**
298 * Returns the number of times this package has done something that could wake up the
299 * device from sleep.
300 *
301 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
302 */
303 public abstract int getWakeups(int which);
304
305 /**
306 * Returns a mapping containing service statistics.
307 */
308 public abstract Map<String, ? extends Serv> getServiceStats();
309
310 /**
311 * The statistics associated with a particular service.
312 */
313 public abstract class Serv {
314
315 /**
316 * Returns the amount of time spent started.
317 *
318 * @param batteryUptime elapsed uptime on battery in microseconds.
319 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
320 * @return
321 */
322 public abstract long getStartTime(long batteryUptime, int which);
323
324 /**
325 * Returns the total number of times startService() has been called.
326 *
327 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
328 */
329 public abstract int getStarts(int which);
330
331 /**
332 * Returns the total number times the service has been launched.
333 *
334 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
335 */
336 public abstract int getLaunches(int which);
337 }
338 }
339 }
340
341 /**
342 * Returns the number of times the device has been started.
343 */
344 public abstract int getStartCount();
345
346 /**
347 * Returns the time in milliseconds that the screen has been on while the device was
348 * running on battery.
349 *
350 * {@hide}
351 */
352 public abstract long getScreenOnTime(long batteryRealtime, int which);
353
Dianne Hackborn617f8772009-03-31 15:04:46 -0700354 public static final int SCREEN_BRIGHTNESS_DARK = 0;
355 public static final int SCREEN_BRIGHTNESS_DIM = 1;
356 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
357 public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
358 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
359
360 static final String[] SCREEN_BRIGHTNESS_NAMES = {
361 "dark", "dim", "medium", "light", "bright"
362 };
363
364 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
365
366 /**
367 * Returns the time in milliseconds that the screen has been on with
368 * the given brightness
369 *
370 * {@hide}
371 */
372 public abstract long getScreenBrightnessTime(int brightnessBin,
373 long batteryRealtime, int which);
374
375 public abstract int getInputEventCount(int which);
376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 /**
378 * Returns the time in milliseconds that the phone has been on while the device was
379 * running on battery.
380 *
381 * {@hide}
382 */
383 public abstract long getPhoneOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700384
Dianne Hackborn627bba72009-03-24 22:32:56 -0700385 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
386 public static final int SIGNAL_STRENGTH_POOR = 1;
387 public static final int SIGNAL_STRENGTH_MODERATE = 2;
388 public static final int SIGNAL_STRENGTH_GOOD = 3;
389 public static final int SIGNAL_STRENGTH_GREAT = 4;
390
391 static final String[] SIGNAL_STRENGTH_NAMES = {
392 "none", "poor", "moderate", "good", "great"
393 };
394
395 public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
396
397 /**
398 * Returns the time in milliseconds that the phone has been running with
399 * the given signal strength.
400 *
401 * {@hide}
402 */
403 public abstract long getPhoneSignalStrengthTime(int strengthBin,
404 long batteryRealtime, int which);
405
Dianne Hackborn617f8772009-03-31 15:04:46 -0700406 /**
407 * Returns the number of times the phone has entered the given signal strength.
408 *
409 * {@hide}
410 */
411 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
412
Dianne Hackborn627bba72009-03-24 22:32:56 -0700413 public static final int DATA_CONNECTION_NONE = 0;
414 public static final int DATA_CONNECTION_GPRS = 1;
415 public static final int DATA_CONNECTION_EDGE = 2;
416 public static final int DATA_CONNECTION_UMTS = 3;
417 public static final int DATA_CONNECTION_OTHER = 4;
418
419 static final String[] DATA_CONNECTION_NAMES = {
420 "none", "gprs", "edge", "umts", "other"
421 };
422
423 public static final int NUM_DATA_CONNECTION_TYPES = 5;
424
425 /**
426 * Returns the time in milliseconds that the phone has been running with
427 * the given data connection.
428 *
429 * {@hide}
430 */
431 public abstract long getPhoneDataConnectionTime(int dataType,
432 long batteryRealtime, int which);
433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700435 * Returns the number of times the phone has entered the given data
436 * connection type.
437 *
438 * {@hide}
439 */
440 public abstract int getPhoneDataConnectionCount(int dataType, int which);
441
442 /**
The Android Open Source Project10592532009-03-18 17:39:46 -0700443 * Returns the time in milliseconds that wifi has been on while the device was
444 * running on battery.
445 *
446 * {@hide}
447 */
448 public abstract long getWifiOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700449
450 /**
451 * Returns the time in milliseconds that wifi has been on and the driver has
452 * been in the running state while the device was running on battery.
453 *
454 * {@hide}
455 */
456 public abstract long getWifiRunningTime(long batteryRealtime, int which);
457
The Android Open Source Project10592532009-03-18 17:39:46 -0700458 /**
459 * Returns the time in milliseconds that bluetooth has been on while the device was
460 * running on battery.
461 *
462 * {@hide}
463 */
464 public abstract long getBluetoothOnTime(long batteryRealtime, int which);
465
466 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 * Return whether we are currently running on battery.
468 */
469 public abstract boolean getIsOnBattery();
470
471 /**
472 * Returns a SparseArray containing the statistics for each uid.
473 */
474 public abstract SparseArray<? extends Uid> getUidStats();
475
476 /**
477 * Returns the current battery uptime in microseconds.
478 *
479 * @param curTime the amount of elapsed realtime in microseconds.
480 */
481 public abstract long getBatteryUptime(long curTime);
482
483 /**
484 * Returns the current battery realtime in microseconds.
485 *
486 * @param curTime the amount of elapsed realtime in microseconds.
487 */
488 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700489
490 /**
Evan Millar633a1742009-04-02 16:36:33 -0700491 * Returns the battery percentage level at the last time the device was unplugged from power, or
492 * the last time it booted on battery power.
The Android Open Source Project10592532009-03-18 17:39:46 -0700493 */
Evan Millar633a1742009-04-02 16:36:33 -0700494 public abstract int getDischargeStartLevel();
The Android Open Source Project10592532009-03-18 17:39:46 -0700495
496 /**
Evan Millar633a1742009-04-02 16:36:33 -0700497 * Returns the current battery percentage level if we are in a discharge cycle, otherwise
498 * returns the level at the last plug event.
The Android Open Source Project10592532009-03-18 17:39:46 -0700499 */
Evan Millar633a1742009-04-02 16:36:33 -0700500 public abstract int getDischargeCurrentLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501
502 /**
503 * Returns the total, last, or current battery uptime in microseconds.
504 *
505 * @param curTime the elapsed realtime in microseconds.
506 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
507 */
508 public abstract long computeBatteryUptime(long curTime, int which);
509
510 /**
511 * Returns the total, last, or current battery realtime in microseconds.
512 *
513 * @param curTime the current elapsed realtime in microseconds.
514 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
515 */
516 public abstract long computeBatteryRealtime(long curTime, int which);
517
518 /**
519 * Returns the total, last, or current uptime in microseconds.
520 *
521 * @param curTime the current elapsed realtime in microseconds.
522 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
523 */
524 public abstract long computeUptime(long curTime, int which);
525
526 /**
527 * Returns the total, last, or current realtime in microseconds.
528 * *
529 * @param curTime the current elapsed realtime in microseconds.
530 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
531 */
532 public abstract long computeRealtime(long curTime, int which);
Evan Millarc64edde2009-04-18 12:26:32 -0700533
534 public abstract Map<String, ? extends Timer> getKernelWakelockStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700536 private final static void formatTimeRaw(StringBuilder out, long seconds) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 long days = seconds / (60 * 60 * 24);
538 if (days != 0) {
539 out.append(days);
540 out.append("d ");
541 }
542 long used = days * 60 * 60 * 24;
543
544 long hours = (seconds - used) / (60 * 60);
545 if (hours != 0 || used != 0) {
546 out.append(hours);
547 out.append("h ");
548 }
549 used += hours * 60 * 60;
550
551 long mins = (seconds-used) / 60;
552 if (mins != 0 || used != 0) {
553 out.append(mins);
554 out.append("m ");
555 }
556 used += mins * 60;
557
558 if (seconds != 0 || used != 0) {
559 out.append(seconds-used);
560 out.append("s ");
561 }
562 }
563
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700564 private final static void formatTime(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 long sec = time / 100;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700566 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 sb.append((time - (sec * 100)) * 10);
568 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 }
570
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700571 private final static void formatTimeMs(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 long sec = time / 1000;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700573 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 sb.append(time - (sec * 1000));
575 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 }
577
578 private final String formatRatioLocked(long num, long den) {
579 if (den == 0L) {
580 return "---%";
581 }
582 float perc = ((float)num) / ((float)den) * 100;
583 mFormatBuilder.setLength(0);
584 mFormatter.format("%.1f%%", perc);
585 return mFormatBuilder.toString();
586 }
587
Evan Millar22ac0432009-03-31 11:33:18 -0700588 private final String formatBytesLocked(long bytes) {
589 mFormatBuilder.setLength(0);
590
591 if (bytes < BYTES_PER_KB) {
592 return bytes + "B";
593 } else if (bytes < BYTES_PER_MB) {
594 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
595 return mFormatBuilder.toString();
596 } else if (bytes < BYTES_PER_GB){
597 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
598 return mFormatBuilder.toString();
599 } else {
600 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
601 return mFormatBuilder.toString();
602 }
603 }
604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 /**
606 *
607 * @param sb a StringBuilder object.
608 * @param timer a Timer object contining the wakelock times.
609 * @param batteryRealtime the current on-battery time in microseconds.
610 * @param name the name of the wakelock.
611 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
612 * @param linePrefix a String to be prepended to each line of output.
613 * @return the line prefix
614 */
615 private static final String printWakeLock(StringBuilder sb, Timer timer,
616 long batteryRealtime, String name, int which, String linePrefix) {
617
618 if (timer != null) {
619 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -0700620 long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
622
Evan Millarc64edde2009-04-18 12:26:32 -0700623 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 if (totalTimeMillis != 0) {
625 sb.append(linePrefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700626 formatTimeMs(sb, totalTimeMillis);
627 if (name != null) sb.append(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 sb.append(' ');
629 sb.append('(');
630 sb.append(count);
631 sb.append(" times)");
632 return ", ";
633 }
634 }
635 return linePrefix;
636 }
637
638 /**
639 * Checkin version of wakelock printer. Prints simple comma-separated list.
640 *
641 * @param sb a StringBuilder object.
642 * @param timer a Timer object contining the wakelock times.
643 * @param now the current time in microseconds.
644 * @param name the name of the wakelock.
645 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
646 * @param linePrefix a String to be prepended to each line of output.
647 * @return the line prefix
648 */
649 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
Evan Millarc64edde2009-04-18 12:26:32 -0700650 String name, int which, String linePrefix) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 long totalTimeMicros = 0;
652 int count = 0;
653 if (timer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700654 totalTimeMicros = timer.getTotalTimeLocked(now, which);
655 count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 }
657 sb.append(linePrefix);
658 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
659 sb.append(',');
Evan Millarc64edde2009-04-18 12:26:32 -0700660 sb.append(name != null ? name + "," : "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 sb.append(count);
662 return ",";
663 }
664
665 /**
666 * Dump a comma-separated line of values for terse checkin mode.
667 *
668 * @param pw the PageWriter to dump log to
669 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
670 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
671 * @param args type-dependent data arguments
672 */
673 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
674 Object... args ) {
675 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
676 pw.print(uid); pw.print(',');
677 pw.print(category); pw.print(',');
678 pw.print(type);
679
680 for (Object arg : args) {
681 pw.print(',');
682 pw.print(arg);
683 }
684 pw.print('\n');
685 }
686
687 /**
688 * Checkin server version of dump to produce more compact, computer-readable log.
689 *
690 * NOTE: all times are expressed in 'ms'.
691 * @param fd
692 * @param pw
693 * @param which
694 */
695 private final void dumpCheckinLocked(PrintWriter pw, int which) {
696 final long rawUptime = SystemClock.uptimeMillis() * 1000;
697 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
698 final long batteryUptime = getBatteryUptime(rawUptime);
699 final long batteryRealtime = getBatteryRealtime(rawRealtime);
700 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
701 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
702 final long totalRealtime = computeRealtime(rawRealtime, which);
703 final long totalUptime = computeUptime(rawUptime, which);
704 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
705 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700706 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700707 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700708 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800709
710 StringBuilder sb = new StringBuilder(128);
711
Evan Millar22ac0432009-03-31 11:33:18 -0700712 SparseArray<? extends Uid> uidStats = getUidStats();
713 final int NU = uidStats.size();
714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715 String category = STAT_NAMES[which];
716
717 // Dump "battery" stat
718 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
719 which == STATS_TOTAL ? getStartCount() : "N/A",
Dianne Hackborn617f8772009-03-31 15:04:46 -0700720 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
721 totalRealtime / 1000, totalUptime / 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722
Evan Millar22ac0432009-03-31 11:33:18 -0700723 // Calculate total network and wakelock times across all uids.
724 long rxTotal = 0;
725 long txTotal = 0;
726 long fullWakeLockTimeTotal = 0;
727 long partialWakeLockTimeTotal = 0;
728
729 for (int iu = 0; iu < NU; iu++) {
730 Uid u = uidStats.valueAt(iu);
731 rxTotal += u.getTcpBytesReceived(which);
732 txTotal += u.getTcpBytesSent(which);
733
734 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
735 if (wakelocks.size() > 0) {
736 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
737 : wakelocks.entrySet()) {
738 Uid.Wakelock wl = ent.getValue();
739
740 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
741 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700742 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
Evan Millar22ac0432009-03-31 11:33:18 -0700743 }
744
745 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
746 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700747 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -0700748 batteryRealtime, which);
749 }
750 }
751 }
752 }
753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 // Dump misc stats
755 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700756 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
Evan Millar22ac0432009-03-31 11:33:18 -0700757 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal,
Dianne Hackborn617f8772009-03-31 15:04:46 -0700758 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
759 getInputEventCount(which));
760
761 // Dump screen brightness stats
762 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
763 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
764 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
765 }
766 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
The Android Open Source Project10592532009-03-18 17:39:46 -0700767
Dianne Hackborn627bba72009-03-24 22:32:56 -0700768 // Dump signal strength stats
Dianne Hackborn617f8772009-03-31 15:04:46 -0700769 args = new Object[NUM_SIGNAL_STRENGTH_BINS];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700770 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
771 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
772 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700773 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
774 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
775 args[i] = getPhoneSignalStrengthCount(i, which);
776 }
777 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700778
779 // Dump network type stats
780 args = new Object[NUM_DATA_CONNECTION_TYPES];
781 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
782 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
783 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700784 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
785 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
786 args[i] = getPhoneDataConnectionCount(i, which);
787 }
788 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700789
The Android Open Source Project10592532009-03-18 17:39:46 -0700790 if (which == STATS_UNPLUGGED) {
Evan Millare84de8d2009-04-02 22:16:12 -0700791 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
Evan Millar633a1742009-04-02 16:36:33 -0700792 getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -0700793 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794
Evan Millarc64edde2009-04-18 12:26:32 -0700795 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
796 if (kernelWakelocks.size() > 0) {
797 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
798 sb.setLength(0);
799 printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
800
801 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
802 sb.toString());
803 }
804 }
805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 for (int iu = 0; iu < NU; iu++) {
807 final int uid = uidStats.keyAt(iu);
808 Uid u = uidStats.valueAt(iu);
809 // Dump Network stats per uid, if any
810 long rx = u.getTcpBytesReceived(which);
811 long tx = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700812 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
813 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700814 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -0700817
Dianne Hackborn617f8772009-03-31 15:04:46 -0700818 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
819 || wifiTurnedOnTime != 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700820 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
Dianne Hackborn617f8772009-03-31 15:04:46 -0700821 fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823
Dianne Hackborn617f8772009-03-31 15:04:46 -0700824 if (u.hasUserActivity()) {
825 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
826 boolean hasData = false;
827 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
828 int val = u.getUserActivityCount(i, which);
829 args[i] = val;
830 if (val != 0) hasData = true;
831 }
832 if (hasData) {
833 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args);
834 }
835 }
836
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
838 if (wakelocks.size() > 0) {
839 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
840 : wakelocks.entrySet()) {
841 Uid.Wakelock wl = ent.getValue();
842 String linePrefix = "";
843 sb.setLength(0);
Evan Millarc64edde2009-04-18 12:26:32 -0700844 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
845 batteryRealtime, "f", which, linePrefix);
846 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
847 batteryRealtime, "p", which, linePrefix);
848 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
849 batteryRealtime, "w", which, linePrefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850
851 // Only log if we had at lease one wakelock...
852 if (sb.length() > 0) {
853 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
854 }
855 }
856 }
857
858 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
859 if (sensors.size() > 0) {
860 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
861 : sensors.entrySet()) {
862 Uid.Sensor se = ent.getValue();
863 int sensorNumber = ent.getKey();
864 Timer timer = se.getSensorTime();
865 if (timer != null) {
866 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -0700867 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
868 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 if (totalTime != 0) {
870 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
871 }
872 }
873 }
874 }
875
876 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
877 if (processStats.size() > 0) {
878 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
879 : processStats.entrySet()) {
880 Uid.Proc ps = ent.getValue();
881
882 long userTime = ps.getUserTime(which);
883 long systemTime = ps.getSystemTime(which);
884 int starts = ps.getStarts(which);
885
886 if (userTime != 0 || systemTime != 0 || starts != 0) {
887 dumpLine(pw, uid, category, PROCESS_DATA,
888 ent.getKey(), // proc
889 userTime * 10, // cpu time in ms
890 systemTime * 10, // user time in ms
891 starts); // process starts
892 }
893 }
894 }
895
896 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
897 if (packageStats.size() > 0) {
898 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
899 : packageStats.entrySet()) {
900
901 Uid.Pkg ps = ent.getValue();
902 int wakeups = ps.getWakeups(which);
903 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
904 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
905 : serviceStats.entrySet()) {
906 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
907 long startTime = ss.getStartTime(batteryUptime, which);
908 int starts = ss.getStarts(which);
909 int launches = ss.getLaunches(which);
910 if (startTime != 0 || starts != 0 || launches != 0) {
911 dumpLine(pw, uid, category, APK_DATA,
912 wakeups, // wakeup alarms
913 ent.getKey(), // Apk
914 sent.getKey(), // service
915 startTime / 1000, // time spent started, in ms
916 starts,
917 launches);
918 }
919 }
920 }
921 }
922 }
923 }
924
925 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700926 private final void dumpLocked(PrintWriter pw, String prefix, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 final long rawUptime = SystemClock.uptimeMillis() * 1000;
928 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
929 final long batteryUptime = getBatteryUptime(rawUptime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700930 final long batteryRealtime = getBatteryRealtime(rawRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931
932 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
933 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
934 final long totalRealtime = computeRealtime(rawRealtime, which);
935 final long totalUptime = computeUptime(rawUptime, which);
936
937 StringBuilder sb = new StringBuilder(128);
Evan Millar22ac0432009-03-31 11:33:18 -0700938
939 SparseArray<? extends Uid> uidStats = getUidStats();
940 final int NU = uidStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700942 sb.setLength(0);
943 sb.append(prefix);
944 sb.append(" Time on battery: ");
945 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
946 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
947 sb.append(") realtime, ");
948 formatTimeMs(sb, whichBatteryUptime / 1000);
949 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
950 sb.append(") uptime");
951 pw.println(sb.toString());
952 sb.setLength(0);
953 sb.append(prefix);
954 sb.append(" Total run time: ");
955 formatTimeMs(sb, totalRealtime / 1000);
956 sb.append("realtime, ");
957 formatTimeMs(sb, totalUptime / 1000);
958 sb.append("uptime, ");
959 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960
The Android Open Source Project10592532009-03-18 17:39:46 -0700961 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
962 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700963 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700964 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
965 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700966 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700967 sb.append(prefix);
968 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
969 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
970 sb.append("), Input events: "); sb.append(getInputEventCount(which));
971 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
972 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
973 sb.append(")");
974 pw.println(sb.toString());
975 sb.setLength(0);
976 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700977 sb.append(" Screen brightnesses: ");
978 boolean didOne = false;
979 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
980 final long time = getScreenBrightnessTime(i, batteryRealtime, which);
981 if (time == 0) {
982 continue;
983 }
984 if (didOne) sb.append(", ");
985 didOne = true;
986 sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
987 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700988 formatTimeMs(sb, time/1000);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700989 sb.append("(");
990 sb.append(formatRatioLocked(time, screenOnTime));
991 sb.append(")");
992 }
993 if (!didOne) sb.append("No activity");
994 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -0700995
Evan Millar22ac0432009-03-31 11:33:18 -0700996 // Calculate total network and wakelock times across all uids.
997 long rxTotal = 0;
998 long txTotal = 0;
999 long fullWakeLockTimeTotalMicros = 0;
1000 long partialWakeLockTimeTotalMicros = 0;
1001
Evan Millarc64edde2009-04-18 12:26:32 -07001002 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1003 if (kernelWakelocks.size() > 0) {
1004 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1005
1006 String linePrefix = ": ";
1007 sb.setLength(0);
1008 sb.append(prefix);
1009 sb.append(" Kernel Wake lock ");
1010 sb.append(ent.getKey());
1011 linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
1012 linePrefix);
1013 if (!linePrefix.equals(": ")) {
1014 sb.append(" realtime");
1015 } else {
1016 sb.append(": (nothing executed)");
1017 }
1018 pw.println(sb.toString());
1019 }
1020 }
1021
Evan Millar22ac0432009-03-31 11:33:18 -07001022 for (int iu = 0; iu < NU; iu++) {
1023 Uid u = uidStats.valueAt(iu);
1024 rxTotal += u.getTcpBytesReceived(which);
1025 txTotal += u.getTcpBytesSent(which);
1026
1027 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1028 if (wakelocks.size() > 0) {
1029 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1030 : wakelocks.entrySet()) {
1031 Uid.Wakelock wl = ent.getValue();
1032
1033 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1034 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001035 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001036 batteryRealtime, which);
1037 }
1038
1039 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1040 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001041 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001042 batteryRealtime, which);
1043 }
1044 }
1045 }
1046 }
1047
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001048 pw.print(prefix);
1049 pw.print(" Total received: "); pw.print(formatBytesLocked(rxTotal));
1050 pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal));
1051 sb.setLength(0);
1052 sb.append(prefix);
1053 sb.append(" Total full wakelock time: "); formatTimeMs(sb,
1054 (fullWakeLockTimeTotalMicros + 500) / 1000);
1055 sb.append(", Total partial waklock time: "); formatTimeMs(sb,
1056 (partialWakeLockTimeTotalMicros + 500) / 1000);
1057 pw.println(sb.toString());
Evan Millar22ac0432009-03-31 11:33:18 -07001058
Dianne Hackborn627bba72009-03-24 22:32:56 -07001059 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001060 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001061 sb.append(" Signal levels: ");
1062 didOne = false;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001063 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
1064 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
1065 if (time == 0) {
1066 continue;
1067 }
1068 if (didOne) sb.append(", ");
1069 didOne = true;
1070 sb.append(SIGNAL_STRENGTH_NAMES[i]);
1071 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001072 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001073 sb.append("(");
1074 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001075 sb.append(") ");
1076 sb.append(getPhoneSignalStrengthCount(i, which));
1077 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001078 }
1079 if (!didOne) sb.append("No activity");
1080 pw.println(sb.toString());
1081
1082 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001083 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001084 sb.append(" Radio types: ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001085 didOne = false;
1086 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1087 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
1088 if (time == 0) {
1089 continue;
1090 }
1091 if (didOne) sb.append(", ");
1092 didOne = true;
1093 sb.append(DATA_CONNECTION_NAMES[i]);
1094 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001095 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001096 sb.append("(");
1097 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001098 sb.append(") ");
1099 sb.append(getPhoneDataConnectionCount(i, which));
1100 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001101 }
1102 if (!didOne) sb.append("No activity");
1103 pw.println(sb.toString());
1104
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001105 sb.setLength(0);
1106 sb.append(prefix);
1107 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
1108 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
1109 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
1110 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
1111 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
1112 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
1113 sb.append(")");
1114 pw.println(sb.toString());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001115
The Android Open Source Project10592532009-03-18 17:39:46 -07001116 pw.println(" ");
1117
1118 if (which == STATS_UNPLUGGED) {
1119 if (getIsOnBattery()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001120 pw.print(prefix); pw.println(" Device is currently unplugged");
1121 pw.print(prefix); pw.print(" Discharge cycle start level: ");
1122 pw.println(getDischargeStartLevel());
1123 pw.print(prefix); pw.print(" Discharge cycle current level: ");
1124 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001125 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001126 pw.print(prefix); pw.println(" Device is currently plugged into power");
1127 pw.print(prefix); pw.print(" Last discharge cycle start level: ");
1128 pw.println(getDischargeStartLevel());
1129 pw.print(prefix); pw.print(" Last discharge cycle end level: ");
1130 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001131 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001132 pw.println(" ");
The Android Open Source Project10592532009-03-18 17:39:46 -07001133 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134
Evan Millar22ac0432009-03-31 11:33:18 -07001135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 for (int iu=0; iu<NU; iu++) {
1137 final int uid = uidStats.keyAt(iu);
1138 Uid u = uidStats.valueAt(iu);
1139 pw.println(prefix + " #" + uid + ":");
1140 boolean uidActivity = false;
1141
1142 long tcpReceived = u.getTcpBytesReceived(which);
1143 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001144 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1145 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001146 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 if (tcpReceived != 0 || tcpSent != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001149 pw.print(prefix); pw.print(" Network: ");
1150 pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, ");
1151 pw.print(formatBytesLocked(tcpSent)); pw.println(" sent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001153
1154 if (u.hasUserActivity()) {
1155 boolean hasData = false;
1156 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1157 int val = u.getUserActivityCount(i, which);
1158 if (val != 0) {
1159 if (!hasData) {
1160 sb.setLength(0);
1161 sb.append(" User activity: ");
1162 hasData = true;
1163 } else {
1164 sb.append(", ");
1165 }
1166 sb.append(val);
1167 sb.append(" ");
1168 sb.append(Uid.USER_ACTIVITY_TYPES[i]);
1169 }
1170 }
1171 if (hasData) {
1172 pw.println(sb.toString());
1173 }
1174 }
1175
1176 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
1177 || wifiTurnedOnTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001178 sb.setLength(0);
1179 sb.append(prefix); sb.append(" Turned Wifi On: ");
1180 formatTimeMs(sb, wifiTurnedOnTime / 1000);
1181 sb.append("("); sb.append(formatRatioLocked(wifiTurnedOnTime,
1182 whichBatteryRealtime)); sb.append(")\n");
1183 sb.append(prefix); sb.append(" Full Wifi Lock: ");
1184 formatTimeMs(sb, fullWifiLockOnTime / 1000);
1185 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
1186 whichBatteryRealtime)); sb.append(")\n");
1187 sb.append(prefix); sb.append(" Scan Wifi Lock: ");
1188 formatTimeMs(sb, scanWifiLockOnTime / 1000);
1189 sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime,
1190 whichBatteryRealtime)); sb.append(")");
1191 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193
1194 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1195 if (wakelocks.size() > 0) {
1196 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1197 : wakelocks.entrySet()) {
1198 Uid.Wakelock wl = ent.getValue();
1199 String linePrefix = ": ";
1200 sb.setLength(0);
1201 sb.append(prefix);
1202 sb.append(" Wake lock ");
1203 sb.append(ent.getKey());
1204 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
1205 "full", which, linePrefix);
1206 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
1207 "partial", which, linePrefix);
1208 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
1209 "window", which, linePrefix);
1210 if (!linePrefix.equals(": ")) {
1211 sb.append(" realtime");
1212 } else {
1213 sb.append(": (nothing executed)");
1214 }
1215 pw.println(sb.toString());
1216 uidActivity = true;
1217 }
1218 }
1219
1220 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1221 if (sensors.size() > 0) {
1222 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1223 : sensors.entrySet()) {
1224 Uid.Sensor se = ent.getValue();
1225 int sensorNumber = ent.getKey();
1226 sb.setLength(0);
1227 sb.append(prefix);
1228 sb.append(" Sensor ");
1229 int handle = se.getHandle();
1230 if (handle == Uid.Sensor.GPS) {
1231 sb.append("GPS");
1232 } else {
1233 sb.append(handle);
1234 }
1235 sb.append(": ");
1236
1237 Timer timer = se.getSensorTime();
1238 if (timer != null) {
1239 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -07001240 long totalTime = (timer.getTotalTimeLocked(
1241 batteryRealtime, which) + 500) / 1000;
1242 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 //timer.logState();
1244 if (totalTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001245 formatTimeMs(sb, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001246 sb.append("realtime (");
1247 sb.append(count);
1248 sb.append(" times)");
1249 } else {
1250 sb.append("(not used)");
1251 }
1252 } else {
1253 sb.append("(not used)");
1254 }
1255
1256 pw.println(sb.toString());
1257 uidActivity = true;
1258 }
1259 }
1260
1261 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1262 if (processStats.size() > 0) {
1263 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1264 : processStats.entrySet()) {
1265 Uid.Proc ps = ent.getValue();
1266 long userTime;
1267 long systemTime;
1268 int starts;
1269
1270 userTime = ps.getUserTime(which);
1271 systemTime = ps.getSystemTime(which);
1272 starts = ps.getStarts(which);
1273
1274 if (userTime != 0 || systemTime != 0 || starts != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001275 sb.setLength(0);
1276 sb.append(prefix); sb.append(" Proc ");
1277 sb.append(ent.getKey()); sb.append(":\n");
1278 sb.append(prefix); sb.append(" CPU: ");
1279 formatTime(sb, userTime); sb.append("usr + ");
1280 formatTime(sb, systemTime); sb.append("krn\n");
1281 sb.append(prefix); sb.append(" "); sb.append(starts);
1282 sb.append(" proc starts");
1283 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 uidActivity = true;
1285 }
1286 }
1287 }
1288
1289 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1290 if (packageStats.size() > 0) {
1291 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1292 : packageStats.entrySet()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001293 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 boolean apkActivity = false;
1295 Uid.Pkg ps = ent.getValue();
1296 int wakeups = ps.getWakeups(which);
1297 if (wakeups != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001298 pw.print(prefix); pw.print(" ");
1299 pw.print(wakeups); pw.println(" wakeup alarms");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 apkActivity = true;
1301 }
1302 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1303 if (serviceStats.size() > 0) {
1304 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1305 : serviceStats.entrySet()) {
1306 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1307 long startTime = ss.getStartTime(batteryUptime, which);
1308 int starts = ss.getStarts(which);
1309 int launches = ss.getLaunches(which);
1310 if (startTime != 0 || starts != 0 || launches != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001311 sb.setLength(0);
1312 sb.append(prefix); sb.append(" Service ");
1313 sb.append(sent.getKey()); sb.append(":\n");
1314 sb.append(prefix); sb.append(" Created for: ");
1315 formatTimeMs(sb, startTime / 1000);
1316 sb.append(" uptime\n");
1317 sb.append(prefix); sb.append(" Starts: ");
1318 sb.append(starts);
1319 sb.append(", launches: "); sb.append(launches);
1320 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 apkActivity = true;
1322 }
1323 }
1324 }
1325 if (!apkActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001326 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327 }
1328 uidActivity = true;
1329 }
1330 }
1331 if (!uidActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001332 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 }
1334 }
1335 }
1336
1337 /**
1338 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
1339 *
1340 * @param pw a Printer to receive the dump output.
1341 */
1342 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001343 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 pw.println("Total Statistics (Current and Historic):");
1345 pw.println(" System starts: " + getStartCount()
1346 + ", currently on battery: " + getIsOnBattery());
1347 dumpLocked(pw, "", STATS_TOTAL);
1348 pw.println("");
1349 pw.println("Last Run Statistics (Previous run of system):");
1350 dumpLocked(pw, "", STATS_LAST);
1351 pw.println("");
1352 pw.println("Current Battery Statistics (Currently running system):");
1353 dumpLocked(pw, "", STATS_CURRENT);
1354 pw.println("");
1355 pw.println("Unplugged Statistics (Since last unplugged from power):");
1356 dumpLocked(pw, "", STATS_UNPLUGGED);
1357 }
1358
1359 @SuppressWarnings("unused")
1360 public void dumpCheckinLocked(PrintWriter pw, String[] args) {
1361 boolean isUnpluggedOnly = false;
1362
1363 for (String arg : args) {
1364 if ("-u".equals(arg)) {
1365 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
1366 isUnpluggedOnly = true;
1367 }
1368 }
1369
1370 if (isUnpluggedOnly) {
1371 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1372 }
1373 else {
1374 dumpCheckinLocked(pw, STATS_TOTAL);
1375 dumpCheckinLocked(pw, STATS_LAST);
1376 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1377 dumpCheckinLocked(pw, STATS_CURRENT);
1378 }
1379 }
1380
1381}