BatteryStats.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
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 * Include all of the data in the stats, including previously saved data. 45 */ 46 public static final int STATS_TOTAL = 0; 47 48 /** 49 * Include only the last run in the stats. 50 */ 51 public static final int STATS_LAST = 1; 52 53 /** 54 * Include only the current run in the stats. 55 */ 56 public static final int STATS_CURRENT = 2; 57 58 /** 59 * Include only the run since the last time the device was unplugged in the stats. 60 */ 61 public static final int STATS_UNPLUGGED = 3; 62 63 /** 64 * Bump the version on this if the checkin format changes. 65 */ 66 private static final int BATTERY_STATS_CHECKIN_VERSION = 1; 67 68 // TODO: Update this list if you add/change any stats above. 69 private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" }; 70 71 private static final String APK_DATA = "apk"; 72 private static final String PROCESS_DATA = "process"; 73 private static final String SENSOR_DATA = "sensor"; 74 private static final String WAKELOCK_DATA = "wakelock"; 75 private static final String NETWORK_DATA = "network"; 76 private static final String BATTERY_DATA = "battery"; 77 private static final String MISC_DATA = "misc"; 78 79 private final StringBuilder mFormatBuilder = new StringBuilder(8); 80 private final Formatter mFormatter = new Formatter(mFormatBuilder); 81 82 /** 83 * State for keeping track of timing information. 84 */ 85 public static abstract class Timer { 86 87 /** 88 * Returns the count associated with this Timer for the 89 * selected type of statistics. 90 * 91 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 92 */ 93 public abstract int getCount(int which); 94 95 /** 96 * Returns the total time in microseconds associated with this Timer for the 97 * selected type of statistics. 98 * 99 * @param batteryRealtime system realtime on battery in microseconds 100 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 101 * @return a time in microseconds 102 */ 103 public abstract long getTotalTime(long batteryRealtime, int which); 104 105 /** 106 * Temporary for debugging. 107 */ 108 public abstract void logState(); 109 } 110 111 /** 112 * The statistics associated with a particular uid. 113 */ 114 public static abstract class Uid { 115 116 /** 117 * Returns a mapping containing wakelock statistics. 118 * 119 * @return a Map from Strings to Uid.Wakelock objects. 120 */ 121 public abstract Map<String, ? extends Wakelock> getWakelockStats(); 122 123 /** 124 * The statistics associated with a particular wake lock. 125 */ 126 public static abstract class Wakelock { 127 public abstract Timer getWakeTime(int type); 128 } 129 130 /** 131 * Returns a mapping containing sensor statistics. 132 * 133 * @return a Map from Integer sensor ids to Uid.Sensor objects. 134 */ 135 public abstract Map<Integer, ? extends Sensor> getSensorStats(); 136 137 /** 138 * Returns a mapping containing process statistics. 139 * 140 * @return a Map from Strings to Uid.Proc objects. 141 */ 142 public abstract Map<String, ? extends Proc> getProcessStats(); 143 144 /** 145 * Returns a mapping containing package statistics. 146 * 147 * @return a Map from Strings to Uid.Pkg objects. 148 */ 149 public abstract Map<String, ? extends Pkg> getPackageStats(); 150 151 /** 152 * {@hide} 153 */ 154 public abstract int getUid(); 155 156 /** 157 * {@hide} 158 */ 159 public abstract long getTcpBytesReceived(int which); 160 161 /** 162 * {@hide} 163 */ 164 public abstract long getTcpBytesSent(int which); 165 166 public static abstract class Sensor { 167 // Magic sensor number for the GPS. 168 public static final int GPS = -10000; 169 170 public abstract int getHandle(); 171 172 public abstract Timer getSensorTime(); 173 } 174 175 /** 176 * The statistics associated with a particular process. 177 */ 178 public static abstract class Proc { 179 180 /** 181 * Returns the total time (in 1/100 sec) spent executing in user code. 182 * 183 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 184 */ 185 public abstract long getUserTime(int which); 186 187 /** 188 * Returns the total time (in 1/100 sec) spent executing in system code. 189 * 190 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 191 */ 192 public abstract long getSystemTime(int which); 193 194 /** 195 * Returns the number of times the process has been started. 196 * 197 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 198 */ 199 public abstract int getStarts(int which); 200 } 201 202 /** 203 * The statistics associated with a particular package. 204 */ 205 public static abstract class Pkg { 206 207 /** 208 * Returns the number of times this package has done something that could wake up the 209 * device from sleep. 210 * 211 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 212 */ 213 public abstract int getWakeups(int which); 214 215 /** 216 * Returns a mapping containing service statistics. 217 */ 218 public abstract Map<String, ? extends Serv> getServiceStats(); 219 220 /** 221 * The statistics associated with a particular service. 222 */ 223 public abstract class Serv { 224 225 /** 226 * Returns the amount of time spent started. 227 * 228 * @param batteryUptime elapsed uptime on battery in microseconds. 229 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 230 * @return 231 */ 232 public abstract long getStartTime(long batteryUptime, int which); 233 234 /** 235 * Returns the total number of times startService() has been called. 236 * 237 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 238 */ 239 public abstract int getStarts(int which); 240 241 /** 242 * Returns the total number times the service has been launched. 243 * 244 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 245 */ 246 public abstract int getLaunches(int which); 247 } 248 } 249 } 250 251 /** 252 * Returns the number of times the device has been started. 253 */ 254 public abstract int getStartCount(); 255 256 /** 257 * Returns the time in milliseconds that the screen has been on while the device was 258 * running on battery. 259 * 260 * {@hide} 261 */ 262 public abstract long getScreenOnTime(long batteryRealtime, int which); 263 264 /** 265 * Returns the time in milliseconds that the phone has been on while the device was 266 * running on battery. 267 * 268 * {@hide} 269 */ 270 public abstract long getPhoneOnTime(long batteryRealtime, int which); 271 272 /** 273 * Return whether we are currently running on battery. 274 */ 275 public abstract boolean getIsOnBattery(); 276 277 /** 278 * Returns a SparseArray containing the statistics for each uid. 279 */ 280 public abstract SparseArray<? extends Uid> getUidStats(); 281 282 /** 283 * Returns the current battery uptime in microseconds. 284 * 285 * @param curTime the amount of elapsed realtime in microseconds. 286 */ 287 public abstract long getBatteryUptime(long curTime); 288 289 /** 290 * Returns the current battery realtime in microseconds. 291 * 292 * @param curTime the amount of elapsed realtime in microseconds. 293 */ 294 public abstract long getBatteryRealtime(long curTime); 295 296 /** 297 * Returns the total, last, or current battery uptime in microseconds. 298 * 299 * @param curTime the elapsed realtime in microseconds. 300 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 301 */ 302 public abstract long computeBatteryUptime(long curTime, int which); 303 304 /** 305 * Returns the total, last, or current battery realtime in microseconds. 306 * 307 * @param curTime the current elapsed realtime in microseconds. 308 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 309 */ 310 public abstract long computeBatteryRealtime(long curTime, int which); 311 312 /** 313 * Returns the total, last, or current uptime in microseconds. 314 * 315 * @param curTime the current elapsed realtime in microseconds. 316 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 317 */ 318 public abstract long computeUptime(long curTime, int which); 319 320 /** 321 * Returns the total, last, or current realtime in microseconds. 322 * * 323 * @param curTime the current elapsed realtime in microseconds. 324 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 325 */ 326 public abstract long computeRealtime(long curTime, int which); 327 328 private final static void formatTime(StringBuilder out, long seconds) { 329 long days = seconds / (60 * 60 * 24); 330 if (days != 0) { 331 out.append(days); 332 out.append("d "); 333 } 334 long used = days * 60 * 60 * 24; 335 336 long hours = (seconds - used) / (60 * 60); 337 if (hours != 0 || used != 0) { 338 out.append(hours); 339 out.append("h "); 340 } 341 used += hours * 60 * 60; 342 343 long mins = (seconds-used) / 60; 344 if (mins != 0 || used != 0) { 345 out.append(mins); 346 out.append("m "); 347 } 348 used += mins * 60; 349 350 if (seconds != 0 || used != 0) { 351 out.append(seconds-used); 352 out.append("s "); 353 } 354 } 355 356 private final static String formatTime(long time) { 357 long sec = time / 100; 358 StringBuilder sb = new StringBuilder(); 359 formatTime(sb, sec); 360 sb.append((time - (sec * 100)) * 10); 361 sb.append("ms "); 362 return sb.toString(); 363 } 364 365 private final static String formatTimeMs(long time) { 366 long sec = time / 1000; 367 StringBuilder sb = new StringBuilder(); 368 formatTime(sb, sec); 369 sb.append(time - (sec * 1000)); 370 sb.append("ms "); 371 return sb.toString(); 372 } 373 374 private final String formatRatioLocked(long num, long den) { 375 if (den == 0L) { 376 return "---%"; 377 } 378 float perc = ((float)num) / ((float)den) * 100; 379 mFormatBuilder.setLength(0); 380 mFormatter.format("%.1f%%", perc); 381 return mFormatBuilder.toString(); 382 } 383 384 /** 385 * 386 * @param sb a StringBuilder object. 387 * @param timer a Timer object contining the wakelock times. 388 * @param batteryRealtime the current on-battery time in microseconds. 389 * @param name the name of the wakelock. 390 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 391 * @param linePrefix a String to be prepended to each line of output. 392 * @return the line prefix 393 */ 394 private static final String printWakeLock(StringBuilder sb, Timer timer, 395 long batteryRealtime, String name, int which, String linePrefix) { 396 397 if (timer != null) { 398 // Convert from microseconds to milliseconds with rounding 399 long totalTimeMicros = timer.getTotalTime(batteryRealtime, which); 400 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 401 402 int count = timer.getCount(which); 403 if (totalTimeMillis != 0) { 404 sb.append(linePrefix); 405 sb.append(formatTimeMs(totalTimeMillis)); 406 sb.append(name); 407 sb.append(' '); 408 sb.append('('); 409 sb.append(count); 410 sb.append(" times)"); 411 return ", "; 412 } 413 } 414 return linePrefix; 415 } 416 417 /** 418 * Checkin version of wakelock printer. Prints simple comma-separated list. 419 * 420 * @param sb a StringBuilder object. 421 * @param timer a Timer object contining the wakelock times. 422 * @param now the current time in microseconds. 423 * @param name the name of the wakelock. 424 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 425 * @param linePrefix a String to be prepended to each line of output. 426 * @return the line prefix 427 */ 428 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now, 429 String name, int which, String linePrefix) { 430 long totalTimeMicros = 0; 431 int count = 0; 432 if (timer != null) { 433 totalTimeMicros = timer.getTotalTime(now, which); 434 count = timer.getCount(which); 435 } 436 sb.append(linePrefix); 437 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 438 sb.append(','); 439 sb.append(name); 440 sb.append(','); 441 sb.append(count); 442 return ","; 443 } 444 445 /** 446 * Dump a comma-separated line of values for terse checkin mode. 447 * 448 * @param pw the PageWriter to dump log to 449 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 450 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 451 * @param args type-dependent data arguments 452 */ 453 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 454 Object... args ) { 455 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 456 pw.print(uid); pw.print(','); 457 pw.print(category); pw.print(','); 458 pw.print(type); 459 460 for (Object arg : args) { 461 pw.print(','); 462 pw.print(arg); 463 } 464 pw.print('\n'); 465 } 466 467 /** 468 * Checkin server version of dump to produce more compact, computer-readable log. 469 * 470 * NOTE: all times are expressed in 'ms'. 471 * @param fd 472 * @param pw 473 * @param which 474 */ 475 private final void dumpCheckinLocked(PrintWriter pw, int which) { 476 final long rawUptime = SystemClock.uptimeMillis() * 1000; 477 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 478 final long batteryUptime = getBatteryUptime(rawUptime); 479 final long batteryRealtime = getBatteryRealtime(rawRealtime); 480 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 481 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 482 final long totalRealtime = computeRealtime(rawRealtime, which); 483 final long totalUptime = computeUptime(rawUptime, which); 484 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 485 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 486 487 StringBuilder sb = new StringBuilder(128); 488 489 String category = STAT_NAMES[which]; 490 491 // Dump "battery" stat 492 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 493 which == STATS_TOTAL ? getStartCount() : "N/A", 494 whichBatteryUptime / 1000, whichBatteryRealtime / 1000, 495 totalUptime / 1000, totalRealtime / 1000); 496 497 // Dump misc stats 498 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 499 screenOnTime / 1000, phoneOnTime / 1000); 500 501 SparseArray<? extends Uid> uidStats = getUidStats(); 502 final int NU = uidStats.size(); 503 for (int iu = 0; iu < NU; iu++) { 504 final int uid = uidStats.keyAt(iu); 505 Uid u = uidStats.valueAt(iu); 506 // Dump Network stats per uid, if any 507 long rx = u.getTcpBytesReceived(which); 508 long tx = u.getTcpBytesSent(which); 509 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx); 510 511 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 512 if (wakelocks.size() > 0) { 513 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 514 : wakelocks.entrySet()) { 515 Uid.Wakelock wl = ent.getValue(); 516 String linePrefix = ""; 517 sb.setLength(0); 518 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 519 "full", which, linePrefix); 520 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 521 "partial", which, linePrefix); 522 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 523 "window", which, linePrefix); 524 525 // Only log if we had at lease one wakelock... 526 if (sb.length() > 0) { 527 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString()); 528 } 529 } 530 } 531 532 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 533 if (sensors.size() > 0) { 534 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 535 : sensors.entrySet()) { 536 Uid.Sensor se = ent.getValue(); 537 int sensorNumber = ent.getKey(); 538 Timer timer = se.getSensorTime(); 539 if (timer != null) { 540 // Convert from microseconds to milliseconds with rounding 541 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000; 542 int count = timer.getCount(which); 543 if (totalTime != 0) { 544 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 545 } 546 } 547 } 548 } 549 550 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 551 if (processStats.size() > 0) { 552 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 553 : processStats.entrySet()) { 554 Uid.Proc ps = ent.getValue(); 555 556 long userTime = ps.getUserTime(which); 557 long systemTime = ps.getSystemTime(which); 558 int starts = ps.getStarts(which); 559 560 if (userTime != 0 || systemTime != 0 || starts != 0) { 561 dumpLine(pw, uid, category, PROCESS_DATA, 562 ent.getKey(), // proc 563 userTime * 10, // cpu time in ms 564 systemTime * 10, // user time in ms 565 starts); // process starts 566 } 567 } 568 } 569 570 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 571 if (packageStats.size() > 0) { 572 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 573 : packageStats.entrySet()) { 574 575 Uid.Pkg ps = ent.getValue(); 576 int wakeups = ps.getWakeups(which); 577 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 578 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 579 : serviceStats.entrySet()) { 580 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 581 long startTime = ss.getStartTime(batteryUptime, which); 582 int starts = ss.getStarts(which); 583 int launches = ss.getLaunches(which); 584 if (startTime != 0 || starts != 0 || launches != 0) { 585 dumpLine(pw, uid, category, APK_DATA, 586 wakeups, // wakeup alarms 587 ent.getKey(), // Apk 588 sent.getKey(), // service 589 startTime / 1000, // time spent started, in ms 590 starts, 591 launches); 592 } 593 } 594 } 595 } 596 } 597 } 598 599 @SuppressWarnings("unused") 600 private final void dumpLocked(Printer pw, String prefix, int which) { 601 final long rawUptime = SystemClock.uptimeMillis() * 1000; 602 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 603 final long batteryUptime = getBatteryUptime(rawUptime); 604 final long batteryRealtime = getBatteryUptime(rawRealtime); 605 606 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 607 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 608 final long totalRealtime = computeRealtime(rawRealtime, which); 609 final long totalUptime = computeUptime(rawUptime, which); 610 611 StringBuilder sb = new StringBuilder(128); 612 613 pw.println(prefix 614 + " Time on battery: " + formatTimeMs(whichBatteryUptime / 1000) 615 + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime) 616 + ") uptime, " 617 + formatTimeMs(whichBatteryRealtime / 1000) + "(" 618 + formatRatioLocked(whichBatteryRealtime, totalRealtime) 619 + ") realtime"); 620 pw.println(prefix 621 + " Total: " 622 + formatTimeMs(totalUptime / 1000) 623 + "uptime, " 624 + formatTimeMs(totalRealtime / 1000) 625 + "realtime"); 626 627 long screenOnTime = getScreenOnTime(batteryRealtime, which); 628 long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 629 pw.println(prefix 630 + " Time with screen on: " + formatTimeMs(screenOnTime / 1000) 631 + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime) 632 + "), time with phone on: " + formatTimeMs(phoneOnTime / 1000) 633 + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime) + ")"); 634 635 pw.println(" "); 636 637 SparseArray<? extends Uid> uidStats = getUidStats(); 638 final int NU = uidStats.size(); 639 for (int iu=0; iu<NU; iu++) { 640 final int uid = uidStats.keyAt(iu); 641 Uid u = uidStats.valueAt(iu); 642 pw.println(prefix + " #" + uid + ":"); 643 boolean uidActivity = false; 644 645 long tcpReceived = u.getTcpBytesReceived(which); 646 long tcpSent = u.getTcpBytesSent(which); 647 if (tcpReceived != 0 || tcpSent != 0) { 648 pw.println(prefix + " Network: " + tcpReceived + " bytes received, " 649 + tcpSent + " bytes sent"); 650 } 651 652 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 653 if (wakelocks.size() > 0) { 654 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 655 : wakelocks.entrySet()) { 656 Uid.Wakelock wl = ent.getValue(); 657 String linePrefix = ": "; 658 sb.setLength(0); 659 sb.append(prefix); 660 sb.append(" Wake lock "); 661 sb.append(ent.getKey()); 662 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 663 "full", which, linePrefix); 664 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 665 "partial", which, linePrefix); 666 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 667 "window", which, linePrefix); 668 if (!linePrefix.equals(": ")) { 669 sb.append(" realtime"); 670 } else { 671 sb.append(": (nothing executed)"); 672 } 673 pw.println(sb.toString()); 674 uidActivity = true; 675 } 676 } 677 678 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 679 if (sensors.size() > 0) { 680 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 681 : sensors.entrySet()) { 682 Uid.Sensor se = ent.getValue(); 683 int sensorNumber = ent.getKey(); 684 sb.setLength(0); 685 sb.append(prefix); 686 sb.append(" Sensor "); 687 int handle = se.getHandle(); 688 if (handle == Uid.Sensor.GPS) { 689 sb.append("GPS"); 690 } else { 691 sb.append(handle); 692 } 693 sb.append(": "); 694 695 Timer timer = se.getSensorTime(); 696 if (timer != null) { 697 // Convert from microseconds to milliseconds with rounding 698 long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000; 699 int count = timer.getCount(which); 700 //timer.logState(); 701 if (totalTime != 0) { 702 sb.append(formatTimeMs(totalTime)); 703 sb.append("realtime ("); 704 sb.append(count); 705 sb.append(" times)"); 706 } else { 707 sb.append("(not used)"); 708 } 709 } else { 710 sb.append("(not used)"); 711 } 712 713 pw.println(sb.toString()); 714 uidActivity = true; 715 } 716 } 717 718 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 719 if (processStats.size() > 0) { 720 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 721 : processStats.entrySet()) { 722 Uid.Proc ps = ent.getValue(); 723 long userTime; 724 long systemTime; 725 int starts; 726 727 userTime = ps.getUserTime(which); 728 systemTime = ps.getSystemTime(which); 729 starts = ps.getStarts(which); 730 731 if (userTime != 0 || systemTime != 0 || starts != 0) { 732 pw.println(prefix + " Proc " + ent.getKey() + ":"); 733 pw.println(prefix + " CPU: " + formatTime(userTime) + "user + " 734 + formatTime(systemTime) + "kernel"); 735 pw.println(prefix + " " + starts + " process starts"); 736 uidActivity = true; 737 } 738 } 739 } 740 741 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 742 if (packageStats.size() > 0) { 743 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 744 : packageStats.entrySet()) { 745 pw.println(prefix + " Apk " + ent.getKey() + ":"); 746 boolean apkActivity = false; 747 Uid.Pkg ps = ent.getValue(); 748 int wakeups = ps.getWakeups(which); 749 if (wakeups != 0) { 750 pw.println(prefix + " " + wakeups + " wakeup alarms"); 751 apkActivity = true; 752 } 753 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 754 if (serviceStats.size() > 0) { 755 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 756 : serviceStats.entrySet()) { 757 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 758 long startTime = ss.getStartTime(batteryUptime, which); 759 int starts = ss.getStarts(which); 760 int launches = ss.getLaunches(which); 761 if (startTime != 0 || starts != 0 || launches != 0) { 762 pw.println(prefix + " Service " + sent.getKey() + ":"); 763 pw.println(prefix + " Created for: " 764 + formatTimeMs(startTime / 1000) 765 + " uptime"); 766 pw.println(prefix + " Starts: " + starts 767 + ", launches: " + launches); 768 apkActivity = true; 769 } 770 } 771 } 772 if (!apkActivity) { 773 pw.println(prefix + " (nothing executed)"); 774 } 775 uidActivity = true; 776 } 777 } 778 if (!uidActivity) { 779 pw.println(prefix + " (nothing executed)"); 780 } 781 } 782 } 783 784 /** 785 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 786 * 787 * @param pw a Printer to receive the dump output. 788 */ 789 @SuppressWarnings("unused") 790 public void dumpLocked(Printer pw) { 791 pw.println("Total Statistics (Current and Historic):"); 792 pw.println(" System starts: " + getStartCount() 793 + ", currently on battery: " + getIsOnBattery()); 794 dumpLocked(pw, "", STATS_TOTAL); 795 pw.println(""); 796 pw.println("Last Run Statistics (Previous run of system):"); 797 dumpLocked(pw, "", STATS_LAST); 798 pw.println(""); 799 pw.println("Current Battery Statistics (Currently running system):"); 800 dumpLocked(pw, "", STATS_CURRENT); 801 pw.println(""); 802 pw.println("Unplugged Statistics (Since last unplugged from power):"); 803 dumpLocked(pw, "", STATS_UNPLUGGED); 804 } 805 806 @SuppressWarnings("unused") 807 public void dumpCheckinLocked(PrintWriter pw, String[] args) { 808 boolean isUnpluggedOnly = false; 809 810 for (String arg : args) { 811 if ("-u".equals(arg)) { 812 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data"); 813 isUnpluggedOnly = true; 814 } 815 } 816 817 if (isUnpluggedOnly) { 818 dumpCheckinLocked(pw, STATS_UNPLUGGED); 819 } 820 else { 821 dumpCheckinLocked(pw, STATS_TOTAL); 822 dumpCheckinLocked(pw, STATS_LAST); 823 dumpCheckinLocked(pw, STATS_UNPLUGGED); 824 dumpCheckinLocked(pw, STATS_CURRENT); 825 } 826 } 827 828} 829