BatteryStats.java revision 94b916da2ce7b5fb8d87e884fad7132ef3091720
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.os; 18 19import java.io.PrintWriter; 20import java.util.Formatter; 21import java.util.Map; 22 23import android.util.Log; 24import android.util.Printer; 25import android.util.SparseArray; 26 27/** 28 * A class providing access to battery usage statistics, including information on 29 * wakelocks, processes, packages, and services. All times are represented in microseconds 30 * except where indicated otherwise. 31 * @hide 32 */ 33public abstract class BatteryStats implements Parcelable { 34 35 private static final boolean LOCAL_LOGV = false; 36 37 /** 38 * A constant indicating a partial wake lock timer. 39 */ 40 public static final int WAKE_TYPE_PARTIAL = 0; 41 42 /** 43 * A constant indicating a full wake lock timer. 44 */ 45 public static final int WAKE_TYPE_FULL = 1; 46 47 /** 48 * A constant indicating a window wake lock timer. 49 */ 50 public static final int WAKE_TYPE_WINDOW = 2; 51 52 /** 53 * A constant indicating a sensor timer. 54 */ 55 public static final int SENSOR = 3; 56 57 /** 58 * A constant indicating a a wifi turn on timer 59 */ 60 public static final int WIFI_TURNED_ON = 4; 61 62 /** 63 * A constant indicating a full wifi lock timer 64 */ 65 public static final int FULL_WIFI_LOCK = 5; 66 67 /** 68 * A constant indicating a scan wifi lock timer 69 */ 70 public static final int SCAN_WIFI_LOCK = 6; 71 72 /** 73 * A constant indicating a wifi multicast timer 74 */ 75 public static final int WIFI_MULTICAST_ENABLED = 7; 76 77 /** 78 * A constant indicating an audio turn on timer 79 */ 80 public static final int AUDIO_TURNED_ON = 7; 81 82 /** 83 * A constant indicating a video turn on timer 84 */ 85 public static final int VIDEO_TURNED_ON = 8; 86 87 /** 88 * Include all of the data in the stats, including previously saved data. 89 */ 90 public static final int STATS_SINCE_CHARGED = 0; 91 92 /** 93 * Include only the last run in the stats. 94 */ 95 public static final int STATS_LAST = 1; 96 97 /** 98 * Include only the current run in the stats. 99 */ 100 public static final int STATS_CURRENT = 2; 101 102 /** 103 * Include only the run since the last time the device was unplugged in the stats. 104 */ 105 public static final int STATS_SINCE_UNPLUGGED = 3; 106 107 // NOTE: Update this list if you add/change any stats above. 108 // These characters are supposed to represent "total", "last", "current", 109 // and "unplugged". They were shortened for effeciency sake. 110 private static final String[] STAT_NAMES = { "t", "l", "c", "u" }; 111 112 /** 113 * Bump the version on this if the checkin format changes. 114 */ 115 private static final int BATTERY_STATS_CHECKIN_VERSION = 5; 116 117 private static final long BYTES_PER_KB = 1024; 118 private static final long BYTES_PER_MB = 1048576; // 1024^2 119 private static final long BYTES_PER_GB = 1073741824; //1024^3 120 121 122 private static final String APK_DATA = "apk"; 123 private static final String PROCESS_DATA = "pr"; 124 private static final String SENSOR_DATA = "sr"; 125 private static final String WAKELOCK_DATA = "wl"; 126 private static final String KERNEL_WAKELOCK_DATA = "kwl"; 127 private static final String NETWORK_DATA = "nt"; 128 private static final String USER_ACTIVITY_DATA = "ua"; 129 private static final String BATTERY_DATA = "bt"; 130 private static final String BATTERY_LEVEL_DATA = "lv"; 131 private static final String WIFI_LOCK_DATA = "wfl"; 132 private static final String MISC_DATA = "m"; 133 private static final String SCREEN_BRIGHTNESS_DATA = "br"; 134 private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt"; 135 private static final String SIGNAL_SCANNING_TIME_DATA = "sst"; 136 private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc"; 137 private static final String DATA_CONNECTION_TIME_DATA = "dct"; 138 private static final String DATA_CONNECTION_COUNT_DATA = "dcc"; 139 140 private final StringBuilder mFormatBuilder = new StringBuilder(32); 141 private final Formatter mFormatter = new Formatter(mFormatBuilder); 142 143 /** 144 * State for keeping track of counting information. 145 */ 146 public static abstract class Counter { 147 148 /** 149 * Returns the count associated with this Counter for the 150 * selected type of statistics. 151 * 152 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 153 */ 154 public abstract int getCountLocked(int which); 155 156 /** 157 * Temporary for debugging. 158 */ 159 public abstract void logState(Printer pw, String prefix); 160 } 161 162 /** 163 * State for keeping track of timing information. 164 */ 165 public static abstract class Timer { 166 167 /** 168 * Returns the count associated with this Timer for the 169 * selected type of statistics. 170 * 171 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 172 */ 173 public abstract int getCountLocked(int which); 174 175 /** 176 * Returns the total time in microseconds associated with this Timer for the 177 * selected type of statistics. 178 * 179 * @param batteryRealtime system realtime on battery in microseconds 180 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 181 * @return a time in microseconds 182 */ 183 public abstract long getTotalTimeLocked(long batteryRealtime, int which); 184 185 /** 186 * Temporary for debugging. 187 */ 188 public abstract void logState(Printer pw, String prefix); 189 } 190 191 /** 192 * The statistics associated with a particular uid. 193 */ 194 public static abstract class Uid { 195 196 /** 197 * Returns a mapping containing wakelock statistics. 198 * 199 * @return a Map from Strings to Uid.Wakelock objects. 200 */ 201 public abstract Map<String, ? extends Wakelock> getWakelockStats(); 202 203 /** 204 * The statistics associated with a particular wake lock. 205 */ 206 public static abstract class Wakelock { 207 public abstract Timer getWakeTime(int type); 208 } 209 210 /** 211 * Returns a mapping containing sensor statistics. 212 * 213 * @return a Map from Integer sensor ids to Uid.Sensor objects. 214 */ 215 public abstract Map<Integer, ? extends Sensor> getSensorStats(); 216 217 /** 218 * Returns a mapping containing process statistics. 219 * 220 * @return a Map from Strings to Uid.Proc objects. 221 */ 222 public abstract Map<String, ? extends Proc> getProcessStats(); 223 224 /** 225 * Returns a mapping containing package statistics. 226 * 227 * @return a Map from Strings to Uid.Pkg objects. 228 */ 229 public abstract Map<String, ? extends Pkg> getPackageStats(); 230 231 /** 232 * {@hide} 233 */ 234 public abstract int getUid(); 235 236 /** 237 * {@hide} 238 */ 239 public abstract long getTcpBytesReceived(int which); 240 241 /** 242 * {@hide} 243 */ 244 public abstract long getTcpBytesSent(int which); 245 246 public abstract void noteWifiTurnedOnLocked(); 247 public abstract void noteWifiTurnedOffLocked(); 248 public abstract void noteFullWifiLockAcquiredLocked(); 249 public abstract void noteFullWifiLockReleasedLocked(); 250 public abstract void noteScanWifiLockAcquiredLocked(); 251 public abstract void noteScanWifiLockReleasedLocked(); 252 public abstract void noteWifiMulticastEnabledLocked(); 253 public abstract void noteWifiMulticastDisabledLocked(); 254 public abstract void noteAudioTurnedOnLocked(); 255 public abstract void noteAudioTurnedOffLocked(); 256 public abstract void noteVideoTurnedOnLocked(); 257 public abstract void noteVideoTurnedOffLocked(); 258 public abstract long getWifiTurnedOnTime(long batteryRealtime, int which); 259 public abstract long getFullWifiLockTime(long batteryRealtime, int which); 260 public abstract long getScanWifiLockTime(long batteryRealtime, int which); 261 public abstract long getWifiMulticastTime(long batteryRealtime, 262 int which); 263 public abstract long getAudioTurnedOnTime(long batteryRealtime, int which); 264 public abstract long getVideoTurnedOnTime(long batteryRealtime, int which); 265 266 /** 267 * Note that these must match the constants in android.os.LocalPowerManager. 268 */ 269 static final String[] USER_ACTIVITY_TYPES = { 270 "other", "cheek", "touch", "long_touch", "touch_up", "button", "unknown" 271 }; 272 273 public static final int NUM_USER_ACTIVITY_TYPES = 7; 274 275 public abstract void noteUserActivityLocked(int type); 276 public abstract boolean hasUserActivity(); 277 public abstract int getUserActivityCount(int type, int which); 278 279 public static abstract class Sensor { 280 // Magic sensor number for the GPS. 281 public static final int GPS = -10000; 282 283 public abstract int getHandle(); 284 285 public abstract Timer getSensorTime(); 286 } 287 288 /** 289 * The statistics associated with a particular process. 290 */ 291 public static abstract class Proc { 292 293 /** 294 * Returns the total time (in 1/100 sec) spent executing in user code. 295 * 296 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 297 */ 298 public abstract long getUserTime(int which); 299 300 /** 301 * Returns the total time (in 1/100 sec) spent executing in system code. 302 * 303 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 304 */ 305 public abstract long getSystemTime(int which); 306 307 /** 308 * Returns the number of times the process has been started. 309 * 310 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 311 */ 312 public abstract int getStarts(int which); 313 314 /** 315 * Returns the cpu time spent in microseconds while the process was in the foreground. 316 * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED 317 * @return foreground cpu time in microseconds 318 */ 319 public abstract long getForegroundTime(int which); 320 321 /** 322 * Returns the approximate cpu time spent in microseconds, at a certain CPU speed. 323 * @param speedStep the index of the CPU speed. This is not the actual speed of the 324 * CPU. 325 * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED 326 * @see BatteryStats#getCpuSpeedSteps() 327 */ 328 public abstract long getTimeAtCpuSpeedStep(int speedStep, int which); 329 } 330 331 /** 332 * The statistics associated with a particular package. 333 */ 334 public static abstract class Pkg { 335 336 /** 337 * Returns the number of times this package has done something that could wake up the 338 * device from sleep. 339 * 340 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 341 */ 342 public abstract int getWakeups(int which); 343 344 /** 345 * Returns a mapping containing service statistics. 346 */ 347 public abstract Map<String, ? extends Serv> getServiceStats(); 348 349 /** 350 * The statistics associated with a particular service. 351 */ 352 public abstract class Serv { 353 354 /** 355 * Returns the amount of time spent started. 356 * 357 * @param batteryUptime elapsed uptime on battery in microseconds. 358 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 359 * @return 360 */ 361 public abstract long getStartTime(long batteryUptime, int which); 362 363 /** 364 * Returns the total number of times startService() has been called. 365 * 366 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 367 */ 368 public abstract int getStarts(int which); 369 370 /** 371 * Returns the total number times the service has been launched. 372 * 373 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 374 */ 375 public abstract int getLaunches(int which); 376 } 377 } 378 } 379 380 public final class HistoryItem implements Parcelable { 381 public HistoryItem next; 382 383 public long time; 384 385 public static final byte CMD_UPDATE = 0; 386 public static final byte CMD_START = 1; 387 388 public byte cmd; 389 390 public byte batteryLevel; 391 public byte batteryStatus; 392 public byte batteryHealth; 393 public byte batteryPlugType; 394 395 public char batteryTemperature; 396 public char batteryVoltage; 397 398 public static final int STATE_BRIGHTNESS_MASK = 0x000000f; 399 public static final int STATE_BRIGHTNESS_SHIFT = 0; 400 public static final int STATE_SIGNAL_STRENGTH_MASK = 0x00000f0; 401 public static final int STATE_SIGNAL_STRENGTH_SHIFT = 4; 402 public static final int STATE_PHONE_STATE_MASK = 0x0000f00; 403 public static final int STATE_PHONE_STATE_SHIFT = 8; 404 public static final int STATE_DATA_CONNECTION_MASK = 0x000f000; 405 public static final int STATE_DATA_CONNECTION_SHIFT = 12; 406 407 public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<30; 408 public static final int STATE_SCREEN_ON_FLAG = 1<<29; 409 public static final int STATE_GPS_ON_FLAG = 1<<28; 410 public static final int STATE_PHONE_ON_FLAG = 1<<27; 411 public static final int STATE_PHONE_SCANNING_FLAG = 1<<26; 412 public static final int STATE_WIFI_ON_FLAG = 1<<25; 413 public static final int STATE_WIFI_RUNNING_FLAG = 1<<24; 414 public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<23; 415 public static final int STATE_WIFI_SCAN_LOCK_FLAG = 1<<22; 416 public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<21; 417 public static final int STATE_BLUETOOTH_ON_FLAG = 1<<20; 418 public static final int STATE_AUDIO_ON_FLAG = 1<<19; 419 public static final int STATE_VIDEO_ON_FLAG = 1<<18; 420 421 public int states; 422 423 public HistoryItem() { 424 } 425 426 public HistoryItem(long time, Parcel src) { 427 this.time = time; 428 int bat = src.readInt(); 429 cmd = (byte)(bat&0xff); 430 batteryLevel = (byte)((bat>>8)&0xff); 431 batteryStatus = (byte)((bat>>16)&0xf); 432 batteryHealth = (byte)((bat>>20)&0xf); 433 batteryPlugType = (byte)((bat>>24)&0xf); 434 bat = src.readInt(); 435 batteryTemperature = (char)(bat&0xffff); 436 batteryVoltage = (char)((bat>>16)&0xffff); 437 states = src.readInt(); 438 } 439 440 public int describeContents() { 441 return 0; 442 } 443 444 public void writeToParcel(Parcel dest, int flags) { 445 dest.writeLong(time); 446 int bat = (((int)cmd)&0xff) 447 | ((((int)batteryLevel)<<8)&0xff00) 448 | ((((int)batteryStatus)<<16)&0xf0000) 449 | ((((int)batteryHealth)<<20)&0xf00000) 450 | ((((int)batteryPlugType)<<24)&0xf000000); 451 dest.writeInt(bat); 452 bat = (((int)batteryTemperature)&0xffff) 453 | ((((int)batteryVoltage)<<16)&0xffff0000); 454 dest.writeInt(bat); 455 dest.writeInt(states); 456 } 457 458 public void setTo(long time, byte cmd, HistoryItem o) { 459 this.time = time; 460 this.cmd = cmd; 461 batteryLevel = o.batteryLevel; 462 batteryStatus = o.batteryStatus; 463 batteryHealth = o.batteryHealth; 464 batteryPlugType = o.batteryPlugType; 465 batteryTemperature = o.batteryTemperature; 466 batteryVoltage = o.batteryVoltage; 467 states = o.states; 468 } 469 } 470 471 public static final class BitDescription { 472 public final int mask; 473 public final int shift; 474 public final String name; 475 public final String[] values; 476 477 public BitDescription(int mask, String name) { 478 this.mask = mask; 479 this.shift = -1; 480 this.name = name; 481 this.values = null; 482 } 483 484 public BitDescription(int mask, int shift, String name, String[] values) { 485 this.mask = mask; 486 this.shift = shift; 487 this.name = name; 488 this.values = values; 489 } 490 } 491 492 /** 493 * Return the current history of battery state changes. 494 */ 495 public abstract HistoryItem getHistory(); 496 497 /** 498 * Returns the number of times the device has been started. 499 */ 500 public abstract int getStartCount(); 501 502 /** 503 * Returns the time in microseconds that the screen has been on while the device was 504 * running on battery. 505 * 506 * {@hide} 507 */ 508 public abstract long getScreenOnTime(long batteryRealtime, int which); 509 510 public static final int SCREEN_BRIGHTNESS_DARK = 0; 511 public static final int SCREEN_BRIGHTNESS_DIM = 1; 512 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2; 513 public static final int SCREEN_BRIGHTNESS_LIGHT = 3; 514 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4; 515 516 static final String[] SCREEN_BRIGHTNESS_NAMES = { 517 "dark", "dim", "medium", "light", "bright" 518 }; 519 520 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5; 521 522 /** 523 * Returns the time in microseconds that the screen has been on with 524 * the given brightness 525 * 526 * {@hide} 527 */ 528 public abstract long getScreenBrightnessTime(int brightnessBin, 529 long batteryRealtime, int which); 530 531 public abstract int getInputEventCount(int which); 532 533 /** 534 * Returns the time in microseconds that the phone has been on while the device was 535 * running on battery. 536 * 537 * {@hide} 538 */ 539 public abstract long getPhoneOnTime(long batteryRealtime, int which); 540 541 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; 542 public static final int SIGNAL_STRENGTH_POOR = 1; 543 public static final int SIGNAL_STRENGTH_MODERATE = 2; 544 public static final int SIGNAL_STRENGTH_GOOD = 3; 545 public static final int SIGNAL_STRENGTH_GREAT = 4; 546 547 static final String[] SIGNAL_STRENGTH_NAMES = { 548 "none", "poor", "moderate", "good", "great" 549 }; 550 551 public static final int NUM_SIGNAL_STRENGTH_BINS = 5; 552 553 /** 554 * Returns the time in microseconds that the phone has been running with 555 * the given signal strength. 556 * 557 * {@hide} 558 */ 559 public abstract long getPhoneSignalStrengthTime(int strengthBin, 560 long batteryRealtime, int which); 561 562 /** 563 * Returns the time in microseconds that the phone has been trying to 564 * acquire a signal. 565 * 566 * {@hide} 567 */ 568 public abstract long getPhoneSignalScanningTime( 569 long batteryRealtime, int which); 570 571 /** 572 * Returns the number of times the phone has entered the given signal strength. 573 * 574 * {@hide} 575 */ 576 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which); 577 578 public static final int DATA_CONNECTION_NONE = 0; 579 public static final int DATA_CONNECTION_GPRS = 1; 580 public static final int DATA_CONNECTION_EDGE = 2; 581 public static final int DATA_CONNECTION_UMTS = 3; 582 public static final int DATA_CONNECTION_CDMA = 4; 583 public static final int DATA_CONNECTION_EVDO_0 = 5; 584 public static final int DATA_CONNECTION_EVDO_A = 6; 585 public static final int DATA_CONNECTION_1xRTT = 7; 586 public static final int DATA_CONNECTION_HSDPA = 8; 587 public static final int DATA_CONNECTION_HSUPA = 9; 588 public static final int DATA_CONNECTION_HSPA = 10; 589 public static final int DATA_CONNECTION_IDEN = 11; 590 public static final int DATA_CONNECTION_EVDO_B = 12; 591 public static final int DATA_CONNECTION_OTHER = 13; 592 593 static final String[] DATA_CONNECTION_NAMES = { 594 "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A", 595 "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "other" 596 }; 597 598 public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1; 599 600 /** 601 * Returns the time in microseconds that the phone has been running with 602 * the given data connection. 603 * 604 * {@hide} 605 */ 606 public abstract long getPhoneDataConnectionTime(int dataType, 607 long batteryRealtime, int which); 608 609 /** 610 * Returns the number of times the phone has entered the given data 611 * connection type. 612 * 613 * {@hide} 614 */ 615 public abstract int getPhoneDataConnectionCount(int dataType, int which); 616 617 public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS 618 = new BitDescription[] { 619 new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged"), 620 new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen"), 621 new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps"), 622 new BitDescription(HistoryItem.STATE_PHONE_ON_FLAG, "phone"), 623 new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning"), 624 new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi"), 625 new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running"), 626 new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock"), 627 new BitDescription(HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG, "wifi_scan_lock"), 628 new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast"), 629 new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth"), 630 new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio"), 631 new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video"), 632 new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK, 633 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", 634 SCREEN_BRIGHTNESS_NAMES), 635 new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK, 636 HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength", 637 SIGNAL_STRENGTH_NAMES), 638 new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK, 639 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", 640 new String[] {"in", "out", "emergency", "off"}), 641 new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK, 642 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", 643 DATA_CONNECTION_NAMES), 644 }; 645 646 /** 647 * Returns the time in microseconds that wifi has been on while the device was 648 * running on battery. 649 * 650 * {@hide} 651 */ 652 public abstract long getWifiOnTime(long batteryRealtime, int which); 653 654 /** 655 * Returns the time in microseconds that wifi has been on and the driver has 656 * been in the running state while the device was running on battery. 657 * 658 * {@hide} 659 */ 660 public abstract long getWifiRunningTime(long batteryRealtime, int which); 661 662 /** 663 * Returns the time in microseconds that bluetooth has been on while the device was 664 * running on battery. 665 * 666 * {@hide} 667 */ 668 public abstract long getBluetoothOnTime(long batteryRealtime, int which); 669 670 /** 671 * Return whether we are currently running on battery. 672 */ 673 public abstract boolean getIsOnBattery(); 674 675 /** 676 * Returns a SparseArray containing the statistics for each uid. 677 */ 678 public abstract SparseArray<? extends Uid> getUidStats(); 679 680 /** 681 * Returns the current battery uptime in microseconds. 682 * 683 * @param curTime the amount of elapsed realtime in microseconds. 684 */ 685 public abstract long getBatteryUptime(long curTime); 686 687 /** 688 * @deprecated use getRadioDataUptime 689 */ 690 public long getRadioDataUptimeMs() { 691 return getRadioDataUptime() / 1000; 692 } 693 694 /** 695 * Returns the time that the radio was on for data transfers. 696 * @return the uptime in microseconds while unplugged 697 */ 698 public abstract long getRadioDataUptime(); 699 700 /** 701 * Returns the current battery realtime in microseconds. 702 * 703 * @param curTime the amount of elapsed realtime in microseconds. 704 */ 705 public abstract long getBatteryRealtime(long curTime); 706 707 /** 708 * Returns the battery percentage level at the last time the device was unplugged from power, or 709 * the last time it booted on battery power. 710 */ 711 public abstract int getDischargeStartLevel(); 712 713 /** 714 * Returns the current battery percentage level if we are in a discharge cycle, otherwise 715 * returns the level at the last plug event. 716 */ 717 public abstract int getDischargeCurrentLevel(); 718 719 /** 720 * Returns the total, last, or current battery uptime in microseconds. 721 * 722 * @param curTime the elapsed realtime in microseconds. 723 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 724 */ 725 public abstract long computeBatteryUptime(long curTime, int which); 726 727 /** 728 * Returns the total, last, or current battery realtime in microseconds. 729 * 730 * @param curTime the current elapsed realtime in microseconds. 731 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 732 */ 733 public abstract long computeBatteryRealtime(long curTime, int which); 734 735 /** 736 * Returns the total, last, or current uptime in microseconds. 737 * 738 * @param curTime the current elapsed realtime in microseconds. 739 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 740 */ 741 public abstract long computeUptime(long curTime, int which); 742 743 /** 744 * Returns the total, last, or current realtime in microseconds. 745 * * 746 * @param curTime the current elapsed realtime in microseconds. 747 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 748 */ 749 public abstract long computeRealtime(long curTime, int which); 750 751 public abstract Map<String, ? extends Timer> getKernelWakelockStats(); 752 753 /** Returns the number of different speeds that the CPU can run at */ 754 public abstract int getCpuSpeedSteps(); 755 756 private final static void formatTimeRaw(StringBuilder out, long seconds) { 757 long days = seconds / (60 * 60 * 24); 758 if (days != 0) { 759 out.append(days); 760 out.append("d "); 761 } 762 long used = days * 60 * 60 * 24; 763 764 long hours = (seconds - used) / (60 * 60); 765 if (hours != 0 || used != 0) { 766 out.append(hours); 767 out.append("h "); 768 } 769 used += hours * 60 * 60; 770 771 long mins = (seconds-used) / 60; 772 if (mins != 0 || used != 0) { 773 out.append(mins); 774 out.append("m "); 775 } 776 used += mins * 60; 777 778 if (seconds != 0 || used != 0) { 779 out.append(seconds-used); 780 out.append("s "); 781 } 782 } 783 784 private final static void formatTime(StringBuilder sb, long time) { 785 long sec = time / 100; 786 formatTimeRaw(sb, sec); 787 sb.append((time - (sec * 100)) * 10); 788 sb.append("ms "); 789 } 790 791 private final static void formatTimeMs(StringBuilder sb, long time) { 792 long sec = time / 1000; 793 formatTimeRaw(sb, sec); 794 sb.append(time - (sec * 1000)); 795 sb.append("ms "); 796 } 797 798 private final String formatRatioLocked(long num, long den) { 799 if (den == 0L) { 800 return "---%"; 801 } 802 float perc = ((float)num) / ((float)den) * 100; 803 mFormatBuilder.setLength(0); 804 mFormatter.format("%.1f%%", perc); 805 return mFormatBuilder.toString(); 806 } 807 808 private final String formatBytesLocked(long bytes) { 809 mFormatBuilder.setLength(0); 810 811 if (bytes < BYTES_PER_KB) { 812 return bytes + "B"; 813 } else if (bytes < BYTES_PER_MB) { 814 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB); 815 return mFormatBuilder.toString(); 816 } else if (bytes < BYTES_PER_GB){ 817 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB); 818 return mFormatBuilder.toString(); 819 } else { 820 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB); 821 return mFormatBuilder.toString(); 822 } 823 } 824 825 /** 826 * 827 * @param sb a StringBuilder object. 828 * @param timer a Timer object contining the wakelock times. 829 * @param batteryRealtime the current on-battery time in microseconds. 830 * @param name the name of the wakelock. 831 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 832 * @param linePrefix a String to be prepended to each line of output. 833 * @return the line prefix 834 */ 835 private static final String printWakeLock(StringBuilder sb, Timer timer, 836 long batteryRealtime, String name, int which, String linePrefix) { 837 838 if (timer != null) { 839 // Convert from microseconds to milliseconds with rounding 840 long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which); 841 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 842 843 int count = timer.getCountLocked(which); 844 if (totalTimeMillis != 0) { 845 sb.append(linePrefix); 846 formatTimeMs(sb, totalTimeMillis); 847 if (name != null) sb.append(name); 848 sb.append(' '); 849 sb.append('('); 850 sb.append(count); 851 sb.append(" times)"); 852 return ", "; 853 } 854 } 855 return linePrefix; 856 } 857 858 /** 859 * Checkin version of wakelock printer. Prints simple comma-separated list. 860 * 861 * @param sb a StringBuilder object. 862 * @param timer a Timer object contining the wakelock times. 863 * @param now the current time in microseconds. 864 * @param name the name of the wakelock. 865 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 866 * @param linePrefix a String to be prepended to each line of output. 867 * @return the line prefix 868 */ 869 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now, 870 String name, int which, String linePrefix) { 871 long totalTimeMicros = 0; 872 int count = 0; 873 if (timer != null) { 874 totalTimeMicros = timer.getTotalTimeLocked(now, which); 875 count = timer.getCountLocked(which); 876 } 877 sb.append(linePrefix); 878 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 879 sb.append(','); 880 sb.append(name != null ? name + "," : ""); 881 sb.append(count); 882 return ","; 883 } 884 885 /** 886 * Dump a comma-separated line of values for terse checkin mode. 887 * 888 * @param pw the PageWriter to dump log to 889 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 890 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 891 * @param args type-dependent data arguments 892 */ 893 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 894 Object... args ) { 895 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 896 pw.print(uid); pw.print(','); 897 pw.print(category); pw.print(','); 898 pw.print(type); 899 900 for (Object arg : args) { 901 pw.print(','); 902 pw.print(arg); 903 } 904 pw.print('\n'); 905 } 906 907 /** 908 * Checkin server version of dump to produce more compact, computer-readable log. 909 * 910 * NOTE: all times are expressed in 'ms'. 911 */ 912 public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) { 913 final long rawUptime = SystemClock.uptimeMillis() * 1000; 914 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 915 final long batteryUptime = getBatteryUptime(rawUptime); 916 final long batteryRealtime = getBatteryRealtime(rawRealtime); 917 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 918 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 919 final long totalRealtime = computeRealtime(rawRealtime, which); 920 final long totalUptime = computeUptime(rawUptime, which); 921 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 922 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 923 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 924 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 925 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 926 927 StringBuilder sb = new StringBuilder(128); 928 929 SparseArray<? extends Uid> uidStats = getUidStats(); 930 final int NU = uidStats.size(); 931 932 String category = STAT_NAMES[which]; 933 934 // Dump "battery" stat 935 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 936 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A", 937 whichBatteryRealtime / 1000, whichBatteryUptime / 1000, 938 totalRealtime / 1000, totalUptime / 1000); 939 940 // Calculate total network and wakelock times across all uids. 941 long rxTotal = 0; 942 long txTotal = 0; 943 long fullWakeLockTimeTotal = 0; 944 long partialWakeLockTimeTotal = 0; 945 946 for (int iu = 0; iu < NU; iu++) { 947 Uid u = uidStats.valueAt(iu); 948 rxTotal += u.getTcpBytesReceived(which); 949 txTotal += u.getTcpBytesSent(which); 950 951 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 952 if (wakelocks.size() > 0) { 953 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 954 : wakelocks.entrySet()) { 955 Uid.Wakelock wl = ent.getValue(); 956 957 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 958 if (fullWakeTimer != null) { 959 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which); 960 } 961 962 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 963 if (partialWakeTimer != null) { 964 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked( 965 batteryRealtime, which); 966 } 967 } 968 } 969 } 970 971 // Dump misc stats 972 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 973 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, 974 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal, 975 fullWakeLockTimeTotal, partialWakeLockTimeTotal, 976 getInputEventCount(which)); 977 978 // Dump screen brightness stats 979 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; 980 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 981 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000; 982 } 983 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args); 984 985 // Dump signal strength stats 986 args = new Object[NUM_SIGNAL_STRENGTH_BINS]; 987 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 988 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000; 989 } 990 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args); 991 dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA, 992 getPhoneSignalScanningTime(batteryRealtime, which) / 1000); 993 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 994 args[i] = getPhoneSignalStrengthCount(i, which); 995 } 996 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args); 997 998 // Dump network type stats 999 args = new Object[NUM_DATA_CONNECTION_TYPES]; 1000 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1001 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000; 1002 } 1003 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args); 1004 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1005 args[i] = getPhoneDataConnectionCount(i, which); 1006 } 1007 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args); 1008 1009 if (which == STATS_SINCE_UNPLUGGED) { 1010 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), 1011 getDischargeCurrentLevel()); 1012 } 1013 1014 if (reqUid < 0) { 1015 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); 1016 if (kernelWakelocks.size() > 0) { 1017 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { 1018 sb.setLength(0); 1019 printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, ""); 1020 1021 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(), 1022 sb.toString()); 1023 } 1024 } 1025 } 1026 1027 for (int iu = 0; iu < NU; iu++) { 1028 final int uid = uidStats.keyAt(iu); 1029 if (reqUid >= 0 && uid != reqUid) { 1030 continue; 1031 } 1032 Uid u = uidStats.valueAt(iu); 1033 // Dump Network stats per uid, if any 1034 long rx = u.getTcpBytesReceived(which); 1035 long tx = u.getTcpBytesSent(which); 1036 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 1037 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 1038 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which); 1039 1040 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx); 1041 1042 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0 1043 || wifiTurnedOnTime != 0) { 1044 dumpLine(pw, uid, category, WIFI_LOCK_DATA, 1045 fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime); 1046 } 1047 1048 if (u.hasUserActivity()) { 1049 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES]; 1050 boolean hasData = false; 1051 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 1052 int val = u.getUserActivityCount(i, which); 1053 args[i] = val; 1054 if (val != 0) hasData = true; 1055 } 1056 if (hasData) { 1057 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args); 1058 } 1059 } 1060 1061 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1062 if (wakelocks.size() > 0) { 1063 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1064 : wakelocks.entrySet()) { 1065 Uid.Wakelock wl = ent.getValue(); 1066 String linePrefix = ""; 1067 sb.setLength(0); 1068 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), 1069 batteryRealtime, "f", which, linePrefix); 1070 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), 1071 batteryRealtime, "p", which, linePrefix); 1072 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), 1073 batteryRealtime, "w", which, linePrefix); 1074 1075 // Only log if we had at lease one wakelock... 1076 if (sb.length() > 0) { 1077 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString()); 1078 } 1079 } 1080 } 1081 1082 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1083 if (sensors.size() > 0) { 1084 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1085 : sensors.entrySet()) { 1086 Uid.Sensor se = ent.getValue(); 1087 int sensorNumber = ent.getKey(); 1088 Timer timer = se.getSensorTime(); 1089 if (timer != null) { 1090 // Convert from microseconds to milliseconds with rounding 1091 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; 1092 int count = timer.getCountLocked(which); 1093 if (totalTime != 0) { 1094 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 1095 } 1096 } 1097 } 1098 } 1099 1100 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 1101 if (processStats.size() > 0) { 1102 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 1103 : processStats.entrySet()) { 1104 Uid.Proc ps = ent.getValue(); 1105 1106 long userTime = ps.getUserTime(which); 1107 long systemTime = ps.getSystemTime(which); 1108 int starts = ps.getStarts(which); 1109 1110 if (userTime != 0 || systemTime != 0 || starts != 0) { 1111 dumpLine(pw, uid, category, PROCESS_DATA, 1112 ent.getKey(), // proc 1113 userTime * 10, // cpu time in ms 1114 systemTime * 10, // user time in ms 1115 starts); // process starts 1116 } 1117 } 1118 } 1119 1120 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 1121 if (packageStats.size() > 0) { 1122 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 1123 : packageStats.entrySet()) { 1124 1125 Uid.Pkg ps = ent.getValue(); 1126 int wakeups = ps.getWakeups(which); 1127 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 1128 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 1129 : serviceStats.entrySet()) { 1130 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 1131 long startTime = ss.getStartTime(batteryUptime, which); 1132 int starts = ss.getStarts(which); 1133 int launches = ss.getLaunches(which); 1134 if (startTime != 0 || starts != 0 || launches != 0) { 1135 dumpLine(pw, uid, category, APK_DATA, 1136 wakeups, // wakeup alarms 1137 ent.getKey(), // Apk 1138 sent.getKey(), // service 1139 startTime / 1000, // time spent started, in ms 1140 starts, 1141 launches); 1142 } 1143 } 1144 } 1145 } 1146 } 1147 } 1148 1149 @SuppressWarnings("unused") 1150 public final void dumpLocked(PrintWriter pw, String prefix, int which, int reqUid) { 1151 final long rawUptime = SystemClock.uptimeMillis() * 1000; 1152 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 1153 final long batteryUptime = getBatteryUptime(rawUptime); 1154 final long batteryRealtime = getBatteryRealtime(rawRealtime); 1155 1156 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 1157 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 1158 final long totalRealtime = computeRealtime(rawRealtime, which); 1159 final long totalUptime = computeUptime(rawUptime, which); 1160 1161 StringBuilder sb = new StringBuilder(128); 1162 1163 SparseArray<? extends Uid> uidStats = getUidStats(); 1164 final int NU = uidStats.size(); 1165 1166 sb.setLength(0); 1167 sb.append(prefix); 1168 sb.append(" Time on battery: "); 1169 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("("); 1170 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime)); 1171 sb.append(") realtime, "); 1172 formatTimeMs(sb, whichBatteryUptime / 1000); 1173 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime)); 1174 sb.append(") uptime"); 1175 pw.println(sb.toString()); 1176 sb.setLength(0); 1177 sb.append(prefix); 1178 sb.append(" Total run time: "); 1179 formatTimeMs(sb, totalRealtime / 1000); 1180 sb.append("realtime, "); 1181 formatTimeMs(sb, totalUptime / 1000); 1182 sb.append("uptime, "); 1183 pw.println(sb.toString()); 1184 1185 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 1186 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 1187 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 1188 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 1189 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 1190 sb.setLength(0); 1191 sb.append(prefix); 1192 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000); 1193 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime)); 1194 sb.append("), Input events: "); sb.append(getInputEventCount(which)); 1195 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000); 1196 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime)); 1197 sb.append(")"); 1198 pw.println(sb.toString()); 1199 sb.setLength(0); 1200 sb.append(prefix); 1201 sb.append(" Screen brightnesses: "); 1202 boolean didOne = false; 1203 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1204 final long time = getScreenBrightnessTime(i, batteryRealtime, which); 1205 if (time == 0) { 1206 continue; 1207 } 1208 if (didOne) sb.append(", "); 1209 didOne = true; 1210 sb.append(SCREEN_BRIGHTNESS_NAMES[i]); 1211 sb.append(" "); 1212 formatTimeMs(sb, time/1000); 1213 sb.append("("); 1214 sb.append(formatRatioLocked(time, screenOnTime)); 1215 sb.append(")"); 1216 } 1217 if (!didOne) sb.append("No activity"); 1218 pw.println(sb.toString()); 1219 1220 // Calculate total network and wakelock times across all uids. 1221 long rxTotal = 0; 1222 long txTotal = 0; 1223 long fullWakeLockTimeTotalMicros = 0; 1224 long partialWakeLockTimeTotalMicros = 0; 1225 1226 if (reqUid < 0) { 1227 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); 1228 if (kernelWakelocks.size() > 0) { 1229 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { 1230 1231 String linePrefix = ": "; 1232 sb.setLength(0); 1233 sb.append(prefix); 1234 sb.append(" Kernel Wake lock "); 1235 sb.append(ent.getKey()); 1236 linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which, 1237 linePrefix); 1238 if (!linePrefix.equals(": ")) { 1239 sb.append(" realtime"); 1240 // Only print out wake locks that were held 1241 pw.println(sb.toString()); 1242 } 1243 } 1244 } 1245 } 1246 1247 for (int iu = 0; iu < NU; iu++) { 1248 Uid u = uidStats.valueAt(iu); 1249 rxTotal += u.getTcpBytesReceived(which); 1250 txTotal += u.getTcpBytesSent(which); 1251 1252 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1253 if (wakelocks.size() > 0) { 1254 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1255 : wakelocks.entrySet()) { 1256 Uid.Wakelock wl = ent.getValue(); 1257 1258 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 1259 if (fullWakeTimer != null) { 1260 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked( 1261 batteryRealtime, which); 1262 } 1263 1264 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 1265 if (partialWakeTimer != null) { 1266 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked( 1267 batteryRealtime, which); 1268 } 1269 } 1270 } 1271 } 1272 1273 pw.print(prefix); 1274 pw.print(" Total received: "); pw.print(formatBytesLocked(rxTotal)); 1275 pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal)); 1276 sb.setLength(0); 1277 sb.append(prefix); 1278 sb.append(" Total full wakelock time: "); formatTimeMs(sb, 1279 (fullWakeLockTimeTotalMicros + 500) / 1000); 1280 sb.append(", Total partial waklock time: "); formatTimeMs(sb, 1281 (partialWakeLockTimeTotalMicros + 500) / 1000); 1282 pw.println(sb.toString()); 1283 1284 sb.setLength(0); 1285 sb.append(prefix); 1286 sb.append(" Signal levels: "); 1287 didOne = false; 1288 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 1289 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which); 1290 if (time == 0) { 1291 continue; 1292 } 1293 if (didOne) sb.append(", "); 1294 didOne = true; 1295 sb.append(SIGNAL_STRENGTH_NAMES[i]); 1296 sb.append(" "); 1297 formatTimeMs(sb, time/1000); 1298 sb.append("("); 1299 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1300 sb.append(") "); 1301 sb.append(getPhoneSignalStrengthCount(i, which)); 1302 sb.append("x"); 1303 } 1304 if (!didOne) sb.append("No activity"); 1305 pw.println(sb.toString()); 1306 1307 sb.setLength(0); 1308 sb.append(prefix); 1309 sb.append(" Signal scanning time: "); 1310 formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000); 1311 pw.println(sb.toString()); 1312 1313 sb.setLength(0); 1314 sb.append(prefix); 1315 sb.append(" Radio types: "); 1316 didOne = false; 1317 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1318 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which); 1319 if (time == 0) { 1320 continue; 1321 } 1322 if (didOne) sb.append(", "); 1323 didOne = true; 1324 sb.append(DATA_CONNECTION_NAMES[i]); 1325 sb.append(" "); 1326 formatTimeMs(sb, time/1000); 1327 sb.append("("); 1328 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1329 sb.append(") "); 1330 sb.append(getPhoneDataConnectionCount(i, which)); 1331 sb.append("x"); 1332 } 1333 if (!didOne) sb.append("No activity"); 1334 pw.println(sb.toString()); 1335 1336 sb.setLength(0); 1337 sb.append(prefix); 1338 sb.append(" Radio data uptime when unplugged: "); 1339 sb.append(getRadioDataUptime() / 1000); 1340 sb.append(" ms"); 1341 pw.println(sb.toString()); 1342 1343 sb.setLength(0); 1344 sb.append(prefix); 1345 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000); 1346 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime)); 1347 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000); 1348 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime)); 1349 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000); 1350 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)); 1351 sb.append(")"); 1352 pw.println(sb.toString()); 1353 1354 pw.println(" "); 1355 1356 if (which == STATS_SINCE_UNPLUGGED) { 1357 if (getIsOnBattery()) { 1358 pw.print(prefix); pw.println(" Device is currently unplugged"); 1359 pw.print(prefix); pw.print(" Discharge cycle start level: "); 1360 pw.println(getDischargeStartLevel()); 1361 pw.print(prefix); pw.print(" Discharge cycle current level: "); 1362 pw.println(getDischargeCurrentLevel()); 1363 } else { 1364 pw.print(prefix); pw.println(" Device is currently plugged into power"); 1365 pw.print(prefix); pw.print(" Last discharge cycle start level: "); 1366 pw.println(getDischargeStartLevel()); 1367 pw.print(prefix); pw.print(" Last discharge cycle end level: "); 1368 pw.println(getDischargeCurrentLevel()); 1369 } 1370 pw.println(" "); 1371 } 1372 1373 1374 for (int iu=0; iu<NU; iu++) { 1375 final int uid = uidStats.keyAt(iu); 1376 if (reqUid >= 0 && uid != reqUid) { 1377 continue; 1378 } 1379 1380 Uid u = uidStats.valueAt(iu); 1381 1382 pw.println(prefix + " #" + uid + ":"); 1383 boolean uidActivity = false; 1384 1385 long tcpReceived = u.getTcpBytesReceived(which); 1386 long tcpSent = u.getTcpBytesSent(which); 1387 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 1388 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 1389 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which); 1390 1391 if (tcpReceived != 0 || tcpSent != 0) { 1392 pw.print(prefix); pw.print(" Network: "); 1393 pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, "); 1394 pw.print(formatBytesLocked(tcpSent)); pw.println(" sent"); 1395 } 1396 1397 if (u.hasUserActivity()) { 1398 boolean hasData = false; 1399 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1400 int val = u.getUserActivityCount(i, which); 1401 if (val != 0) { 1402 if (!hasData) { 1403 sb.setLength(0); 1404 sb.append(" User activity: "); 1405 hasData = true; 1406 } else { 1407 sb.append(", "); 1408 } 1409 sb.append(val); 1410 sb.append(" "); 1411 sb.append(Uid.USER_ACTIVITY_TYPES[i]); 1412 } 1413 } 1414 if (hasData) { 1415 pw.println(sb.toString()); 1416 } 1417 } 1418 1419 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0 1420 || wifiTurnedOnTime != 0) { 1421 sb.setLength(0); 1422 sb.append(prefix); sb.append(" Turned Wifi On: "); 1423 formatTimeMs(sb, wifiTurnedOnTime / 1000); 1424 sb.append("("); sb.append(formatRatioLocked(wifiTurnedOnTime, 1425 whichBatteryRealtime)); sb.append(")\n"); 1426 sb.append(prefix); sb.append(" Full Wifi Lock: "); 1427 formatTimeMs(sb, fullWifiLockOnTime / 1000); 1428 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime, 1429 whichBatteryRealtime)); sb.append(")\n"); 1430 sb.append(prefix); sb.append(" Scan Wifi Lock: "); 1431 formatTimeMs(sb, scanWifiLockOnTime / 1000); 1432 sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime, 1433 whichBatteryRealtime)); sb.append(")"); 1434 pw.println(sb.toString()); 1435 } 1436 1437 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1438 if (wakelocks.size() > 0) { 1439 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1440 : wakelocks.entrySet()) { 1441 Uid.Wakelock wl = ent.getValue(); 1442 String linePrefix = ": "; 1443 sb.setLength(0); 1444 sb.append(prefix); 1445 sb.append(" Wake lock "); 1446 sb.append(ent.getKey()); 1447 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 1448 "full", which, linePrefix); 1449 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 1450 "partial", which, linePrefix); 1451 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 1452 "window", which, linePrefix); 1453 if (!linePrefix.equals(": ")) { 1454 sb.append(" realtime"); 1455 // Only print out wake locks that were held 1456 pw.println(sb.toString()); 1457 uidActivity = true; 1458 } 1459 } 1460 } 1461 1462 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1463 if (sensors.size() > 0) { 1464 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1465 : sensors.entrySet()) { 1466 Uid.Sensor se = ent.getValue(); 1467 int sensorNumber = ent.getKey(); 1468 sb.setLength(0); 1469 sb.append(prefix); 1470 sb.append(" Sensor "); 1471 int handle = se.getHandle(); 1472 if (handle == Uid.Sensor.GPS) { 1473 sb.append("GPS"); 1474 } else { 1475 sb.append(handle); 1476 } 1477 sb.append(": "); 1478 1479 Timer timer = se.getSensorTime(); 1480 if (timer != null) { 1481 // Convert from microseconds to milliseconds with rounding 1482 long totalTime = (timer.getTotalTimeLocked( 1483 batteryRealtime, which) + 500) / 1000; 1484 int count = timer.getCountLocked(which); 1485 //timer.logState(); 1486 if (totalTime != 0) { 1487 formatTimeMs(sb, totalTime); 1488 sb.append("realtime ("); 1489 sb.append(count); 1490 sb.append(" times)"); 1491 } else { 1492 sb.append("(not used)"); 1493 } 1494 } else { 1495 sb.append("(not used)"); 1496 } 1497 1498 pw.println(sb.toString()); 1499 uidActivity = true; 1500 } 1501 } 1502 1503 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 1504 if (processStats.size() > 0) { 1505 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 1506 : processStats.entrySet()) { 1507 Uid.Proc ps = ent.getValue(); 1508 long userTime; 1509 long systemTime; 1510 int starts; 1511 1512 userTime = ps.getUserTime(which); 1513 systemTime = ps.getSystemTime(which); 1514 starts = ps.getStarts(which); 1515 1516 if (userTime != 0 || systemTime != 0 || starts != 0) { 1517 sb.setLength(0); 1518 sb.append(prefix); sb.append(" Proc "); 1519 sb.append(ent.getKey()); sb.append(":\n"); 1520 sb.append(prefix); sb.append(" CPU: "); 1521 formatTime(sb, userTime); sb.append("usr + "); 1522 formatTime(sb, systemTime); sb.append("krn\n"); 1523 sb.append(prefix); sb.append(" "); sb.append(starts); 1524 sb.append(" proc starts"); 1525 pw.println(sb.toString()); 1526 uidActivity = true; 1527 } 1528 } 1529 } 1530 1531 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 1532 if (packageStats.size() > 0) { 1533 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 1534 : packageStats.entrySet()) { 1535 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":"); 1536 boolean apkActivity = false; 1537 Uid.Pkg ps = ent.getValue(); 1538 int wakeups = ps.getWakeups(which); 1539 if (wakeups != 0) { 1540 pw.print(prefix); pw.print(" "); 1541 pw.print(wakeups); pw.println(" wakeup alarms"); 1542 apkActivity = true; 1543 } 1544 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 1545 if (serviceStats.size() > 0) { 1546 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 1547 : serviceStats.entrySet()) { 1548 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 1549 long startTime = ss.getStartTime(batteryUptime, which); 1550 int starts = ss.getStarts(which); 1551 int launches = ss.getLaunches(which); 1552 if (startTime != 0 || starts != 0 || launches != 0) { 1553 sb.setLength(0); 1554 sb.append(prefix); sb.append(" Service "); 1555 sb.append(sent.getKey()); sb.append(":\n"); 1556 sb.append(prefix); sb.append(" Created for: "); 1557 formatTimeMs(sb, startTime / 1000); 1558 sb.append(" uptime\n"); 1559 sb.append(prefix); sb.append(" Starts: "); 1560 sb.append(starts); 1561 sb.append(", launches: "); sb.append(launches); 1562 pw.println(sb.toString()); 1563 apkActivity = true; 1564 } 1565 } 1566 } 1567 if (!apkActivity) { 1568 pw.print(prefix); pw.println(" (nothing executed)"); 1569 } 1570 uidActivity = true; 1571 } 1572 } 1573 if (!uidActivity) { 1574 pw.print(prefix); pw.println(" (nothing executed)"); 1575 } 1576 } 1577 } 1578 1579 void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) { 1580 int diff = oldval ^ newval; 1581 if (diff == 0) return; 1582 for (int i=0; i<descriptions.length; i++) { 1583 BitDescription bd = descriptions[i]; 1584 if ((diff&bd.mask) != 0) { 1585 if (bd.shift < 0) { 1586 pw.print((newval&bd.mask) != 0 ? " +" : " -"); 1587 pw.print(bd.name); 1588 } else { 1589 pw.print(" "); 1590 pw.print(bd.name); 1591 pw.print("="); 1592 int val = (newval&bd.mask)>>bd.shift; 1593 if (bd.values != null && val >= 0 && val < bd.values.length) { 1594 pw.print(bd.values[val]); 1595 } else { 1596 pw.print(val); 1597 } 1598 } 1599 } 1600 } 1601 } 1602 1603 /** 1604 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 1605 * 1606 * @param pw a Printer to receive the dump output. 1607 */ 1608 @SuppressWarnings("unused") 1609 public void dumpLocked(PrintWriter pw) { 1610 HistoryItem rec = getHistory(); 1611 if (rec != null) { 1612 pw.println("Battery History:"); 1613 int oldState = 0; 1614 int oldStatus = -1; 1615 int oldHealth = -1; 1616 int oldPlug = -1; 1617 int oldTemp = -1; 1618 int oldVolt = -1; 1619 while (rec != null) { 1620 pw.print(" "); 1621 pw.print(rec.time); 1622 pw.print(" "); 1623 if (rec.cmd == HistoryItem.CMD_START) { 1624 pw.println(" START"); 1625 } else { 1626 if (rec.batteryLevel < 10) pw.print("00"); 1627 else if (rec.batteryLevel < 100) pw.print("0"); 1628 pw.print(rec.batteryLevel); 1629 pw.print(" "); 1630 if (rec.states < 0x10) pw.print("0000000"); 1631 else if (rec.states < 0x100) pw.print("000000"); 1632 else if (rec.states < 0x1000) pw.print("00000"); 1633 else if (rec.states < 0x10000) pw.print("0000"); 1634 else if (rec.states < 0x100000) pw.print("000"); 1635 else if (rec.states < 0x1000000) pw.print("00"); 1636 else if (rec.states < 0x10000000) pw.print("0"); 1637 pw.print(Integer.toHexString(rec.states)); 1638 if (oldStatus != rec.batteryStatus) { 1639 oldStatus = rec.batteryStatus; 1640 pw.print(" status="); 1641 switch (oldStatus) { 1642 case BatteryManager.BATTERY_STATUS_UNKNOWN: 1643 pw.print("unknown"); 1644 break; 1645 case BatteryManager.BATTERY_STATUS_CHARGING: 1646 pw.print("charging"); 1647 break; 1648 case BatteryManager.BATTERY_STATUS_DISCHARGING: 1649 pw.print("discharging"); 1650 break; 1651 case BatteryManager.BATTERY_STATUS_NOT_CHARGING: 1652 pw.print("not-charging"); 1653 break; 1654 case BatteryManager.BATTERY_STATUS_FULL: 1655 pw.print("full"); 1656 break; 1657 default: 1658 pw.print(oldStatus); 1659 break; 1660 } 1661 } 1662 if (oldHealth != rec.batteryHealth) { 1663 oldHealth = rec.batteryHealth; 1664 pw.print(" health="); 1665 switch (oldHealth) { 1666 case BatteryManager.BATTERY_HEALTH_UNKNOWN: 1667 pw.print("unknown"); 1668 break; 1669 case BatteryManager.BATTERY_HEALTH_GOOD: 1670 pw.print("good"); 1671 break; 1672 case BatteryManager.BATTERY_HEALTH_OVERHEAT: 1673 pw.print("overheat"); 1674 break; 1675 case BatteryManager.BATTERY_HEALTH_DEAD: 1676 pw.print("dead"); 1677 break; 1678 case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: 1679 pw.print("over-voltage"); 1680 break; 1681 case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: 1682 pw.print("failure"); 1683 break; 1684 default: 1685 pw.print(oldHealth); 1686 break; 1687 } 1688 } 1689 if (oldPlug != rec.batteryPlugType) { 1690 oldPlug = rec.batteryPlugType; 1691 pw.print(" plug="); 1692 switch (oldPlug) { 1693 case 0: 1694 pw.print("none"); 1695 break; 1696 case BatteryManager.BATTERY_PLUGGED_AC: 1697 pw.print("ac"); 1698 break; 1699 case BatteryManager.BATTERY_PLUGGED_USB: 1700 pw.print("usb"); 1701 break; 1702 default: 1703 pw.print(oldPlug); 1704 break; 1705 } 1706 } 1707 if (oldTemp != rec.batteryTemperature) { 1708 oldTemp = rec.batteryTemperature; 1709 pw.print(" temp="); 1710 pw.print(oldTemp); 1711 } 1712 if (oldVolt != rec.batteryVoltage) { 1713 oldVolt = rec.batteryVoltage; 1714 pw.print(" volt="); 1715 pw.print(oldVolt); 1716 } 1717 printBitDescriptions(pw, oldState, rec.states, 1718 HISTORY_STATE_DESCRIPTIONS); 1719 pw.println(); 1720 } 1721 oldState = rec.states; 1722 rec = rec.next; 1723 } 1724 } 1725 1726 pw.println("Statistics since last charge:"); 1727 pw.println(" System starts: " + getStartCount() 1728 + ", currently on battery: " + getIsOnBattery()); 1729 dumpLocked(pw, "", STATS_SINCE_CHARGED, -1); 1730 pw.println(""); 1731 pw.println("Statistics since last unplugged:"); 1732 dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, -1); 1733 } 1734 1735 @SuppressWarnings("unused") 1736 public void dumpCheckinLocked(PrintWriter pw, String[] args) { 1737 boolean isUnpluggedOnly = false; 1738 1739 for (String arg : args) { 1740 if ("-u".equals(arg)) { 1741 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data"); 1742 isUnpluggedOnly = true; 1743 } 1744 } 1745 1746 if (isUnpluggedOnly) { 1747 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1); 1748 } 1749 else { 1750 dumpCheckinLocked(pw, STATS_SINCE_CHARGED, -1); 1751 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1); 1752 } 1753 } 1754} 1755