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