BatteryStats.java revision d4c5f8919b0522bcaab41a5863c313fec52d3a79
1package android.os; 2 3import java.io.PrintWriter; 4import java.util.Formatter; 5import java.util.Map; 6 7import com.android.internal.os.BatteryStatsImpl.Timer; 8 9import android.util.Log; 10import android.util.Printer; 11import android.util.SparseArray; 12 13/** 14 * A class providing access to battery usage statistics, including information on 15 * wakelocks, processes, packages, and services. All times are represented in microseconds 16 * except where indicated otherwise. 17 * @hide 18 */ 19public abstract class BatteryStats implements Parcelable { 20 21 private static final boolean LOCAL_LOGV = false; 22 23 /** 24 * A constant indicating a partial wake lock timer. 25 */ 26 public static final int WAKE_TYPE_PARTIAL = 0; 27 28 /** 29 * A constant indicating a full wake lock timer. 30 */ 31 public static final int WAKE_TYPE_FULL = 1; 32 33 /** 34 * A constant indicating a window wake lock timer. 35 */ 36 public static final int WAKE_TYPE_WINDOW = 2; 37 38 /** 39 * A constant indicating a sensor timer. 40 * 41 * {@hide} 42 */ 43 public static final int SENSOR = 3; 44 45 /** 46 * A constant indicating a full wifi lock timer 47 * 48 * {@hide} 49 */ 50 public static final int FULL_WIFI_LOCK = 4; 51 52 /** 53 * A constant indicating a scan wifi lock timer 54 * 55 * {@hide} 56 */ 57 public static final int SCAN_WIFI_LOCK = 5; 58 59 /** 60 * Include all of the data in the stats, including previously saved data. 61 */ 62 public static final int STATS_TOTAL = 0; 63 64 /** 65 * Include only the last run in the stats. 66 */ 67 public static final int STATS_LAST = 1; 68 69 /** 70 * Include only the current run in the stats. 71 */ 72 public static final int STATS_CURRENT = 2; 73 74 /** 75 * Include only the run since the last time the device was unplugged in the stats. 76 */ 77 public static final int STATS_UNPLUGGED = 3; 78 79 /** 80 * Bump the version on this if the checkin format changes. 81 */ 82 private static final int BATTERY_STATS_CHECKIN_VERSION = 1; 83 84 // TODO: Update this list if you add/change any stats above. 85 private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" }; 86 87 private static final String APK_DATA = "apk"; 88 private static final String PROCESS_DATA = "process"; 89 private static final String SENSOR_DATA = "sensor"; 90 private static final String WAKELOCK_DATA = "wakelock"; 91 private static final String NETWORK_DATA = "network"; 92 private static final String BATTERY_DATA = "battery"; 93 private static final String WIFI_LOCK_DATA = "wifilock"; 94 private static final String MISC_DATA = "misc"; 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(); 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 /** 297 * Returns the time in milliseconds that wifi has been on while the device was 298 * running on battery. 299 * 300 * {@hide} 301 */ 302 public abstract long getWifiOnTime(long batteryRealtime, int which); 303 304 /** 305 * Returns the time in milliseconds that wifi has been on and the driver has 306 * been in the running state while the device was running on battery. 307 * 308 * {@hide} 309 */ 310 public abstract long getWifiRunningTime(long batteryRealtime, int which); 311 312 /** 313 * Returns the time in milliseconds that bluetooth has been on while the device was 314 * running on battery. 315 * 316 * {@hide} 317 */ 318 public abstract long getBluetoothOnTime(long batteryRealtime, int which); 319 320 /** 321 * Return whether we are currently running on battery. 322 */ 323 public abstract boolean getIsOnBattery(); 324 325 /** 326 * Returns a SparseArray containing the statistics for each uid. 327 */ 328 public abstract SparseArray<? extends Uid> getUidStats(); 329 330 /** 331 * Returns the current battery uptime in microseconds. 332 * 333 * @param curTime the amount of elapsed realtime in microseconds. 334 */ 335 public abstract long getBatteryUptime(long curTime); 336 337 /** 338 * Returns the current battery realtime in microseconds. 339 * 340 * @param curTime the amount of elapsed realtime in microseconds. 341 */ 342 public abstract long getBatteryRealtime(long curTime); 343 344 /** 345 * Returns the battery percentage level at the last time the device was unplugged from power, 346 * or the last time it was booted while unplugged. 347 */ 348 public abstract int getUnpluggedStartLevel(); 349 350 /** 351 * Returns the battery percentage level at the last time the device was plugged into power. 352 */ 353 public abstract int getPluggedStartLevel(); 354 355 /** 356 * Returns the total, last, or current battery uptime in microseconds. 357 * 358 * @param curTime the elapsed realtime in microseconds. 359 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 360 */ 361 public abstract long computeBatteryUptime(long curTime, int which); 362 363 /** 364 * Returns the total, last, or current battery realtime in microseconds. 365 * 366 * @param curTime the current elapsed realtime in microseconds. 367 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 368 */ 369 public abstract long computeBatteryRealtime(long curTime, int which); 370 371 /** 372 * Returns the total, last, or current uptime in microseconds. 373 * 374 * @param curTime the current elapsed realtime in microseconds. 375 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 376 */ 377 public abstract long computeUptime(long curTime, int which); 378 379 /** 380 * Returns the total, last, or current realtime in microseconds. 381 * * 382 * @param curTime the current elapsed realtime in microseconds. 383 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 384 */ 385 public abstract long computeRealtime(long curTime, int which); 386 387 private final static void formatTime(StringBuilder out, long seconds) { 388 long days = seconds / (60 * 60 * 24); 389 if (days != 0) { 390 out.append(days); 391 out.append("d "); 392 } 393 long used = days * 60 * 60 * 24; 394 395 long hours = (seconds - used) / (60 * 60); 396 if (hours != 0 || used != 0) { 397 out.append(hours); 398 out.append("h "); 399 } 400 used += hours * 60 * 60; 401 402 long mins = (seconds-used) / 60; 403 if (mins != 0 || used != 0) { 404 out.append(mins); 405 out.append("m "); 406 } 407 used += mins * 60; 408 409 if (seconds != 0 || used != 0) { 410 out.append(seconds-used); 411 out.append("s "); 412 } 413 } 414 415 private final static String formatTime(long time) { 416 long sec = time / 100; 417 StringBuilder sb = new StringBuilder(); 418 formatTime(sb, sec); 419 sb.append((time - (sec * 100)) * 10); 420 sb.append("ms "); 421 return sb.toString(); 422 } 423 424 private final static String formatTimeMs(long time) { 425 long sec = time / 1000; 426 StringBuilder sb = new StringBuilder(); 427 formatTime(sb, sec); 428 sb.append(time - (sec * 1000)); 429 sb.append("ms "); 430 return sb.toString(); 431 } 432 433 private final String formatRatioLocked(long num, long den) { 434 if (den == 0L) { 435 return "---%"; 436 } 437 float perc = ((float)num) / ((float)den) * 100; 438 mFormatBuilder.setLength(0); 439 mFormatter.format("%.1f%%", perc); 440 return mFormatBuilder.toString(); 441 } 442 443 /** 444 * 445 * @param sb a StringBuilder object. 446 * @param timer a Timer object contining the wakelock times. 447 * @param batteryRealtime the current on-battery time in microseconds. 448 * @param name the name of the wakelock. 449 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 450 * @param linePrefix a String to be prepended to each line of output. 451 * @return the line prefix 452 */ 453 private static final String printWakeLock(StringBuilder sb, Timer timer, 454 long batteryRealtime, String name, int which, String linePrefix) { 455 456 if (timer != null) { 457 // Convert from microseconds to milliseconds with rounding 458 long totalTimeMicros = timer.getTotalTime(batteryRealtime, which); 459 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 460 461 int count = timer.getCount(which); 462 if (totalTimeMillis != 0) { 463 sb.append(linePrefix); 464 sb.append(formatTimeMs(totalTimeMillis)); 465 sb.append(name); 466 sb.append(' '); 467 sb.append('('); 468 sb.append(count); 469 sb.append(" times)"); 470 return ", "; 471 } 472 } 473 return linePrefix; 474 } 475 476 /** 477 * Checkin version of wakelock printer. Prints simple comma-separated list. 478 * 479 * @param sb a StringBuilder object. 480 * @param timer a Timer object contining the wakelock times. 481 * @param now the current time in microseconds. 482 * @param name the name of the wakelock. 483 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 484 * @param linePrefix a String to be prepended to each line of output. 485 * @return the line prefix 486 */ 487 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now, 488 String name, int which, String linePrefix) { 489 long totalTimeMicros = 0; 490 int count = 0; 491 if (timer != null) { 492 totalTimeMicros = timer.getTotalTime(now, which); 493 count = timer.getCount(which); 494 } 495 sb.append(linePrefix); 496 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 497 sb.append(','); 498 sb.append(name); 499 sb.append(','); 500 sb.append(count); 501 return ","; 502 } 503 504 /** 505 * Dump a comma-separated line of values for terse checkin mode. 506 * 507 * @param pw the PageWriter to dump log to 508 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 509 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 510 * @param args type-dependent data arguments 511 */ 512 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 513 Object... args ) { 514 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 515 pw.print(uid); pw.print(','); 516 pw.print(category); pw.print(','); 517 pw.print(type); 518 519 for (Object arg : args) { 520 pw.print(','); 521 pw.print(arg); 522 } 523 pw.print('\n'); 524 } 525 526 /** 527 * Checkin server version of dump to produce more compact, computer-readable log. 528 * 529 * NOTE: all times are expressed in 'ms'. 530 * @param fd 531 * @param pw 532 * @param which 533 */ 534 private final void dumpCheckinLocked(PrintWriter pw, int which) { 535 final long rawUptime = SystemClock.uptimeMillis() * 1000; 536 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 537 final long batteryUptime = getBatteryUptime(rawUptime); 538 final long batteryRealtime = getBatteryRealtime(rawRealtime); 539 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 540 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 541 final long totalRealtime = computeRealtime(rawRealtime, which); 542 final long totalUptime = computeUptime(rawUptime, which); 543 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 544 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 545 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 546 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 547 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 548 549 StringBuilder sb = new StringBuilder(128); 550 551 String category = STAT_NAMES[which]; 552 553 // Dump "battery" stat 554 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 555 which == STATS_TOTAL ? getStartCount() : "N/A", 556 whichBatteryUptime / 1000, whichBatteryRealtime / 1000, 557 totalUptime / 1000, totalRealtime / 1000); 558 559 // Dump misc stats 560 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 561 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, 562 wifiRunningTime / 1000, bluetoothOnTime / 1000); 563 564 if (which == STATS_UNPLUGGED) { 565 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, getUnpluggedStartLevel(), 566 getPluggedStartLevel()); 567 } 568 569 SparseArray<? extends Uid> uidStats = getUidStats(); 570 final int NU = uidStats.size(); 571 for (int iu = 0; iu < NU; iu++) { 572 final int uid = uidStats.keyAt(iu); 573 Uid u = uidStats.valueAt(iu); 574 // Dump Network stats per uid, if any 575 long rx = u.getTcpBytesReceived(which); 576 long tx = u.getTcpBytesSent(which); 577 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 578 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 579 580 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx); 581 582 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) { 583 dumpLine(pw, uid, category, WIFI_LOCK_DATA, 584 fullWifiLockOnTime, scanWifiLockOnTime); 585 } 586 587 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 588 if (wakelocks.size() > 0) { 589 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 590 : wakelocks.entrySet()) { 591 Uid.Wakelock wl = ent.getValue(); 592 String linePrefix = ""; 593 sb.setLength(0); 594 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 595 "full", which, linePrefix); 596 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 597 "partial", which, linePrefix); 598 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 599 "window", which, linePrefix); 600 601 // Only log if we had at lease one wakelock... 602 if (sb.length() > 0) { 603 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString()); 604 } 605 } 606 } 607 608 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 609 if (sensors.size() > 0) { 610 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 611 : sensors.entrySet()) { 612 Uid.Sensor se = ent.getValue(); 613 int sensorNumber = ent.getKey(); 614 Timer timer = se.getSensorTime(); 615 if (timer != null) { 616 // Convert from microseconds to milliseconds with rounding 617 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000; 618 int count = timer.getCount(which); 619 if (totalTime != 0) { 620 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 621 } 622 } 623 } 624 } 625 626 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 627 if (processStats.size() > 0) { 628 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 629 : processStats.entrySet()) { 630 Uid.Proc ps = ent.getValue(); 631 632 long userTime = ps.getUserTime(which); 633 long systemTime = ps.getSystemTime(which); 634 int starts = ps.getStarts(which); 635 636 if (userTime != 0 || systemTime != 0 || starts != 0) { 637 dumpLine(pw, uid, category, PROCESS_DATA, 638 ent.getKey(), // proc 639 userTime * 10, // cpu time in ms 640 systemTime * 10, // user time in ms 641 starts); // process starts 642 } 643 } 644 } 645 646 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 647 if (packageStats.size() > 0) { 648 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 649 : packageStats.entrySet()) { 650 651 Uid.Pkg ps = ent.getValue(); 652 int wakeups = ps.getWakeups(which); 653 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 654 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 655 : serviceStats.entrySet()) { 656 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 657 long startTime = ss.getStartTime(batteryUptime, which); 658 int starts = ss.getStarts(which); 659 int launches = ss.getLaunches(which); 660 if (startTime != 0 || starts != 0 || launches != 0) { 661 dumpLine(pw, uid, category, APK_DATA, 662 wakeups, // wakeup alarms 663 ent.getKey(), // Apk 664 sent.getKey(), // service 665 startTime / 1000, // time spent started, in ms 666 starts, 667 launches); 668 } 669 } 670 } 671 } 672 } 673 } 674 675 @SuppressWarnings("unused") 676 private final void dumpLocked(Printer pw, String prefix, int which) { 677 final long rawUptime = SystemClock.uptimeMillis() * 1000; 678 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 679 final long batteryUptime = getBatteryUptime(rawUptime); 680 final long batteryRealtime = getBatteryRealtime(rawRealtime); 681 682 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 683 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 684 final long totalRealtime = computeRealtime(rawRealtime, which); 685 final long totalUptime = computeUptime(rawUptime, which); 686 687 StringBuilder sb = new StringBuilder(128); 688 689 pw.println(prefix 690 + " Time on battery: " + formatTimeMs(whichBatteryUptime / 1000) 691 + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime) 692 + ") uptime, " 693 + formatTimeMs(whichBatteryRealtime / 1000) + "(" 694 + formatRatioLocked(whichBatteryRealtime, totalRealtime) 695 + ") realtime"); 696 pw.println(prefix 697 + " Total: " 698 + formatTimeMs(totalUptime / 1000) 699 + "uptime, " 700 + formatTimeMs(totalRealtime / 1000) 701 + "realtime"); 702 703 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 704 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 705 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 706 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 707 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 708 pw.println(prefix 709 + " Time with screen on: " + formatTimeMs(screenOnTime / 1000) 710 + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime) 711 + "), time with phone on: " + formatTimeMs(phoneOnTime / 1000) 712 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime) 713 + "), time with wifi on: " + formatTimeMs(wifiOnTime / 1000) 714 + "(" + formatRatioLocked(wifiOnTime, whichBatteryRealtime) 715 + "), time with wifi running: " + formatTimeMs(wifiRunningTime / 1000) 716 + "(" + formatRatioLocked(wifiRunningTime, whichBatteryRealtime) 717 + "), time with bluetooth on: " + formatTimeMs(bluetoothOnTime / 1000) 718 + "(" + formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)+ ")"); 719 720 pw.println(" "); 721 722 if (which == STATS_UNPLUGGED) { 723 if (getIsOnBattery()) { 724 pw.println(prefix + " Device is currently unplugged"); 725 pw.println(prefix + " Discharge cycle start level: " + 726 getUnpluggedStartLevel()); 727 } else { 728 pw.println(prefix + " Device is currently plugged into power"); 729 pw.println(prefix + " Last discharge cycle start level: " + 730 getUnpluggedStartLevel()); 731 pw.println(prefix + " Last discharge cycle end level: " + 732 getPluggedStartLevel()); 733 } 734 } 735 736 pw.println(" "); 737 738 SparseArray<? extends Uid> uidStats = getUidStats(); 739 final int NU = uidStats.size(); 740 for (int iu=0; iu<NU; iu++) { 741 final int uid = uidStats.keyAt(iu); 742 Uid u = uidStats.valueAt(iu); 743 pw.println(prefix + " #" + uid + ":"); 744 boolean uidActivity = false; 745 746 long tcpReceived = u.getTcpBytesReceived(which); 747 long tcpSent = u.getTcpBytesSent(which); 748 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 749 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 750 751 if (tcpReceived != 0 || tcpSent != 0) { 752 pw.println(prefix + " Network: " + tcpReceived + " bytes received, " 753 + tcpSent + " bytes sent"); 754 } 755 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0) { 756 pw.println(prefix + " Full Wifi Lock Time: " 757 + formatTime(fullWifiLockOnTime / 1000) 758 + "(" + formatRatioLocked(fullWifiLockOnTime, 759 whichBatteryRealtime)+ ")"); 760 pw.println(prefix + " Scan Wifi Lock Time: " 761 + formatTime(scanWifiLockOnTime / 1000) 762 + "(" + formatRatioLocked(scanWifiLockOnTime, 763 whichBatteryRealtime)+ ")"); 764 } 765 766 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 767 if (wakelocks.size() > 0) { 768 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 769 : wakelocks.entrySet()) { 770 Uid.Wakelock wl = ent.getValue(); 771 String linePrefix = ": "; 772 sb.setLength(0); 773 sb.append(prefix); 774 sb.append(" Wake lock "); 775 sb.append(ent.getKey()); 776 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 777 "full", which, linePrefix); 778 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 779 "partial", which, linePrefix); 780 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 781 "window", which, linePrefix); 782 if (!linePrefix.equals(": ")) { 783 sb.append(" realtime"); 784 } else { 785 sb.append(": (nothing executed)"); 786 } 787 pw.println(sb.toString()); 788 uidActivity = true; 789 } 790 } 791 792 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 793 if (sensors.size() > 0) { 794 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 795 : sensors.entrySet()) { 796 Uid.Sensor se = ent.getValue(); 797 int sensorNumber = ent.getKey(); 798 sb.setLength(0); 799 sb.append(prefix); 800 sb.append(" Sensor "); 801 int handle = se.getHandle(); 802 if (handle == Uid.Sensor.GPS) { 803 sb.append("GPS"); 804 } else { 805 sb.append(handle); 806 } 807 sb.append(": "); 808 809 Timer timer = se.getSensorTime(); 810 if (timer != null) { 811 // Convert from microseconds to milliseconds with rounding 812 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000; 813 int count = timer.getCount(which); 814 //timer.logState(); 815 if (totalTime != 0) { 816 sb.append(formatTimeMs(totalTime)); 817 sb.append("realtime ("); 818 sb.append(count); 819 sb.append(" times)"); 820 } else { 821 sb.append("(not used)"); 822 } 823 } else { 824 sb.append("(not used)"); 825 } 826 827 pw.println(sb.toString()); 828 uidActivity = true; 829 } 830 } 831 832 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 833 if (processStats.size() > 0) { 834 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 835 : processStats.entrySet()) { 836 Uid.Proc ps = ent.getValue(); 837 long userTime; 838 long systemTime; 839 int starts; 840 841 userTime = ps.getUserTime(which); 842 systemTime = ps.getSystemTime(which); 843 starts = ps.getStarts(which); 844 845 if (userTime != 0 || systemTime != 0 || starts != 0) { 846 pw.println(prefix + " Proc " + ent.getKey() + ":"); 847 pw.println(prefix + " CPU: " + formatTime(userTime) + "user + " 848 + formatTime(systemTime) + "kernel"); 849 pw.println(prefix + " " + starts + " process starts"); 850 uidActivity = true; 851 } 852 } 853 } 854 855 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 856 if (packageStats.size() > 0) { 857 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 858 : packageStats.entrySet()) { 859 pw.println(prefix + " Apk " + ent.getKey() + ":"); 860 boolean apkActivity = false; 861 Uid.Pkg ps = ent.getValue(); 862 int wakeups = ps.getWakeups(which); 863 if (wakeups != 0) { 864 pw.println(prefix + " " + wakeups + " wakeup alarms"); 865 apkActivity = true; 866 } 867 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 868 if (serviceStats.size() > 0) { 869 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 870 : serviceStats.entrySet()) { 871 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 872 long startTime = ss.getStartTime(batteryUptime, which); 873 int starts = ss.getStarts(which); 874 int launches = ss.getLaunches(which); 875 if (startTime != 0 || starts != 0 || launches != 0) { 876 pw.println(prefix + " Service " + sent.getKey() + ":"); 877 pw.println(prefix + " Created for: " 878 + formatTimeMs(startTime / 1000) 879 + " uptime"); 880 pw.println(prefix + " Starts: " + starts 881 + ", launches: " + launches); 882 apkActivity = true; 883 } 884 } 885 } 886 if (!apkActivity) { 887 pw.println(prefix + " (nothing executed)"); 888 } 889 uidActivity = true; 890 } 891 } 892 if (!uidActivity) { 893 pw.println(prefix + " (nothing executed)"); 894 } 895 } 896 } 897 898 /** 899 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 900 * 901 * @param pw a Printer to receive the dump output. 902 */ 903 @SuppressWarnings("unused") 904 public void dumpLocked(Printer pw) { 905 pw.println("Total Statistics (Current and Historic):"); 906 pw.println(" System starts: " + getStartCount() 907 + ", currently on battery: " + getIsOnBattery()); 908 dumpLocked(pw, "", STATS_TOTAL); 909 pw.println(""); 910 pw.println("Last Run Statistics (Previous run of system):"); 911 dumpLocked(pw, "", STATS_LAST); 912 pw.println(""); 913 pw.println("Current Battery Statistics (Currently running system):"); 914 dumpLocked(pw, "", STATS_CURRENT); 915 pw.println(""); 916 pw.println("Unplugged Statistics (Since last unplugged from power):"); 917 dumpLocked(pw, "", STATS_UNPLUGGED); 918 } 919 920 @SuppressWarnings("unused") 921 public void dumpCheckinLocked(PrintWriter pw, String[] args) { 922 boolean isUnpluggedOnly = false; 923 924 for (String arg : args) { 925 if ("-u".equals(arg)) { 926 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data"); 927 isUnpluggedOnly = true; 928 } 929 } 930 931 if (isUnpluggedOnly) { 932 dumpCheckinLocked(pw, STATS_UNPLUGGED); 933 } 934 else { 935 dumpCheckinLocked(pw, STATS_TOTAL); 936 dumpCheckinLocked(pw, STATS_LAST); 937 dumpCheckinLocked(pw, STATS_UNPLUGGED); 938 dumpCheckinLocked(pw, STATS_CURRENT); 939 } 940 } 941 942} 943