BatteryStats.java revision 627bba736d022c39696b7c582a6af5592d2b8c33
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 full wifi lock timer 45 * 46 * {@hide} 47 */ 48 public static final int FULL_WIFI_LOCK = 4; 49 50 /** 51 * A constant indicating a scan wifi lock timer 52 * 53 * {@hide} 54 */ 55 public static final int SCAN_WIFI_LOCK = 5; 56 57 /** 58 * Include all of the data in the stats, including previously saved data. 59 */ 60 public static final int STATS_TOTAL = 0; 61 62 /** 63 * Include only the last run in the stats. 64 */ 65 public static final int STATS_LAST = 1; 66 67 /** 68 * Include only the current run in the stats. 69 */ 70 public static final int STATS_CURRENT = 2; 71 72 /** 73 * Include only the run since the last time the device was unplugged in the stats. 74 */ 75 public static final int STATS_UNPLUGGED = 3; 76 77 /** 78 * Bump the version on this if the checkin format changes. 79 */ 80 private static final int BATTERY_STATS_CHECKIN_VERSION = 1; 81 82 // TODO: Update this list if you add/change any stats above. 83 private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" }; 84 85 private static final String APK_DATA = "apk"; 86 private static final String PROCESS_DATA = "process"; 87 private static final String SENSOR_DATA = "sensor"; 88 private static final String WAKELOCK_DATA = "wakelock"; 89 private static final String NETWORK_DATA = "network"; 90 private static final String BATTERY_DATA = "battery"; 91 private static final String WIFI_LOCK_DATA = "wifilock"; 92 private static final String MISC_DATA = "misc"; 93 private static final String SIGNAL_STRENGTH_DATA = "signal"; 94 private static final String DATA_CONNECTION_DATA = "dataconn"; 95 96 private final StringBuilder mFormatBuilder = new StringBuilder(8); 97 private final Formatter mFormatter = new Formatter(mFormatBuilder); 98 99 /** 100 * State for keeping track of timing information. 101 */ 102 public static abstract class Timer { 103 104 /** 105 * Returns the count associated with this Timer for the 106 * selected type of statistics. 107 * 108 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 109 */ 110 public abstract int getCount(int which); 111 112 /** 113 * Returns the total time in microseconds associated with this Timer for the 114 * selected type of statistics. 115 * 116 * @param batteryRealtime system realtime on battery in microseconds 117 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 118 * @return a time in microseconds 119 */ 120 public abstract long getTotalTime(long batteryRealtime, int which); 121 122 /** 123 * Temporary for debugging. 124 */ 125 public abstract void logState(Printer pw, String prefix); 126 } 127 128 /** 129 * The statistics associated with a particular uid. 130 */ 131 public static abstract class Uid { 132 133 /** 134 * Returns a mapping containing wakelock statistics. 135 * 136 * @return a Map from Strings to Uid.Wakelock objects. 137 */ 138 public abstract Map<String, ? extends Wakelock> getWakelockStats(); 139 140 /** 141 * The statistics associated with a particular wake lock. 142 */ 143 public static abstract class Wakelock { 144 public abstract Timer getWakeTime(int type); 145 } 146 147 /** 148 * Returns a mapping containing sensor statistics. 149 * 150 * @return a Map from Integer sensor ids to Uid.Sensor objects. 151 */ 152 public abstract Map<Integer, ? extends Sensor> getSensorStats(); 153 154 /** 155 * Returns a mapping containing process statistics. 156 * 157 * @return a Map from Strings to Uid.Proc objects. 158 */ 159 public abstract Map<String, ? extends Proc> getProcessStats(); 160 161 /** 162 * Returns a mapping containing package statistics. 163 * 164 * @return a Map from Strings to Uid.Pkg objects. 165 */ 166 public abstract Map<String, ? extends Pkg> getPackageStats(); 167 168 /** 169 * {@hide} 170 */ 171 public abstract int getUid(); 172 173 /** 174 * {@hide} 175 */ 176 public abstract long getTcpBytesReceived(int which); 177 178 /** 179 * {@hide} 180 */ 181 public abstract long getTcpBytesSent(int which); 182 183 public abstract void noteFullWifiLockAcquiredLocked(); 184 public abstract void noteFullWifiLockReleasedLocked(); 185 public abstract void noteScanWifiLockAcquiredLocked(); 186 public abstract void noteScanWifiLockReleasedLocked(); 187 public abstract long getFullWifiLockTime(long batteryRealtime, int which); 188 public abstract long getScanWifiLockTime(long batteryRealtime, int which); 189 190 public static abstract class Sensor { 191 // Magic sensor number for the GPS. 192 public static final int GPS = -10000; 193 194 public abstract int getHandle(); 195 196 public abstract Timer getSensorTime(); 197 } 198 199 /** 200 * The statistics associated with a particular process. 201 */ 202 public static abstract class Proc { 203 204 /** 205 * Returns the total time (in 1/100 sec) spent executing in user code. 206 * 207 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 208 */ 209 public abstract long getUserTime(int which); 210 211 /** 212 * Returns the total time (in 1/100 sec) spent executing in system code. 213 * 214 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 215 */ 216 public abstract long getSystemTime(int which); 217 218 /** 219 * Returns the number of times the process has been started. 220 * 221 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 222 */ 223 public abstract int getStarts(int which); 224 } 225 226 /** 227 * The statistics associated with a particular package. 228 */ 229 public static abstract class Pkg { 230 231 /** 232 * Returns the number of times this package has done something that could wake up the 233 * device from sleep. 234 * 235 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 236 */ 237 public abstract int getWakeups(int which); 238 239 /** 240 * Returns a mapping containing service statistics. 241 */ 242 public abstract Map<String, ? extends Serv> getServiceStats(); 243 244 /** 245 * The statistics associated with a particular service. 246 */ 247 public abstract class Serv { 248 249 /** 250 * Returns the amount of time spent started. 251 * 252 * @param batteryUptime elapsed uptime on battery in microseconds. 253 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 254 * @return 255 */ 256 public abstract long getStartTime(long batteryUptime, int which); 257 258 /** 259 * Returns the total number of times startService() has been called. 260 * 261 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 262 */ 263 public abstract int getStarts(int which); 264 265 /** 266 * Returns the total number times the service has been launched. 267 * 268 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 269 */ 270 public abstract int getLaunches(int which); 271 } 272 } 273 } 274 275 /** 276 * Returns the number of times the device has been started. 277 */ 278 public abstract int getStartCount(); 279 280 /** 281 * Returns the time in milliseconds that the screen has been on while the device was 282 * running on battery. 283 * 284 * {@hide} 285 */ 286 public abstract long getScreenOnTime(long batteryRealtime, int which); 287 288 /** 289 * Returns the time in milliseconds that the phone has been on while the device was 290 * running on battery. 291 * 292 * {@hide} 293 */ 294 public abstract long getPhoneOnTime(long batteryRealtime, int which); 295 296 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; 297 public static final int SIGNAL_STRENGTH_POOR = 1; 298 public static final int SIGNAL_STRENGTH_MODERATE = 2; 299 public static final int SIGNAL_STRENGTH_GOOD = 3; 300 public static final int SIGNAL_STRENGTH_GREAT = 4; 301 302 static final String[] SIGNAL_STRENGTH_NAMES = { 303 "none", "poor", "moderate", "good", "great" 304 }; 305 306 public static final int NUM_SIGNAL_STRENGTH_BINS = 5; 307 308 /** 309 * Returns the time in milliseconds that the phone has been running with 310 * the given signal strength. 311 * 312 * {@hide} 313 */ 314 public abstract long getPhoneSignalStrengthTime(int strengthBin, 315 long batteryRealtime, int which); 316 317 public static final int DATA_CONNECTION_NONE = 0; 318 public static final int DATA_CONNECTION_GPRS = 1; 319 public static final int DATA_CONNECTION_EDGE = 2; 320 public static final int DATA_CONNECTION_UMTS = 3; 321 public static final int DATA_CONNECTION_OTHER = 4; 322 323 static final String[] DATA_CONNECTION_NAMES = { 324 "none", "gprs", "edge", "umts", "other" 325 }; 326 327 public static final int NUM_DATA_CONNECTION_TYPES = 5; 328 329 /** 330 * Returns the time in milliseconds that the phone has been running with 331 * the given data connection. 332 * 333 * {@hide} 334 */ 335 public abstract long getPhoneDataConnectionTime(int dataType, 336 long batteryRealtime, int which); 337 338 /** 339 * Returns the time in milliseconds that wifi has been on while the device was 340 * running on battery. 341 * 342 * {@hide} 343 */ 344 public abstract long getWifiOnTime(long batteryRealtime, int which); 345 346 /** 347 * Returns the time in milliseconds that wifi has been on and the driver has 348 * been in the running state while the device was running on battery. 349 * 350 * {@hide} 351 */ 352 public abstract long getWifiRunningTime(long batteryRealtime, int which); 353 354 /** 355 * Returns the time in milliseconds that bluetooth has been on while the device was 356 * running on battery. 357 * 358 * {@hide} 359 */ 360 public abstract long getBluetoothOnTime(long batteryRealtime, int which); 361 362 /** 363 * Return whether we are currently running on battery. 364 */ 365 public abstract boolean getIsOnBattery(); 366 367 /** 368 * Returns a SparseArray containing the statistics for each uid. 369 */ 370 public abstract SparseArray<? extends Uid> getUidStats(); 371 372 /** 373 * Returns the current battery uptime in microseconds. 374 * 375 * @param curTime the amount of elapsed realtime in microseconds. 376 */ 377 public abstract long getBatteryUptime(long curTime); 378 379 /** 380 * Returns the current battery realtime in microseconds. 381 * 382 * @param curTime the amount of elapsed realtime in microseconds. 383 */ 384 public abstract long getBatteryRealtime(long curTime); 385 386 /** 387 * Returns the battery percentage level at the last time the device was unplugged from power, 388 * or the last time it was booted while unplugged. 389 */ 390 public abstract int getUnpluggedStartLevel(); 391 392 /** 393 * Returns the battery percentage level at the last time the device was plugged into power. 394 */ 395 public abstract int getPluggedStartLevel(); 396 397 /** 398 * Returns the total, last, or current battery uptime in microseconds. 399 * 400 * @param curTime the elapsed realtime in microseconds. 401 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 402 */ 403 public abstract long computeBatteryUptime(long curTime, int which); 404 405 /** 406 * Returns the total, last, or current battery realtime in microseconds. 407 * 408 * @param curTime the current elapsed realtime in microseconds. 409 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 410 */ 411 public abstract long computeBatteryRealtime(long curTime, int which); 412 413 /** 414 * Returns the total, last, or current uptime in microseconds. 415 * 416 * @param curTime the current elapsed realtime in microseconds. 417 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 418 */ 419 public abstract long computeUptime(long curTime, int which); 420 421 /** 422 * Returns the total, last, or current realtime in microseconds. 423 * * 424 * @param curTime the current elapsed realtime in microseconds. 425 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 426 */ 427 public abstract long computeRealtime(long curTime, int which); 428 429 private final static void formatTime(StringBuilder out, long seconds) { 430 long days = seconds / (60 * 60 * 24); 431 if (days != 0) { 432 out.append(days); 433 out.append("d "); 434 } 435 long used = days * 60 * 60 * 24; 436 437 long hours = (seconds - used) / (60 * 60); 438 if (hours != 0 || used != 0) { 439 out.append(hours); 440 out.append("h "); 441 } 442 used += hours * 60 * 60; 443 444 long mins = (seconds-used) / 60; 445 if (mins != 0 || used != 0) { 446 out.append(mins); 447 out.append("m "); 448 } 449 used += mins * 60; 450 451 if (seconds != 0 || used != 0) { 452 out.append(seconds-used); 453 out.append("s "); 454 } 455 } 456 457 private final static String formatTime(long time) { 458 long sec = time / 100; 459 StringBuilder sb = new StringBuilder(); 460 formatTime(sb, sec); 461 sb.append((time - (sec * 100)) * 10); 462 sb.append("ms "); 463 return sb.toString(); 464 } 465 466 private final static String formatTimeMs(long time) { 467 long sec = time / 1000; 468 StringBuilder sb = new StringBuilder(); 469 formatTime(sb, sec); 470 sb.append(time - (sec * 1000)); 471 sb.append("ms "); 472 return sb.toString(); 473 } 474 475 private final String formatRatioLocked(long num, long den) { 476 if (den == 0L) { 477 return "---%"; 478 } 479 float perc = ((float)num) / ((float)den) * 100; 480 mFormatBuilder.setLength(0); 481 mFormatter.format("%.1f%%", perc); 482 return mFormatBuilder.toString(); 483 } 484 485 /** 486 * 487 * @param sb a StringBuilder object. 488 * @param timer a Timer object contining the wakelock times. 489 * @param batteryRealtime the current on-battery time in microseconds. 490 * @param name the name of the wakelock. 491 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 492 * @param linePrefix a String to be prepended to each line of output. 493 * @return the line prefix 494 */ 495 private static final String printWakeLock(StringBuilder sb, Timer timer, 496 long batteryRealtime, String name, int which, String linePrefix) { 497 498 if (timer != null) { 499 // Convert from microseconds to milliseconds with rounding 500 long totalTimeMicros = timer.getTotalTime(batteryRealtime, which); 501 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 502 503 int count = timer.getCount(which); 504 if (totalTimeMillis != 0) { 505 sb.append(linePrefix); 506 sb.append(formatTimeMs(totalTimeMillis)); 507 sb.append(name); 508 sb.append(' '); 509 sb.append('('); 510 sb.append(count); 511 sb.append(" times)"); 512 return ", "; 513 } 514 } 515 return linePrefix; 516 } 517 518 /** 519 * Checkin version of wakelock printer. Prints simple comma-separated list. 520 * 521 * @param sb a StringBuilder object. 522 * @param timer a Timer object contining the wakelock times. 523 * @param now the current time in microseconds. 524 * @param name the name of the wakelock. 525 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 526 * @param linePrefix a String to be prepended to each line of output. 527 * @return the line prefix 528 */ 529 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now, 530 String name, int which, String linePrefix) { 531 long totalTimeMicros = 0; 532 int count = 0; 533 if (timer != null) { 534 totalTimeMicros = timer.getTotalTime(now, which); 535 count = timer.getCount(which); 536 } 537 sb.append(linePrefix); 538 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 539 sb.append(','); 540 sb.append(name); 541 sb.append(','); 542 sb.append(count); 543 return ","; 544 } 545 546 /** 547 * Dump a comma-separated line of values for terse checkin mode. 548 * 549 * @param pw the PageWriter to dump log to 550 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 551 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 552 * @param args type-dependent data arguments 553 */ 554 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 555 Object... args ) { 556 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 557 pw.print(uid); pw.print(','); 558 pw.print(category); pw.print(','); 559 pw.print(type); 560 561 for (Object arg : args) { 562 pw.print(','); 563 pw.print(arg); 564 } 565 pw.print('\n'); 566 } 567 568 /** 569 * Checkin server version of dump to produce more compact, computer-readable log. 570 * 571 * NOTE: all times are expressed in 'ms'. 572 * @param fd 573 * @param pw 574 * @param which 575 */ 576 private final void dumpCheckinLocked(PrintWriter pw, int which) { 577 final long rawUptime = SystemClock.uptimeMillis() * 1000; 578 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 579 final long batteryUptime = getBatteryUptime(rawUptime); 580 final long batteryRealtime = getBatteryRealtime(rawRealtime); 581 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 582 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 583 final long totalRealtime = computeRealtime(rawRealtime, which); 584 final long totalUptime = computeUptime(rawUptime, which); 585 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 586 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 587 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 588 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 589 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 590 591 StringBuilder sb = new StringBuilder(128); 592 593 String category = STAT_NAMES[which]; 594 595 // Dump "battery" stat 596 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 597 which == STATS_TOTAL ? getStartCount() : "N/A", 598 whichBatteryUptime / 1000, whichBatteryRealtime / 1000, 599 totalUptime / 1000, totalRealtime / 1000); 600 601 // Dump misc stats 602 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 603 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, 604 wifiRunningTime / 1000, bluetoothOnTime / 1000); 605 606 // Dump signal strength stats 607 Object[] args = new Object[NUM_SIGNAL_STRENGTH_BINS]; 608 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 609 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000; 610 } 611 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_DATA, args); 612 613 // Dump network type stats 614 args = new Object[NUM_DATA_CONNECTION_TYPES]; 615 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 616 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000; 617 } 618 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_DATA, args); 619 620 if (which == STATS_UNPLUGGED) { 621 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, getUnpluggedStartLevel(), 622 getPluggedStartLevel()); 623 } 624 625 SparseArray<? extends Uid> uidStats = getUidStats(); 626 final int NU = uidStats.size(); 627 for (int iu = 0; iu < NU; iu++) { 628 final int uid = uidStats.keyAt(iu); 629 Uid u = uidStats.valueAt(iu); 630 // Dump Network stats per uid, if any 631 long rx = u.getTcpBytesReceived(which); 632 long tx = u.getTcpBytesSent(which); 633 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 634 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 635 636 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx); 637 638 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) { 639 dumpLine(pw, uid, category, WIFI_LOCK_DATA, 640 fullWifiLockOnTime, scanWifiLockOnTime); 641 } 642 643 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 644 if (wakelocks.size() > 0) { 645 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 646 : wakelocks.entrySet()) { 647 Uid.Wakelock wl = ent.getValue(); 648 String linePrefix = ""; 649 sb.setLength(0); 650 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 651 "full", which, linePrefix); 652 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 653 "partial", which, linePrefix); 654 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 655 "window", which, linePrefix); 656 657 // Only log if we had at lease one wakelock... 658 if (sb.length() > 0) { 659 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString()); 660 } 661 } 662 } 663 664 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 665 if (sensors.size() > 0) { 666 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 667 : sensors.entrySet()) { 668 Uid.Sensor se = ent.getValue(); 669 int sensorNumber = ent.getKey(); 670 Timer timer = se.getSensorTime(); 671 if (timer != null) { 672 // Convert from microseconds to milliseconds with rounding 673 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000; 674 int count = timer.getCount(which); 675 if (totalTime != 0) { 676 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 677 } 678 } 679 } 680 } 681 682 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 683 if (processStats.size() > 0) { 684 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 685 : processStats.entrySet()) { 686 Uid.Proc ps = ent.getValue(); 687 688 long userTime = ps.getUserTime(which); 689 long systemTime = ps.getSystemTime(which); 690 int starts = ps.getStarts(which); 691 692 if (userTime != 0 || systemTime != 0 || starts != 0) { 693 dumpLine(pw, uid, category, PROCESS_DATA, 694 ent.getKey(), // proc 695 userTime * 10, // cpu time in ms 696 systemTime * 10, // user time in ms 697 starts); // process starts 698 } 699 } 700 } 701 702 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 703 if (packageStats.size() > 0) { 704 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 705 : packageStats.entrySet()) { 706 707 Uid.Pkg ps = ent.getValue(); 708 int wakeups = ps.getWakeups(which); 709 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 710 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 711 : serviceStats.entrySet()) { 712 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 713 long startTime = ss.getStartTime(batteryUptime, which); 714 int starts = ss.getStarts(which); 715 int launches = ss.getLaunches(which); 716 if (startTime != 0 || starts != 0 || launches != 0) { 717 dumpLine(pw, uid, category, APK_DATA, 718 wakeups, // wakeup alarms 719 ent.getKey(), // Apk 720 sent.getKey(), // service 721 startTime / 1000, // time spent started, in ms 722 starts, 723 launches); 724 } 725 } 726 } 727 } 728 } 729 } 730 731 @SuppressWarnings("unused") 732 private final void dumpLocked(Printer pw, String prefix, int which) { 733 final long rawUptime = SystemClock.uptimeMillis() * 1000; 734 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 735 final long batteryUptime = getBatteryUptime(rawUptime); 736 final long batteryRealtime = getBatteryRealtime(rawRealtime); 737 738 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 739 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 740 final long totalRealtime = computeRealtime(rawRealtime, which); 741 final long totalUptime = computeUptime(rawUptime, which); 742 743 StringBuilder sb = new StringBuilder(128); 744 745 pw.println(prefix 746 + " Time on battery: " + formatTimeMs(whichBatteryUptime / 1000) 747 + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime) 748 + ") uptime, " 749 + formatTimeMs(whichBatteryRealtime / 1000) + "(" 750 + formatRatioLocked(whichBatteryRealtime, totalRealtime) 751 + ") realtime"); 752 pw.println(prefix 753 + " Total: " 754 + formatTimeMs(totalUptime / 1000) 755 + "uptime, " 756 + formatTimeMs(totalRealtime / 1000) 757 + "realtime"); 758 759 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 760 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 761 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 762 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 763 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 764 pw.println(prefix 765 + " Screen on: " + formatTimeMs(screenOnTime / 1000) 766 + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime) 767 + "), Phone on: " + formatTimeMs(phoneOnTime / 1000) 768 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime)); 769 pw.println(prefix 770 + " Wifi on: " + formatTimeMs(wifiOnTime / 1000) 771 + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime) 772 + "), Wifi running: " + formatTimeMs(wifiRunningTime / 1000) 773 + "(" + formatRatioLocked(wifiRunningTime, whichBatteryRealtime) 774 + "), Bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000) 775 + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")"); 776 777 sb.setLength(0); 778 sb.append(" Signal strengths: "); 779 boolean didOne = false; 780 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 781 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which); 782 if (time == 0) { 783 continue; 784 } 785 if (didOne) sb.append(", "); 786 didOne = true; 787 sb.append(SIGNAL_STRENGTH_NAMES[i]); 788 sb.append(" "); 789 sb.append(formatTimeMs(time/1000)); 790 sb.append("("); 791 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 792 sb.append(")"); 793 } 794 if (!didOne) sb.append("No activity"); 795 pw.println(sb.toString()); 796 797 sb.setLength(0); 798 sb.append(" Data types: "); 799 didOne = false; 800 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 801 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which); 802 if (time == 0) { 803 continue; 804 } 805 if (didOne) sb.append(", "); 806 didOne = true; 807 sb.append(DATA_CONNECTION_NAMES[i]); 808 sb.append(" "); 809 sb.append(formatTimeMs(time/1000)); 810 sb.append("("); 811 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 812 sb.append(")"); 813 } 814 if (!didOne) sb.append("No activity"); 815 pw.println(sb.toString()); 816 817 pw.println(" "); 818 819 if (which == STATS_UNPLUGGED) { 820 if (getIsOnBattery()) { 821 pw.println(prefix + " Device is currently unplugged"); 822 pw.println(prefix + " Discharge cycle start level: " + 823 getUnpluggedStartLevel()); 824 } else { 825 pw.println(prefix + " Device is currently plugged into power"); 826 pw.println(prefix + " Last discharge cycle start level: " + 827 getUnpluggedStartLevel()); 828 pw.println(prefix + " Last discharge cycle end level: " + 829 getPluggedStartLevel()); 830 } 831 } 832 833 pw.println(" "); 834 835 SparseArray<? extends Uid> uidStats = getUidStats(); 836 final int NU = uidStats.size(); 837 for (int iu=0; iu<NU; iu++) { 838 final int uid = uidStats.keyAt(iu); 839 Uid u = uidStats.valueAt(iu); 840 pw.println(prefix + " #" + uid + ":"); 841 boolean uidActivity = false; 842 843 long tcpReceived = u.getTcpBytesReceived(which); 844 long tcpSent = u.getTcpBytesSent(which); 845 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 846 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 847 848 if (tcpReceived != 0 || tcpSent != 0) { 849 pw.println(prefix + " Network: " + tcpReceived + " bytes received, " 850 + tcpSent + " bytes sent"); 851 } 852 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) { 853 pw.println(prefix + " Full Wifi Lock Time: " 854 + formatTime(fullWifiLockOnTime / 1000) 855 + "(" + formatRatioLocked(fullWifiLockOnTime, 856 whichBatteryRealtime)+ ")"); 857 pw.println(prefix + " Scan Wifi Lock Time: " 858 + formatTime(scanWifiLockOnTime / 1000) 859 + "(" + formatRatioLocked(scanWifiLockOnTime, 860 whichBatteryRealtime)+ ")"); 861 } 862 863 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 864 if (wakelocks.size() > 0) { 865 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 866 : wakelocks.entrySet()) { 867 Uid.Wakelock wl = ent.getValue(); 868 String linePrefix = ": "; 869 sb.setLength(0); 870 sb.append(prefix); 871 sb.append(" Wake lock "); 872 sb.append(ent.getKey()); 873 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 874 "full", which, linePrefix); 875 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 876 "partial", which, linePrefix); 877 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 878 "window", which, linePrefix); 879 if (!linePrefix.equals(": ")) { 880 sb.append(" realtime"); 881 } else { 882 sb.append(": (nothing executed)"); 883 } 884 pw.println(sb.toString()); 885 uidActivity = true; 886 } 887 } 888 889 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 890 if (sensors.size() > 0) { 891 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 892 : sensors.entrySet()) { 893 Uid.Sensor se = ent.getValue(); 894 int sensorNumber = ent.getKey(); 895 sb.setLength(0); 896 sb.append(prefix); 897 sb.append(" Sensor "); 898 int handle = se.getHandle(); 899 if (handle == Uid.Sensor.GPS) { 900 sb.append("GPS"); 901 } else { 902 sb.append(handle); 903 } 904 sb.append(": "); 905 906 Timer timer = se.getSensorTime(); 907 if (timer != null) { 908 // Convert from microseconds to milliseconds with rounding 909 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000; 910 int count = timer.getCount(which); 911 //timer.logState(); 912 if (totalTime != 0) { 913 sb.append(formatTimeMs(totalTime)); 914 sb.append("realtime ("); 915 sb.append(count); 916 sb.append(" times)"); 917 } else { 918 sb.append("(not used)"); 919 } 920 } else { 921 sb.append("(not used)"); 922 } 923 924 pw.println(sb.toString()); 925 uidActivity = true; 926 } 927 } 928 929 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 930 if (processStats.size() > 0) { 931 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 932 : processStats.entrySet()) { 933 Uid.Proc ps = ent.getValue(); 934 long userTime; 935 long systemTime; 936 int starts; 937 938 userTime = ps.getUserTime(which); 939 systemTime = ps.getSystemTime(which); 940 starts = ps.getStarts(which); 941 942 if (userTime != 0 || systemTime != 0 || starts != 0) { 943 pw.println(prefix + " Proc " + ent.getKey() + ":"); 944 pw.println(prefix + " CPU: " + formatTime(userTime) + "user + " 945 + formatTime(systemTime) + "kernel"); 946 pw.println(prefix + " " + starts + " process starts"); 947 uidActivity = true; 948 } 949 } 950 } 951 952 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 953 if (packageStats.size() > 0) { 954 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 955 : packageStats.entrySet()) { 956 pw.println(prefix + " Apk " + ent.getKey() + ":"); 957 boolean apkActivity = false; 958 Uid.Pkg ps = ent.getValue(); 959 int wakeups = ps.getWakeups(which); 960 if (wakeups != 0) { 961 pw.println(prefix + " " + wakeups + " wakeup alarms"); 962 apkActivity = true; 963 } 964 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 965 if (serviceStats.size() > 0) { 966 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 967 : serviceStats.entrySet()) { 968 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 969 long startTime = ss.getStartTime(batteryUptime, which); 970 int starts = ss.getStarts(which); 971 int launches = ss.getLaunches(which); 972 if (startTime != 0 || starts != 0 || launches != 0) { 973 pw.println(prefix + " Service " + sent.getKey() + ":"); 974 pw.println(prefix + " Created for: " 975 + formatTimeMs(startTime / 1000) 976 + " uptime"); 977 pw.println(prefix + " Starts: " + starts 978 + ", launches: " + launches); 979 apkActivity = true; 980 } 981 } 982 } 983 if (!apkActivity) { 984 pw.println(prefix + " (nothing executed)"); 985 } 986 uidActivity = true; 987 } 988 } 989 if (!uidActivity) { 990 pw.println(prefix + " (nothing executed)"); 991 } 992 } 993 } 994 995 /** 996 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 997 * 998 * @param pw a Printer to receive the dump output. 999 */ 1000 @SuppressWarnings("unused") 1001 public void dumpLocked(Printer pw) { 1002 pw.println("Total Statistics (Current and Historic):"); 1003 pw.println(" System starts: " + getStartCount() 1004 + ", currently on battery: " + getIsOnBattery()); 1005 dumpLocked(pw, "", STATS_TOTAL); 1006 pw.println(""); 1007 pw.println("Last Run Statistics (Previous run of system):"); 1008 dumpLocked(pw, "", STATS_LAST); 1009 pw.println(""); 1010 pw.println("Current Battery Statistics (Currently running system):"); 1011 dumpLocked(pw, "", STATS_CURRENT); 1012 pw.println(""); 1013 pw.println("Unplugged Statistics (Since last unplugged from power):"); 1014 dumpLocked(pw, "", STATS_UNPLUGGED); 1015 } 1016 1017 @SuppressWarnings("unused") 1018 public void dumpCheckinLocked(PrintWriter pw, String[] args) { 1019 boolean isUnpluggedOnly = false; 1020 1021 for (String arg : args) { 1022 if ("-u".equals(arg)) { 1023 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data"); 1024 isUnpluggedOnly = true; 1025 } 1026 } 1027 1028 if (isUnpluggedOnly) { 1029 dumpCheckinLocked(pw, STATS_UNPLUGGED); 1030 } 1031 else { 1032 dumpCheckinLocked(pw, STATS_TOTAL); 1033 dumpCheckinLocked(pw, STATS_LAST); 1034 dumpCheckinLocked(pw, STATS_UNPLUGGED); 1035 dumpCheckinLocked(pw, STATS_CURRENT); 1036 } 1037 } 1038 1039} 1040