BatteryStats.java revision 3bee5af8162c177f8c8f4199489a401058ab26a9
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 efficiency 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 // Constants from SCREEN_BRIGHTNESS_* 399 public static final int STATE_BRIGHTNESS_MASK = 0x000000f; 400 public static final int STATE_BRIGHTNESS_SHIFT = 0; 401 // Constants from SIGNAL_STRENGTH_* 402 public static final int STATE_SIGNAL_STRENGTH_MASK = 0x00000f0; 403 public static final int STATE_SIGNAL_STRENGTH_SHIFT = 4; 404 // Constants from ServiceState.STATE_* 405 public static final int STATE_PHONE_STATE_MASK = 0x0000f00; 406 public static final int STATE_PHONE_STATE_SHIFT = 8; 407 // Constants from DATA_CONNECTION_* 408 public static final int STATE_DATA_CONNECTION_MASK = 0x000f000; 409 public static final int STATE_DATA_CONNECTION_SHIFT = 12; 410 411 public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<30; 412 public static final int STATE_SCREEN_ON_FLAG = 1<<29; 413 public static final int STATE_GPS_ON_FLAG = 1<<28; 414 public static final int STATE_PHONE_IN_CALL_FLAG = 1<<27; 415 public static final int STATE_PHONE_SCANNING_FLAG = 1<<26; 416 public static final int STATE_WIFI_ON_FLAG = 1<<25; 417 public static final int STATE_WIFI_RUNNING_FLAG = 1<<24; 418 public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<23; 419 public static final int STATE_WIFI_SCAN_LOCK_FLAG = 1<<22; 420 public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<21; 421 public static final int STATE_BLUETOOTH_ON_FLAG = 1<<20; 422 public static final int STATE_AUDIO_ON_FLAG = 1<<19; 423 public static final int STATE_VIDEO_ON_FLAG = 1<<18; 424 425 public int states; 426 427 public HistoryItem() { 428 } 429 430 public HistoryItem(long time, Parcel src) { 431 this.time = time; 432 int bat = src.readInt(); 433 cmd = (byte)(bat&0xff); 434 batteryLevel = (byte)((bat>>8)&0xff); 435 batteryStatus = (byte)((bat>>16)&0xf); 436 batteryHealth = (byte)((bat>>20)&0xf); 437 batteryPlugType = (byte)((bat>>24)&0xf); 438 bat = src.readInt(); 439 batteryTemperature = (char)(bat&0xffff); 440 batteryVoltage = (char)((bat>>16)&0xffff); 441 states = src.readInt(); 442 } 443 444 public int describeContents() { 445 return 0; 446 } 447 448 public void writeToParcel(Parcel dest, int flags) { 449 dest.writeLong(time); 450 int bat = (((int)cmd)&0xff) 451 | ((((int)batteryLevel)<<8)&0xff00) 452 | ((((int)batteryStatus)<<16)&0xf0000) 453 | ((((int)batteryHealth)<<20)&0xf00000) 454 | ((((int)batteryPlugType)<<24)&0xf000000); 455 dest.writeInt(bat); 456 bat = (((int)batteryTemperature)&0xffff) 457 | ((((int)batteryVoltage)<<16)&0xffff0000); 458 dest.writeInt(bat); 459 dest.writeInt(states); 460 } 461 462 public void setTo(long time, byte cmd, HistoryItem o) { 463 this.time = time; 464 this.cmd = cmd; 465 batteryLevel = o.batteryLevel; 466 batteryStatus = o.batteryStatus; 467 batteryHealth = o.batteryHealth; 468 batteryPlugType = o.batteryPlugType; 469 batteryTemperature = o.batteryTemperature; 470 batteryVoltage = o.batteryVoltage; 471 states = o.states; 472 } 473 } 474 475 public static final class BitDescription { 476 public final int mask; 477 public final int shift; 478 public final String name; 479 public final String[] values; 480 481 public BitDescription(int mask, String name) { 482 this.mask = mask; 483 this.shift = -1; 484 this.name = name; 485 this.values = null; 486 } 487 488 public BitDescription(int mask, int shift, String name, String[] values) { 489 this.mask = mask; 490 this.shift = shift; 491 this.name = name; 492 this.values = values; 493 } 494 } 495 496 /** 497 * Return the current history of battery state changes. 498 */ 499 public abstract HistoryItem getHistory(); 500 501 /** 502 * Returns the number of times the device has been started. 503 */ 504 public abstract int getStartCount(); 505 506 /** 507 * Returns the time in microseconds that the screen has been on while the device was 508 * running on battery. 509 * 510 * {@hide} 511 */ 512 public abstract long getScreenOnTime(long batteryRealtime, int which); 513 514 public static final int SCREEN_BRIGHTNESS_DARK = 0; 515 public static final int SCREEN_BRIGHTNESS_DIM = 1; 516 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2; 517 public static final int SCREEN_BRIGHTNESS_LIGHT = 3; 518 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4; 519 520 static final String[] SCREEN_BRIGHTNESS_NAMES = { 521 "dark", "dim", "medium", "light", "bright" 522 }; 523 524 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5; 525 526 /** 527 * Returns the time in microseconds that the screen has been on with 528 * the given brightness 529 * 530 * {@hide} 531 */ 532 public abstract long getScreenBrightnessTime(int brightnessBin, 533 long batteryRealtime, int which); 534 535 public abstract int getInputEventCount(int which); 536 537 /** 538 * Returns the time in microseconds that the phone has been on while the device was 539 * running on battery. 540 * 541 * {@hide} 542 */ 543 public abstract long getPhoneOnTime(long batteryRealtime, int which); 544 545 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; 546 public static final int SIGNAL_STRENGTH_POOR = 1; 547 public static final int SIGNAL_STRENGTH_MODERATE = 2; 548 public static final int SIGNAL_STRENGTH_GOOD = 3; 549 public static final int SIGNAL_STRENGTH_GREAT = 4; 550 551 static final String[] SIGNAL_STRENGTH_NAMES = { 552 "none", "poor", "moderate", "good", "great" 553 }; 554 555 public static final int NUM_SIGNAL_STRENGTH_BINS = 5; 556 557 /** 558 * Returns the time in microseconds that the phone has been running with 559 * the given signal strength. 560 * 561 * {@hide} 562 */ 563 public abstract long getPhoneSignalStrengthTime(int strengthBin, 564 long batteryRealtime, int which); 565 566 /** 567 * Returns the time in microseconds that the phone has been trying to 568 * acquire a signal. 569 * 570 * {@hide} 571 */ 572 public abstract long getPhoneSignalScanningTime( 573 long batteryRealtime, int which); 574 575 /** 576 * Returns the number of times the phone has entered the given signal strength. 577 * 578 * {@hide} 579 */ 580 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which); 581 582 public static final int DATA_CONNECTION_NONE = 0; 583 public static final int DATA_CONNECTION_GPRS = 1; 584 public static final int DATA_CONNECTION_EDGE = 2; 585 public static final int DATA_CONNECTION_UMTS = 3; 586 public static final int DATA_CONNECTION_CDMA = 4; 587 public static final int DATA_CONNECTION_EVDO_0 = 5; 588 public static final int DATA_CONNECTION_EVDO_A = 6; 589 public static final int DATA_CONNECTION_1xRTT = 7; 590 public static final int DATA_CONNECTION_HSDPA = 8; 591 public static final int DATA_CONNECTION_HSUPA = 9; 592 public static final int DATA_CONNECTION_HSPA = 10; 593 public static final int DATA_CONNECTION_IDEN = 11; 594 public static final int DATA_CONNECTION_EVDO_B = 12; 595 public static final int DATA_CONNECTION_OTHER = 13; 596 597 static final String[] DATA_CONNECTION_NAMES = { 598 "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A", 599 "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "other" 600 }; 601 602 public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1; 603 604 /** 605 * Returns the time in microseconds that the phone has been running with 606 * the given data connection. 607 * 608 * {@hide} 609 */ 610 public abstract long getPhoneDataConnectionTime(int dataType, 611 long batteryRealtime, int which); 612 613 /** 614 * Returns the number of times the phone has entered the given data 615 * connection type. 616 * 617 * {@hide} 618 */ 619 public abstract int getPhoneDataConnectionCount(int dataType, int which); 620 621 public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS 622 = new BitDescription[] { 623 new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged"), 624 new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen"), 625 new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps"), 626 new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call"), 627 new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning"), 628 new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi"), 629 new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running"), 630 new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock"), 631 new BitDescription(HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG, "wifi_scan_lock"), 632 new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast"), 633 new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth"), 634 new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio"), 635 new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video"), 636 new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK, 637 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", 638 SCREEN_BRIGHTNESS_NAMES), 639 new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK, 640 HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength", 641 SIGNAL_STRENGTH_NAMES), 642 new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK, 643 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", 644 new String[] {"in", "out", "emergency", "off"}), 645 new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK, 646 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", 647 DATA_CONNECTION_NAMES), 648 }; 649 650 /** 651 * Returns the time in microseconds that wifi has been on while the device was 652 * running on battery. 653 * 654 * {@hide} 655 */ 656 public abstract long getWifiOnTime(long batteryRealtime, int which); 657 658 /** 659 * Returns the time in microseconds that wifi has been on and the driver has 660 * been in the running state while the device was running on battery. 661 * 662 * {@hide} 663 */ 664 public abstract long getWifiRunningTime(long batteryRealtime, int which); 665 666 /** 667 * Returns the time in microseconds that bluetooth has been on while the device was 668 * running on battery. 669 * 670 * {@hide} 671 */ 672 public abstract long getBluetoothOnTime(long batteryRealtime, int which); 673 674 /** 675 * Return whether we are currently running on battery. 676 */ 677 public abstract boolean getIsOnBattery(); 678 679 /** 680 * Returns a SparseArray containing the statistics for each uid. 681 */ 682 public abstract SparseArray<? extends Uid> getUidStats(); 683 684 /** 685 * Returns the current battery uptime in microseconds. 686 * 687 * @param curTime the amount of elapsed realtime in microseconds. 688 */ 689 public abstract long getBatteryUptime(long curTime); 690 691 /** 692 * @deprecated use getRadioDataUptime 693 */ 694 public long getRadioDataUptimeMs() { 695 return getRadioDataUptime() / 1000; 696 } 697 698 /** 699 * Returns the time that the radio was on for data transfers. 700 * @return the uptime in microseconds while unplugged 701 */ 702 public abstract long getRadioDataUptime(); 703 704 /** 705 * Returns the current battery realtime in microseconds. 706 * 707 * @param curTime the amount of elapsed realtime in microseconds. 708 */ 709 public abstract long getBatteryRealtime(long curTime); 710 711 /** 712 * Returns the battery percentage level at the last time the device was unplugged from power, or 713 * the last time it booted on battery power. 714 */ 715 public abstract int getDischargeStartLevel(); 716 717 /** 718 * Returns the current battery percentage level if we are in a discharge cycle, otherwise 719 * returns the level at the last plug event. 720 */ 721 public abstract int getDischargeCurrentLevel(); 722 723 /** 724 * Get the amount the battery has discharged since the stats were 725 * last reset after charging, as a lower-end approximation. 726 */ 727 public abstract int getLowDischargeAmountSinceCharge(); 728 729 /** 730 * Get the amount the battery has discharged since the stats were 731 * last reset after charging, as an upper-end approximation. 732 */ 733 public abstract int getHighDischargeAmountSinceCharge(); 734 735 /** 736 * Returns the total, last, or current battery uptime in microseconds. 737 * 738 * @param curTime the elapsed realtime in microseconds. 739 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 740 */ 741 public abstract long computeBatteryUptime(long curTime, int which); 742 743 /** 744 * Returns the total, last, or current battery 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 computeBatteryRealtime(long curTime, int which); 750 751 /** 752 * Returns the total, last, or current uptime in microseconds. 753 * 754 * @param curTime the current elapsed realtime in microseconds. 755 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 756 */ 757 public abstract long computeUptime(long curTime, int which); 758 759 /** 760 * Returns the total, last, or current realtime in microseconds. 761 * * 762 * @param curTime the current elapsed realtime in microseconds. 763 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 764 */ 765 public abstract long computeRealtime(long curTime, int which); 766 767 public abstract Map<String, ? extends Timer> getKernelWakelockStats(); 768 769 /** Returns the number of different speeds that the CPU can run at */ 770 public abstract int getCpuSpeedSteps(); 771 772 private final static void formatTimeRaw(StringBuilder out, long seconds) { 773 long days = seconds / (60 * 60 * 24); 774 if (days != 0) { 775 out.append(days); 776 out.append("d "); 777 } 778 long used = days * 60 * 60 * 24; 779 780 long hours = (seconds - used) / (60 * 60); 781 if (hours != 0 || used != 0) { 782 out.append(hours); 783 out.append("h "); 784 } 785 used += hours * 60 * 60; 786 787 long mins = (seconds-used) / 60; 788 if (mins != 0 || used != 0) { 789 out.append(mins); 790 out.append("m "); 791 } 792 used += mins * 60; 793 794 if (seconds != 0 || used != 0) { 795 out.append(seconds-used); 796 out.append("s "); 797 } 798 } 799 800 private final static void formatTime(StringBuilder sb, long time) { 801 long sec = time / 100; 802 formatTimeRaw(sb, sec); 803 sb.append((time - (sec * 100)) * 10); 804 sb.append("ms "); 805 } 806 807 private final static void formatTimeMs(StringBuilder sb, long time) { 808 long sec = time / 1000; 809 formatTimeRaw(sb, sec); 810 sb.append(time - (sec * 1000)); 811 sb.append("ms "); 812 } 813 814 private final String formatRatioLocked(long num, long den) { 815 if (den == 0L) { 816 return "---%"; 817 } 818 float perc = ((float)num) / ((float)den) * 100; 819 mFormatBuilder.setLength(0); 820 mFormatter.format("%.1f%%", perc); 821 return mFormatBuilder.toString(); 822 } 823 824 private final String formatBytesLocked(long bytes) { 825 mFormatBuilder.setLength(0); 826 827 if (bytes < BYTES_PER_KB) { 828 return bytes + "B"; 829 } else if (bytes < BYTES_PER_MB) { 830 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB); 831 return mFormatBuilder.toString(); 832 } else if (bytes < BYTES_PER_GB){ 833 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB); 834 return mFormatBuilder.toString(); 835 } else { 836 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB); 837 return mFormatBuilder.toString(); 838 } 839 } 840 841 /** 842 * 843 * @param sb a StringBuilder object. 844 * @param timer a Timer object contining the wakelock times. 845 * @param batteryRealtime the current on-battery time in microseconds. 846 * @param name the name of the wakelock. 847 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 848 * @param linePrefix a String to be prepended to each line of output. 849 * @return the line prefix 850 */ 851 private static final String printWakeLock(StringBuilder sb, Timer timer, 852 long batteryRealtime, String name, int which, String linePrefix) { 853 854 if (timer != null) { 855 // Convert from microseconds to milliseconds with rounding 856 long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which); 857 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 858 859 int count = timer.getCountLocked(which); 860 if (totalTimeMillis != 0) { 861 sb.append(linePrefix); 862 formatTimeMs(sb, totalTimeMillis); 863 if (name != null) sb.append(name); 864 sb.append(' '); 865 sb.append('('); 866 sb.append(count); 867 sb.append(" times)"); 868 return ", "; 869 } 870 } 871 return linePrefix; 872 } 873 874 /** 875 * Checkin version of wakelock printer. Prints simple comma-separated list. 876 * 877 * @param sb a StringBuilder object. 878 * @param timer a Timer object contining the wakelock times. 879 * @param now the current time in microseconds. 880 * @param name the name of the wakelock. 881 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 882 * @param linePrefix a String to be prepended to each line of output. 883 * @return the line prefix 884 */ 885 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now, 886 String name, int which, String linePrefix) { 887 long totalTimeMicros = 0; 888 int count = 0; 889 if (timer != null) { 890 totalTimeMicros = timer.getTotalTimeLocked(now, which); 891 count = timer.getCountLocked(which); 892 } 893 sb.append(linePrefix); 894 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 895 sb.append(','); 896 sb.append(name != null ? name + "," : ""); 897 sb.append(count); 898 return ","; 899 } 900 901 /** 902 * Dump a comma-separated line of values for terse checkin mode. 903 * 904 * @param pw the PageWriter to dump log to 905 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 906 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 907 * @param args type-dependent data arguments 908 */ 909 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 910 Object... args ) { 911 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 912 pw.print(uid); pw.print(','); 913 pw.print(category); pw.print(','); 914 pw.print(type); 915 916 for (Object arg : args) { 917 pw.print(','); 918 pw.print(arg); 919 } 920 pw.print('\n'); 921 } 922 923 /** 924 * Checkin server version of dump to produce more compact, computer-readable log. 925 * 926 * NOTE: all times are expressed in 'ms'. 927 */ 928 public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) { 929 final long rawUptime = SystemClock.uptimeMillis() * 1000; 930 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 931 final long batteryUptime = getBatteryUptime(rawUptime); 932 final long batteryRealtime = getBatteryRealtime(rawRealtime); 933 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 934 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 935 final long totalRealtime = computeRealtime(rawRealtime, which); 936 final long totalUptime = computeUptime(rawUptime, which); 937 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 938 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 939 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 940 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 941 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 942 943 StringBuilder sb = new StringBuilder(128); 944 945 SparseArray<? extends Uid> uidStats = getUidStats(); 946 final int NU = uidStats.size(); 947 948 String category = STAT_NAMES[which]; 949 950 // Dump "battery" stat 951 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 952 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A", 953 whichBatteryRealtime / 1000, whichBatteryUptime / 1000, 954 totalRealtime / 1000, totalUptime / 1000); 955 956 // Calculate total network and wakelock times across all uids. 957 long rxTotal = 0; 958 long txTotal = 0; 959 long fullWakeLockTimeTotal = 0; 960 long partialWakeLockTimeTotal = 0; 961 962 for (int iu = 0; iu < NU; iu++) { 963 Uid u = uidStats.valueAt(iu); 964 rxTotal += u.getTcpBytesReceived(which); 965 txTotal += u.getTcpBytesSent(which); 966 967 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 968 if (wakelocks.size() > 0) { 969 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 970 : wakelocks.entrySet()) { 971 Uid.Wakelock wl = ent.getValue(); 972 973 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 974 if (fullWakeTimer != null) { 975 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which); 976 } 977 978 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 979 if (partialWakeTimer != null) { 980 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked( 981 batteryRealtime, which); 982 } 983 } 984 } 985 } 986 987 // Dump misc stats 988 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 989 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, 990 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal, 991 fullWakeLockTimeTotal, partialWakeLockTimeTotal, 992 getInputEventCount(which)); 993 994 // Dump screen brightness stats 995 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; 996 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 997 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000; 998 } 999 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args); 1000 1001 // Dump signal strength stats 1002 args = new Object[NUM_SIGNAL_STRENGTH_BINS]; 1003 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 1004 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000; 1005 } 1006 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args); 1007 dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA, 1008 getPhoneSignalScanningTime(batteryRealtime, which) / 1000); 1009 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 1010 args[i] = getPhoneSignalStrengthCount(i, which); 1011 } 1012 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args); 1013 1014 // Dump network type stats 1015 args = new Object[NUM_DATA_CONNECTION_TYPES]; 1016 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1017 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000; 1018 } 1019 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args); 1020 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1021 args[i] = getPhoneDataConnectionCount(i, which); 1022 } 1023 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args); 1024 1025 if (which == STATS_SINCE_UNPLUGGED) { 1026 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), 1027 getDischargeCurrentLevel()); 1028 } 1029 1030 if (reqUid < 0) { 1031 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); 1032 if (kernelWakelocks.size() > 0) { 1033 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { 1034 sb.setLength(0); 1035 printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, ""); 1036 1037 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(), 1038 sb.toString()); 1039 } 1040 } 1041 } 1042 1043 for (int iu = 0; iu < NU; iu++) { 1044 final int uid = uidStats.keyAt(iu); 1045 if (reqUid >= 0 && uid != reqUid) { 1046 continue; 1047 } 1048 Uid u = uidStats.valueAt(iu); 1049 // Dump Network stats per uid, if any 1050 long rx = u.getTcpBytesReceived(which); 1051 long tx = u.getTcpBytesSent(which); 1052 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 1053 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 1054 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which); 1055 1056 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx); 1057 1058 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0 1059 || wifiTurnedOnTime != 0) { 1060 dumpLine(pw, uid, category, WIFI_LOCK_DATA, 1061 fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime); 1062 } 1063 1064 if (u.hasUserActivity()) { 1065 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES]; 1066 boolean hasData = false; 1067 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 1068 int val = u.getUserActivityCount(i, which); 1069 args[i] = val; 1070 if (val != 0) hasData = true; 1071 } 1072 if (hasData) { 1073 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args); 1074 } 1075 } 1076 1077 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1078 if (wakelocks.size() > 0) { 1079 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1080 : wakelocks.entrySet()) { 1081 Uid.Wakelock wl = ent.getValue(); 1082 String linePrefix = ""; 1083 sb.setLength(0); 1084 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), 1085 batteryRealtime, "f", which, linePrefix); 1086 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), 1087 batteryRealtime, "p", which, linePrefix); 1088 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), 1089 batteryRealtime, "w", which, linePrefix); 1090 1091 // Only log if we had at lease one wakelock... 1092 if (sb.length() > 0) { 1093 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString()); 1094 } 1095 } 1096 } 1097 1098 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1099 if (sensors.size() > 0) { 1100 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1101 : sensors.entrySet()) { 1102 Uid.Sensor se = ent.getValue(); 1103 int sensorNumber = ent.getKey(); 1104 Timer timer = se.getSensorTime(); 1105 if (timer != null) { 1106 // Convert from microseconds to milliseconds with rounding 1107 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; 1108 int count = timer.getCountLocked(which); 1109 if (totalTime != 0) { 1110 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 1111 } 1112 } 1113 } 1114 } 1115 1116 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 1117 if (processStats.size() > 0) { 1118 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 1119 : processStats.entrySet()) { 1120 Uid.Proc ps = ent.getValue(); 1121 1122 long userTime = ps.getUserTime(which); 1123 long systemTime = ps.getSystemTime(which); 1124 int starts = ps.getStarts(which); 1125 1126 if (userTime != 0 || systemTime != 0 || starts != 0) { 1127 dumpLine(pw, uid, category, PROCESS_DATA, 1128 ent.getKey(), // proc 1129 userTime * 10, // cpu time in ms 1130 systemTime * 10, // user time in ms 1131 starts); // process starts 1132 } 1133 } 1134 } 1135 1136 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 1137 if (packageStats.size() > 0) { 1138 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 1139 : packageStats.entrySet()) { 1140 1141 Uid.Pkg ps = ent.getValue(); 1142 int wakeups = ps.getWakeups(which); 1143 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 1144 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 1145 : serviceStats.entrySet()) { 1146 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 1147 long startTime = ss.getStartTime(batteryUptime, which); 1148 int starts = ss.getStarts(which); 1149 int launches = ss.getLaunches(which); 1150 if (startTime != 0 || starts != 0 || launches != 0) { 1151 dumpLine(pw, uid, category, APK_DATA, 1152 wakeups, // wakeup alarms 1153 ent.getKey(), // Apk 1154 sent.getKey(), // service 1155 startTime / 1000, // time spent started, in ms 1156 starts, 1157 launches); 1158 } 1159 } 1160 } 1161 } 1162 } 1163 } 1164 1165 @SuppressWarnings("unused") 1166 public final void dumpLocked(PrintWriter pw, String prefix, int which, int reqUid) { 1167 final long rawUptime = SystemClock.uptimeMillis() * 1000; 1168 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 1169 final long batteryUptime = getBatteryUptime(rawUptime); 1170 final long batteryRealtime = getBatteryRealtime(rawRealtime); 1171 1172 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 1173 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 1174 final long totalRealtime = computeRealtime(rawRealtime, which); 1175 final long totalUptime = computeUptime(rawUptime, which); 1176 1177 StringBuilder sb = new StringBuilder(128); 1178 1179 SparseArray<? extends Uid> uidStats = getUidStats(); 1180 final int NU = uidStats.size(); 1181 1182 sb.setLength(0); 1183 sb.append(prefix); 1184 sb.append(" Time on battery: "); 1185 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("("); 1186 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime)); 1187 sb.append(") realtime, "); 1188 formatTimeMs(sb, whichBatteryUptime / 1000); 1189 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime)); 1190 sb.append(") uptime"); 1191 pw.println(sb.toString()); 1192 sb.setLength(0); 1193 sb.append(prefix); 1194 sb.append(" Total run time: "); 1195 formatTimeMs(sb, totalRealtime / 1000); 1196 sb.append("realtime, "); 1197 formatTimeMs(sb, totalUptime / 1000); 1198 sb.append("uptime, "); 1199 pw.println(sb.toString()); 1200 1201 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 1202 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 1203 final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which); 1204 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 1205 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 1206 sb.setLength(0); 1207 sb.append(prefix); 1208 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000); 1209 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime)); 1210 sb.append("), Input events: "); sb.append(getInputEventCount(which)); 1211 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000); 1212 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime)); 1213 sb.append(")"); 1214 pw.println(sb.toString()); 1215 sb.setLength(0); 1216 sb.append(prefix); 1217 sb.append(" Screen brightnesses: "); 1218 boolean didOne = false; 1219 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1220 final long time = getScreenBrightnessTime(i, batteryRealtime, which); 1221 if (time == 0) { 1222 continue; 1223 } 1224 if (didOne) sb.append(", "); 1225 didOne = true; 1226 sb.append(SCREEN_BRIGHTNESS_NAMES[i]); 1227 sb.append(" "); 1228 formatTimeMs(sb, time/1000); 1229 sb.append("("); 1230 sb.append(formatRatioLocked(time, screenOnTime)); 1231 sb.append(")"); 1232 } 1233 if (!didOne) sb.append("No activity"); 1234 pw.println(sb.toString()); 1235 1236 // Calculate total network and wakelock times across all uids. 1237 long rxTotal = 0; 1238 long txTotal = 0; 1239 long fullWakeLockTimeTotalMicros = 0; 1240 long partialWakeLockTimeTotalMicros = 0; 1241 1242 if (reqUid < 0) { 1243 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); 1244 if (kernelWakelocks.size() > 0) { 1245 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { 1246 1247 String linePrefix = ": "; 1248 sb.setLength(0); 1249 sb.append(prefix); 1250 sb.append(" Kernel Wake lock "); 1251 sb.append(ent.getKey()); 1252 linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which, 1253 linePrefix); 1254 if (!linePrefix.equals(": ")) { 1255 sb.append(" realtime"); 1256 // Only print out wake locks that were held 1257 pw.println(sb.toString()); 1258 } 1259 } 1260 } 1261 } 1262 1263 for (int iu = 0; iu < NU; iu++) { 1264 Uid u = uidStats.valueAt(iu); 1265 rxTotal += u.getTcpBytesReceived(which); 1266 txTotal += u.getTcpBytesSent(which); 1267 1268 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1269 if (wakelocks.size() > 0) { 1270 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1271 : wakelocks.entrySet()) { 1272 Uid.Wakelock wl = ent.getValue(); 1273 1274 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 1275 if (fullWakeTimer != null) { 1276 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked( 1277 batteryRealtime, which); 1278 } 1279 1280 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 1281 if (partialWakeTimer != null) { 1282 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked( 1283 batteryRealtime, which); 1284 } 1285 } 1286 } 1287 } 1288 1289 pw.print(prefix); 1290 pw.print(" Total received: "); pw.print(formatBytesLocked(rxTotal)); 1291 pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal)); 1292 sb.setLength(0); 1293 sb.append(prefix); 1294 sb.append(" Total full wakelock time: "); formatTimeMs(sb, 1295 (fullWakeLockTimeTotalMicros + 500) / 1000); 1296 sb.append(", Total partial waklock time: "); formatTimeMs(sb, 1297 (partialWakeLockTimeTotalMicros + 500) / 1000); 1298 pw.println(sb.toString()); 1299 1300 sb.setLength(0); 1301 sb.append(prefix); 1302 sb.append(" Signal levels: "); 1303 didOne = false; 1304 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 1305 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which); 1306 if (time == 0) { 1307 continue; 1308 } 1309 if (didOne) sb.append(", "); 1310 didOne = true; 1311 sb.append(SIGNAL_STRENGTH_NAMES[i]); 1312 sb.append(" "); 1313 formatTimeMs(sb, time/1000); 1314 sb.append("("); 1315 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1316 sb.append(") "); 1317 sb.append(getPhoneSignalStrengthCount(i, which)); 1318 sb.append("x"); 1319 } 1320 if (!didOne) sb.append("No activity"); 1321 pw.println(sb.toString()); 1322 1323 sb.setLength(0); 1324 sb.append(prefix); 1325 sb.append(" Signal scanning time: "); 1326 formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000); 1327 pw.println(sb.toString()); 1328 1329 sb.setLength(0); 1330 sb.append(prefix); 1331 sb.append(" Radio types: "); 1332 didOne = false; 1333 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1334 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which); 1335 if (time == 0) { 1336 continue; 1337 } 1338 if (didOne) sb.append(", "); 1339 didOne = true; 1340 sb.append(DATA_CONNECTION_NAMES[i]); 1341 sb.append(" "); 1342 formatTimeMs(sb, time/1000); 1343 sb.append("("); 1344 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1345 sb.append(") "); 1346 sb.append(getPhoneDataConnectionCount(i, which)); 1347 sb.append("x"); 1348 } 1349 if (!didOne) sb.append("No activity"); 1350 pw.println(sb.toString()); 1351 1352 sb.setLength(0); 1353 sb.append(prefix); 1354 sb.append(" Radio data uptime when unplugged: "); 1355 sb.append(getRadioDataUptime() / 1000); 1356 sb.append(" ms"); 1357 pw.println(sb.toString()); 1358 1359 sb.setLength(0); 1360 sb.append(prefix); 1361 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000); 1362 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime)); 1363 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000); 1364 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime)); 1365 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000); 1366 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)); 1367 sb.append(")"); 1368 pw.println(sb.toString()); 1369 1370 pw.println(" "); 1371 1372 if (which == STATS_SINCE_UNPLUGGED) { 1373 if (getIsOnBattery()) { 1374 pw.print(prefix); pw.println(" Device is currently unplugged"); 1375 pw.print(prefix); pw.print(" Discharge cycle start level: "); 1376 pw.println(getDischargeStartLevel()); 1377 pw.print(prefix); pw.print(" Discharge cycle current level: "); 1378 pw.println(getDischargeCurrentLevel()); 1379 } else { 1380 pw.print(prefix); pw.println(" Device is currently plugged into power"); 1381 pw.print(prefix); pw.print(" Last discharge cycle start level: "); 1382 pw.println(getDischargeStartLevel()); 1383 pw.print(prefix); pw.print(" Last discharge cycle end level: "); 1384 pw.println(getDischargeCurrentLevel()); 1385 } 1386 pw.println(" "); 1387 } 1388 1389 1390 for (int iu=0; iu<NU; iu++) { 1391 final int uid = uidStats.keyAt(iu); 1392 if (reqUid >= 0 && uid != reqUid) { 1393 continue; 1394 } 1395 1396 Uid u = uidStats.valueAt(iu); 1397 1398 pw.println(prefix + " #" + uid + ":"); 1399 boolean uidActivity = false; 1400 1401 long tcpReceived = u.getTcpBytesReceived(which); 1402 long tcpSent = u.getTcpBytesSent(which); 1403 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 1404 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which); 1405 long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which); 1406 1407 if (tcpReceived != 0 || tcpSent != 0) { 1408 pw.print(prefix); pw.print(" Network: "); 1409 pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, "); 1410 pw.print(formatBytesLocked(tcpSent)); pw.println(" sent"); 1411 } 1412 1413 if (u.hasUserActivity()) { 1414 boolean hasData = false; 1415 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1416 int val = u.getUserActivityCount(i, which); 1417 if (val != 0) { 1418 if (!hasData) { 1419 sb.setLength(0); 1420 sb.append(" User activity: "); 1421 hasData = true; 1422 } else { 1423 sb.append(", "); 1424 } 1425 sb.append(val); 1426 sb.append(" "); 1427 sb.append(Uid.USER_ACTIVITY_TYPES[i]); 1428 } 1429 } 1430 if (hasData) { 1431 pw.println(sb.toString()); 1432 } 1433 } 1434 1435 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0 1436 || wifiTurnedOnTime != 0) { 1437 sb.setLength(0); 1438 sb.append(prefix); sb.append(" Turned Wifi On: "); 1439 formatTimeMs(sb, wifiTurnedOnTime / 1000); 1440 sb.append("("); sb.append(formatRatioLocked(wifiTurnedOnTime, 1441 whichBatteryRealtime)); sb.append(")\n"); 1442 sb.append(prefix); sb.append(" Full Wifi Lock: "); 1443 formatTimeMs(sb, fullWifiLockOnTime / 1000); 1444 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime, 1445 whichBatteryRealtime)); sb.append(")\n"); 1446 sb.append(prefix); sb.append(" Scan Wifi Lock: "); 1447 formatTimeMs(sb, scanWifiLockOnTime / 1000); 1448 sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime, 1449 whichBatteryRealtime)); sb.append(")"); 1450 pw.println(sb.toString()); 1451 } 1452 1453 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1454 if (wakelocks.size() > 0) { 1455 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1456 : wakelocks.entrySet()) { 1457 Uid.Wakelock wl = ent.getValue(); 1458 String linePrefix = ": "; 1459 sb.setLength(0); 1460 sb.append(prefix); 1461 sb.append(" Wake lock "); 1462 sb.append(ent.getKey()); 1463 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 1464 "full", which, linePrefix); 1465 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 1466 "partial", which, linePrefix); 1467 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 1468 "window", which, linePrefix); 1469 if (!linePrefix.equals(": ")) { 1470 sb.append(" realtime"); 1471 // Only print out wake locks that were held 1472 pw.println(sb.toString()); 1473 uidActivity = true; 1474 } 1475 } 1476 } 1477 1478 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1479 if (sensors.size() > 0) { 1480 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1481 : sensors.entrySet()) { 1482 Uid.Sensor se = ent.getValue(); 1483 int sensorNumber = ent.getKey(); 1484 sb.setLength(0); 1485 sb.append(prefix); 1486 sb.append(" Sensor "); 1487 int handle = se.getHandle(); 1488 if (handle == Uid.Sensor.GPS) { 1489 sb.append("GPS"); 1490 } else { 1491 sb.append(handle); 1492 } 1493 sb.append(": "); 1494 1495 Timer timer = se.getSensorTime(); 1496 if (timer != null) { 1497 // Convert from microseconds to milliseconds with rounding 1498 long totalTime = (timer.getTotalTimeLocked( 1499 batteryRealtime, which) + 500) / 1000; 1500 int count = timer.getCountLocked(which); 1501 //timer.logState(); 1502 if (totalTime != 0) { 1503 formatTimeMs(sb, totalTime); 1504 sb.append("realtime ("); 1505 sb.append(count); 1506 sb.append(" times)"); 1507 } else { 1508 sb.append("(not used)"); 1509 } 1510 } else { 1511 sb.append("(not used)"); 1512 } 1513 1514 pw.println(sb.toString()); 1515 uidActivity = true; 1516 } 1517 } 1518 1519 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 1520 if (processStats.size() > 0) { 1521 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 1522 : processStats.entrySet()) { 1523 Uid.Proc ps = ent.getValue(); 1524 long userTime; 1525 long systemTime; 1526 int starts; 1527 1528 userTime = ps.getUserTime(which); 1529 systemTime = ps.getSystemTime(which); 1530 starts = ps.getStarts(which); 1531 1532 if (userTime != 0 || systemTime != 0 || starts != 0) { 1533 sb.setLength(0); 1534 sb.append(prefix); sb.append(" Proc "); 1535 sb.append(ent.getKey()); sb.append(":\n"); 1536 sb.append(prefix); sb.append(" CPU: "); 1537 formatTime(sb, userTime); sb.append("usr + "); 1538 formatTime(sb, systemTime); sb.append("krn\n"); 1539 sb.append(prefix); sb.append(" "); sb.append(starts); 1540 sb.append(" proc starts"); 1541 pw.println(sb.toString()); 1542 uidActivity = true; 1543 } 1544 } 1545 } 1546 1547 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 1548 if (packageStats.size() > 0) { 1549 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 1550 : packageStats.entrySet()) { 1551 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":"); 1552 boolean apkActivity = false; 1553 Uid.Pkg ps = ent.getValue(); 1554 int wakeups = ps.getWakeups(which); 1555 if (wakeups != 0) { 1556 pw.print(prefix); pw.print(" "); 1557 pw.print(wakeups); pw.println(" wakeup alarms"); 1558 apkActivity = true; 1559 } 1560 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 1561 if (serviceStats.size() > 0) { 1562 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 1563 : serviceStats.entrySet()) { 1564 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 1565 long startTime = ss.getStartTime(batteryUptime, which); 1566 int starts = ss.getStarts(which); 1567 int launches = ss.getLaunches(which); 1568 if (startTime != 0 || starts != 0 || launches != 0) { 1569 sb.setLength(0); 1570 sb.append(prefix); sb.append(" Service "); 1571 sb.append(sent.getKey()); sb.append(":\n"); 1572 sb.append(prefix); sb.append(" Created for: "); 1573 formatTimeMs(sb, startTime / 1000); 1574 sb.append(" uptime\n"); 1575 sb.append(prefix); sb.append(" Starts: "); 1576 sb.append(starts); 1577 sb.append(", launches: "); sb.append(launches); 1578 pw.println(sb.toString()); 1579 apkActivity = true; 1580 } 1581 } 1582 } 1583 if (!apkActivity) { 1584 pw.print(prefix); pw.println(" (nothing executed)"); 1585 } 1586 uidActivity = true; 1587 } 1588 } 1589 if (!uidActivity) { 1590 pw.print(prefix); pw.println(" (nothing executed)"); 1591 } 1592 } 1593 } 1594 1595 void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) { 1596 int diff = oldval ^ newval; 1597 if (diff == 0) return; 1598 for (int i=0; i<descriptions.length; i++) { 1599 BitDescription bd = descriptions[i]; 1600 if ((diff&bd.mask) != 0) { 1601 if (bd.shift < 0) { 1602 pw.print((newval&bd.mask) != 0 ? " +" : " -"); 1603 pw.print(bd.name); 1604 } else { 1605 pw.print(" "); 1606 pw.print(bd.name); 1607 pw.print("="); 1608 int val = (newval&bd.mask)>>bd.shift; 1609 if (bd.values != null && val >= 0 && val < bd.values.length) { 1610 pw.print(bd.values[val]); 1611 } else { 1612 pw.print(val); 1613 } 1614 } 1615 } 1616 } 1617 } 1618 1619 /** 1620 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 1621 * 1622 * @param pw a Printer to receive the dump output. 1623 */ 1624 @SuppressWarnings("unused") 1625 public void dumpLocked(PrintWriter pw) { 1626 HistoryItem rec = getHistory(); 1627 if (rec != null) { 1628 pw.println("Battery History:"); 1629 int oldState = 0; 1630 int oldStatus = -1; 1631 int oldHealth = -1; 1632 int oldPlug = -1; 1633 int oldTemp = -1; 1634 int oldVolt = -1; 1635 while (rec != null) { 1636 pw.print(" "); 1637 pw.print(rec.time); 1638 pw.print(" "); 1639 if (rec.cmd == HistoryItem.CMD_START) { 1640 pw.println(" START"); 1641 } else { 1642 if (rec.batteryLevel < 10) pw.print("00"); 1643 else if (rec.batteryLevel < 100) pw.print("0"); 1644 pw.print(rec.batteryLevel); 1645 pw.print(" "); 1646 if (rec.states < 0x10) pw.print("0000000"); 1647 else if (rec.states < 0x100) pw.print("000000"); 1648 else if (rec.states < 0x1000) pw.print("00000"); 1649 else if (rec.states < 0x10000) pw.print("0000"); 1650 else if (rec.states < 0x100000) pw.print("000"); 1651 else if (rec.states < 0x1000000) pw.print("00"); 1652 else if (rec.states < 0x10000000) pw.print("0"); 1653 pw.print(Integer.toHexString(rec.states)); 1654 if (oldStatus != rec.batteryStatus) { 1655 oldStatus = rec.batteryStatus; 1656 pw.print(" status="); 1657 switch (oldStatus) { 1658 case BatteryManager.BATTERY_STATUS_UNKNOWN: 1659 pw.print("unknown"); 1660 break; 1661 case BatteryManager.BATTERY_STATUS_CHARGING: 1662 pw.print("charging"); 1663 break; 1664 case BatteryManager.BATTERY_STATUS_DISCHARGING: 1665 pw.print("discharging"); 1666 break; 1667 case BatteryManager.BATTERY_STATUS_NOT_CHARGING: 1668 pw.print("not-charging"); 1669 break; 1670 case BatteryManager.BATTERY_STATUS_FULL: 1671 pw.print("full"); 1672 break; 1673 default: 1674 pw.print(oldStatus); 1675 break; 1676 } 1677 } 1678 if (oldHealth != rec.batteryHealth) { 1679 oldHealth = rec.batteryHealth; 1680 pw.print(" health="); 1681 switch (oldHealth) { 1682 case BatteryManager.BATTERY_HEALTH_UNKNOWN: 1683 pw.print("unknown"); 1684 break; 1685 case BatteryManager.BATTERY_HEALTH_GOOD: 1686 pw.print("good"); 1687 break; 1688 case BatteryManager.BATTERY_HEALTH_OVERHEAT: 1689 pw.print("overheat"); 1690 break; 1691 case BatteryManager.BATTERY_HEALTH_DEAD: 1692 pw.print("dead"); 1693 break; 1694 case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: 1695 pw.print("over-voltage"); 1696 break; 1697 case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: 1698 pw.print("failure"); 1699 break; 1700 default: 1701 pw.print(oldHealth); 1702 break; 1703 } 1704 } 1705 if (oldPlug != rec.batteryPlugType) { 1706 oldPlug = rec.batteryPlugType; 1707 pw.print(" plug="); 1708 switch (oldPlug) { 1709 case 0: 1710 pw.print("none"); 1711 break; 1712 case BatteryManager.BATTERY_PLUGGED_AC: 1713 pw.print("ac"); 1714 break; 1715 case BatteryManager.BATTERY_PLUGGED_USB: 1716 pw.print("usb"); 1717 break; 1718 default: 1719 pw.print(oldPlug); 1720 break; 1721 } 1722 } 1723 if (oldTemp != rec.batteryTemperature) { 1724 oldTemp = rec.batteryTemperature; 1725 pw.print(" temp="); 1726 pw.print(oldTemp); 1727 } 1728 if (oldVolt != rec.batteryVoltage) { 1729 oldVolt = rec.batteryVoltage; 1730 pw.print(" volt="); 1731 pw.print(oldVolt); 1732 } 1733 printBitDescriptions(pw, oldState, rec.states, 1734 HISTORY_STATE_DESCRIPTIONS); 1735 pw.println(); 1736 } 1737 oldState = rec.states; 1738 rec = rec.next; 1739 } 1740 } 1741 1742 pw.println("Statistics since last charge:"); 1743 pw.println(" System starts: " + getStartCount() 1744 + ", currently on battery: " + getIsOnBattery()); 1745 dumpLocked(pw, "", STATS_SINCE_CHARGED, -1); 1746 pw.println(""); 1747 pw.println("Statistics since last unplugged:"); 1748 dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, -1); 1749 } 1750 1751 @SuppressWarnings("unused") 1752 public void dumpCheckinLocked(PrintWriter pw, String[] args) { 1753 boolean isUnpluggedOnly = false; 1754 1755 for (String arg : args) { 1756 if ("-u".equals(arg)) { 1757 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data"); 1758 isUnpluggedOnly = true; 1759 } 1760 } 1761 1762 if (isUnpluggedOnly) { 1763 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1); 1764 } 1765 else { 1766 dumpCheckinLocked(pw, STATS_SINCE_CHARGED, -1); 1767 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1); 1768 } 1769 } 1770} 1771