blob: 333ba731742ede97e3c51d0f711fb853c1250d79 [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
64 /**
65 * Include all of the data in the stats, including previously saved data.
66 */
67 public static final int STATS_TOTAL = 0;
68
69 /**
70 * Include only the last run in the stats.
71 */
72 public static final int STATS_LAST = 1;
73
74 /**
75 * Include only the current run in the stats.
76 */
77 public static final int STATS_CURRENT = 2;
78
79 /**
80 * Include only the run since the last time the device was unplugged in the stats.
81 */
82 public static final int STATS_UNPLUGGED = 3;
Evan Millare84de8d2009-04-02 22:16:12 -070083
84 // NOTE: Update this list if you add/change any stats above.
85 // These characters are supposed to represent "total", "last", "current",
86 // and "unplugged". They were shortened for effeciency sake.
87 private static final String[] STAT_NAMES = { "t", "l", "c", "u" };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
89 /**
90 * Bump the version on this if the checkin format changes.
91 */
Evan Millarc64edde2009-04-18 12:26:32 -070092 private static final int BATTERY_STATS_CHECKIN_VERSION = 5;
Evan Millar22ac0432009-03-31 11:33:18 -070093
94 private static final long BYTES_PER_KB = 1024;
95 private static final long BYTES_PER_MB = 1048576; // 1024^2
96 private static final long BYTES_PER_GB = 1073741824; //1024^3
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098
99 private static final String APK_DATA = "apk";
Evan Millare84de8d2009-04-02 22:16:12 -0700100 private static final String PROCESS_DATA = "pr";
101 private static final String SENSOR_DATA = "sr";
102 private static final String WAKELOCK_DATA = "wl";
Evan Millarc64edde2009-04-18 12:26:32 -0700103 private static final String KERNEL_WAKELOCK_DATA = "kwl";
Evan Millare84de8d2009-04-02 22:16:12 -0700104 private static final String NETWORK_DATA = "nt";
105 private static final String USER_ACTIVITY_DATA = "ua";
106 private static final String BATTERY_DATA = "bt";
107 private static final String BATTERY_LEVEL_DATA = "lv";
108 private static final String WIFI_LOCK_DATA = "wfl";
109 private static final String MISC_DATA = "m";
110 private static final String SCREEN_BRIGHTNESS_DATA = "br";
111 private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
112 private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
113 private static final String DATA_CONNECTION_TIME_DATA = "dct";
114 private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700116 private final StringBuilder mFormatBuilder = new StringBuilder(32);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 private final Formatter mFormatter = new Formatter(mFormatBuilder);
118
119 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700120 * State for keeping track of counting information.
121 */
122 public static abstract class Counter {
123
124 /**
125 * Returns the count associated with this Counter for the
126 * selected type of statistics.
127 *
128 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
129 */
Evan Millarc64edde2009-04-18 12:26:32 -0700130 public abstract int getCountLocked(int which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700131
132 /**
133 * Temporary for debugging.
134 */
135 public abstract void logState(Printer pw, String prefix);
136 }
137
138 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 * State for keeping track of timing information.
140 */
141 public static abstract class Timer {
142
143 /**
144 * Returns the count associated with this Timer for the
145 * selected type of statistics.
146 *
147 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
148 */
Evan Millarc64edde2009-04-18 12:26:32 -0700149 public abstract int getCountLocked(int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150
151 /**
152 * Returns the total time in microseconds associated with this Timer for the
153 * selected type of statistics.
154 *
155 * @param batteryRealtime system realtime on battery in microseconds
156 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
157 * @return a time in microseconds
158 */
Evan Millarc64edde2009-04-18 12:26:32 -0700159 public abstract long getTotalTimeLocked(long batteryRealtime, int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160
161 /**
162 * Temporary for debugging.
163 */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700164 public abstract void logState(Printer pw, String prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 }
166
167 /**
168 * The statistics associated with a particular uid.
169 */
170 public static abstract class Uid {
171
172 /**
173 * Returns a mapping containing wakelock statistics.
174 *
175 * @return a Map from Strings to Uid.Wakelock objects.
176 */
177 public abstract Map<String, ? extends Wakelock> getWakelockStats();
178
179 /**
180 * The statistics associated with a particular wake lock.
181 */
182 public static abstract class Wakelock {
183 public abstract Timer getWakeTime(int type);
184 }
185
186 /**
187 * Returns a mapping containing sensor statistics.
188 *
189 * @return a Map from Integer sensor ids to Uid.Sensor objects.
190 */
191 public abstract Map<Integer, ? extends Sensor> getSensorStats();
192
193 /**
194 * Returns a mapping containing process statistics.
195 *
196 * @return a Map from Strings to Uid.Proc objects.
197 */
198 public abstract Map<String, ? extends Proc> getProcessStats();
199
200 /**
201 * Returns a mapping containing package statistics.
202 *
203 * @return a Map from Strings to Uid.Pkg objects.
204 */
205 public abstract Map<String, ? extends Pkg> getPackageStats();
206
207 /**
208 * {@hide}
209 */
210 public abstract int getUid();
211
212 /**
213 * {@hide}
214 */
215 public abstract long getTcpBytesReceived(int which);
216
217 /**
218 * {@hide}
219 */
220 public abstract long getTcpBytesSent(int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700221
Dianne Hackborn617f8772009-03-31 15:04:46 -0700222 public abstract void noteWifiTurnedOnLocked();
223 public abstract void noteWifiTurnedOffLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700224 public abstract void noteFullWifiLockAcquiredLocked();
225 public abstract void noteFullWifiLockReleasedLocked();
226 public abstract void noteScanWifiLockAcquiredLocked();
227 public abstract void noteScanWifiLockReleasedLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700228 public abstract long getWifiTurnedOnTime(long batteryRealtime, int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700229 public abstract long getFullWifiLockTime(long batteryRealtime, int which);
230 public abstract long getScanWifiLockTime(long batteryRealtime, int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231
Dianne Hackborn617f8772009-03-31 15:04:46 -0700232 /**
233 * Note that these must match the constants in android.os.LocalPowerManager.
234 */
235 static final String[] USER_ACTIVITY_TYPES = {
236 "other", "cheek", "touch", "long_touch", "touch_up", "button", "unknown"
237 };
238
239 public static final int NUM_USER_ACTIVITY_TYPES = 7;
240
241 public abstract void noteUserActivityLocked(int type);
242 public abstract boolean hasUserActivity();
243 public abstract int getUserActivityCount(int type, int which);
244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 public static abstract class Sensor {
246 // Magic sensor number for the GPS.
247 public static final int GPS = -10000;
248
249 public abstract int getHandle();
250
251 public abstract Timer getSensorTime();
252 }
253
254 /**
255 * The statistics associated with a particular process.
256 */
257 public static abstract class Proc {
258
259 /**
260 * Returns the total time (in 1/100 sec) spent executing in user code.
261 *
262 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
263 */
264 public abstract long getUserTime(int which);
265
266 /**
267 * Returns the total time (in 1/100 sec) spent executing in system code.
268 *
269 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
270 */
271 public abstract long getSystemTime(int which);
272
273 /**
274 * Returns the number of times the process has been started.
275 *
276 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
277 */
278 public abstract int getStarts(int which);
279 }
280
281 /**
282 * The statistics associated with a particular package.
283 */
284 public static abstract class Pkg {
285
286 /**
287 * Returns the number of times this package has done something that could wake up the
288 * device from sleep.
289 *
290 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
291 */
292 public abstract int getWakeups(int which);
293
294 /**
295 * Returns a mapping containing service statistics.
296 */
297 public abstract Map<String, ? extends Serv> getServiceStats();
298
299 /**
300 * The statistics associated with a particular service.
301 */
302 public abstract class Serv {
303
304 /**
305 * Returns the amount of time spent started.
306 *
307 * @param batteryUptime elapsed uptime on battery in microseconds.
308 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
309 * @return
310 */
311 public abstract long getStartTime(long batteryUptime, int which);
312
313 /**
314 * Returns the total number of times startService() has been called.
315 *
316 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
317 */
318 public abstract int getStarts(int which);
319
320 /**
321 * Returns the total number times the service has been launched.
322 *
323 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
324 */
325 public abstract int getLaunches(int which);
326 }
327 }
328 }
329
330 /**
331 * Returns the number of times the device has been started.
332 */
333 public abstract int getStartCount();
334
335 /**
336 * Returns the time in milliseconds that the screen has been on while the device was
337 * running on battery.
338 *
339 * {@hide}
340 */
341 public abstract long getScreenOnTime(long batteryRealtime, int which);
342
Dianne Hackborn617f8772009-03-31 15:04:46 -0700343 public static final int SCREEN_BRIGHTNESS_DARK = 0;
344 public static final int SCREEN_BRIGHTNESS_DIM = 1;
345 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
346 public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
347 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
348
349 static final String[] SCREEN_BRIGHTNESS_NAMES = {
350 "dark", "dim", "medium", "light", "bright"
351 };
352
353 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
354
355 /**
356 * Returns the time in milliseconds that the screen has been on with
357 * the given brightness
358 *
359 * {@hide}
360 */
361 public abstract long getScreenBrightnessTime(int brightnessBin,
362 long batteryRealtime, int which);
363
364 public abstract int getInputEventCount(int which);
365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 /**
367 * Returns the time in milliseconds that the phone has been on while the device was
368 * running on battery.
369 *
370 * {@hide}
371 */
372 public abstract long getPhoneOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700373
Dianne Hackborn627bba72009-03-24 22:32:56 -0700374 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
375 public static final int SIGNAL_STRENGTH_POOR = 1;
376 public static final int SIGNAL_STRENGTH_MODERATE = 2;
377 public static final int SIGNAL_STRENGTH_GOOD = 3;
378 public static final int SIGNAL_STRENGTH_GREAT = 4;
379
380 static final String[] SIGNAL_STRENGTH_NAMES = {
381 "none", "poor", "moderate", "good", "great"
382 };
383
384 public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
385
386 /**
387 * Returns the time in milliseconds that the phone has been running with
388 * the given signal strength.
389 *
390 * {@hide}
391 */
392 public abstract long getPhoneSignalStrengthTime(int strengthBin,
393 long batteryRealtime, int which);
394
Dianne Hackborn617f8772009-03-31 15:04:46 -0700395 /**
396 * Returns the number of times the phone has entered the given signal strength.
397 *
398 * {@hide}
399 */
400 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
401
Dianne Hackborn627bba72009-03-24 22:32:56 -0700402 public static final int DATA_CONNECTION_NONE = 0;
403 public static final int DATA_CONNECTION_GPRS = 1;
404 public static final int DATA_CONNECTION_EDGE = 2;
405 public static final int DATA_CONNECTION_UMTS = 3;
406 public static final int DATA_CONNECTION_OTHER = 4;
407
408 static final String[] DATA_CONNECTION_NAMES = {
409 "none", "gprs", "edge", "umts", "other"
410 };
411
412 public static final int NUM_DATA_CONNECTION_TYPES = 5;
413
414 /**
415 * Returns the time in milliseconds that the phone has been running with
416 * the given data connection.
417 *
418 * {@hide}
419 */
420 public abstract long getPhoneDataConnectionTime(int dataType,
421 long batteryRealtime, int which);
422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700424 * Returns the number of times the phone has entered the given data
425 * connection type.
426 *
427 * {@hide}
428 */
429 public abstract int getPhoneDataConnectionCount(int dataType, int which);
430
431 /**
The Android Open Source Project10592532009-03-18 17:39:46 -0700432 * Returns the time in milliseconds that wifi has been on while the device was
433 * running on battery.
434 *
435 * {@hide}
436 */
437 public abstract long getWifiOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700438
439 /**
440 * Returns the time in milliseconds that wifi has been on and the driver has
441 * been in the running state while the device was running on battery.
442 *
443 * {@hide}
444 */
445 public abstract long getWifiRunningTime(long batteryRealtime, int which);
446
The Android Open Source Project10592532009-03-18 17:39:46 -0700447 /**
448 * Returns the time in milliseconds that bluetooth has been on while the device was
449 * running on battery.
450 *
451 * {@hide}
452 */
453 public abstract long getBluetoothOnTime(long batteryRealtime, int which);
454
455 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 * Return whether we are currently running on battery.
457 */
458 public abstract boolean getIsOnBattery();
459
460 /**
461 * Returns a SparseArray containing the statistics for each uid.
462 */
463 public abstract SparseArray<? extends Uid> getUidStats();
464
465 /**
466 * Returns the current battery uptime in microseconds.
467 *
468 * @param curTime the amount of elapsed realtime in microseconds.
469 */
470 public abstract long getBatteryUptime(long curTime);
471
472 /**
473 * Returns the current battery realtime in microseconds.
474 *
475 * @param curTime the amount of elapsed realtime in microseconds.
476 */
477 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700478
479 /**
Evan Millar633a1742009-04-02 16:36:33 -0700480 * Returns the battery percentage level at the last time the device was unplugged from power, or
481 * the last time it booted on battery power.
The Android Open Source Project10592532009-03-18 17:39:46 -0700482 */
Evan Millar633a1742009-04-02 16:36:33 -0700483 public abstract int getDischargeStartLevel();
The Android Open Source Project10592532009-03-18 17:39:46 -0700484
485 /**
Evan Millar633a1742009-04-02 16:36:33 -0700486 * Returns the current battery percentage level if we are in a discharge cycle, otherwise
487 * returns the level at the last plug event.
The Android Open Source Project10592532009-03-18 17:39:46 -0700488 */
Evan Millar633a1742009-04-02 16:36:33 -0700489 public abstract int getDischargeCurrentLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490
491 /**
492 * Returns the total, last, or current battery uptime in microseconds.
493 *
494 * @param curTime the elapsed realtime in microseconds.
495 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
496 */
497 public abstract long computeBatteryUptime(long curTime, int which);
498
499 /**
500 * Returns the total, last, or current battery realtime in microseconds.
501 *
502 * @param curTime the current elapsed realtime in microseconds.
503 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
504 */
505 public abstract long computeBatteryRealtime(long curTime, int which);
506
507 /**
508 * Returns the total, last, or current uptime in microseconds.
509 *
510 * @param curTime the current elapsed realtime in microseconds.
511 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
512 */
513 public abstract long computeUptime(long curTime, int which);
514
515 /**
516 * Returns the total, last, or current realtime in microseconds.
517 * *
518 * @param curTime the current elapsed realtime in microseconds.
519 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
520 */
521 public abstract long computeRealtime(long curTime, int which);
Evan Millarc64edde2009-04-18 12:26:32 -0700522
523 public abstract Map<String, ? extends Timer> getKernelWakelockStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700525 private final static void formatTimeRaw(StringBuilder out, long seconds) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 long days = seconds / (60 * 60 * 24);
527 if (days != 0) {
528 out.append(days);
529 out.append("d ");
530 }
531 long used = days * 60 * 60 * 24;
532
533 long hours = (seconds - used) / (60 * 60);
534 if (hours != 0 || used != 0) {
535 out.append(hours);
536 out.append("h ");
537 }
538 used += hours * 60 * 60;
539
540 long mins = (seconds-used) / 60;
541 if (mins != 0 || used != 0) {
542 out.append(mins);
543 out.append("m ");
544 }
545 used += mins * 60;
546
547 if (seconds != 0 || used != 0) {
548 out.append(seconds-used);
549 out.append("s ");
550 }
551 }
552
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700553 private final static void formatTime(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 long sec = time / 100;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700555 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 sb.append((time - (sec * 100)) * 10);
557 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 }
559
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700560 private final static void formatTimeMs(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 long sec = time / 1000;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700562 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 sb.append(time - (sec * 1000));
564 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 }
566
567 private final String formatRatioLocked(long num, long den) {
568 if (den == 0L) {
569 return "---%";
570 }
571 float perc = ((float)num) / ((float)den) * 100;
572 mFormatBuilder.setLength(0);
573 mFormatter.format("%.1f%%", perc);
574 return mFormatBuilder.toString();
575 }
576
Evan Millar22ac0432009-03-31 11:33:18 -0700577 private final String formatBytesLocked(long bytes) {
578 mFormatBuilder.setLength(0);
579
580 if (bytes < BYTES_PER_KB) {
581 return bytes + "B";
582 } else if (bytes < BYTES_PER_MB) {
583 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
584 return mFormatBuilder.toString();
585 } else if (bytes < BYTES_PER_GB){
586 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
587 return mFormatBuilder.toString();
588 } else {
589 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
590 return mFormatBuilder.toString();
591 }
592 }
593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 /**
595 *
596 * @param sb a StringBuilder object.
597 * @param timer a Timer object contining the wakelock times.
598 * @param batteryRealtime the current on-battery time in microseconds.
599 * @param name the name of the wakelock.
600 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
601 * @param linePrefix a String to be prepended to each line of output.
602 * @return the line prefix
603 */
604 private static final String printWakeLock(StringBuilder sb, Timer timer,
605 long batteryRealtime, String name, int which, String linePrefix) {
606
607 if (timer != null) {
608 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -0700609 long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
611
Evan Millarc64edde2009-04-18 12:26:32 -0700612 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 if (totalTimeMillis != 0) {
614 sb.append(linePrefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700615 formatTimeMs(sb, totalTimeMillis);
616 if (name != null) sb.append(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 sb.append(' ');
618 sb.append('(');
619 sb.append(count);
620 sb.append(" times)");
621 return ", ";
622 }
623 }
624 return linePrefix;
625 }
626
627 /**
628 * Checkin version of wakelock printer. Prints simple comma-separated list.
629 *
630 * @param sb a StringBuilder object.
631 * @param timer a Timer object contining the wakelock times.
632 * @param now the current time in microseconds.
633 * @param name the name of the wakelock.
634 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
635 * @param linePrefix a String to be prepended to each line of output.
636 * @return the line prefix
637 */
638 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
Evan Millarc64edde2009-04-18 12:26:32 -0700639 String name, int which, String linePrefix) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 long totalTimeMicros = 0;
641 int count = 0;
642 if (timer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700643 totalTimeMicros = timer.getTotalTimeLocked(now, which);
644 count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645 }
646 sb.append(linePrefix);
647 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
648 sb.append(',');
Evan Millarc64edde2009-04-18 12:26:32 -0700649 sb.append(name != null ? name + "," : "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 sb.append(count);
651 return ",";
652 }
653
654 /**
655 * Dump a comma-separated line of values for terse checkin mode.
656 *
657 * @param pw the PageWriter to dump log to
658 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
659 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
660 * @param args type-dependent data arguments
661 */
662 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
663 Object... args ) {
664 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
665 pw.print(uid); pw.print(',');
666 pw.print(category); pw.print(',');
667 pw.print(type);
668
669 for (Object arg : args) {
670 pw.print(',');
671 pw.print(arg);
672 }
673 pw.print('\n');
674 }
675
676 /**
677 * Checkin server version of dump to produce more compact, computer-readable log.
678 *
679 * NOTE: all times are expressed in 'ms'.
680 * @param fd
681 * @param pw
682 * @param which
683 */
684 private final void dumpCheckinLocked(PrintWriter pw, int which) {
685 final long rawUptime = SystemClock.uptimeMillis() * 1000;
686 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
687 final long batteryUptime = getBatteryUptime(rawUptime);
688 final long batteryRealtime = getBatteryRealtime(rawRealtime);
689 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
690 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
691 final long totalRealtime = computeRealtime(rawRealtime, which);
692 final long totalUptime = computeUptime(rawUptime, which);
693 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
694 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700695 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700696 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700697 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698
699 StringBuilder sb = new StringBuilder(128);
700
Evan Millar22ac0432009-03-31 11:33:18 -0700701 SparseArray<? extends Uid> uidStats = getUidStats();
702 final int NU = uidStats.size();
703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 String category = STAT_NAMES[which];
705
706 // Dump "battery" stat
707 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
708 which == STATS_TOTAL ? getStartCount() : "N/A",
Dianne Hackborn617f8772009-03-31 15:04:46 -0700709 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
710 totalRealtime / 1000, totalUptime / 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800711
Evan Millar22ac0432009-03-31 11:33:18 -0700712 // Calculate total network and wakelock times across all uids.
713 long rxTotal = 0;
714 long txTotal = 0;
715 long fullWakeLockTimeTotal = 0;
716 long partialWakeLockTimeTotal = 0;
717
718 for (int iu = 0; iu < NU; iu++) {
719 Uid u = uidStats.valueAt(iu);
720 rxTotal += u.getTcpBytesReceived(which);
721 txTotal += u.getTcpBytesSent(which);
722
723 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
724 if (wakelocks.size() > 0) {
725 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
726 : wakelocks.entrySet()) {
727 Uid.Wakelock wl = ent.getValue();
728
729 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
730 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700731 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
Evan Millar22ac0432009-03-31 11:33:18 -0700732 }
733
734 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
735 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700736 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -0700737 batteryRealtime, which);
738 }
739 }
740 }
741 }
742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 // Dump misc stats
744 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700745 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
Evan Millar22ac0432009-03-31 11:33:18 -0700746 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal,
Dianne Hackborn617f8772009-03-31 15:04:46 -0700747 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
748 getInputEventCount(which));
749
750 // Dump screen brightness stats
751 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
752 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
753 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
754 }
755 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
The Android Open Source Project10592532009-03-18 17:39:46 -0700756
Dianne Hackborn627bba72009-03-24 22:32:56 -0700757 // Dump signal strength stats
Dianne Hackborn617f8772009-03-31 15:04:46 -0700758 args = new Object[NUM_SIGNAL_STRENGTH_BINS];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700759 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
760 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
761 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700762 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
763 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
764 args[i] = getPhoneSignalStrengthCount(i, which);
765 }
766 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700767
768 // Dump network type stats
769 args = new Object[NUM_DATA_CONNECTION_TYPES];
770 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
771 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
772 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700773 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
774 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
775 args[i] = getPhoneDataConnectionCount(i, which);
776 }
777 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700778
The Android Open Source Project10592532009-03-18 17:39:46 -0700779 if (which == STATS_UNPLUGGED) {
Evan Millare84de8d2009-04-02 22:16:12 -0700780 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
Evan Millar633a1742009-04-02 16:36:33 -0700781 getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -0700782 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783
Evan Millarc64edde2009-04-18 12:26:32 -0700784 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
785 if (kernelWakelocks.size() > 0) {
786 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
787 sb.setLength(0);
788 printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
789
790 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
791 sb.toString());
792 }
793 }
794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800795 for (int iu = 0; iu < NU; iu++) {
796 final int uid = uidStats.keyAt(iu);
797 Uid u = uidStats.valueAt(iu);
798 // Dump Network stats per uid, if any
799 long rx = u.getTcpBytesReceived(which);
800 long tx = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700801 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
802 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700803 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -0700806
Dianne Hackborn617f8772009-03-31 15:04:46 -0700807 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
808 || wifiTurnedOnTime != 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700809 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
Dianne Hackborn617f8772009-03-31 15:04:46 -0700810 fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700811 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812
Dianne Hackborn617f8772009-03-31 15:04:46 -0700813 if (u.hasUserActivity()) {
814 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
815 boolean hasData = false;
816 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
817 int val = u.getUserActivityCount(i, which);
818 args[i] = val;
819 if (val != 0) hasData = true;
820 }
821 if (hasData) {
822 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args);
823 }
824 }
825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
827 if (wakelocks.size() > 0) {
828 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
829 : wakelocks.entrySet()) {
830 Uid.Wakelock wl = ent.getValue();
831 String linePrefix = "";
832 sb.setLength(0);
Evan Millarc64edde2009-04-18 12:26:32 -0700833 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
834 batteryRealtime, "f", which, linePrefix);
835 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
836 batteryRealtime, "p", which, linePrefix);
837 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
838 batteryRealtime, "w", which, linePrefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839
840 // Only log if we had at lease one wakelock...
841 if (sb.length() > 0) {
842 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
843 }
844 }
845 }
846
847 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
848 if (sensors.size() > 0) {
849 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
850 : sensors.entrySet()) {
851 Uid.Sensor se = ent.getValue();
852 int sensorNumber = ent.getKey();
853 Timer timer = se.getSensorTime();
854 if (timer != null) {
855 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -0700856 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
857 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 if (totalTime != 0) {
859 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
860 }
861 }
862 }
863 }
864
865 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
866 if (processStats.size() > 0) {
867 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
868 : processStats.entrySet()) {
869 Uid.Proc ps = ent.getValue();
870
871 long userTime = ps.getUserTime(which);
872 long systemTime = ps.getSystemTime(which);
873 int starts = ps.getStarts(which);
874
875 if (userTime != 0 || systemTime != 0 || starts != 0) {
876 dumpLine(pw, uid, category, PROCESS_DATA,
877 ent.getKey(), // proc
878 userTime * 10, // cpu time in ms
879 systemTime * 10, // user time in ms
880 starts); // process starts
881 }
882 }
883 }
884
885 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
886 if (packageStats.size() > 0) {
887 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
888 : packageStats.entrySet()) {
889
890 Uid.Pkg ps = ent.getValue();
891 int wakeups = ps.getWakeups(which);
892 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
893 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
894 : serviceStats.entrySet()) {
895 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
896 long startTime = ss.getStartTime(batteryUptime, which);
897 int starts = ss.getStarts(which);
898 int launches = ss.getLaunches(which);
899 if (startTime != 0 || starts != 0 || launches != 0) {
900 dumpLine(pw, uid, category, APK_DATA,
901 wakeups, // wakeup alarms
902 ent.getKey(), // Apk
903 sent.getKey(), // service
904 startTime / 1000, // time spent started, in ms
905 starts,
906 launches);
907 }
908 }
909 }
910 }
911 }
912 }
913
914 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700915 private final void dumpLocked(PrintWriter pw, String prefix, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 final long rawUptime = SystemClock.uptimeMillis() * 1000;
917 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
918 final long batteryUptime = getBatteryUptime(rawUptime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700919 final long batteryRealtime = getBatteryRealtime(rawRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920
921 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
922 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
923 final long totalRealtime = computeRealtime(rawRealtime, which);
924 final long totalUptime = computeUptime(rawUptime, which);
925
926 StringBuilder sb = new StringBuilder(128);
Evan Millar22ac0432009-03-31 11:33:18 -0700927
928 SparseArray<? extends Uid> uidStats = getUidStats();
929 final int NU = uidStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700931 sb.setLength(0);
932 sb.append(prefix);
933 sb.append(" Time on battery: ");
934 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
935 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
936 sb.append(") realtime, ");
937 formatTimeMs(sb, whichBatteryUptime / 1000);
938 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
939 sb.append(") uptime");
940 pw.println(sb.toString());
941 sb.setLength(0);
942 sb.append(prefix);
943 sb.append(" Total run time: ");
944 formatTimeMs(sb, totalRealtime / 1000);
945 sb.append("realtime, ");
946 formatTimeMs(sb, totalUptime / 1000);
947 sb.append("uptime, ");
948 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949
The Android Open Source Project10592532009-03-18 17:39:46 -0700950 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
951 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700952 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700953 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
954 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700955 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700956 sb.append(prefix);
957 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
958 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
959 sb.append("), Input events: "); sb.append(getInputEventCount(which));
960 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
961 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
962 sb.append(")");
963 pw.println(sb.toString());
964 sb.setLength(0);
965 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700966 sb.append(" Screen brightnesses: ");
967 boolean didOne = false;
968 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
969 final long time = getScreenBrightnessTime(i, batteryRealtime, which);
970 if (time == 0) {
971 continue;
972 }
973 if (didOne) sb.append(", ");
974 didOne = true;
975 sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
976 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700977 formatTimeMs(sb, time/1000);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700978 sb.append("(");
979 sb.append(formatRatioLocked(time, screenOnTime));
980 sb.append(")");
981 }
982 if (!didOne) sb.append("No activity");
983 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -0700984
Evan Millar22ac0432009-03-31 11:33:18 -0700985 // Calculate total network and wakelock times across all uids.
986 long rxTotal = 0;
987 long txTotal = 0;
988 long fullWakeLockTimeTotalMicros = 0;
989 long partialWakeLockTimeTotalMicros = 0;
990
Evan Millarc64edde2009-04-18 12:26:32 -0700991 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
992 if (kernelWakelocks.size() > 0) {
993 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
994
995 String linePrefix = ": ";
996 sb.setLength(0);
997 sb.append(prefix);
998 sb.append(" Kernel Wake lock ");
999 sb.append(ent.getKey());
1000 linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
1001 linePrefix);
1002 if (!linePrefix.equals(": ")) {
1003 sb.append(" realtime");
1004 } else {
1005 sb.append(": (nothing executed)");
1006 }
1007 pw.println(sb.toString());
1008 }
1009 }
1010
Evan Millar22ac0432009-03-31 11:33:18 -07001011 for (int iu = 0; iu < NU; iu++) {
1012 Uid u = uidStats.valueAt(iu);
1013 rxTotal += u.getTcpBytesReceived(which);
1014 txTotal += u.getTcpBytesSent(which);
1015
1016 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1017 if (wakelocks.size() > 0) {
1018 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1019 : wakelocks.entrySet()) {
1020 Uid.Wakelock wl = ent.getValue();
1021
1022 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1023 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001024 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001025 batteryRealtime, which);
1026 }
1027
1028 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1029 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001030 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001031 batteryRealtime, which);
1032 }
1033 }
1034 }
1035 }
1036
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001037 pw.print(prefix);
1038 pw.print(" Total received: "); pw.print(formatBytesLocked(rxTotal));
1039 pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal));
1040 sb.setLength(0);
1041 sb.append(prefix);
1042 sb.append(" Total full wakelock time: "); formatTimeMs(sb,
1043 (fullWakeLockTimeTotalMicros + 500) / 1000);
1044 sb.append(", Total partial waklock time: "); formatTimeMs(sb,
1045 (partialWakeLockTimeTotalMicros + 500) / 1000);
1046 pw.println(sb.toString());
Evan Millar22ac0432009-03-31 11:33:18 -07001047
Dianne Hackborn627bba72009-03-24 22:32:56 -07001048 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001049 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001050 sb.append(" Signal levels: ");
1051 didOne = false;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001052 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
1053 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
1054 if (time == 0) {
1055 continue;
1056 }
1057 if (didOne) sb.append(", ");
1058 didOne = true;
1059 sb.append(SIGNAL_STRENGTH_NAMES[i]);
1060 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001061 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001062 sb.append("(");
1063 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001064 sb.append(") ");
1065 sb.append(getPhoneSignalStrengthCount(i, which));
1066 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001067 }
1068 if (!didOne) sb.append("No activity");
1069 pw.println(sb.toString());
1070
1071 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001072 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001073 sb.append(" Radio types: ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001074 didOne = false;
1075 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1076 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
1077 if (time == 0) {
1078 continue;
1079 }
1080 if (didOne) sb.append(", ");
1081 didOne = true;
1082 sb.append(DATA_CONNECTION_NAMES[i]);
1083 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001084 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001085 sb.append("(");
1086 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001087 sb.append(") ");
1088 sb.append(getPhoneDataConnectionCount(i, which));
1089 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001090 }
1091 if (!didOne) sb.append("No activity");
1092 pw.println(sb.toString());
1093
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001094 sb.setLength(0);
1095 sb.append(prefix);
1096 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
1097 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
1098 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
1099 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
1100 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
1101 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
1102 sb.append(")");
1103 pw.println(sb.toString());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001104
The Android Open Source Project10592532009-03-18 17:39:46 -07001105 pw.println(" ");
1106
1107 if (which == STATS_UNPLUGGED) {
1108 if (getIsOnBattery()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001109 pw.print(prefix); pw.println(" Device is currently unplugged");
1110 pw.print(prefix); pw.print(" Discharge cycle start level: ");
1111 pw.println(getDischargeStartLevel());
1112 pw.print(prefix); pw.print(" Discharge cycle current level: ");
1113 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001114 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001115 pw.print(prefix); pw.println(" Device is currently plugged into power");
1116 pw.print(prefix); pw.print(" Last discharge cycle start level: ");
1117 pw.println(getDischargeStartLevel());
1118 pw.print(prefix); pw.print(" Last discharge cycle end level: ");
1119 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001120 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001121 pw.println(" ");
The Android Open Source Project10592532009-03-18 17:39:46 -07001122 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123
Evan Millar22ac0432009-03-31 11:33:18 -07001124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 for (int iu=0; iu<NU; iu++) {
1126 final int uid = uidStats.keyAt(iu);
1127 Uid u = uidStats.valueAt(iu);
1128 pw.println(prefix + " #" + uid + ":");
1129 boolean uidActivity = false;
1130
1131 long tcpReceived = u.getTcpBytesReceived(which);
1132 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001133 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1134 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001135 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137 if (tcpReceived != 0 || tcpSent != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001138 pw.print(prefix); pw.print(" Network: ");
1139 pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, ");
1140 pw.print(formatBytesLocked(tcpSent)); pw.println(" sent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001142
1143 if (u.hasUserActivity()) {
1144 boolean hasData = false;
1145 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1146 int val = u.getUserActivityCount(i, which);
1147 if (val != 0) {
1148 if (!hasData) {
1149 sb.setLength(0);
1150 sb.append(" User activity: ");
1151 hasData = true;
1152 } else {
1153 sb.append(", ");
1154 }
1155 sb.append(val);
1156 sb.append(" ");
1157 sb.append(Uid.USER_ACTIVITY_TYPES[i]);
1158 }
1159 }
1160 if (hasData) {
1161 pw.println(sb.toString());
1162 }
1163 }
1164
1165 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
1166 || wifiTurnedOnTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001167 sb.setLength(0);
1168 sb.append(prefix); sb.append(" Turned Wifi On: ");
1169 formatTimeMs(sb, wifiTurnedOnTime / 1000);
1170 sb.append("("); sb.append(formatRatioLocked(wifiTurnedOnTime,
1171 whichBatteryRealtime)); sb.append(")\n");
1172 sb.append(prefix); sb.append(" Full Wifi Lock: ");
1173 formatTimeMs(sb, fullWifiLockOnTime / 1000);
1174 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
1175 whichBatteryRealtime)); sb.append(")\n");
1176 sb.append(prefix); sb.append(" Scan Wifi Lock: ");
1177 formatTimeMs(sb, scanWifiLockOnTime / 1000);
1178 sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime,
1179 whichBatteryRealtime)); sb.append(")");
1180 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182
1183 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1184 if (wakelocks.size() > 0) {
1185 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1186 : wakelocks.entrySet()) {
1187 Uid.Wakelock wl = ent.getValue();
1188 String linePrefix = ": ";
1189 sb.setLength(0);
1190 sb.append(prefix);
1191 sb.append(" Wake lock ");
1192 sb.append(ent.getKey());
1193 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
1194 "full", which, linePrefix);
1195 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
1196 "partial", which, linePrefix);
1197 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
1198 "window", which, linePrefix);
1199 if (!linePrefix.equals(": ")) {
1200 sb.append(" realtime");
1201 } else {
1202 sb.append(": (nothing executed)");
1203 }
1204 pw.println(sb.toString());
1205 uidActivity = true;
1206 }
1207 }
1208
1209 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1210 if (sensors.size() > 0) {
1211 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1212 : sensors.entrySet()) {
1213 Uid.Sensor se = ent.getValue();
1214 int sensorNumber = ent.getKey();
1215 sb.setLength(0);
1216 sb.append(prefix);
1217 sb.append(" Sensor ");
1218 int handle = se.getHandle();
1219 if (handle == Uid.Sensor.GPS) {
1220 sb.append("GPS");
1221 } else {
1222 sb.append(handle);
1223 }
1224 sb.append(": ");
1225
1226 Timer timer = se.getSensorTime();
1227 if (timer != null) {
1228 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -07001229 long totalTime = (timer.getTotalTimeLocked(
1230 batteryRealtime, which) + 500) / 1000;
1231 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 //timer.logState();
1233 if (totalTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001234 formatTimeMs(sb, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 sb.append("realtime (");
1236 sb.append(count);
1237 sb.append(" times)");
1238 } else {
1239 sb.append("(not used)");
1240 }
1241 } else {
1242 sb.append("(not used)");
1243 }
1244
1245 pw.println(sb.toString());
1246 uidActivity = true;
1247 }
1248 }
1249
1250 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1251 if (processStats.size() > 0) {
1252 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1253 : processStats.entrySet()) {
1254 Uid.Proc ps = ent.getValue();
1255 long userTime;
1256 long systemTime;
1257 int starts;
1258
1259 userTime = ps.getUserTime(which);
1260 systemTime = ps.getSystemTime(which);
1261 starts = ps.getStarts(which);
1262
1263 if (userTime != 0 || systemTime != 0 || starts != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001264 sb.setLength(0);
1265 sb.append(prefix); sb.append(" Proc ");
1266 sb.append(ent.getKey()); sb.append(":\n");
1267 sb.append(prefix); sb.append(" CPU: ");
1268 formatTime(sb, userTime); sb.append("usr + ");
1269 formatTime(sb, systemTime); sb.append("krn\n");
1270 sb.append(prefix); sb.append(" "); sb.append(starts);
1271 sb.append(" proc starts");
1272 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001273 uidActivity = true;
1274 }
1275 }
1276 }
1277
1278 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1279 if (packageStats.size() > 0) {
1280 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1281 : packageStats.entrySet()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001282 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 boolean apkActivity = false;
1284 Uid.Pkg ps = ent.getValue();
1285 int wakeups = ps.getWakeups(which);
1286 if (wakeups != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001287 pw.print(prefix); pw.print(" ");
1288 pw.print(wakeups); pw.println(" wakeup alarms");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 apkActivity = true;
1290 }
1291 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1292 if (serviceStats.size() > 0) {
1293 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1294 : serviceStats.entrySet()) {
1295 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1296 long startTime = ss.getStartTime(batteryUptime, which);
1297 int starts = ss.getStarts(which);
1298 int launches = ss.getLaunches(which);
1299 if (startTime != 0 || starts != 0 || launches != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001300 sb.setLength(0);
1301 sb.append(prefix); sb.append(" Service ");
1302 sb.append(sent.getKey()); sb.append(":\n");
1303 sb.append(prefix); sb.append(" Created for: ");
1304 formatTimeMs(sb, startTime / 1000);
1305 sb.append(" uptime\n");
1306 sb.append(prefix); sb.append(" Starts: ");
1307 sb.append(starts);
1308 sb.append(", launches: "); sb.append(launches);
1309 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 apkActivity = true;
1311 }
1312 }
1313 }
1314 if (!apkActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001315 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 }
1317 uidActivity = true;
1318 }
1319 }
1320 if (!uidActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001321 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 }
1323 }
1324 }
1325
1326 /**
1327 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
1328 *
1329 * @param pw a Printer to receive the dump output.
1330 */
1331 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001332 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 pw.println("Total Statistics (Current and Historic):");
1334 pw.println(" System starts: " + getStartCount()
1335 + ", currently on battery: " + getIsOnBattery());
1336 dumpLocked(pw, "", STATS_TOTAL);
1337 pw.println("");
1338 pw.println("Last Run Statistics (Previous run of system):");
1339 dumpLocked(pw, "", STATS_LAST);
1340 pw.println("");
1341 pw.println("Current Battery Statistics (Currently running system):");
1342 dumpLocked(pw, "", STATS_CURRENT);
1343 pw.println("");
1344 pw.println("Unplugged Statistics (Since last unplugged from power):");
1345 dumpLocked(pw, "", STATS_UNPLUGGED);
1346 }
1347
1348 @SuppressWarnings("unused")
1349 public void dumpCheckinLocked(PrintWriter pw, String[] args) {
1350 boolean isUnpluggedOnly = false;
1351
1352 for (String arg : args) {
1353 if ("-u".equals(arg)) {
1354 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
1355 isUnpluggedOnly = true;
1356 }
1357 }
1358
1359 if (isUnpluggedOnly) {
1360 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1361 }
1362 else {
1363 dumpCheckinLocked(pw, STATS_TOTAL);
1364 dumpCheckinLocked(pw, STATS_LAST);
1365 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1366 dumpCheckinLocked(pw, STATS_CURRENT);
1367 }
1368 }
1369
1370}