blob: b706c5c1cae40c399d06fa8a203e8f13a3c12afa [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 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -070072 * A constant indicating an audio turn on timer
73 *
74 * {@hide}
75 */
76 public static final int AUDIO_TURNED_ON = 7;
77
78 /**
79 * A constant indicating a video turn on timer
80 *
81 * {@hide}
82 */
83 public static final int VIDEO_TURNED_ON = 8;
84
85 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 * Include all of the data in the stats, including previously saved data.
87 */
88 public static final int STATS_TOTAL = 0;
89
90 /**
91 * Include only the last run in the stats.
92 */
93 public static final int STATS_LAST = 1;
94
95 /**
96 * Include only the current run in the stats.
97 */
98 public static final int STATS_CURRENT = 2;
99
100 /**
101 * Include only the run since the last time the device was unplugged in the stats.
102 */
103 public static final int STATS_UNPLUGGED = 3;
Evan Millare84de8d2009-04-02 22:16:12 -0700104
105 // NOTE: Update this list if you add/change any stats above.
106 // These characters are supposed to represent "total", "last", "current",
107 // and "unplugged". They were shortened for effeciency sake.
108 private static final String[] STAT_NAMES = { "t", "l", "c", "u" };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109
110 /**
111 * Bump the version on this if the checkin format changes.
112 */
Evan Millarc64edde2009-04-18 12:26:32 -0700113 private static final int BATTERY_STATS_CHECKIN_VERSION = 5;
Evan Millar22ac0432009-03-31 11:33:18 -0700114
115 private static final long BYTES_PER_KB = 1024;
116 private static final long BYTES_PER_MB = 1048576; // 1024^2
117 private static final long BYTES_PER_GB = 1073741824; //1024^3
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119
120 private static final String APK_DATA = "apk";
Evan Millare84de8d2009-04-02 22:16:12 -0700121 private static final String PROCESS_DATA = "pr";
122 private static final String SENSOR_DATA = "sr";
123 private static final String WAKELOCK_DATA = "wl";
Evan Millarc64edde2009-04-18 12:26:32 -0700124 private static final String KERNEL_WAKELOCK_DATA = "kwl";
Evan Millare84de8d2009-04-02 22:16:12 -0700125 private static final String NETWORK_DATA = "nt";
126 private static final String USER_ACTIVITY_DATA = "ua";
127 private static final String BATTERY_DATA = "bt";
128 private static final String BATTERY_LEVEL_DATA = "lv";
129 private static final String WIFI_LOCK_DATA = "wfl";
130 private static final String MISC_DATA = "m";
131 private static final String SCREEN_BRIGHTNESS_DATA = "br";
132 private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
Amith Yamasanif37447b2009-10-08 18:28:01 -0700133 private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
Evan Millare84de8d2009-04-02 22:16:12 -0700134 private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
135 private static final String DATA_CONNECTION_TIME_DATA = "dct";
136 private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700138 private final StringBuilder mFormatBuilder = new StringBuilder(32);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 private final Formatter mFormatter = new Formatter(mFormatBuilder);
140
141 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700142 * State for keeping track of counting information.
143 */
144 public static abstract class Counter {
145
146 /**
147 * Returns the count associated with this Counter for the
148 * selected type of statistics.
149 *
150 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
151 */
Evan Millarc64edde2009-04-18 12:26:32 -0700152 public abstract int getCountLocked(int which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700153
154 /**
155 * Temporary for debugging.
156 */
157 public abstract void logState(Printer pw, String prefix);
158 }
159
160 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 * State for keeping track of timing information.
162 */
163 public static abstract class Timer {
164
165 /**
166 * Returns the count associated with this Timer for the
167 * selected type of statistics.
168 *
169 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
170 */
Evan Millarc64edde2009-04-18 12:26:32 -0700171 public abstract int getCountLocked(int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172
173 /**
174 * Returns the total time in microseconds associated with this Timer for the
175 * selected type of statistics.
176 *
177 * @param batteryRealtime system realtime on battery in microseconds
178 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
179 * @return a time in microseconds
180 */
Evan Millarc64edde2009-04-18 12:26:32 -0700181 public abstract long getTotalTimeLocked(long batteryRealtime, int which);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 /**
184 * Temporary for debugging.
185 */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700186 public abstract void logState(Printer pw, String prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 }
188
189 /**
190 * The statistics associated with a particular uid.
191 */
192 public static abstract class Uid {
193
194 /**
195 * Returns a mapping containing wakelock statistics.
196 *
197 * @return a Map from Strings to Uid.Wakelock objects.
198 */
199 public abstract Map<String, ? extends Wakelock> getWakelockStats();
200
201 /**
202 * The statistics associated with a particular wake lock.
203 */
204 public static abstract class Wakelock {
205 public abstract Timer getWakeTime(int type);
206 }
207
208 /**
209 * Returns a mapping containing sensor statistics.
210 *
211 * @return a Map from Integer sensor ids to Uid.Sensor objects.
212 */
213 public abstract Map<Integer, ? extends Sensor> getSensorStats();
214
215 /**
216 * Returns a mapping containing process statistics.
217 *
218 * @return a Map from Strings to Uid.Proc objects.
219 */
220 public abstract Map<String, ? extends Proc> getProcessStats();
221
222 /**
223 * Returns a mapping containing package statistics.
224 *
225 * @return a Map from Strings to Uid.Pkg objects.
226 */
227 public abstract Map<String, ? extends Pkg> getPackageStats();
228
229 /**
230 * {@hide}
231 */
232 public abstract int getUid();
233
234 /**
235 * {@hide}
236 */
237 public abstract long getTcpBytesReceived(int which);
238
239 /**
240 * {@hide}
241 */
242 public abstract long getTcpBytesSent(int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700243
Dianne Hackborn617f8772009-03-31 15:04:46 -0700244 public abstract void noteWifiTurnedOnLocked();
245 public abstract void noteWifiTurnedOffLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700246 public abstract void noteFullWifiLockAcquiredLocked();
247 public abstract void noteFullWifiLockReleasedLocked();
248 public abstract void noteScanWifiLockAcquiredLocked();
249 public abstract void noteScanWifiLockReleasedLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700250 public abstract void noteWifiMulticastEnabledLocked();
251 public abstract void noteWifiMulticastDisabledLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700252 public abstract void noteAudioTurnedOnLocked();
253 public abstract void noteAudioTurnedOffLocked();
254 public abstract void noteVideoTurnedOnLocked();
255 public abstract void noteVideoTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700256 public abstract long getWifiTurnedOnTime(long batteryRealtime, int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700257 public abstract long getFullWifiLockTime(long batteryRealtime, int which);
258 public abstract long getScanWifiLockTime(long batteryRealtime, int which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700259 public abstract long getWifiMulticastTime(long batteryRealtime,
260 int which);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700261 public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
262 public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263
Dianne Hackborn617f8772009-03-31 15:04:46 -0700264 /**
265 * Note that these must match the constants in android.os.LocalPowerManager.
266 */
267 static final String[] USER_ACTIVITY_TYPES = {
268 "other", "cheek", "touch", "long_touch", "touch_up", "button", "unknown"
269 };
270
271 public static final int NUM_USER_ACTIVITY_TYPES = 7;
272
273 public abstract void noteUserActivityLocked(int type);
274 public abstract boolean hasUserActivity();
275 public abstract int getUserActivityCount(int type, int which);
276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 public static abstract class Sensor {
278 // Magic sensor number for the GPS.
279 public static final int GPS = -10000;
280
281 public abstract int getHandle();
282
283 public abstract Timer getSensorTime();
284 }
285
286 /**
287 * The statistics associated with a particular process.
288 */
289 public static abstract class Proc {
290
291 /**
292 * Returns the total time (in 1/100 sec) spent executing in user code.
293 *
294 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
295 */
296 public abstract long getUserTime(int which);
297
298 /**
299 * Returns the total time (in 1/100 sec) spent executing in system code.
300 *
301 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
302 */
303 public abstract long getSystemTime(int which);
304
305 /**
306 * Returns the number of times the process has been started.
307 *
308 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
309 */
310 public abstract int getStarts(int which);
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700311
312 /**
313 * Returns the cpu time spent in microseconds while the process was in the foreground.
314 * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
315 * @return foreground cpu time in microseconds
316 */
317 public abstract long getForegroundTime(int which);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700318
319 /**
320 * Returns the approximate cpu time spent in microseconds, at a certain CPU speed.
321 * @param speedStep the index of the CPU speed. This is not the actual speed of the
322 * CPU.
323 * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
324 * @see BatteryStats#getCpuSpeedSteps()
325 */
326 public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 }
328
329 /**
330 * The statistics associated with a particular package.
331 */
332 public static abstract class Pkg {
333
334 /**
335 * Returns the number of times this package has done something that could wake up the
336 * device from sleep.
337 *
338 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
339 */
340 public abstract int getWakeups(int which);
341
342 /**
343 * Returns a mapping containing service statistics.
344 */
345 public abstract Map<String, ? extends Serv> getServiceStats();
346
347 /**
348 * The statistics associated with a particular service.
349 */
350 public abstract class Serv {
351
352 /**
353 * Returns the amount of time spent started.
354 *
355 * @param batteryUptime elapsed uptime on battery in microseconds.
356 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
357 * @return
358 */
359 public abstract long getStartTime(long batteryUptime, int which);
360
361 /**
362 * Returns the total number of times startService() has been called.
363 *
364 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
365 */
366 public abstract int getStarts(int which);
367
368 /**
369 * Returns the total number times the service has been launched.
370 *
371 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
372 */
373 public abstract int getLaunches(int which);
374 }
375 }
376 }
377
378 /**
379 * Returns the number of times the device has been started.
380 */
381 public abstract int getStartCount();
382
383 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700384 * Returns the time in microseconds that the screen has been on while the device was
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 * running on battery.
386 *
387 * {@hide}
388 */
389 public abstract long getScreenOnTime(long batteryRealtime, int which);
390
Dianne Hackborn617f8772009-03-31 15:04:46 -0700391 public static final int SCREEN_BRIGHTNESS_DARK = 0;
392 public static final int SCREEN_BRIGHTNESS_DIM = 1;
393 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
394 public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
395 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
396
397 static final String[] SCREEN_BRIGHTNESS_NAMES = {
398 "dark", "dim", "medium", "light", "bright"
399 };
400
401 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
402
403 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700404 * Returns the time in microseconds that the screen has been on with
Dianne Hackborn617f8772009-03-31 15:04:46 -0700405 * the given brightness
406 *
407 * {@hide}
408 */
409 public abstract long getScreenBrightnessTime(int brightnessBin,
410 long batteryRealtime, int which);
411
412 public abstract int getInputEventCount(int which);
413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700415 * Returns the time in microseconds that the phone has been on while the device was
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 * running on battery.
417 *
418 * {@hide}
419 */
420 public abstract long getPhoneOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700421
Dianne Hackborn627bba72009-03-24 22:32:56 -0700422 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
423 public static final int SIGNAL_STRENGTH_POOR = 1;
424 public static final int SIGNAL_STRENGTH_MODERATE = 2;
425 public static final int SIGNAL_STRENGTH_GOOD = 3;
426 public static final int SIGNAL_STRENGTH_GREAT = 4;
427
428 static final String[] SIGNAL_STRENGTH_NAMES = {
429 "none", "poor", "moderate", "good", "great"
430 };
431
432 public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
433
434 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700435 * Returns the time in microseconds that the phone has been running with
Dianne Hackborn627bba72009-03-24 22:32:56 -0700436 * the given signal strength.
437 *
438 * {@hide}
439 */
440 public abstract long getPhoneSignalStrengthTime(int strengthBin,
441 long batteryRealtime, int which);
442
Dianne Hackborn617f8772009-03-31 15:04:46 -0700443 /**
Amith Yamasanif37447b2009-10-08 18:28:01 -0700444 * Returns the time in microseconds that the phone has been trying to
445 * acquire a signal.
446 *
447 * {@hide}
448 */
449 public abstract long getPhoneSignalScanningTime(
450 long batteryRealtime, int which);
451
452 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700453 * Returns the number of times the phone has entered the given signal strength.
454 *
455 * {@hide}
456 */
457 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
458
Dianne Hackborn627bba72009-03-24 22:32:56 -0700459 public static final int DATA_CONNECTION_NONE = 0;
460 public static final int DATA_CONNECTION_GPRS = 1;
461 public static final int DATA_CONNECTION_EDGE = 2;
462 public static final int DATA_CONNECTION_UMTS = 3;
463 public static final int DATA_CONNECTION_OTHER = 4;
464
465 static final String[] DATA_CONNECTION_NAMES = {
466 "none", "gprs", "edge", "umts", "other"
467 };
468
469 public static final int NUM_DATA_CONNECTION_TYPES = 5;
470
471 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700472 * Returns the time in microseconds that the phone has been running with
Dianne Hackborn627bba72009-03-24 22:32:56 -0700473 * the given data connection.
474 *
475 * {@hide}
476 */
477 public abstract long getPhoneDataConnectionTime(int dataType,
478 long batteryRealtime, int which);
479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700481 * Returns the number of times the phone has entered the given data
482 * connection type.
483 *
484 * {@hide}
485 */
486 public abstract int getPhoneDataConnectionCount(int dataType, int which);
487
488 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700489 * Returns the time in microseconds that wifi has been on while the device was
The Android Open Source Project10592532009-03-18 17:39:46 -0700490 * running on battery.
491 *
492 * {@hide}
493 */
494 public abstract long getWifiOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700495
496 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700497 * Returns the time in microseconds that wifi has been on and the driver has
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700498 * been in the running state while the device was running on battery.
499 *
500 * {@hide}
501 */
502 public abstract long getWifiRunningTime(long batteryRealtime, int which);
503
The Android Open Source Project10592532009-03-18 17:39:46 -0700504 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700505 * Returns the time in microseconds that bluetooth has been on while the device was
The Android Open Source Project10592532009-03-18 17:39:46 -0700506 * running on battery.
507 *
508 * {@hide}
509 */
510 public abstract long getBluetoothOnTime(long batteryRealtime, int which);
511
512 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 * Return whether we are currently running on battery.
514 */
515 public abstract boolean getIsOnBattery();
516
517 /**
518 * Returns a SparseArray containing the statistics for each uid.
519 */
520 public abstract SparseArray<? extends Uid> getUidStats();
521
522 /**
523 * Returns the current battery uptime in microseconds.
524 *
525 * @param curTime the amount of elapsed realtime in microseconds.
526 */
527 public abstract long getBatteryUptime(long curTime);
528
529 /**
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700530 * @deprecated use getRadioDataUptime
531 */
532 public long getRadioDataUptimeMs() {
533 return getRadioDataUptime() / 1000;
534 }
535
536 /**
537 * Returns the time that the radio was on for data transfers.
538 * @return the uptime in microseconds while unplugged
539 */
540 public abstract long getRadioDataUptime();
541
542 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 * Returns the current battery realtime in microseconds.
544 *
545 * @param curTime the amount of elapsed realtime in microseconds.
546 */
547 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700548
549 /**
Evan Millar633a1742009-04-02 16:36:33 -0700550 * Returns the battery percentage level at the last time the device was unplugged from power, or
551 * the last time it booted on battery power.
The Android Open Source Project10592532009-03-18 17:39:46 -0700552 */
Evan Millar633a1742009-04-02 16:36:33 -0700553 public abstract int getDischargeStartLevel();
The Android Open Source Project10592532009-03-18 17:39:46 -0700554
555 /**
Evan Millar633a1742009-04-02 16:36:33 -0700556 * Returns the current battery percentage level if we are in a discharge cycle, otherwise
557 * returns the level at the last plug event.
The Android Open Source Project10592532009-03-18 17:39:46 -0700558 */
Evan Millar633a1742009-04-02 16:36:33 -0700559 public abstract int getDischargeCurrentLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560
561 /**
562 * Returns the total, last, or current battery uptime in microseconds.
563 *
564 * @param curTime the elapsed realtime in microseconds.
565 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
566 */
567 public abstract long computeBatteryUptime(long curTime, int which);
568
569 /**
570 * Returns the total, last, or current battery realtime in microseconds.
571 *
572 * @param curTime the current elapsed realtime in microseconds.
573 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
574 */
575 public abstract long computeBatteryRealtime(long curTime, int which);
576
577 /**
578 * Returns the total, last, or current uptime in microseconds.
579 *
580 * @param curTime the current elapsed realtime in microseconds.
581 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
582 */
583 public abstract long computeUptime(long curTime, int which);
584
585 /**
586 * Returns the total, last, or current realtime in microseconds.
587 * *
588 * @param curTime the current elapsed realtime in microseconds.
589 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
590 */
591 public abstract long computeRealtime(long curTime, int which);
Evan Millarc64edde2009-04-18 12:26:32 -0700592
593 public abstract Map<String, ? extends Timer> getKernelWakelockStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594
Amith Yamasanie43530a2009-08-21 13:11:37 -0700595 /** Returns the number of different speeds that the CPU can run at */
596 public abstract int getCpuSpeedSteps();
597
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700598 private final static void formatTimeRaw(StringBuilder out, long seconds) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 long days = seconds / (60 * 60 * 24);
600 if (days != 0) {
601 out.append(days);
602 out.append("d ");
603 }
604 long used = days * 60 * 60 * 24;
605
606 long hours = (seconds - used) / (60 * 60);
607 if (hours != 0 || used != 0) {
608 out.append(hours);
609 out.append("h ");
610 }
611 used += hours * 60 * 60;
612
613 long mins = (seconds-used) / 60;
614 if (mins != 0 || used != 0) {
615 out.append(mins);
616 out.append("m ");
617 }
618 used += mins * 60;
619
620 if (seconds != 0 || used != 0) {
621 out.append(seconds-used);
622 out.append("s ");
623 }
624 }
625
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700626 private final static void formatTime(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 long sec = time / 100;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700628 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 sb.append((time - (sec * 100)) * 10);
630 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 }
632
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700633 private final static void formatTimeMs(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800634 long sec = time / 1000;
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700635 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636 sb.append(time - (sec * 1000));
637 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800638 }
639
640 private final String formatRatioLocked(long num, long den) {
641 if (den == 0L) {
642 return "---%";
643 }
644 float perc = ((float)num) / ((float)den) * 100;
645 mFormatBuilder.setLength(0);
646 mFormatter.format("%.1f%%", perc);
647 return mFormatBuilder.toString();
648 }
649
Evan Millar22ac0432009-03-31 11:33:18 -0700650 private final String formatBytesLocked(long bytes) {
651 mFormatBuilder.setLength(0);
652
653 if (bytes < BYTES_PER_KB) {
654 return bytes + "B";
655 } else if (bytes < BYTES_PER_MB) {
656 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
657 return mFormatBuilder.toString();
658 } else if (bytes < BYTES_PER_GB){
659 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
660 return mFormatBuilder.toString();
661 } else {
662 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
663 return mFormatBuilder.toString();
664 }
665 }
666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667 /**
668 *
669 * @param sb a StringBuilder object.
670 * @param timer a Timer object contining the wakelock times.
671 * @param batteryRealtime the current on-battery time in microseconds.
672 * @param name the name of the wakelock.
673 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
674 * @param linePrefix a String to be prepended to each line of output.
675 * @return the line prefix
676 */
677 private static final String printWakeLock(StringBuilder sb, Timer timer,
678 long batteryRealtime, String name, int which, String linePrefix) {
679
680 if (timer != null) {
681 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -0700682 long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800683 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
684
Evan Millarc64edde2009-04-18 12:26:32 -0700685 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 if (totalTimeMillis != 0) {
687 sb.append(linePrefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700688 formatTimeMs(sb, totalTimeMillis);
689 if (name != null) sb.append(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 sb.append(' ');
691 sb.append('(');
692 sb.append(count);
693 sb.append(" times)");
694 return ", ";
695 }
696 }
697 return linePrefix;
698 }
699
700 /**
701 * Checkin version of wakelock printer. Prints simple comma-separated list.
702 *
703 * @param sb a StringBuilder object.
704 * @param timer a Timer object contining the wakelock times.
705 * @param now the current time in microseconds.
706 * @param name the name of the wakelock.
707 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
708 * @param linePrefix a String to be prepended to each line of output.
709 * @return the line prefix
710 */
711 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
Evan Millarc64edde2009-04-18 12:26:32 -0700712 String name, int which, String linePrefix) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713 long totalTimeMicros = 0;
714 int count = 0;
715 if (timer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700716 totalTimeMicros = timer.getTotalTimeLocked(now, which);
717 count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800718 }
719 sb.append(linePrefix);
720 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
721 sb.append(',');
Evan Millarc64edde2009-04-18 12:26:32 -0700722 sb.append(name != null ? name + "," : "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 sb.append(count);
724 return ",";
725 }
726
727 /**
728 * Dump a comma-separated line of values for terse checkin mode.
729 *
730 * @param pw the PageWriter to dump log to
731 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
732 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
733 * @param args type-dependent data arguments
734 */
735 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
736 Object... args ) {
737 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
738 pw.print(uid); pw.print(',');
739 pw.print(category); pw.print(',');
740 pw.print(type);
741
742 for (Object arg : args) {
743 pw.print(',');
744 pw.print(arg);
745 }
746 pw.print('\n');
747 }
748
749 /**
750 * Checkin server version of dump to produce more compact, computer-readable log.
751 *
752 * NOTE: all times are expressed in 'ms'.
753 * @param fd
754 * @param pw
755 * @param which
756 */
757 private final void dumpCheckinLocked(PrintWriter pw, int which) {
758 final long rawUptime = SystemClock.uptimeMillis() * 1000;
759 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
760 final long batteryUptime = getBatteryUptime(rawUptime);
761 final long batteryRealtime = getBatteryRealtime(rawRealtime);
762 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
763 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
764 final long totalRealtime = computeRealtime(rawRealtime, which);
765 final long totalUptime = computeUptime(rawUptime, which);
766 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
767 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700768 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700769 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700770 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771
772 StringBuilder sb = new StringBuilder(128);
773
Evan Millar22ac0432009-03-31 11:33:18 -0700774 SparseArray<? extends Uid> uidStats = getUidStats();
775 final int NU = uidStats.size();
776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800777 String category = STAT_NAMES[which];
778
779 // Dump "battery" stat
780 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
781 which == STATS_TOTAL ? getStartCount() : "N/A",
Dianne Hackborn617f8772009-03-31 15:04:46 -0700782 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
783 totalRealtime / 1000, totalUptime / 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784
Evan Millar22ac0432009-03-31 11:33:18 -0700785 // Calculate total network and wakelock times across all uids.
786 long rxTotal = 0;
787 long txTotal = 0;
788 long fullWakeLockTimeTotal = 0;
789 long partialWakeLockTimeTotal = 0;
790
791 for (int iu = 0; iu < NU; iu++) {
792 Uid u = uidStats.valueAt(iu);
793 rxTotal += u.getTcpBytesReceived(which);
794 txTotal += u.getTcpBytesSent(which);
795
796 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
797 if (wakelocks.size() > 0) {
798 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
799 : wakelocks.entrySet()) {
800 Uid.Wakelock wl = ent.getValue();
801
802 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
803 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700804 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
Evan Millar22ac0432009-03-31 11:33:18 -0700805 }
806
807 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
808 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -0700809 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -0700810 batteryRealtime, which);
811 }
812 }
813 }
814 }
815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 // Dump misc stats
817 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700818 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
Evan Millar22ac0432009-03-31 11:33:18 -0700819 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal,
Dianne Hackborn617f8772009-03-31 15:04:46 -0700820 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
821 getInputEventCount(which));
822
823 // Dump screen brightness stats
824 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
825 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
826 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
827 }
828 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
The Android Open Source Project10592532009-03-18 17:39:46 -0700829
Dianne Hackborn627bba72009-03-24 22:32:56 -0700830 // Dump signal strength stats
Dianne Hackborn617f8772009-03-31 15:04:46 -0700831 args = new Object[NUM_SIGNAL_STRENGTH_BINS];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700832 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
833 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
834 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700835 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
Amith Yamasanif37447b2009-10-08 18:28:01 -0700836 dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
837 getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700838 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
839 args[i] = getPhoneSignalStrengthCount(i, which);
840 }
841 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700842
843 // Dump network type stats
844 args = new Object[NUM_DATA_CONNECTION_TYPES];
845 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
846 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
847 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700848 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
849 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
850 args[i] = getPhoneDataConnectionCount(i, which);
851 }
852 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700853
The Android Open Source Project10592532009-03-18 17:39:46 -0700854 if (which == STATS_UNPLUGGED) {
Evan Millare84de8d2009-04-02 22:16:12 -0700855 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
Evan Millar633a1742009-04-02 16:36:33 -0700856 getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -0700857 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858
Evan Millarc64edde2009-04-18 12:26:32 -0700859 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
860 if (kernelWakelocks.size() > 0) {
861 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
862 sb.setLength(0);
863 printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
864
865 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
866 sb.toString());
867 }
868 }
869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 for (int iu = 0; iu < NU; iu++) {
871 final int uid = uidStats.keyAt(iu);
872 Uid u = uidStats.valueAt(iu);
873 // Dump Network stats per uid, if any
874 long rx = u.getTcpBytesReceived(which);
875 long tx = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700876 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
877 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700878 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700879
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -0700881
Dianne Hackborn617f8772009-03-31 15:04:46 -0700882 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
883 || wifiTurnedOnTime != 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700884 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
Dianne Hackborn617f8772009-03-31 15:04:46 -0700885 fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700886 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887
Dianne Hackborn617f8772009-03-31 15:04:46 -0700888 if (u.hasUserActivity()) {
889 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
890 boolean hasData = false;
891 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
892 int val = u.getUserActivityCount(i, which);
893 args[i] = val;
894 if (val != 0) hasData = true;
895 }
896 if (hasData) {
897 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args);
898 }
899 }
900
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800901 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
902 if (wakelocks.size() > 0) {
903 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
904 : wakelocks.entrySet()) {
905 Uid.Wakelock wl = ent.getValue();
906 String linePrefix = "";
907 sb.setLength(0);
Evan Millarc64edde2009-04-18 12:26:32 -0700908 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
909 batteryRealtime, "f", which, linePrefix);
910 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
911 batteryRealtime, "p", which, linePrefix);
912 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
913 batteryRealtime, "w", which, linePrefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914
915 // Only log if we had at lease one wakelock...
916 if (sb.length() > 0) {
917 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
918 }
919 }
920 }
921
922 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
923 if (sensors.size() > 0) {
924 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
925 : sensors.entrySet()) {
926 Uid.Sensor se = ent.getValue();
927 int sensorNumber = ent.getKey();
928 Timer timer = se.getSensorTime();
929 if (timer != null) {
930 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -0700931 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
932 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 if (totalTime != 0) {
934 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
935 }
936 }
937 }
938 }
939
940 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
941 if (processStats.size() > 0) {
942 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
943 : processStats.entrySet()) {
944 Uid.Proc ps = ent.getValue();
945
946 long userTime = ps.getUserTime(which);
947 long systemTime = ps.getSystemTime(which);
948 int starts = ps.getStarts(which);
949
950 if (userTime != 0 || systemTime != 0 || starts != 0) {
951 dumpLine(pw, uid, category, PROCESS_DATA,
952 ent.getKey(), // proc
953 userTime * 10, // cpu time in ms
954 systemTime * 10, // user time in ms
955 starts); // process starts
956 }
957 }
958 }
959
960 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
961 if (packageStats.size() > 0) {
962 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
963 : packageStats.entrySet()) {
964
965 Uid.Pkg ps = ent.getValue();
966 int wakeups = ps.getWakeups(which);
967 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
968 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
969 : serviceStats.entrySet()) {
970 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
971 long startTime = ss.getStartTime(batteryUptime, which);
972 int starts = ss.getStarts(which);
973 int launches = ss.getLaunches(which);
974 if (startTime != 0 || starts != 0 || launches != 0) {
975 dumpLine(pw, uid, category, APK_DATA,
976 wakeups, // wakeup alarms
977 ent.getKey(), // Apk
978 sent.getKey(), // service
979 startTime / 1000, // time spent started, in ms
980 starts,
981 launches);
982 }
983 }
984 }
985 }
986 }
987 }
988
989 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700990 private final void dumpLocked(PrintWriter pw, String prefix, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 final long rawUptime = SystemClock.uptimeMillis() * 1000;
992 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
993 final long batteryUptime = getBatteryUptime(rawUptime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700994 final long batteryRealtime = getBatteryRealtime(rawRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995
996 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
997 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
998 final long totalRealtime = computeRealtime(rawRealtime, which);
999 final long totalUptime = computeUptime(rawUptime, which);
1000
1001 StringBuilder sb = new StringBuilder(128);
Evan Millar22ac0432009-03-31 11:33:18 -07001002
1003 SparseArray<? extends Uid> uidStats = getUidStats();
1004 final int NU = uidStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001006 sb.setLength(0);
1007 sb.append(prefix);
1008 sb.append(" Time on battery: ");
1009 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
1010 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
1011 sb.append(") realtime, ");
1012 formatTimeMs(sb, whichBatteryUptime / 1000);
1013 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
1014 sb.append(") uptime");
1015 pw.println(sb.toString());
1016 sb.setLength(0);
1017 sb.append(prefix);
1018 sb.append(" Total run time: ");
1019 formatTimeMs(sb, totalRealtime / 1000);
1020 sb.append("realtime, ");
1021 formatTimeMs(sb, totalUptime / 1000);
1022 sb.append("uptime, ");
1023 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024
The Android Open Source Project10592532009-03-18 17:39:46 -07001025 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
1026 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001027 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001028 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
1029 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001030 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001031 sb.append(prefix);
1032 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
1033 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
1034 sb.append("), Input events: "); sb.append(getInputEventCount(which));
1035 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
1036 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
1037 sb.append(")");
1038 pw.println(sb.toString());
1039 sb.setLength(0);
1040 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001041 sb.append(" Screen brightnesses: ");
1042 boolean didOne = false;
1043 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1044 final long time = getScreenBrightnessTime(i, batteryRealtime, which);
1045 if (time == 0) {
1046 continue;
1047 }
1048 if (didOne) sb.append(", ");
1049 didOne = true;
1050 sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
1051 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001052 formatTimeMs(sb, time/1000);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001053 sb.append("(");
1054 sb.append(formatRatioLocked(time, screenOnTime));
1055 sb.append(")");
1056 }
1057 if (!didOne) sb.append("No activity");
1058 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001059
Evan Millar22ac0432009-03-31 11:33:18 -07001060 // Calculate total network and wakelock times across all uids.
1061 long rxTotal = 0;
1062 long txTotal = 0;
1063 long fullWakeLockTimeTotalMicros = 0;
1064 long partialWakeLockTimeTotalMicros = 0;
1065
Evan Millarc64edde2009-04-18 12:26:32 -07001066 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1067 if (kernelWakelocks.size() > 0) {
1068 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1069
1070 String linePrefix = ": ";
1071 sb.setLength(0);
1072 sb.append(prefix);
1073 sb.append(" Kernel Wake lock ");
1074 sb.append(ent.getKey());
1075 linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
1076 linePrefix);
1077 if (!linePrefix.equals(": ")) {
1078 sb.append(" realtime");
1079 } else {
1080 sb.append(": (nothing executed)");
1081 }
1082 pw.println(sb.toString());
1083 }
1084 }
1085
Evan Millar22ac0432009-03-31 11:33:18 -07001086 for (int iu = 0; iu < NU; iu++) {
1087 Uid u = uidStats.valueAt(iu);
1088 rxTotal += u.getTcpBytesReceived(which);
1089 txTotal += u.getTcpBytesSent(which);
1090
1091 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1092 if (wakelocks.size() > 0) {
1093 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1094 : wakelocks.entrySet()) {
1095 Uid.Wakelock wl = ent.getValue();
1096
1097 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1098 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001099 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001100 batteryRealtime, which);
1101 }
1102
1103 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1104 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001105 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001106 batteryRealtime, which);
1107 }
1108 }
1109 }
1110 }
1111
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001112 pw.print(prefix);
1113 pw.print(" Total received: "); pw.print(formatBytesLocked(rxTotal));
1114 pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal));
1115 sb.setLength(0);
1116 sb.append(prefix);
1117 sb.append(" Total full wakelock time: "); formatTimeMs(sb,
1118 (fullWakeLockTimeTotalMicros + 500) / 1000);
1119 sb.append(", Total partial waklock time: "); formatTimeMs(sb,
1120 (partialWakeLockTimeTotalMicros + 500) / 1000);
1121 pw.println(sb.toString());
Evan Millar22ac0432009-03-31 11:33:18 -07001122
Dianne Hackborn627bba72009-03-24 22:32:56 -07001123 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001124 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001125 sb.append(" Signal levels: ");
1126 didOne = false;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001127 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
1128 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
1129 if (time == 0) {
1130 continue;
1131 }
1132 if (didOne) sb.append(", ");
1133 didOne = true;
1134 sb.append(SIGNAL_STRENGTH_NAMES[i]);
1135 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001136 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001137 sb.append("(");
1138 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001139 sb.append(") ");
1140 sb.append(getPhoneSignalStrengthCount(i, which));
1141 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001142 }
1143 if (!didOne) sb.append("No activity");
1144 pw.println(sb.toString());
Amith Yamasanif37447b2009-10-08 18:28:01 -07001145
1146 sb.setLength(0);
1147 sb.append(prefix);
1148 sb.append(" Signal scanning time: ");
1149 formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
1150 pw.println(sb.toString());
1151
Dianne Hackborn627bba72009-03-24 22:32:56 -07001152 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001153 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001154 sb.append(" Radio types: ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001155 didOne = false;
1156 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1157 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
1158 if (time == 0) {
1159 continue;
1160 }
1161 if (didOne) sb.append(", ");
1162 didOne = true;
1163 sb.append(DATA_CONNECTION_NAMES[i]);
1164 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001165 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001166 sb.append("(");
1167 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001168 sb.append(") ");
1169 sb.append(getPhoneDataConnectionCount(i, which));
1170 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001171 }
1172 if (!didOne) sb.append("No activity");
1173 pw.println(sb.toString());
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001174
1175 sb.setLength(0);
1176 sb.append(prefix);
1177 sb.append(" Radio data uptime when unplugged: ");
1178 sb.append(getRadioDataUptime() / 1000);
1179 sb.append(" ms");
1180 pw.println(sb.toString());
1181
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001182 sb.setLength(0);
1183 sb.append(prefix);
1184 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
1185 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
1186 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
1187 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
1188 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
1189 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
1190 sb.append(")");
1191 pw.println(sb.toString());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001192
The Android Open Source Project10592532009-03-18 17:39:46 -07001193 pw.println(" ");
1194
1195 if (which == STATS_UNPLUGGED) {
1196 if (getIsOnBattery()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001197 pw.print(prefix); pw.println(" Device is currently unplugged");
1198 pw.print(prefix); pw.print(" Discharge cycle start level: ");
1199 pw.println(getDischargeStartLevel());
1200 pw.print(prefix); pw.print(" Discharge cycle current level: ");
1201 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001202 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001203 pw.print(prefix); pw.println(" Device is currently plugged into power");
1204 pw.print(prefix); pw.print(" Last discharge cycle start level: ");
1205 pw.println(getDischargeStartLevel());
1206 pw.print(prefix); pw.print(" Last discharge cycle end level: ");
1207 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001208 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001209 pw.println(" ");
The Android Open Source Project10592532009-03-18 17:39:46 -07001210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211
Evan Millar22ac0432009-03-31 11:33:18 -07001212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 for (int iu=0; iu<NU; iu++) {
1214 final int uid = uidStats.keyAt(iu);
1215 Uid u = uidStats.valueAt(iu);
1216 pw.println(prefix + " #" + uid + ":");
1217 boolean uidActivity = false;
1218
1219 long tcpReceived = u.getTcpBytesReceived(which);
1220 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001221 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1222 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001223 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 if (tcpReceived != 0 || tcpSent != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001226 pw.print(prefix); pw.print(" Network: ");
1227 pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, ");
1228 pw.print(formatBytesLocked(tcpSent)); pw.println(" sent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001230
1231 if (u.hasUserActivity()) {
1232 boolean hasData = false;
1233 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1234 int val = u.getUserActivityCount(i, which);
1235 if (val != 0) {
1236 if (!hasData) {
1237 sb.setLength(0);
1238 sb.append(" User activity: ");
1239 hasData = true;
1240 } else {
1241 sb.append(", ");
1242 }
1243 sb.append(val);
1244 sb.append(" ");
1245 sb.append(Uid.USER_ACTIVITY_TYPES[i]);
1246 }
1247 }
1248 if (hasData) {
1249 pw.println(sb.toString());
1250 }
1251 }
1252
1253 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
1254 || wifiTurnedOnTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001255 sb.setLength(0);
1256 sb.append(prefix); sb.append(" Turned Wifi On: ");
1257 formatTimeMs(sb, wifiTurnedOnTime / 1000);
1258 sb.append("("); sb.append(formatRatioLocked(wifiTurnedOnTime,
1259 whichBatteryRealtime)); sb.append(")\n");
1260 sb.append(prefix); sb.append(" Full Wifi Lock: ");
1261 formatTimeMs(sb, fullWifiLockOnTime / 1000);
1262 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
1263 whichBatteryRealtime)); sb.append(")\n");
1264 sb.append(prefix); sb.append(" Scan Wifi Lock: ");
1265 formatTimeMs(sb, scanWifiLockOnTime / 1000);
1266 sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime,
1267 whichBatteryRealtime)); sb.append(")");
1268 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001269 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270
1271 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1272 if (wakelocks.size() > 0) {
1273 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1274 : wakelocks.entrySet()) {
1275 Uid.Wakelock wl = ent.getValue();
1276 String linePrefix = ": ";
1277 sb.setLength(0);
1278 sb.append(prefix);
1279 sb.append(" Wake lock ");
1280 sb.append(ent.getKey());
1281 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
1282 "full", which, linePrefix);
1283 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
1284 "partial", which, linePrefix);
1285 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
1286 "window", which, linePrefix);
1287 if (!linePrefix.equals(": ")) {
1288 sb.append(" realtime");
1289 } else {
1290 sb.append(": (nothing executed)");
1291 }
1292 pw.println(sb.toString());
1293 uidActivity = true;
1294 }
1295 }
1296
1297 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1298 if (sensors.size() > 0) {
1299 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1300 : sensors.entrySet()) {
1301 Uid.Sensor se = ent.getValue();
1302 int sensorNumber = ent.getKey();
1303 sb.setLength(0);
1304 sb.append(prefix);
1305 sb.append(" Sensor ");
1306 int handle = se.getHandle();
1307 if (handle == Uid.Sensor.GPS) {
1308 sb.append("GPS");
1309 } else {
1310 sb.append(handle);
1311 }
1312 sb.append(": ");
1313
1314 Timer timer = se.getSensorTime();
1315 if (timer != null) {
1316 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -07001317 long totalTime = (timer.getTotalTimeLocked(
1318 batteryRealtime, which) + 500) / 1000;
1319 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 //timer.logState();
1321 if (totalTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001322 formatTimeMs(sb, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 sb.append("realtime (");
1324 sb.append(count);
1325 sb.append(" times)");
1326 } else {
1327 sb.append("(not used)");
1328 }
1329 } else {
1330 sb.append("(not used)");
1331 }
1332
1333 pw.println(sb.toString());
1334 uidActivity = true;
1335 }
1336 }
1337
1338 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1339 if (processStats.size() > 0) {
1340 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1341 : processStats.entrySet()) {
1342 Uid.Proc ps = ent.getValue();
1343 long userTime;
1344 long systemTime;
1345 int starts;
1346
1347 userTime = ps.getUserTime(which);
1348 systemTime = ps.getSystemTime(which);
1349 starts = ps.getStarts(which);
1350
1351 if (userTime != 0 || systemTime != 0 || starts != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001352 sb.setLength(0);
1353 sb.append(prefix); sb.append(" Proc ");
1354 sb.append(ent.getKey()); sb.append(":\n");
1355 sb.append(prefix); sb.append(" CPU: ");
1356 formatTime(sb, userTime); sb.append("usr + ");
1357 formatTime(sb, systemTime); sb.append("krn\n");
1358 sb.append(prefix); sb.append(" "); sb.append(starts);
1359 sb.append(" proc starts");
1360 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 uidActivity = true;
1362 }
1363 }
1364 }
1365
1366 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1367 if (packageStats.size() > 0) {
1368 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1369 : packageStats.entrySet()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001370 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001371 boolean apkActivity = false;
1372 Uid.Pkg ps = ent.getValue();
1373 int wakeups = ps.getWakeups(which);
1374 if (wakeups != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001375 pw.print(prefix); pw.print(" ");
1376 pw.print(wakeups); pw.println(" wakeup alarms");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 apkActivity = true;
1378 }
1379 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1380 if (serviceStats.size() > 0) {
1381 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1382 : serviceStats.entrySet()) {
1383 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1384 long startTime = ss.getStartTime(batteryUptime, which);
1385 int starts = ss.getStarts(which);
1386 int launches = ss.getLaunches(which);
1387 if (startTime != 0 || starts != 0 || launches != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001388 sb.setLength(0);
1389 sb.append(prefix); sb.append(" Service ");
1390 sb.append(sent.getKey()); sb.append(":\n");
1391 sb.append(prefix); sb.append(" Created for: ");
1392 formatTimeMs(sb, startTime / 1000);
1393 sb.append(" uptime\n");
1394 sb.append(prefix); sb.append(" Starts: ");
1395 sb.append(starts);
1396 sb.append(", launches: "); sb.append(launches);
1397 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 apkActivity = true;
1399 }
1400 }
1401 }
1402 if (!apkActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001403 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 }
1405 uidActivity = true;
1406 }
1407 }
1408 if (!uidActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001409 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 }
1411 }
1412 }
1413
1414 /**
1415 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
1416 *
1417 * @param pw a Printer to receive the dump output.
1418 */
1419 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001420 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421 pw.println("Total Statistics (Current and Historic):");
1422 pw.println(" System starts: " + getStartCount()
1423 + ", currently on battery: " + getIsOnBattery());
1424 dumpLocked(pw, "", STATS_TOTAL);
1425 pw.println("");
1426 pw.println("Last Run Statistics (Previous run of system):");
1427 dumpLocked(pw, "", STATS_LAST);
1428 pw.println("");
1429 pw.println("Current Battery Statistics (Currently running system):");
1430 dumpLocked(pw, "", STATS_CURRENT);
1431 pw.println("");
1432 pw.println("Unplugged Statistics (Since last unplugged from power):");
1433 dumpLocked(pw, "", STATS_UNPLUGGED);
1434 }
1435
1436 @SuppressWarnings("unused")
1437 public void dumpCheckinLocked(PrintWriter pw, String[] args) {
1438 boolean isUnpluggedOnly = false;
1439
1440 for (String arg : args) {
1441 if ("-u".equals(arg)) {
1442 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
1443 isUnpluggedOnly = true;
1444 }
1445 }
1446
1447 if (isUnpluggedOnly) {
1448 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1449 }
1450 else {
1451 dumpCheckinLocked(pw, STATS_TOTAL);
1452 dumpCheckinLocked(pw, STATS_LAST);
1453 dumpCheckinLocked(pw, STATS_UNPLUGGED);
1454 dumpCheckinLocked(pw, STATS_CURRENT);
1455 }
1456 }
1457
1458}