BatteryStats.java revision 617f877c06c82584a38f41bb60d836e08c5e3bda
1package android.os; 2 3import java.io.PrintWriter; 4import java.util.Formatter; 5import java.util.Map; 6 7import android.util.Log; 8import android.util.Printer; 9import android.util.SparseArray; 10 11/** 12 * A class providing access to battery usage statistics, including information on 13 * wakelocks, processes, packages, and services. All times are represented in microseconds 14 * except where indicated otherwise. 15 * @hide 16 */ 17public abstract class BatteryStats implements Parcelable { 18 19 private static final boolean LOCAL_LOGV = false; 20 21 /** 22 * A constant indicating a partial wake lock timer. 23 */ 24 public static final int WAKE_TYPE_PARTIAL = 0; 25 26 /** 27 * A constant indicating a full wake lock timer. 28 */ 29 public static final int WAKE_TYPE_FULL = 1; 30 31 /** 32 * A constant indicating a window wake lock timer. 33 */ 34 public static final int WAKE_TYPE_WINDOW = 2; 35 36 /** 37 * A constant indicating a sensor timer. 38 * 39 * {@hide} 40 */ 41 public static final int SENSOR = 3; 42 43 /** 44 * A constant indicating a a wifi turn on timer 45 * 46 * {@hide} 47 */ 48 public static final int WIFI_TURNED_ON = 4; 49 50 /** 51 * A constant indicating a full wifi lock timer 52 * 53 * {@hide} 54 */ 55 public static final int FULL_WIFI_LOCK = 5; 56 57 /** 58 * A constant indicating a scan wifi lock timer 59 * 60 * {@hide} 61 */ 62 public static final int SCAN_WIFI_LOCK = 6; 63 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; 83 84 /** 85 * Bump the version on this if the checkin format changes. 86 */ 87 private static final int BATTERY_STATS_CHECKIN_VERSION = 3; 88 89 private static final long BYTES_PER_KB = 1024; 90 private static final long BYTES_PER_MB = 1048576; // 1024^2 91 private static final long BYTES_PER_GB = 1073741824; //1024^3 92 93 // TODO: Update this list if you add/change any stats above. 94 private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" }; 95 96 private static final String APK_DATA = "apk"; 97 private static final String PROCESS_DATA = "process"; 98 private static final String SENSOR_DATA = "sensor"; 99 private static final String WAKELOCK_DATA = "wakelock"; 100 private static final String NETWORK_DATA = "network"; 101 private static final String USER_ACTIVITY_DATA = "useract"; 102 private static final String BATTERY_DATA = "battery"; 103 private static final String WIFI_LOCK_DATA = "wifilock"; 104 private static final String MISC_DATA = "misc"; 105 private static final String SCREEN_BRIGHTNESS_DATA = "brightness"; 106 private static final String SIGNAL_STRENGTH_TIME_DATA = "sigtime"; 107 private static final String SIGNAL_STRENGTH_COUNT_DATA = "sigcnt"; 108 private static final String DATA_CONNECTION_TIME_DATA = "dconntime"; 109 private static final String DATA_CONNECTION_COUNT_DATA = "dconncnt"; 110 111 private final StringBuilder mFormatBuilder = new StringBuilder(8); 112 private final Formatter mFormatter = new Formatter(mFormatBuilder); 113 114 /** 115 * State for keeping track of counting information. 116 */ 117 public static abstract class Counter { 118 119 /** 120 * Returns the count associated with this Counter for the 121 * selected type of statistics. 122 * 123 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 124 */ 125 public abstract int getCount(int which); 126 127 /** 128 * Temporary for debugging. 129 */ 130 public abstract void logState(Printer pw, String prefix); 131 } 132 133 /** 134 * State for keeping track of timing information. 135 */ 136 public static abstract class Timer { 137 138 /** 139 * Returns the count associated with this Timer for the 140 * selected type of statistics. 141 * 142 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 143 */ 144 public abstract int getCount(int which); 145 146 /** 147 * Returns the total time in microseconds associated with this Timer for the 148 * selected type of statistics. 149 * 150 * @param batteryRealtime system realtime on battery in microseconds 151 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 152 * @return a time in microseconds 153 */ 154 public abstract long getTotalTime(long batteryRealtime, int which); 155 156 /** 157 * Temporary for debugging. 158 */ 159 public abstract void logState(Printer pw, String prefix); 160 } 161 162 /** 163 * The statistics associated with a particular uid. 164 */ 165 public static abstract class Uid { 166 167 /** 168 * Returns a mapping containing wakelock statistics. 169 * 170 * @return a Map from Strings to Uid.Wakelock objects. 171 */ 172 public abstract Map<String, ? extends Wakelock> getWakelockStats(); 173 174 /** 175 * The statistics associated with a particular wake lock. 176 */ 177 public static abstract class Wakelock { 178 public abstract Timer getWakeTime(int type); 179 } 180 181 /** 182 * Returns a mapping containing sensor statistics. 183 * 184 * @return a Map from Integer sensor ids to Uid.Sensor objects. 185 */ 186 public abstract Map<Integer, ? extends Sensor> getSensorStats(); 187 188 /** 189 * Returns a mapping containing process statistics. 190 * 191 * @return a Map from Strings to Uid.Proc objects. 192 */ 193 public abstract Map<String, ? extends Proc> getProcessStats(); 194 195 /** 196 * Returns a mapping containing package statistics. 197 * 198 * @return a Map from Strings to Uid.Pkg objects. 199 */ 200 public abstract Map<String, ? extends Pkg> getPackageStats(); 201 202 /** 203 * {@hide} 204 */ 205 public abstract int getUid(); 206 207 /** 208 * {@hide} 209 */ 210 public abstract long getTcpBytesReceived(int which); 211 212 /** 213 * {@hide} 214 */ 215 public abstract long getTcpBytesSent(int which); 216 217 public abstract void noteWifiTurnedOnLocked(); 218 public abstract void noteWifiTurnedOffLocked(); 219 public abstract void noteFullWifiLockAcquiredLocked(); 220 public abstract void noteFullWifiLockReleasedLocked(); 221 public abstract void noteScanWifiLockAcquiredLocked(); 222 public abstract void noteScanWifiLockReleasedLocked(); 223 public abstract long getWifiTurnedOnTime(long batteryRealtime, int which); 224 public abstract long getFullWifiLockTime(long batteryRealtime, int which); 225 public abstract long getScanWifiLockTime(long batteryRealtime, int which); 226 227 /** 228 * Note that these must match the constants in android.os.LocalPowerManager. 229 */ 230 static final String[] USER_ACTIVITY_TYPES = { 231 "other", "cheek", "touch", "long_touch", "touch_up", "button", "unknown" 232 }; 233 234 public static final int NUM_USER_ACTIVITY_TYPES = 7; 235 236 public abstract void noteUserActivityLocked(int type); 237 public abstract boolean hasUserActivity(); 238 public abstract int getUserActivityCount(int type, int which); 239 240 public static abstract class Sensor { 241 // Magic sensor number for the GPS. 242 public static final int GPS = -10000; 243 244 public abstract int getHandle(); 245 246 public abstract Timer getSensorTime(); 247 } 248 249 /** 250 * The statistics associated with a particular process. 251 */ 252 public static abstract class Proc { 253 254 /** 255 * Returns the total time (in 1/100 sec) spent executing in user code. 256 * 257 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 258 */ 259 public abstract long getUserTime(int which); 260 261 /** 262 * Returns the total time (in 1/100 sec) spent executing in system code. 263 * 264 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 265 */ 266 public abstract long getSystemTime(int which); 267 268 /** 269 * Returns the number of times the process has been started. 270 * 271 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 272 */ 273 public abstract int getStarts(int which); 274 } 275 276 /** 277 * The statistics associated with a particular package. 278 */ 279 public static abstract class Pkg { 280 281 /** 282 * Returns the number of times this package has done something that could wake up the 283 * device from sleep. 284 * 285 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 286 */ 287 public abstract int getWakeups(int which); 288 289 /** 290 * Returns a mapping containing service statistics. 291 */ 292 public abstract Map<String, ? extends Serv> getServiceStats(); 293 294 /** 295 * The statistics associated with a particular service. 296 */ 297 public abstract class Serv { 298 299 /** 300 * Returns the amount of time spent started. 301 * 302 * @param batteryUptime elapsed uptime on battery in microseconds. 303 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 304 * @return 305 */ 306 public abstract long getStartTime(long batteryUptime, int which); 307 308 /** 309 * Returns the total number of times startService() has been called. 310 * 311 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 312 */ 313 public abstract int getStarts(int which); 314 315 /** 316 * Returns the total number times the service has been launched. 317 * 318 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 319 */ 320 public abstract int getLaunches(int which); 321 } 322 } 323 } 324 325 /** 326 * Returns the number of times the device has been started. 327 */ 328 public abstract int getStartCount(); 329 330 /** 331 * Returns the time in milliseconds that the screen has been on while the device was 332 * running on battery. 333 * 334 * {@hide} 335 */ 336 public abstract long getScreenOnTime(long batteryRealtime, int which); 337 338 public static final int SCREEN_BRIGHTNESS_DARK = 0; 339 public static final int SCREEN_BRIGHTNESS_DIM = 1; 340 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2; 341 public static final int SCREEN_BRIGHTNESS_LIGHT = 3; 342 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4; 343 344 static final String[] SCREEN_BRIGHTNESS_NAMES = { 345 "dark", "dim", "medium", "light", "bright" 346 }; 347 348 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5; 349 350 /** 351 * Returns the time in milliseconds that the screen has been on with 352 * the given brightness 353 * 354 * {@hide} 355 */ 356 public abstract long getScreenBrightnessTime(int brightnessBin, 357 long batteryRealtime, int which); 358 359 public abstract int getInputEventCount(int which); 360 361 /** 362 * Returns the time in milliseconds that the phone has been on while the device was 363 * running on battery. 364 * 365 * {@hide} 366 */ 367 public abstract long getPhoneOnTime(long batteryRealtime, int which); 368 369 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; 370 public static final int SIGNAL_STRENGTH_POOR = 1; 371 public static final int SIGNAL_STRENGTH_MODERATE = 2; 372 public static final int SIGNAL_STRENGTH_GOOD = 3; 373 public static final int SIGNAL_STRENGTH_GREAT = 4; 374 375 static final String[] SIGNAL_STRENGTH_NAMES = { 376 "none", "poor", "moderate", "good", "great" 377 }; 378 379 public static final int NUM_SIGNAL_STRENGTH_BINS = 5; 380 381 /** 382 * Returns the time in milliseconds that the phone has been running with 383 * the given signal strength. 384 * 385 * {@hide} 386 */ 387 public abstract long getPhoneSignalStrengthTime(int strengthBin, 388 long batteryRealtime, int which); 389 390 /** 391 * Returns the number of times the phone has entered the given signal strength. 392 * 393 * {@hide} 394 */ 395 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which); 396 397 public static final int DATA_CONNECTION_NONE = 0; 398 public static final int DATA_CONNECTION_GPRS = 1; 399 public static final int DATA_CONNECTION_EDGE = 2; 400 public static final int DATA_CONNECTION_UMTS = 3; 401 public static final int DATA_CONNECTION_OTHER = 4; 402 403 static final String[] DATA_CONNECTION_NAMES = { 404 "none", "gprs", "edge", "umts", "other" 405 }; 406 407 public static final int NUM_DATA_CONNECTION_TYPES = 5; 408 409 /** 410 * Returns the time in milliseconds that the phone has been running with 411 * the given data connection. 412 * 413 * {@hide} 414 */ 415 public abstract long getPhoneDataConnectionTime(int dataType, 416 long batteryRealtime, int which); 417 418 /** 419 * Returns the number of times the phone has entered the given data 420 * connection type. 421 * 422 * {@hide} 423 */ 424 public abstract int getPhoneDataConnectionCount(int dataType, int which); 425 426 /** 427 * Returns the time in milliseconds that wifi has been on while the device was 428 * running on battery. 429 * 430 * {@hide} 431 */ 432 public abstract long getWifiOnTime(long batteryRealtime, int which); 433 434 /** 435 * Returns the time in milliseconds that wifi has been on and the driver has 436 * been in the running state while the device was running on battery. 437 * 438 * {@hide} 439 */ 440 public abstract long getWifiRunningTime(long batteryRealtime, int which); 441 442 /** 443 * Returns the time in milliseconds that bluetooth has been on while the device was 444 * running on battery. 445 * 446 * {@hide} 447 */ 448 public abstract long getBluetoothOnTime(long batteryRealtime, int which); 449 450 /** 451 * Return whether we are currently running on battery. 452 */ 453 public abstract boolean getIsOnBattery(); 454 455 /** 456 * Returns a SparseArray containing the statistics for each uid. 457 */ 458 public abstract SparseArray<? extends Uid> getUidStats(); 459 460 /** 461 * Returns the current battery uptime in microseconds. 462 * 463 * @param curTime the amount of elapsed realtime in microseconds. 464 */ 465 public abstract long getBatteryUptime(long curTime); 466 467 /** 468 * Returns the current battery realtime in microseconds. 469 * 470 * @param curTime the amount of elapsed realtime in microseconds. 471 */ 472 public abstract long getBatteryRealtime(long curTime); 473 474 /** 475 * Returns the battery percentage level at the last time the device was unplugged from power, 476 * or the last time it was booted while unplugged. 477 */ 478 public abstract int getUnpluggedStartLevel(); 479 480 /** 481 * Returns the battery percentage level at the last time the device was plugged into power. 482 */ 483 public abstract int getPluggedStartLevel(); 484 485 /** 486 * Returns the total, last, or current battery uptime in microseconds. 487 * 488 * @param curTime the elapsed realtime in microseconds. 489 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 490 */ 491 public abstract long computeBatteryUptime(long curTime, int which); 492 493 /** 494 * Returns the total, last, or current battery realtime in microseconds. 495 * 496 * @param curTime the current elapsed realtime in microseconds. 497 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 498 */ 499 public abstract long computeBatteryRealtime(long curTime, int which); 500 501 /** 502 * Returns the total, last, or current uptime in microseconds. 503 * 504 * @param curTime the current elapsed realtime in microseconds. 505 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 506 */ 507 public abstract long computeUptime(long curTime, int which); 508 509 /** 510 * Returns the total, last, or current realtime in microseconds. 511 * * 512 * @param curTime the current elapsed realtime in microseconds. 513 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 514 */ 515 public abstract long computeRealtime(long curTime, int which); 516 517 private final static void formatTime(StringBuilder out, long seconds) { 518 long days = seconds / (60 * 60 * 24); 519 if (days != 0) { 520 out.append(days); 521 out.append("d "); 522 } 523 long used = days * 60 * 60 * 24; 524 525 long hours = (seconds - used) / (60 * 60); 526 if (hours != 0 || used != 0) { 527 out.append(hours); 528 out.append("h "); 529 } 530 used += hours * 60 * 60; 531 532 long mins = (seconds-used) / 60; 533 if (mins != 0 || used != 0) { 534 out.append(mins); 535 out.append("m "); 536 } 537 used += mins * 60; 538 539 if (seconds != 0 || used != 0) { 540 out.append(seconds-used); 541 out.append("s "); 542 } 543 } 544 545 private final static String formatTime(long time) { 546 long sec = time / 100; 547 StringBuilder sb = new StringBuilder(); 548 formatTime(sb, sec); 549 sb.append((time - (sec * 100)) * 10); 550 sb.append("ms "); 551 return sb.toString(); 552 } 553 554 private final static String formatTimeMs(long time) { 555 long sec = time / 1000; 556 StringBuilder sb = new StringBuilder(); 557 formatTime(sb, sec); 558 sb.append(time - (sec * 1000)); 559 sb.append("ms "); 560 return sb.toString(); 561 } 562 563 private final String formatRatioLocked(long num, long den) { 564 if (den == 0L) { 565 return "---%"; 566 } 567 float perc = ((float)num) / ((float)den) * 100; 568 mFormatBuilder.setLength(0); 569 mFormatter.format("%.1f%%", perc); 570 return mFormatBuilder.toString(); 571 } 572 573 private final String formatBytesLocked(long bytes) { 574 mFormatBuilder.setLength(0); 575 576 if (bytes < BYTES_PER_KB) { 577 return bytes + "B"; 578 } else if (bytes < BYTES_PER_MB) { 579 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB); 580 return mFormatBuilder.toString(); 581 } else if (bytes < BYTES_PER_GB){ 582 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB); 583 return mFormatBuilder.toString(); 584 } else { 585 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB); 586 return mFormatBuilder.toString(); 587 } 588 } 589 590 /** 591 * 592 * @param sb a StringBuilder object. 593 * @param timer a Timer object contining the wakelock times. 594 * @param batteryRealtime the current on-battery time in microseconds. 595 * @param name the name of the wakelock. 596 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 597 * @param linePrefix a String to be prepended to each line of output. 598 * @return the line prefix 599 */ 600 private static final String printWakeLock(StringBuilder sb, Timer timer, 601 long batteryRealtime, String name, int which, String linePrefix) { 602 603 if (timer != null) { 604 // Convert from microseconds to milliseconds with rounding 605 long totalTimeMicros = timer.getTotalTime(batteryRealtime, which); 606 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 607 608 int count = timer.getCount(which); 609 if (totalTimeMillis != 0) { 610 sb.append(linePrefix); 611 sb.append(formatTimeMs(totalTimeMillis)); 612 sb.append(name); 613 sb.append(' '); 614 sb.append('('); 615 sb.append(count); 616 sb.append(" times)"); 617 return ", "; 618 } 619 } 620 return linePrefix; 621 } 622 623 /** 624 * Checkin version of wakelock printer. Prints simple comma-separated list. 625 * 626 * @param sb a StringBuilder object. 627 * @param timer a Timer object contining the wakelock times. 628 * @param now the current time in microseconds. 629 * @param name the name of the wakelock. 630 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 631 * @param linePrefix a String to be prepended to each line of output. 632 * @return the line prefix 633 */ 634 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now, 635 String name, int which, String linePrefix) { 636 long totalTimeMicros = 0; 637 int count = 0; 638 if (timer != null) { 639 totalTimeMicros = timer.getTotalTime(now, which); 640 count = timer.getCount(which); 641 } 642 sb.append(linePrefix); 643 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 644 sb.append(','); 645 sb.append(name); 646 sb.append(','); 647 sb.append(count); 648 return ","; 649 } 650 651 /** 652 * Dump a comma-separated line of values for terse checkin mode. 653 * 654 * @param pw the PageWriter to dump log to 655 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 656 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 657 * @param args type-dependent data arguments 658 */ 659 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 660 Object... args ) { 661 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 662 pw.print(uid); pw.print(','); 663 pw.print(category); pw.print(','); 664 pw.print(type); 665 666 for (Object arg : args) { 667 pw.print(','); 668 pw.print(arg); 669 } 670 pw.print('\n'); 671 } 672 673 /** 674 * Checkin server version of dump to produce more compact, computer-readable log. 675 * 676 * NOTE: all times are expressed in 'ms'. 677 * @param fd 678 * @param pw 679 * @param which 680 */ 681 private final void dumpCheckinLocked(PrintWriter pw, int which) { 682 final long rawUptime = SystemClock.uptimeMillis() * 1000; 683 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 684 final long batteryUptime = getBatteryUptime(rawUptime); 685 final long batteryRealtime = getBatteryRealtime(rawRealtime); 686 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 687 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 688 final long totalRealtime = computeRealtime(rawRealtime, which); 689 final long totalUptime = computeUptime(rawUptime, which); 690 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 691 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 692 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 693 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 694 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 695 696 StringBuilder sb = new StringBuilder(128); 697 698 SparseArray<? extends Uid> uidStats = getUidStats(); 699 final int NU = uidStats.size(); 700 701 String category = STAT_NAMES[which]; 702 703 // Dump "battery" stat 704 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 705 which == STATS_TOTAL ? getStartCount() : "N/A", 706 whichBatteryRealtime / 1000, whichBatteryUptime / 1000, 707 totalRealtime / 1000, totalUptime / 1000); 708 709 // Calculate total network and wakelock times across all uids. 710 long rxTotal = 0; 711 long txTotal = 0; 712 long fullWakeLockTimeTotal = 0; 713 long partialWakeLockTimeTotal = 0; 714 715 for (int iu = 0; iu < NU; iu++) { 716 Uid u = uidStats.valueAt(iu); 717 rxTotal += u.getTcpBytesReceived(which); 718 txTotal += u.getTcpBytesSent(which); 719 720 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 721 if (wakelocks.size() > 0) { 722 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 723 : wakelocks.entrySet()) { 724 Uid.Wakelock wl = ent.getValue(); 725 726 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 727 if (fullWakeTimer != null) { 728 fullWakeLockTimeTotal += fullWakeTimer.getTotalTime(batteryRealtime, which); 729 } 730 731 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 732 if (partialWakeTimer != null) { 733 partialWakeLockTimeTotal += partialWakeTimer.getTotalTime( 734 batteryRealtime, which); 735 } 736 } 737 } 738 } 739 740 // Dump misc stats 741 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 742 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, 743 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal, 744 fullWakeLockTimeTotal, partialWakeLockTimeTotal, 745 getInputEventCount(which)); 746 747 // Dump screen brightness stats 748 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; 749 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 750 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000; 751 } 752 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args); 753 754 // Dump signal strength stats 755 args = new Object[NUM_SIGNAL_STRENGTH_BINS]; 756 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 757 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000; 758 } 759 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args); 760 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 761 args[i] = getPhoneSignalStrengthCount(i, which); 762 } 763 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args); 764 765 // Dump network type stats 766 args = new Object[NUM_DATA_CONNECTION_TYPES]; 767 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 768 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000; 769 } 770 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args); 771 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 772 args[i] = getPhoneDataConnectionCount(i, which); 773 } 774 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args); 775 776 if (which == STATS_UNPLUGGED) { 777 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, getUnpluggedStartLevel(), 778 getPluggedStartLevel()); 779 } 780 781 for (int iu = 0; iu < NU; iu++) { 782 final int uid = uidStats.keyAt(iu); 783 Uid u = uidStats.valueAt(iu); 784 // Dump Network stats per uid, if any 785 long rx = u.getTcpBytesReceived(which); 786 long tx = u.getTcpBytesSent(which); 787 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 788 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 789 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which); 790 791 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx); 792 793 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0 794 || wifiTurnedOnTime != 0) { 795 dumpLine(pw, uid, category, WIFI_LOCK_DATA, 796 fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime); 797 } 798 799 if (u.hasUserActivity()) { 800 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES]; 801 boolean hasData = false; 802 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 803 int val = u.getUserActivityCount(i, which); 804 args[i] = val; 805 if (val != 0) hasData = true; 806 } 807 if (hasData) { 808 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args); 809 } 810 } 811 812 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 813 if (wakelocks.size() > 0) { 814 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 815 : wakelocks.entrySet()) { 816 Uid.Wakelock wl = ent.getValue(); 817 String linePrefix = ""; 818 sb.setLength(0); 819 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 820 "full", which, linePrefix); 821 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 822 "partial", which, linePrefix); 823 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 824 "window", which, linePrefix); 825 826 // Only log if we had at lease one wakelock... 827 if (sb.length() > 0) { 828 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString()); 829 } 830 } 831 } 832 833 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 834 if (sensors.size() > 0) { 835 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 836 : sensors.entrySet()) { 837 Uid.Sensor se = ent.getValue(); 838 int sensorNumber = ent.getKey(); 839 Timer timer = se.getSensorTime(); 840 if (timer != null) { 841 // Convert from microseconds to milliseconds with rounding 842 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000; 843 int count = timer.getCount(which); 844 if (totalTime != 0) { 845 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 846 } 847 } 848 } 849 } 850 851 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 852 if (processStats.size() > 0) { 853 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 854 : processStats.entrySet()) { 855 Uid.Proc ps = ent.getValue(); 856 857 long userTime = ps.getUserTime(which); 858 long systemTime = ps.getSystemTime(which); 859 int starts = ps.getStarts(which); 860 861 if (userTime != 0 || systemTime != 0 || starts != 0) { 862 dumpLine(pw, uid, category, PROCESS_DATA, 863 ent.getKey(), // proc 864 userTime * 10, // cpu time in ms 865 systemTime * 10, // user time in ms 866 starts); // process starts 867 } 868 } 869 } 870 871 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 872 if (packageStats.size() > 0) { 873 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 874 : packageStats.entrySet()) { 875 876 Uid.Pkg ps = ent.getValue(); 877 int wakeups = ps.getWakeups(which); 878 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 879 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 880 : serviceStats.entrySet()) { 881 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 882 long startTime = ss.getStartTime(batteryUptime, which); 883 int starts = ss.getStarts(which); 884 int launches = ss.getLaunches(which); 885 if (startTime != 0 || starts != 0 || launches != 0) { 886 dumpLine(pw, uid, category, APK_DATA, 887 wakeups, // wakeup alarms 888 ent.getKey(), // Apk 889 sent.getKey(), // service 890 startTime / 1000, // time spent started, in ms 891 starts, 892 launches); 893 } 894 } 895 } 896 } 897 } 898 } 899 900 @SuppressWarnings("unused") 901 private final void dumpLocked(Printer pw, String prefix, int which) { 902 final long rawUptime = SystemClock.uptimeMillis() * 1000; 903 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 904 final long batteryUptime = getBatteryUptime(rawUptime); 905 final long batteryRealtime = getBatteryRealtime(rawRealtime); 906 907 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 908 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 909 final long totalRealtime = computeRealtime(rawRealtime, which); 910 final long totalUptime = computeUptime(rawUptime, which); 911 912 StringBuilder sb = new StringBuilder(128); 913 914 SparseArray<? extends Uid> uidStats = getUidStats(); 915 final int NU = uidStats.size(); 916 917 pw.println(prefix 918 + " Time on battery: " 919 + formatTimeMs(whichBatteryRealtime / 1000) + "(" 920 + formatRatioLocked(whichBatteryRealtime, totalRealtime) 921 + ") realtime, " 922 + formatTimeMs(whichBatteryUptime / 1000) 923 + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime) 924 + ") uptime"); 925 pw.println(prefix 926 + " Total run time: " 927 + formatTimeMs(totalRealtime / 1000) 928 + "realtime, " 929 + formatTimeMs(totalUptime / 1000) 930 + "uptime, "); 931 932 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 933 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 934 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 935 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 936 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 937 pw.println(prefix 938 + " Screen on: " + formatTimeMs(screenOnTime / 1000) 939 + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime) 940 + "), Input events: " + getInputEventCount(which) 941 + ", Active phone call: " + formatTimeMs(phoneOnTime / 1000) 942 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime) + ")"); 943 sb.setLength(0); 944 sb.append(" Screen brightnesses: "); 945 boolean didOne = false; 946 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 947 final long time = getScreenBrightnessTime(i, batteryRealtime, which); 948 if (time == 0) { 949 continue; 950 } 951 if (didOne) sb.append(", "); 952 didOne = true; 953 sb.append(SCREEN_BRIGHTNESS_NAMES[i]); 954 sb.append(" "); 955 sb.append(formatTimeMs(time/1000)); 956 sb.append("("); 957 sb.append(formatRatioLocked(time, screenOnTime)); 958 sb.append(")"); 959 } 960 if (!didOne) sb.append("No activity"); 961 pw.println(sb.toString()); 962 963 // Calculate total network and wakelock times across all uids. 964 long rxTotal = 0; 965 long txTotal = 0; 966 long fullWakeLockTimeTotalMicros = 0; 967 long partialWakeLockTimeTotalMicros = 0; 968 969 for (int iu = 0; iu < NU; iu++) { 970 Uid u = uidStats.valueAt(iu); 971 rxTotal += u.getTcpBytesReceived(which); 972 txTotal += u.getTcpBytesSent(which); 973 974 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 975 if (wakelocks.size() > 0) { 976 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 977 : wakelocks.entrySet()) { 978 Uid.Wakelock wl = ent.getValue(); 979 980 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 981 if (fullWakeTimer != null) { 982 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTime( 983 batteryRealtime, which); 984 } 985 986 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 987 if (partialWakeTimer != null) { 988 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTime( 989 batteryRealtime, which); 990 } 991 } 992 } 993 } 994 995 pw.println(prefix 996 + " Total received: " + formatBytesLocked(rxTotal) 997 + ", Total sent: " + formatBytesLocked(txTotal)); 998 pw.println(prefix 999 + " Total full wakelock time: " + formatTimeMs( 1000 (fullWakeLockTimeTotalMicros + 500) / 1000) 1001 + ", Total partial waklock time: " + formatTimeMs( 1002 (partialWakeLockTimeTotalMicros + 500) / 1000)); 1003 1004 sb.setLength(0); 1005 sb.append(" Signal levels: "); 1006 didOne = false; 1007 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 1008 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which); 1009 if (time == 0) { 1010 continue; 1011 } 1012 if (didOne) sb.append(", "); 1013 didOne = true; 1014 sb.append(SIGNAL_STRENGTH_NAMES[i]); 1015 sb.append(" "); 1016 sb.append(formatTimeMs(time/1000)); 1017 sb.append("("); 1018 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1019 sb.append(") "); 1020 sb.append(getPhoneSignalStrengthCount(i, which)); 1021 sb.append("x"); 1022 } 1023 if (!didOne) sb.append("No activity"); 1024 pw.println(sb.toString()); 1025 1026 sb.setLength(0); 1027 sb.append(" Radio types: "); 1028 didOne = false; 1029 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1030 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which); 1031 if (time == 0) { 1032 continue; 1033 } 1034 if (didOne) sb.append(", "); 1035 didOne = true; 1036 sb.append(DATA_CONNECTION_NAMES[i]); 1037 sb.append(" "); 1038 sb.append(formatTimeMs(time/1000)); 1039 sb.append("("); 1040 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1041 sb.append(") "); 1042 sb.append(getPhoneDataConnectionCount(i, which)); 1043 sb.append("x"); 1044 } 1045 if (!didOne) sb.append("No activity"); 1046 pw.println(sb.toString()); 1047 1048 pw.println(prefix 1049 + " Wifi on: " + formatTimeMs(wifiOnTime / 1000) 1050 + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime) 1051 + "), Wifi running: " + formatTimeMs(wifiRunningTime / 1000) 1052 + "(" + formatRatioLocked(wifiRunningTime, whichBatteryRealtime) 1053 + "), Bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000) 1054 + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")"); 1055 1056 pw.println(" "); 1057 1058 if (which == STATS_UNPLUGGED) { 1059 if (getIsOnBattery()) { 1060 pw.println(prefix + " Device is currently unplugged"); 1061 pw.println(prefix + " Discharge cycle start level: " + 1062 getUnpluggedStartLevel()); 1063 } else { 1064 pw.println(prefix + " Device is currently plugged into power"); 1065 pw.println(prefix + " Last discharge cycle start level: " + 1066 getUnpluggedStartLevel()); 1067 pw.println(prefix + " Last discharge cycle end level: " + 1068 getPluggedStartLevel()); 1069 } 1070 pw.println(" "); 1071 } 1072 1073 1074 for (int iu=0; iu<NU; iu++) { 1075 final int uid = uidStats.keyAt(iu); 1076 Uid u = uidStats.valueAt(iu); 1077 pw.println(prefix + " #" + uid + ":"); 1078 boolean uidActivity = false; 1079 1080 long tcpReceived = u.getTcpBytesReceived(which); 1081 long tcpSent = u.getTcpBytesSent(which); 1082 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 1083 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 1084 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which); 1085 1086 if (tcpReceived != 0 || tcpSent != 0) { 1087 pw.println(prefix + " Network: " + formatBytesLocked(tcpReceived) + " received, " 1088 + formatBytesLocked(tcpSent) + " sent"); 1089 } 1090 1091 if (u.hasUserActivity()) { 1092 boolean hasData = false; 1093 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1094 int val = u.getUserActivityCount(i, which); 1095 if (val != 0) { 1096 if (!hasData) { 1097 sb.setLength(0); 1098 sb.append(" User activity: "); 1099 hasData = true; 1100 } else { 1101 sb.append(", "); 1102 } 1103 sb.append(val); 1104 sb.append(" "); 1105 sb.append(Uid.USER_ACTIVITY_TYPES[i]); 1106 } 1107 } 1108 if (hasData) { 1109 pw.println(sb.toString()); 1110 } 1111 } 1112 1113 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0 1114 || wifiTurnedOnTime != 0) { 1115 pw.println(prefix + " Turned Wifi On Time: " 1116 + formatTimeMs(wifiTurnedOnTime / 1000) 1117 + "(" + formatRatioLocked(wifiTurnedOnTime, 1118 whichBatteryRealtime)+ ")"); 1119 pw.println(prefix + " Full Wifi Lock Time: " 1120 + formatTimeMs(fullWifiLockOnTime / 1000) 1121 + "(" + formatRatioLocked(fullWifiLockOnTime, 1122 whichBatteryRealtime)+ ")"); 1123 pw.println(prefix + " Scan Wifi Lock Time: " 1124 + formatTimeMs(scanWifiLockOnTime / 1000) 1125 + "(" + formatRatioLocked(scanWifiLockOnTime, 1126 whichBatteryRealtime)+ ")"); 1127 } 1128 1129 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1130 if (wakelocks.size() > 0) { 1131 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1132 : wakelocks.entrySet()) { 1133 Uid.Wakelock wl = ent.getValue(); 1134 String linePrefix = ": "; 1135 sb.setLength(0); 1136 sb.append(prefix); 1137 sb.append(" Wake lock "); 1138 sb.append(ent.getKey()); 1139 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 1140 "full", which, linePrefix); 1141 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 1142 "partial", which, linePrefix); 1143 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 1144 "window", which, linePrefix); 1145 if (!linePrefix.equals(": ")) { 1146 sb.append(" realtime"); 1147 } else { 1148 sb.append(": (nothing executed)"); 1149 } 1150 pw.println(sb.toString()); 1151 uidActivity = true; 1152 } 1153 } 1154 1155 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1156 if (sensors.size() > 0) { 1157 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1158 : sensors.entrySet()) { 1159 Uid.Sensor se = ent.getValue(); 1160 int sensorNumber = ent.getKey(); 1161 sb.setLength(0); 1162 sb.append(prefix); 1163 sb.append(" Sensor "); 1164 int handle = se.getHandle(); 1165 if (handle == Uid.Sensor.GPS) { 1166 sb.append("GPS"); 1167 } else { 1168 sb.append(handle); 1169 } 1170 sb.append(": "); 1171 1172 Timer timer = se.getSensorTime(); 1173 if (timer != null) { 1174 // Convert from microseconds to milliseconds with rounding 1175 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000; 1176 int count = timer.getCount(which); 1177 //timer.logState(); 1178 if (totalTime != 0) { 1179 sb.append(formatTimeMs(totalTime)); 1180 sb.append("realtime ("); 1181 sb.append(count); 1182 sb.append(" times)"); 1183 } else { 1184 sb.append("(not used)"); 1185 } 1186 } else { 1187 sb.append("(not used)"); 1188 } 1189 1190 pw.println(sb.toString()); 1191 uidActivity = true; 1192 } 1193 } 1194 1195 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 1196 if (processStats.size() > 0) { 1197 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 1198 : processStats.entrySet()) { 1199 Uid.Proc ps = ent.getValue(); 1200 long userTime; 1201 long systemTime; 1202 int starts; 1203 1204 userTime = ps.getUserTime(which); 1205 systemTime = ps.getSystemTime(which); 1206 starts = ps.getStarts(which); 1207 1208 if (userTime != 0 || systemTime != 0 || starts != 0) { 1209 pw.println(prefix + " Proc " + ent.getKey() + ":"); 1210 pw.println(prefix + " CPU: " + formatTime(userTime) + "user + " 1211 + formatTime(systemTime) + "kernel"); 1212 pw.println(prefix + " " + starts + " process starts"); 1213 uidActivity = true; 1214 } 1215 } 1216 } 1217 1218 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 1219 if (packageStats.size() > 0) { 1220 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 1221 : packageStats.entrySet()) { 1222 pw.println(prefix + " Apk " + ent.getKey() + ":"); 1223 boolean apkActivity = false; 1224 Uid.Pkg ps = ent.getValue(); 1225 int wakeups = ps.getWakeups(which); 1226 if (wakeups != 0) { 1227 pw.println(prefix + " " + wakeups + " wakeup alarms"); 1228 apkActivity = true; 1229 } 1230 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 1231 if (serviceStats.size() > 0) { 1232 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 1233 : serviceStats.entrySet()) { 1234 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 1235 long startTime = ss.getStartTime(batteryUptime, which); 1236 int starts = ss.getStarts(which); 1237 int launches = ss.getLaunches(which); 1238 if (startTime != 0 || starts != 0 || launches != 0) { 1239 pw.println(prefix + " Service " + sent.getKey() + ":"); 1240 pw.println(prefix + " Created for: " 1241 + formatTimeMs(startTime / 1000) 1242 + " uptime"); 1243 pw.println(prefix + " Starts: " + starts 1244 + ", launches: " + launches); 1245 apkActivity = true; 1246 } 1247 } 1248 } 1249 if (!apkActivity) { 1250 pw.println(prefix + " (nothing executed)"); 1251 } 1252 uidActivity = true; 1253 } 1254 } 1255 if (!uidActivity) { 1256 pw.println(prefix + " (nothing executed)"); 1257 } 1258 } 1259 } 1260 1261 /** 1262 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 1263 * 1264 * @param pw a Printer to receive the dump output. 1265 */ 1266 @SuppressWarnings("unused") 1267 public void dumpLocked(Printer pw) { 1268 pw.println("Total Statistics (Current and Historic):"); 1269 pw.println(" System starts: " + getStartCount() 1270 + ", currently on battery: " + getIsOnBattery()); 1271 dumpLocked(pw, "", STATS_TOTAL); 1272 pw.println(""); 1273 pw.println("Last Run Statistics (Previous run of system):"); 1274 dumpLocked(pw, "", STATS_LAST); 1275 pw.println(""); 1276 pw.println("Current Battery Statistics (Currently running system):"); 1277 dumpLocked(pw, "", STATS_CURRENT); 1278 pw.println(""); 1279 pw.println("Unplugged Statistics (Since last unplugged from power):"); 1280 dumpLocked(pw, "", STATS_UNPLUGGED); 1281 } 1282 1283 @SuppressWarnings("unused") 1284 public void dumpCheckinLocked(PrintWriter pw, String[] args) { 1285 boolean isUnpluggedOnly = false; 1286 1287 for (String arg : args) { 1288 if ("-u".equals(arg)) { 1289 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data"); 1290 isUnpluggedOnly = true; 1291 } 1292 } 1293 1294 if (isUnpluggedOnly) { 1295 dumpCheckinLocked(pw, STATS_UNPLUGGED); 1296 } 1297 else { 1298 dumpCheckinLocked(pw, STATS_TOTAL); 1299 dumpCheckinLocked(pw, STATS_LAST); 1300 dumpCheckinLocked(pw, STATS_UNPLUGGED); 1301 dumpCheckinLocked(pw, STATS_CURRENT); 1302 } 1303 } 1304 1305} 1306