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