BatteryStats.java revision 633a1740ce5951ccb5d478ba2795f6f4fada1646
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, or 476 * the last time it booted on battery power. 477 */ 478 public abstract int getDischargeStartLevel(); 479 480 /** 481 * Returns the current battery percentage level if we are in a discharge cycle, otherwise 482 * returns the level at the last plug event. 483 */ 484 public abstract int getDischargeCurrentLevel(); 485 486 /** 487 * Returns the total, last, or current battery uptime in microseconds. 488 * 489 * @param curTime the elapsed realtime in microseconds. 490 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 491 */ 492 public abstract long computeBatteryUptime(long curTime, int which); 493 494 /** 495 * Returns the total, last, or current battery realtime in microseconds. 496 * 497 * @param curTime the current elapsed realtime in microseconds. 498 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 499 */ 500 public abstract long computeBatteryRealtime(long curTime, int which); 501 502 /** 503 * Returns the total, last, or current uptime in microseconds. 504 * 505 * @param curTime the current elapsed realtime in microseconds. 506 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 507 */ 508 public abstract long computeUptime(long curTime, int which); 509 510 /** 511 * Returns the total, last, or current realtime in microseconds. 512 * * 513 * @param curTime the current elapsed realtime in microseconds. 514 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 515 */ 516 public abstract long computeRealtime(long curTime, int which); 517 518 private final static void formatTime(StringBuilder out, long seconds) { 519 long days = seconds / (60 * 60 * 24); 520 if (days != 0) { 521 out.append(days); 522 out.append("d "); 523 } 524 long used = days * 60 * 60 * 24; 525 526 long hours = (seconds - used) / (60 * 60); 527 if (hours != 0 || used != 0) { 528 out.append(hours); 529 out.append("h "); 530 } 531 used += hours * 60 * 60; 532 533 long mins = (seconds-used) / 60; 534 if (mins != 0 || used != 0) { 535 out.append(mins); 536 out.append("m "); 537 } 538 used += mins * 60; 539 540 if (seconds != 0 || used != 0) { 541 out.append(seconds-used); 542 out.append("s "); 543 } 544 } 545 546 private final static String formatTime(long time) { 547 long sec = time / 100; 548 StringBuilder sb = new StringBuilder(); 549 formatTime(sb, sec); 550 sb.append((time - (sec * 100)) * 10); 551 sb.append("ms "); 552 return sb.toString(); 553 } 554 555 private final static String formatTimeMs(long time) { 556 long sec = time / 1000; 557 StringBuilder sb = new StringBuilder(); 558 formatTime(sb, sec); 559 sb.append(time - (sec * 1000)); 560 sb.append("ms "); 561 return sb.toString(); 562 } 563 564 private final String formatRatioLocked(long num, long den) { 565 if (den == 0L) { 566 return "---%"; 567 } 568 float perc = ((float)num) / ((float)den) * 100; 569 mFormatBuilder.setLength(0); 570 mFormatter.format("%.1f%%", perc); 571 return mFormatBuilder.toString(); 572 } 573 574 private final String formatBytesLocked(long bytes) { 575 mFormatBuilder.setLength(0); 576 577 if (bytes < BYTES_PER_KB) { 578 return bytes + "B"; 579 } else if (bytes < BYTES_PER_MB) { 580 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB); 581 return mFormatBuilder.toString(); 582 } else if (bytes < BYTES_PER_GB){ 583 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB); 584 return mFormatBuilder.toString(); 585 } else { 586 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB); 587 return mFormatBuilder.toString(); 588 } 589 } 590 591 /** 592 * 593 * @param sb a StringBuilder object. 594 * @param timer a Timer object contining the wakelock times. 595 * @param batteryRealtime the current on-battery time in microseconds. 596 * @param name the name of the wakelock. 597 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 598 * @param linePrefix a String to be prepended to each line of output. 599 * @return the line prefix 600 */ 601 private static final String printWakeLock(StringBuilder sb, Timer timer, 602 long batteryRealtime, String name, int which, String linePrefix) { 603 604 if (timer != null) { 605 // Convert from microseconds to milliseconds with rounding 606 long totalTimeMicros = timer.getTotalTime(batteryRealtime, which); 607 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 608 609 int count = timer.getCount(which); 610 if (totalTimeMillis != 0) { 611 sb.append(linePrefix); 612 sb.append(formatTimeMs(totalTimeMillis)); 613 sb.append(name); 614 sb.append(' '); 615 sb.append('('); 616 sb.append(count); 617 sb.append(" times)"); 618 return ", "; 619 } 620 } 621 return linePrefix; 622 } 623 624 /** 625 * Checkin version of wakelock printer. Prints simple comma-separated list. 626 * 627 * @param sb a StringBuilder object. 628 * @param timer a Timer object contining the wakelock times. 629 * @param now the current time in microseconds. 630 * @param name the name of the wakelock. 631 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 632 * @param linePrefix a String to be prepended to each line of output. 633 * @return the line prefix 634 */ 635 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now, 636 String name, int which, String linePrefix) { 637 long totalTimeMicros = 0; 638 int count = 0; 639 if (timer != null) { 640 totalTimeMicros = timer.getTotalTime(now, which); 641 count = timer.getCount(which); 642 } 643 sb.append(linePrefix); 644 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 645 sb.append(','); 646 sb.append(name); 647 sb.append(','); 648 sb.append(count); 649 return ","; 650 } 651 652 /** 653 * Dump a comma-separated line of values for terse checkin mode. 654 * 655 * @param pw the PageWriter to dump log to 656 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 657 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 658 * @param args type-dependent data arguments 659 */ 660 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 661 Object... args ) { 662 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 663 pw.print(uid); pw.print(','); 664 pw.print(category); pw.print(','); 665 pw.print(type); 666 667 for (Object arg : args) { 668 pw.print(','); 669 pw.print(arg); 670 } 671 pw.print('\n'); 672 } 673 674 /** 675 * Checkin server version of dump to produce more compact, computer-readable log. 676 * 677 * NOTE: all times are expressed in 'ms'. 678 * @param fd 679 * @param pw 680 * @param which 681 */ 682 private final void dumpCheckinLocked(PrintWriter pw, int which) { 683 final long rawUptime = SystemClock.uptimeMillis() * 1000; 684 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 685 final long batteryUptime = getBatteryUptime(rawUptime); 686 final long batteryRealtime = getBatteryRealtime(rawRealtime); 687 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 688 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 689 final long totalRealtime = computeRealtime(rawRealtime, which); 690 final long totalUptime = computeUptime(rawUptime, which); 691 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 692 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 693 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 694 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 695 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 696 697 StringBuilder sb = new StringBuilder(128); 698 699 SparseArray<? extends Uid> uidStats = getUidStats(); 700 final int NU = uidStats.size(); 701 702 String category = STAT_NAMES[which]; 703 704 // Dump "battery" stat 705 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 706 which == STATS_TOTAL ? getStartCount() : "N/A", 707 whichBatteryRealtime / 1000, whichBatteryUptime / 1000, 708 totalRealtime / 1000, totalUptime / 1000); 709 710 // Calculate total network and wakelock times across all uids. 711 long rxTotal = 0; 712 long txTotal = 0; 713 long fullWakeLockTimeTotal = 0; 714 long partialWakeLockTimeTotal = 0; 715 716 for (int iu = 0; iu < NU; iu++) { 717 Uid u = uidStats.valueAt(iu); 718 rxTotal += u.getTcpBytesReceived(which); 719 txTotal += u.getTcpBytesSent(which); 720 721 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 722 if (wakelocks.size() > 0) { 723 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 724 : wakelocks.entrySet()) { 725 Uid.Wakelock wl = ent.getValue(); 726 727 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 728 if (fullWakeTimer != null) { 729 fullWakeLockTimeTotal += fullWakeTimer.getTotalTime(batteryRealtime, which); 730 } 731 732 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 733 if (partialWakeTimer != null) { 734 partialWakeLockTimeTotal += partialWakeTimer.getTotalTime( 735 batteryRealtime, which); 736 } 737 } 738 } 739 } 740 741 // Dump misc stats 742 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 743 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, 744 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal, 745 fullWakeLockTimeTotal, partialWakeLockTimeTotal, 746 getInputEventCount(which)); 747 748 // Dump screen brightness stats 749 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; 750 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 751 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000; 752 } 753 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args); 754 755 // Dump signal strength stats 756 args = new Object[NUM_SIGNAL_STRENGTH_BINS]; 757 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 758 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000; 759 } 760 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args); 761 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 762 args[i] = getPhoneSignalStrengthCount(i, which); 763 } 764 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args); 765 766 // Dump network type stats 767 args = new Object[NUM_DATA_CONNECTION_TYPES]; 768 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 769 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000; 770 } 771 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args); 772 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 773 args[i] = getPhoneDataConnectionCount(i, which); 774 } 775 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args); 776 777 if (which == STATS_UNPLUGGED) { 778 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, getDischargeStartLevel(), 779 getDischargeCurrentLevel()); 780 } 781 782 for (int iu = 0; iu < NU; iu++) { 783 final int uid = uidStats.keyAt(iu); 784 Uid u = uidStats.valueAt(iu); 785 // Dump Network stats per uid, if any 786 long rx = u.getTcpBytesReceived(which); 787 long tx = u.getTcpBytesSent(which); 788 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 789 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 790 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which); 791 792 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx); 793 794 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0 795 || wifiTurnedOnTime != 0) { 796 dumpLine(pw, uid, category, WIFI_LOCK_DATA, 797 fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime); 798 } 799 800 if (u.hasUserActivity()) { 801 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES]; 802 boolean hasData = false; 803 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 804 int val = u.getUserActivityCount(i, which); 805 args[i] = val; 806 if (val != 0) hasData = true; 807 } 808 if (hasData) { 809 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args); 810 } 811 } 812 813 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 814 if (wakelocks.size() > 0) { 815 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 816 : wakelocks.entrySet()) { 817 Uid.Wakelock wl = ent.getValue(); 818 String linePrefix = ""; 819 sb.setLength(0); 820 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 821 "full", which, linePrefix); 822 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 823 "partial", which, linePrefix); 824 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 825 "window", which, linePrefix); 826 827 // Only log if we had at lease one wakelock... 828 if (sb.length() > 0) { 829 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString()); 830 } 831 } 832 } 833 834 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 835 if (sensors.size() > 0) { 836 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 837 : sensors.entrySet()) { 838 Uid.Sensor se = ent.getValue(); 839 int sensorNumber = ent.getKey(); 840 Timer timer = se.getSensorTime(); 841 if (timer != null) { 842 // Convert from microseconds to milliseconds with rounding 843 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000; 844 int count = timer.getCount(which); 845 if (totalTime != 0) { 846 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 847 } 848 } 849 } 850 } 851 852 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 853 if (processStats.size() > 0) { 854 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 855 : processStats.entrySet()) { 856 Uid.Proc ps = ent.getValue(); 857 858 long userTime = ps.getUserTime(which); 859 long systemTime = ps.getSystemTime(which); 860 int starts = ps.getStarts(which); 861 862 if (userTime != 0 || systemTime != 0 || starts != 0) { 863 dumpLine(pw, uid, category, PROCESS_DATA, 864 ent.getKey(), // proc 865 userTime * 10, // cpu time in ms 866 systemTime * 10, // user time in ms 867 starts); // process starts 868 } 869 } 870 } 871 872 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 873 if (packageStats.size() > 0) { 874 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 875 : packageStats.entrySet()) { 876 877 Uid.Pkg ps = ent.getValue(); 878 int wakeups = ps.getWakeups(which); 879 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 880 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 881 : serviceStats.entrySet()) { 882 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 883 long startTime = ss.getStartTime(batteryUptime, which); 884 int starts = ss.getStarts(which); 885 int launches = ss.getLaunches(which); 886 if (startTime != 0 || starts != 0 || launches != 0) { 887 dumpLine(pw, uid, category, APK_DATA, 888 wakeups, // wakeup alarms 889 ent.getKey(), // Apk 890 sent.getKey(), // service 891 startTime / 1000, // time spent started, in ms 892 starts, 893 launches); 894 } 895 } 896 } 897 } 898 } 899 } 900 901 @SuppressWarnings("unused") 902 private final void dumpLocked(Printer pw, String prefix, int which) { 903 final long rawUptime = SystemClock.uptimeMillis() * 1000; 904 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 905 final long batteryUptime = getBatteryUptime(rawUptime); 906 final long batteryRealtime = getBatteryRealtime(rawRealtime); 907 908 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 909 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 910 final long totalRealtime = computeRealtime(rawRealtime, which); 911 final long totalUptime = computeUptime(rawUptime, which); 912 913 StringBuilder sb = new StringBuilder(128); 914 915 SparseArray<? extends Uid> uidStats = getUidStats(); 916 final int NU = uidStats.size(); 917 918 pw.println(prefix 919 + " Time on battery: " 920 + formatTimeMs(whichBatteryRealtime / 1000) + "(" 921 + formatRatioLocked(whichBatteryRealtime, totalRealtime) 922 + ") realtime, " 923 + formatTimeMs(whichBatteryUptime / 1000) 924 + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime) 925 + ") uptime"); 926 pw.println(prefix 927 + " Total run time: " 928 + formatTimeMs(totalRealtime / 1000) 929 + "realtime, " 930 + formatTimeMs(totalUptime / 1000) 931 + "uptime, "); 932 933 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 934 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 935 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 936 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 937 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 938 pw.println(prefix 939 + " Screen on: " + formatTimeMs(screenOnTime / 1000) 940 + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime) 941 + "), Input events: " + getInputEventCount(which) 942 + ", Active phone call: " + formatTimeMs(phoneOnTime / 1000) 943 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime) + ")"); 944 sb.setLength(0); 945 sb.append(" Screen brightnesses: "); 946 boolean didOne = false; 947 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 948 final long time = getScreenBrightnessTime(i, batteryRealtime, which); 949 if (time == 0) { 950 continue; 951 } 952 if (didOne) sb.append(", "); 953 didOne = true; 954 sb.append(SCREEN_BRIGHTNESS_NAMES[i]); 955 sb.append(" "); 956 sb.append(formatTimeMs(time/1000)); 957 sb.append("("); 958 sb.append(formatRatioLocked(time, screenOnTime)); 959 sb.append(")"); 960 } 961 if (!didOne) sb.append("No activity"); 962 pw.println(sb.toString()); 963 964 // Calculate total network and wakelock times across all uids. 965 long rxTotal = 0; 966 long txTotal = 0; 967 long fullWakeLockTimeTotalMicros = 0; 968 long partialWakeLockTimeTotalMicros = 0; 969 970 for (int iu = 0; iu < NU; iu++) { 971 Uid u = uidStats.valueAt(iu); 972 rxTotal += u.getTcpBytesReceived(which); 973 txTotal += u.getTcpBytesSent(which); 974 975 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 976 if (wakelocks.size() > 0) { 977 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 978 : wakelocks.entrySet()) { 979 Uid.Wakelock wl = ent.getValue(); 980 981 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 982 if (fullWakeTimer != null) { 983 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTime( 984 batteryRealtime, which); 985 } 986 987 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 988 if (partialWakeTimer != null) { 989 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTime( 990 batteryRealtime, which); 991 } 992 } 993 } 994 } 995 996 pw.println(prefix 997 + " Total received: " + formatBytesLocked(rxTotal) 998 + ", Total sent: " + formatBytesLocked(txTotal)); 999 pw.println(prefix 1000 + " Total full wakelock time: " + formatTimeMs( 1001 (fullWakeLockTimeTotalMicros + 500) / 1000) 1002 + ", Total partial waklock time: " + formatTimeMs( 1003 (partialWakeLockTimeTotalMicros + 500) / 1000)); 1004 1005 sb.setLength(0); 1006 sb.append(" Signal levels: "); 1007 didOne = false; 1008 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 1009 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which); 1010 if (time == 0) { 1011 continue; 1012 } 1013 if (didOne) sb.append(", "); 1014 didOne = true; 1015 sb.append(SIGNAL_STRENGTH_NAMES[i]); 1016 sb.append(" "); 1017 sb.append(formatTimeMs(time/1000)); 1018 sb.append("("); 1019 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1020 sb.append(") "); 1021 sb.append(getPhoneSignalStrengthCount(i, which)); 1022 sb.append("x"); 1023 } 1024 if (!didOne) sb.append("No activity"); 1025 pw.println(sb.toString()); 1026 1027 sb.setLength(0); 1028 sb.append(" Radio types: "); 1029 didOne = false; 1030 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1031 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which); 1032 if (time == 0) { 1033 continue; 1034 } 1035 if (didOne) sb.append(", "); 1036 didOne = true; 1037 sb.append(DATA_CONNECTION_NAMES[i]); 1038 sb.append(" "); 1039 sb.append(formatTimeMs(time/1000)); 1040 sb.append("("); 1041 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1042 sb.append(") "); 1043 sb.append(getPhoneDataConnectionCount(i, which)); 1044 sb.append("x"); 1045 } 1046 if (!didOne) sb.append("No activity"); 1047 pw.println(sb.toString()); 1048 1049 pw.println(prefix 1050 + " Wifi on: " + formatTimeMs(wifiOnTime / 1000) 1051 + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime) 1052 + "), Wifi running: " + formatTimeMs(wifiRunningTime / 1000) 1053 + "(" + formatRatioLocked(wifiRunningTime, whichBatteryRealtime) 1054 + "), Bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000) 1055 + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")"); 1056 1057 pw.println(" "); 1058 1059 if (which == STATS_UNPLUGGED) { 1060 if (getIsOnBattery()) { 1061 pw.println(prefix + " Device is currently unplugged"); 1062 pw.println(prefix + " Discharge cycle start level: " + 1063 getDischargeStartLevel()); 1064 pw.println(prefix + " Discharge cycle current level: " + 1065 getDischargeCurrentLevel()); 1066 } else { 1067 pw.println(prefix + " Device is currently plugged into power"); 1068 pw.println(prefix + " Last discharge cycle start level: " + 1069 getDischargeStartLevel()); 1070 pw.println(prefix + " Last discharge cycle end level: " + 1071 getDischargeCurrentLevel()); 1072 } 1073 pw.println(" "); 1074 } 1075 1076 1077 for (int iu=0; iu<NU; iu++) { 1078 final int uid = uidStats.keyAt(iu); 1079 Uid u = uidStats.valueAt(iu); 1080 pw.println(prefix + " #" + uid + ":"); 1081 boolean uidActivity = false; 1082 1083 long tcpReceived = u.getTcpBytesReceived(which); 1084 long tcpSent = u.getTcpBytesSent(which); 1085 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 1086 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 1087 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which); 1088 1089 if (tcpReceived != 0 || tcpSent != 0) { 1090 pw.println(prefix + " Network: " + formatBytesLocked(tcpReceived) + " received, " 1091 + formatBytesLocked(tcpSent) + " sent"); 1092 } 1093 1094 if (u.hasUserActivity()) { 1095 boolean hasData = false; 1096 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1097 int val = u.getUserActivityCount(i, which); 1098 if (val != 0) { 1099 if (!hasData) { 1100 sb.setLength(0); 1101 sb.append(" User activity: "); 1102 hasData = true; 1103 } else { 1104 sb.append(", "); 1105 } 1106 sb.append(val); 1107 sb.append(" "); 1108 sb.append(Uid.USER_ACTIVITY_TYPES[i]); 1109 } 1110 } 1111 if (hasData) { 1112 pw.println(sb.toString()); 1113 } 1114 } 1115 1116 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0 1117 || wifiTurnedOnTime != 0) { 1118 pw.println(prefix + " Turned Wifi On Time: " 1119 + formatTimeMs(wifiTurnedOnTime / 1000) 1120 + "(" + formatRatioLocked(wifiTurnedOnTime, 1121 whichBatteryRealtime)+ ")"); 1122 pw.println(prefix + " Full Wifi Lock Time: " 1123 + formatTimeMs(fullWifiLockOnTime / 1000) 1124 + "(" + formatRatioLocked(fullWifiLockOnTime, 1125 whichBatteryRealtime)+ ")"); 1126 pw.println(prefix + " Scan Wifi Lock Time: " 1127 + formatTimeMs(scanWifiLockOnTime / 1000) 1128 + "(" + formatRatioLocked(scanWifiLockOnTime, 1129 whichBatteryRealtime)+ ")"); 1130 } 1131 1132 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1133 if (wakelocks.size() > 0) { 1134 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1135 : wakelocks.entrySet()) { 1136 Uid.Wakelock wl = ent.getValue(); 1137 String linePrefix = ": "; 1138 sb.setLength(0); 1139 sb.append(prefix); 1140 sb.append(" Wake lock "); 1141 sb.append(ent.getKey()); 1142 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 1143 "full", which, linePrefix); 1144 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 1145 "partial", which, linePrefix); 1146 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 1147 "window", which, linePrefix); 1148 if (!linePrefix.equals(": ")) { 1149 sb.append(" realtime"); 1150 } else { 1151 sb.append(": (nothing executed)"); 1152 } 1153 pw.println(sb.toString()); 1154 uidActivity = true; 1155 } 1156 } 1157 1158 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1159 if (sensors.size() > 0) { 1160 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1161 : sensors.entrySet()) { 1162 Uid.Sensor se = ent.getValue(); 1163 int sensorNumber = ent.getKey(); 1164 sb.setLength(0); 1165 sb.append(prefix); 1166 sb.append(" Sensor "); 1167 int handle = se.getHandle(); 1168 if (handle == Uid.Sensor.GPS) { 1169 sb.append("GPS"); 1170 } else { 1171 sb.append(handle); 1172 } 1173 sb.append(": "); 1174 1175 Timer timer = se.getSensorTime(); 1176 if (timer != null) { 1177 // Convert from microseconds to milliseconds with rounding 1178 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000; 1179 int count = timer.getCount(which); 1180 //timer.logState(); 1181 if (totalTime != 0) { 1182 sb.append(formatTimeMs(totalTime)); 1183 sb.append("realtime ("); 1184 sb.append(count); 1185 sb.append(" times)"); 1186 } else { 1187 sb.append("(not used)"); 1188 } 1189 } else { 1190 sb.append("(not used)"); 1191 } 1192 1193 pw.println(sb.toString()); 1194 uidActivity = true; 1195 } 1196 } 1197 1198 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 1199 if (processStats.size() > 0) { 1200 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 1201 : processStats.entrySet()) { 1202 Uid.Proc ps = ent.getValue(); 1203 long userTime; 1204 long systemTime; 1205 int starts; 1206 1207 userTime = ps.getUserTime(which); 1208 systemTime = ps.getSystemTime(which); 1209 starts = ps.getStarts(which); 1210 1211 if (userTime != 0 || systemTime != 0 || starts != 0) { 1212 pw.println(prefix + " Proc " + ent.getKey() + ":"); 1213 pw.println(prefix + " CPU: " + formatTime(userTime) + "user + " 1214 + formatTime(systemTime) + "kernel"); 1215 pw.println(prefix + " " + starts + " process starts"); 1216 uidActivity = true; 1217 } 1218 } 1219 } 1220 1221 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 1222 if (packageStats.size() > 0) { 1223 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 1224 : packageStats.entrySet()) { 1225 pw.println(prefix + " Apk " + ent.getKey() + ":"); 1226 boolean apkActivity = false; 1227 Uid.Pkg ps = ent.getValue(); 1228 int wakeups = ps.getWakeups(which); 1229 if (wakeups != 0) { 1230 pw.println(prefix + " " + wakeups + " wakeup alarms"); 1231 apkActivity = true; 1232 } 1233 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 1234 if (serviceStats.size() > 0) { 1235 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 1236 : serviceStats.entrySet()) { 1237 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 1238 long startTime = ss.getStartTime(batteryUptime, which); 1239 int starts = ss.getStarts(which); 1240 int launches = ss.getLaunches(which); 1241 if (startTime != 0 || starts != 0 || launches != 0) { 1242 pw.println(prefix + " Service " + sent.getKey() + ":"); 1243 pw.println(prefix + " Created for: " 1244 + formatTimeMs(startTime / 1000) 1245 + " uptime"); 1246 pw.println(prefix + " Starts: " + starts 1247 + ", launches: " + launches); 1248 apkActivity = true; 1249 } 1250 } 1251 } 1252 if (!apkActivity) { 1253 pw.println(prefix + " (nothing executed)"); 1254 } 1255 uidActivity = true; 1256 } 1257 } 1258 if (!uidActivity) { 1259 pw.println(prefix + " (nothing executed)"); 1260 } 1261 } 1262 } 1263 1264 /** 1265 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 1266 * 1267 * @param pw a Printer to receive the dump output. 1268 */ 1269 @SuppressWarnings("unused") 1270 public void dumpLocked(Printer pw) { 1271 pw.println("Total Statistics (Current and Historic):"); 1272 pw.println(" System starts: " + getStartCount() 1273 + ", currently on battery: " + getIsOnBattery()); 1274 dumpLocked(pw, "", STATS_TOTAL); 1275 pw.println(""); 1276 pw.println("Last Run Statistics (Previous run of system):"); 1277 dumpLocked(pw, "", STATS_LAST); 1278 pw.println(""); 1279 pw.println("Current Battery Statistics (Currently running system):"); 1280 dumpLocked(pw, "", STATS_CURRENT); 1281 pw.println(""); 1282 pw.println("Unplugged Statistics (Since last unplugged from power):"); 1283 dumpLocked(pw, "", STATS_UNPLUGGED); 1284 } 1285 1286 @SuppressWarnings("unused") 1287 public void dumpCheckinLocked(PrintWriter pw, String[] args) { 1288 boolean isUnpluggedOnly = false; 1289 1290 for (String arg : args) { 1291 if ("-u".equals(arg)) { 1292 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data"); 1293 isUnpluggedOnly = true; 1294 } 1295 } 1296 1297 if (isUnpluggedOnly) { 1298 dumpCheckinLocked(pw, STATS_UNPLUGGED); 1299 } 1300 else { 1301 dumpCheckinLocked(pw, STATS_TOTAL); 1302 dumpCheckinLocked(pw, STATS_LAST); 1303 dumpCheckinLocked(pw, STATS_UNPLUGGED); 1304 dumpCheckinLocked(pw, STATS_CURRENT); 1305 } 1306 } 1307 1308} 1309