BatteryStats.java revision ec43a6bc17d90058ba2c00e016846c863ab239bc
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.ArrayList; 21import java.util.Collections; 22import java.util.Comparator; 23import java.util.Formatter; 24import java.util.List; 25import java.util.Map; 26 27import android.content.pm.ApplicationInfo; 28import android.telephony.SignalStrength; 29import android.util.Log; 30import android.util.Printer; 31import android.util.Slog; 32import android.util.SparseArray; 33import android.util.TimeUtils; 34 35/** 36 * A class providing access to battery usage statistics, including information on 37 * wakelocks, processes, packages, and services. All times are represented in microseconds 38 * except where indicated otherwise. 39 * @hide 40 */ 41public abstract class BatteryStats implements Parcelable { 42 43 private static final boolean LOCAL_LOGV = false; 44 45 /** 46 * A constant indicating a partial wake lock timer. 47 */ 48 public static final int WAKE_TYPE_PARTIAL = 0; 49 50 /** 51 * A constant indicating a full wake lock timer. 52 */ 53 public static final int WAKE_TYPE_FULL = 1; 54 55 /** 56 * A constant indicating a window wake lock timer. 57 */ 58 public static final int WAKE_TYPE_WINDOW = 2; 59 60 /** 61 * A constant indicating a sensor timer. 62 */ 63 public static final int SENSOR = 3; 64 65 /** 66 * A constant indicating a a wifi running timer 67 */ 68 public static final int WIFI_RUNNING = 4; 69 70 /** 71 * A constant indicating a full wifi lock timer 72 */ 73 public static final int FULL_WIFI_LOCK = 5; 74 75 /** 76 * A constant indicating a wifi scan 77 */ 78 public static final int WIFI_SCAN = 6; 79 80 /** 81 * A constant indicating a wifi multicast timer 82 */ 83 public static final int WIFI_MULTICAST_ENABLED = 7; 84 85 /** 86 * A constant indicating an audio turn on timer 87 */ 88 public static final int AUDIO_TURNED_ON = 7; 89 90 /** 91 * A constant indicating a video turn on timer 92 */ 93 public static final int VIDEO_TURNED_ON = 8; 94 95 /** 96 * A constant indicating a vibrator on timer 97 */ 98 public static final int VIBRATOR_ON = 9; 99 100 /** 101 * A constant indicating a foreground activity timer 102 */ 103 public static final int FOREGROUND_ACTIVITY = 10; 104 105 /** 106 * Include all of the data in the stats, including previously saved data. 107 */ 108 public static final int STATS_SINCE_CHARGED = 0; 109 110 /** 111 * Include only the last run in the stats. 112 */ 113 public static final int STATS_LAST = 1; 114 115 /** 116 * Include only the current run in the stats. 117 */ 118 public static final int STATS_CURRENT = 2; 119 120 /** 121 * Include only the run since the last time the device was unplugged in the stats. 122 */ 123 public static final int STATS_SINCE_UNPLUGGED = 3; 124 125 // NOTE: Update this list if you add/change any stats above. 126 // These characters are supposed to represent "total", "last", "current", 127 // and "unplugged". They were shortened for efficiency sake. 128 private static final String[] STAT_NAMES = { "t", "l", "c", "u" }; 129 130 /** 131 * Bump the version on this if the checkin format changes. 132 */ 133 private static final int BATTERY_STATS_CHECKIN_VERSION = 6; 134 135 private static final long BYTES_PER_KB = 1024; 136 private static final long BYTES_PER_MB = 1048576; // 1024^2 137 private static final long BYTES_PER_GB = 1073741824; //1024^3 138 139 140 private static final String UID_DATA = "uid"; 141 private static final String APK_DATA = "apk"; 142 private static final String PROCESS_DATA = "pr"; 143 private static final String SENSOR_DATA = "sr"; 144 private static final String VIBRATOR_DATA = "vib"; 145 private static final String FOREGROUND_DATA = "fg"; 146 private static final String WAKELOCK_DATA = "wl"; 147 private static final String KERNEL_WAKELOCK_DATA = "kwl"; 148 private static final String NETWORK_DATA = "nt"; 149 private static final String USER_ACTIVITY_DATA = "ua"; 150 private static final String BATTERY_DATA = "bt"; 151 private static final String BATTERY_DISCHARGE_DATA = "dc"; 152 private static final String BATTERY_LEVEL_DATA = "lv"; 153 private static final String WIFI_DATA = "wfl"; 154 private static final String MISC_DATA = "m"; 155 private static final String SCREEN_BRIGHTNESS_DATA = "br"; 156 private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt"; 157 private static final String SIGNAL_SCANNING_TIME_DATA = "sst"; 158 private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc"; 159 private static final String DATA_CONNECTION_TIME_DATA = "dct"; 160 private static final String DATA_CONNECTION_COUNT_DATA = "dcc"; 161 162 private final StringBuilder mFormatBuilder = new StringBuilder(32); 163 private final Formatter mFormatter = new Formatter(mFormatBuilder); 164 165 /** 166 * State for keeping track of counting information. 167 */ 168 public static abstract class Counter { 169 170 /** 171 * Returns the count associated with this Counter for the 172 * selected type of statistics. 173 * 174 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 175 */ 176 public abstract int getCountLocked(int which); 177 178 /** 179 * Temporary for debugging. 180 */ 181 public abstract void logState(Printer pw, String prefix); 182 } 183 184 /** 185 * State for keeping track of timing information. 186 */ 187 public static abstract class Timer { 188 189 /** 190 * Returns the count associated with this Timer for the 191 * selected type of statistics. 192 * 193 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 194 */ 195 public abstract int getCountLocked(int which); 196 197 /** 198 * Returns the total time in microseconds associated with this Timer for the 199 * selected type of statistics. 200 * 201 * @param batteryRealtime system realtime on battery in microseconds 202 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT 203 * @return a time in microseconds 204 */ 205 public abstract long getTotalTimeLocked(long batteryRealtime, int which); 206 207 /** 208 * Temporary for debugging. 209 */ 210 public abstract void logState(Printer pw, String prefix); 211 } 212 213 /** 214 * The statistics associated with a particular uid. 215 */ 216 public static abstract class Uid { 217 218 /** 219 * Returns a mapping containing wakelock statistics. 220 * 221 * @return a Map from Strings to Uid.Wakelock objects. 222 */ 223 public abstract Map<String, ? extends Wakelock> getWakelockStats(); 224 225 /** 226 * The statistics associated with a particular wake lock. 227 */ 228 public static abstract class Wakelock { 229 public abstract Timer getWakeTime(int type); 230 } 231 232 /** 233 * Returns a mapping containing sensor statistics. 234 * 235 * @return a Map from Integer sensor ids to Uid.Sensor objects. 236 */ 237 public abstract Map<Integer, ? extends Sensor> getSensorStats(); 238 239 /** 240 * Returns a mapping containing active process data. 241 */ 242 public abstract SparseArray<? extends Pid> getPidStats(); 243 244 /** 245 * Returns a mapping containing process statistics. 246 * 247 * @return a Map from Strings to Uid.Proc objects. 248 */ 249 public abstract Map<String, ? extends Proc> getProcessStats(); 250 251 /** 252 * Returns a mapping containing package statistics. 253 * 254 * @return a Map from Strings to Uid.Pkg objects. 255 */ 256 public abstract Map<String, ? extends Pkg> getPackageStats(); 257 258 /** 259 * {@hide} 260 */ 261 public abstract int getUid(); 262 263 /** 264 * {@hide} 265 */ 266 public abstract long getTcpBytesReceived(int which); 267 268 /** 269 * {@hide} 270 */ 271 public abstract long getTcpBytesSent(int which); 272 273 public abstract void noteWifiRunningLocked(); 274 public abstract void noteWifiStoppedLocked(); 275 public abstract void noteFullWifiLockAcquiredLocked(); 276 public abstract void noteFullWifiLockReleasedLocked(); 277 public abstract void noteWifiScanStartedLocked(); 278 public abstract void noteWifiScanStoppedLocked(); 279 public abstract void noteWifiMulticastEnabledLocked(); 280 public abstract void noteWifiMulticastDisabledLocked(); 281 public abstract void noteAudioTurnedOnLocked(); 282 public abstract void noteAudioTurnedOffLocked(); 283 public abstract void noteVideoTurnedOnLocked(); 284 public abstract void noteVideoTurnedOffLocked(); 285 public abstract void noteActivityResumedLocked(); 286 public abstract void noteActivityPausedLocked(); 287 public abstract long getWifiRunningTime(long batteryRealtime, int which); 288 public abstract long getFullWifiLockTime(long batteryRealtime, int which); 289 public abstract long getWifiScanTime(long batteryRealtime, int which); 290 public abstract long getWifiMulticastTime(long batteryRealtime, 291 int which); 292 public abstract long getAudioTurnedOnTime(long batteryRealtime, int which); 293 public abstract long getVideoTurnedOnTime(long batteryRealtime, int which); 294 public abstract Timer getForegroundActivityTimer(); 295 public abstract Timer getVibratorOnTimer(); 296 297 /** 298 * Note that these must match the constants in android.os.PowerManager. 299 * Also, if the user activity types change, the BatteryStatsImpl.VERSION must 300 * also be bumped. 301 */ 302 static final String[] USER_ACTIVITY_TYPES = { 303 "other", "button", "touch" 304 }; 305 306 public static final int NUM_USER_ACTIVITY_TYPES = 3; 307 308 public abstract void noteUserActivityLocked(int type); 309 public abstract boolean hasUserActivity(); 310 public abstract int getUserActivityCount(int type, int which); 311 312 public static abstract class Sensor { 313 /* 314 * FIXME: it's not correct to use this magic value because it 315 * could clash with a sensor handle (which are defined by 316 * the sensor HAL, and therefore out of our control 317 */ 318 // Magic sensor number for the GPS. 319 public static final int GPS = -10000; 320 321 public abstract int getHandle(); 322 323 public abstract Timer getSensorTime(); 324 } 325 326 public class Pid { 327 public long mWakeSum; 328 public long mWakeStart; 329 } 330 331 /** 332 * The statistics associated with a particular process. 333 */ 334 public static abstract class Proc { 335 336 public static class ExcessivePower { 337 public static final int TYPE_WAKE = 1; 338 public static final int TYPE_CPU = 2; 339 340 public int type; 341 public long overTime; 342 public long usedTime; 343 } 344 345 /** 346 * Returns the total time (in 1/100 sec) spent executing in user code. 347 * 348 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 349 */ 350 public abstract long getUserTime(int which); 351 352 /** 353 * Returns the total time (in 1/100 sec) spent executing in system code. 354 * 355 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 356 */ 357 public abstract long getSystemTime(int which); 358 359 /** 360 * Returns the number of times the process has been started. 361 * 362 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 363 */ 364 public abstract int getStarts(int which); 365 366 /** 367 * Returns the cpu time spent in microseconds while the process was in the foreground. 368 * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED 369 * @return foreground cpu time in microseconds 370 */ 371 public abstract long getForegroundTime(int which); 372 373 /** 374 * Returns the approximate cpu time spent in microseconds, at a certain CPU speed. 375 * @param speedStep the index of the CPU speed. This is not the actual speed of the 376 * CPU. 377 * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED 378 * @see BatteryStats#getCpuSpeedSteps() 379 */ 380 public abstract long getTimeAtCpuSpeedStep(int speedStep, int which); 381 382 public abstract int countExcessivePowers(); 383 384 public abstract ExcessivePower getExcessivePower(int i); 385 } 386 387 /** 388 * The statistics associated with a particular package. 389 */ 390 public static abstract class Pkg { 391 392 /** 393 * Returns the number of times this package has done something that could wake up the 394 * device from sleep. 395 * 396 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 397 */ 398 public abstract int getWakeups(int which); 399 400 /** 401 * Returns a mapping containing service statistics. 402 */ 403 public abstract Map<String, ? extends Serv> getServiceStats(); 404 405 /** 406 * The statistics associated with a particular service. 407 */ 408 public abstract class Serv { 409 410 /** 411 * Returns the amount of time spent started. 412 * 413 * @param batteryUptime elapsed uptime on battery in microseconds. 414 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 415 * @return 416 */ 417 public abstract long getStartTime(long batteryUptime, int which); 418 419 /** 420 * Returns the total number of times startService() has been called. 421 * 422 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 423 */ 424 public abstract int getStarts(int which); 425 426 /** 427 * Returns the total number times the service has been launched. 428 * 429 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 430 */ 431 public abstract int getLaunches(int which); 432 } 433 } 434 } 435 436 public final static class HistoryItem implements Parcelable { 437 static final String TAG = "HistoryItem"; 438 static final boolean DEBUG = false; 439 440 public HistoryItem next; 441 442 public long time; 443 444 public static final byte CMD_NULL = 0; 445 public static final byte CMD_UPDATE = 1; 446 public static final byte CMD_START = 2; 447 public static final byte CMD_OVERFLOW = 3; 448 449 public byte cmd = CMD_NULL; 450 451 public byte batteryLevel; 452 public byte batteryStatus; 453 public byte batteryHealth; 454 public byte batteryPlugType; 455 456 public char batteryTemperature; 457 public char batteryVoltage; 458 459 // Constants from SCREEN_BRIGHTNESS_* 460 public static final int STATE_BRIGHTNESS_MASK = 0x0000000f; 461 public static final int STATE_BRIGHTNESS_SHIFT = 0; 462 // Constants from SIGNAL_STRENGTH_* 463 public static final int STATE_SIGNAL_STRENGTH_MASK = 0x000000f0; 464 public static final int STATE_SIGNAL_STRENGTH_SHIFT = 4; 465 // Constants from ServiceState.STATE_* 466 public static final int STATE_PHONE_STATE_MASK = 0x00000f00; 467 public static final int STATE_PHONE_STATE_SHIFT = 8; 468 // Constants from DATA_CONNECTION_* 469 public static final int STATE_DATA_CONNECTION_MASK = 0x0000f000; 470 public static final int STATE_DATA_CONNECTION_SHIFT = 12; 471 472 // These states always appear directly in the first int token 473 // of a delta change; they should be ones that change relatively 474 // frequently. 475 public static final int STATE_WAKE_LOCK_FLAG = 1<<30; 476 public static final int STATE_SENSOR_ON_FLAG = 1<<29; 477 public static final int STATE_GPS_ON_FLAG = 1<<28; 478 public static final int STATE_PHONE_SCANNING_FLAG = 1<<27; 479 public static final int STATE_WIFI_RUNNING_FLAG = 1<<26; 480 public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<25; 481 public static final int STATE_WIFI_SCAN_FLAG = 1<<24; 482 public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<23; 483 // These are on the lower bits used for the command; if they change 484 // we need to write another int of data. 485 public static final int STATE_AUDIO_ON_FLAG = 1<<22; 486 public static final int STATE_VIDEO_ON_FLAG = 1<<21; 487 public static final int STATE_SCREEN_ON_FLAG = 1<<20; 488 public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; 489 public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18; 490 public static final int STATE_WIFI_ON_FLAG = 1<<17; 491 public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16; 492 493 public static final int MOST_INTERESTING_STATES = 494 STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG 495 | STATE_GPS_ON_FLAG | STATE_PHONE_IN_CALL_FLAG; 496 497 public int states; 498 499 public HistoryItem() { 500 } 501 502 public HistoryItem(long time, Parcel src) { 503 this.time = time; 504 readFromParcel(src); 505 } 506 507 public int describeContents() { 508 return 0; 509 } 510 511 public void writeToParcel(Parcel dest, int flags) { 512 dest.writeLong(time); 513 int bat = (((int)cmd)&0xff) 514 | ((((int)batteryLevel)<<8)&0xff00) 515 | ((((int)batteryStatus)<<16)&0xf0000) 516 | ((((int)batteryHealth)<<20)&0xf00000) 517 | ((((int)batteryPlugType)<<24)&0xf000000); 518 dest.writeInt(bat); 519 bat = (((int)batteryTemperature)&0xffff) 520 | ((((int)batteryVoltage)<<16)&0xffff0000); 521 dest.writeInt(bat); 522 dest.writeInt(states); 523 } 524 525 private void readFromParcel(Parcel src) { 526 int bat = src.readInt(); 527 cmd = (byte)(bat&0xff); 528 batteryLevel = (byte)((bat>>8)&0xff); 529 batteryStatus = (byte)((bat>>16)&0xf); 530 batteryHealth = (byte)((bat>>20)&0xf); 531 batteryPlugType = (byte)((bat>>24)&0xf); 532 bat = src.readInt(); 533 batteryTemperature = (char)(bat&0xffff); 534 batteryVoltage = (char)((bat>>16)&0xffff); 535 states = src.readInt(); 536 } 537 538 // Part of initial delta int that specifies the time delta. 539 static final int DELTA_TIME_MASK = 0x3ffff; 540 static final int DELTA_TIME_ABS = 0x3fffd; // Following is an entire abs update. 541 static final int DELTA_TIME_INT = 0x3fffe; // The delta is a following int 542 static final int DELTA_TIME_LONG = 0x3ffff; // The delta is a following long 543 // Part of initial delta int holding the command code. 544 static final int DELTA_CMD_MASK = 0x3; 545 static final int DELTA_CMD_SHIFT = 18; 546 // Flag in delta int: a new battery level int follows. 547 static final int DELTA_BATTERY_LEVEL_FLAG = 1<<20; 548 // Flag in delta int: a new full state and battery status int follows. 549 static final int DELTA_STATE_FLAG = 1<<21; 550 static final int DELTA_STATE_MASK = 0xffc00000; 551 552 public void writeDelta(Parcel dest, HistoryItem last) { 553 if (last == null || last.cmd != CMD_UPDATE) { 554 dest.writeInt(DELTA_TIME_ABS); 555 writeToParcel(dest, 0); 556 return; 557 } 558 559 final long deltaTime = time - last.time; 560 final int lastBatteryLevelInt = last.buildBatteryLevelInt(); 561 final int lastStateInt = last.buildStateInt(); 562 563 int deltaTimeToken; 564 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 565 deltaTimeToken = DELTA_TIME_LONG; 566 } else if (deltaTime >= DELTA_TIME_ABS) { 567 deltaTimeToken = DELTA_TIME_INT; 568 } else { 569 deltaTimeToken = (int)deltaTime; 570 } 571 int firstToken = deltaTimeToken 572 | (cmd<<DELTA_CMD_SHIFT) 573 | (states&DELTA_STATE_MASK); 574 final int batteryLevelInt = buildBatteryLevelInt(); 575 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 576 if (batteryLevelIntChanged) { 577 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 578 } 579 final int stateInt = buildStateInt(); 580 final boolean stateIntChanged = stateInt != lastStateInt; 581 if (stateIntChanged) { 582 firstToken |= DELTA_STATE_FLAG; 583 } 584 dest.writeInt(firstToken); 585 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 586 + " deltaTime=" + deltaTime); 587 588 if (deltaTimeToken >= DELTA_TIME_INT) { 589 if (deltaTimeToken == DELTA_TIME_INT) { 590 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 591 dest.writeInt((int)deltaTime); 592 } else { 593 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 594 dest.writeLong(deltaTime); 595 } 596 } 597 if (batteryLevelIntChanged) { 598 dest.writeInt(batteryLevelInt); 599 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 600 + Integer.toHexString(batteryLevelInt) 601 + " batteryLevel=" + batteryLevel 602 + " batteryTemp=" + (int)batteryTemperature 603 + " batteryVolt=" + (int)batteryVoltage); 604 } 605 if (stateIntChanged) { 606 dest.writeInt(stateInt); 607 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 608 + Integer.toHexString(stateInt) 609 + " batteryStatus=" + batteryStatus 610 + " batteryHealth=" + batteryHealth 611 + " batteryPlugType=" + batteryPlugType 612 + " states=0x" + Integer.toHexString(states)); 613 } 614 } 615 616 private int buildBatteryLevelInt() { 617 return ((((int)batteryLevel)<<24)&0xff000000) 618 | ((((int)batteryTemperature)<<14)&0x00ffc000) 619 | (((int)batteryVoltage)&0x00003fff); 620 } 621 622 private int buildStateInt() { 623 return ((((int)batteryStatus)<<28)&0xf0000000) 624 | ((((int)batteryHealth)<<24)&0x0f000000) 625 | ((((int)batteryPlugType)<<22)&0x00c00000) 626 | (states&(~DELTA_STATE_MASK)); 627 } 628 629 public void readDelta(Parcel src) { 630 int firstToken = src.readInt(); 631 int deltaTimeToken = firstToken&DELTA_TIME_MASK; 632 cmd = (byte)((firstToken>>DELTA_CMD_SHIFT)&DELTA_CMD_MASK); 633 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) 634 + " deltaTimeToken=" + deltaTimeToken); 635 636 if (deltaTimeToken < DELTA_TIME_ABS) { 637 time += deltaTimeToken; 638 } else if (deltaTimeToken == DELTA_TIME_ABS) { 639 time = src.readLong(); 640 readFromParcel(src); 641 return; 642 } else if (deltaTimeToken == DELTA_TIME_INT) { 643 int delta = src.readInt(); 644 time += delta; 645 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + time); 646 } else { 647 long delta = src.readLong(); 648 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + time); 649 time += delta; 650 } 651 652 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) { 653 int batteryLevelInt = src.readInt(); 654 batteryLevel = (byte)((batteryLevelInt>>24)&0xff); 655 batteryTemperature = (char)((batteryLevelInt>>14)&0x3ff); 656 batteryVoltage = (char)(batteryLevelInt&0x3fff); 657 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x" 658 + Integer.toHexString(batteryLevelInt) 659 + " batteryLevel=" + batteryLevel 660 + " batteryTemp=" + (int)batteryTemperature 661 + " batteryVolt=" + (int)batteryVoltage); 662 } 663 664 if ((firstToken&DELTA_STATE_FLAG) != 0) { 665 int stateInt = src.readInt(); 666 states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK)); 667 batteryStatus = (byte)((stateInt>>28)&0xf); 668 batteryHealth = (byte)((stateInt>>24)&0xf); 669 batteryPlugType = (byte)((stateInt>>22)&0x3); 670 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x" 671 + Integer.toHexString(stateInt) 672 + " batteryStatus=" + batteryStatus 673 + " batteryHealth=" + batteryHealth 674 + " batteryPlugType=" + batteryPlugType 675 + " states=0x" + Integer.toHexString(states)); 676 } else { 677 states = (firstToken&DELTA_STATE_MASK) | (states&(~DELTA_STATE_MASK)); 678 } 679 } 680 681 public void clear() { 682 time = 0; 683 cmd = CMD_NULL; 684 batteryLevel = 0; 685 batteryStatus = 0; 686 batteryHealth = 0; 687 batteryPlugType = 0; 688 batteryTemperature = 0; 689 batteryVoltage = 0; 690 states = 0; 691 } 692 693 public void setTo(HistoryItem o) { 694 time = o.time; 695 cmd = o.cmd; 696 batteryLevel = o.batteryLevel; 697 batteryStatus = o.batteryStatus; 698 batteryHealth = o.batteryHealth; 699 batteryPlugType = o.batteryPlugType; 700 batteryTemperature = o.batteryTemperature; 701 batteryVoltage = o.batteryVoltage; 702 states = o.states; 703 } 704 705 public void setTo(long time, byte cmd, HistoryItem o) { 706 this.time = time; 707 this.cmd = cmd; 708 batteryLevel = o.batteryLevel; 709 batteryStatus = o.batteryStatus; 710 batteryHealth = o.batteryHealth; 711 batteryPlugType = o.batteryPlugType; 712 batteryTemperature = o.batteryTemperature; 713 batteryVoltage = o.batteryVoltage; 714 states = o.states; 715 } 716 717 public boolean same(HistoryItem o) { 718 return batteryLevel == o.batteryLevel 719 && batteryStatus == o.batteryStatus 720 && batteryHealth == o.batteryHealth 721 && batteryPlugType == o.batteryPlugType 722 && batteryTemperature == o.batteryTemperature 723 && batteryVoltage == o.batteryVoltage 724 && states == o.states; 725 } 726 } 727 728 public static final class BitDescription { 729 public final int mask; 730 public final int shift; 731 public final String name; 732 public final String[] values; 733 734 public BitDescription(int mask, String name) { 735 this.mask = mask; 736 this.shift = -1; 737 this.name = name; 738 this.values = null; 739 } 740 741 public BitDescription(int mask, int shift, String name, String[] values) { 742 this.mask = mask; 743 this.shift = shift; 744 this.name = name; 745 this.values = values; 746 } 747 } 748 749 public abstract boolean startIteratingHistoryLocked(); 750 751 public abstract boolean getNextHistoryLocked(HistoryItem out); 752 753 public abstract void finishIteratingHistoryLocked(); 754 755 public abstract boolean startIteratingOldHistoryLocked(); 756 757 public abstract boolean getNextOldHistoryLocked(HistoryItem out); 758 759 public abstract void finishIteratingOldHistoryLocked(); 760 761 /** 762 * Return the base time offset for the battery history. 763 */ 764 public abstract long getHistoryBaseTime(); 765 766 /** 767 * Returns the number of times the device has been started. 768 */ 769 public abstract int getStartCount(); 770 771 /** 772 * Returns the time in microseconds that the screen has been on while the device was 773 * running on battery. 774 * 775 * {@hide} 776 */ 777 public abstract long getScreenOnTime(long batteryRealtime, int which); 778 779 public static final int SCREEN_BRIGHTNESS_DARK = 0; 780 public static final int SCREEN_BRIGHTNESS_DIM = 1; 781 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2; 782 public static final int SCREEN_BRIGHTNESS_LIGHT = 3; 783 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4; 784 785 static final String[] SCREEN_BRIGHTNESS_NAMES = { 786 "dark", "dim", "medium", "light", "bright" 787 }; 788 789 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5; 790 791 /** 792 * Returns the time in microseconds that the screen has been on with 793 * the given brightness 794 * 795 * {@hide} 796 */ 797 public abstract long getScreenBrightnessTime(int brightnessBin, 798 long batteryRealtime, int which); 799 800 public abstract int getInputEventCount(int which); 801 802 /** 803 * Returns the time in microseconds that the phone has been on while the device was 804 * running on battery. 805 * 806 * {@hide} 807 */ 808 public abstract long getPhoneOnTime(long batteryRealtime, int which); 809 810 /** 811 * Returns the time in microseconds that the phone has been running with 812 * the given signal strength. 813 * 814 * {@hide} 815 */ 816 public abstract long getPhoneSignalStrengthTime(int strengthBin, 817 long batteryRealtime, int which); 818 819 /** 820 * Returns the time in microseconds that the phone has been trying to 821 * acquire a signal. 822 * 823 * {@hide} 824 */ 825 public abstract long getPhoneSignalScanningTime( 826 long batteryRealtime, int which); 827 828 /** 829 * Returns the number of times the phone has entered the given signal strength. 830 * 831 * {@hide} 832 */ 833 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which); 834 835 public static final int DATA_CONNECTION_NONE = 0; 836 public static final int DATA_CONNECTION_GPRS = 1; 837 public static final int DATA_CONNECTION_EDGE = 2; 838 public static final int DATA_CONNECTION_UMTS = 3; 839 public static final int DATA_CONNECTION_CDMA = 4; 840 public static final int DATA_CONNECTION_EVDO_0 = 5; 841 public static final int DATA_CONNECTION_EVDO_A = 6; 842 public static final int DATA_CONNECTION_1xRTT = 7; 843 public static final int DATA_CONNECTION_HSDPA = 8; 844 public static final int DATA_CONNECTION_HSUPA = 9; 845 public static final int DATA_CONNECTION_HSPA = 10; 846 public static final int DATA_CONNECTION_IDEN = 11; 847 public static final int DATA_CONNECTION_EVDO_B = 12; 848 public static final int DATA_CONNECTION_LTE = 13; 849 public static final int DATA_CONNECTION_EHRPD = 14; 850 public static final int DATA_CONNECTION_OTHER = 15; 851 852 static final String[] DATA_CONNECTION_NAMES = { 853 "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A", 854 "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte", 855 "ehrpd", "other" 856 }; 857 858 public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1; 859 860 /** 861 * Returns the time in microseconds that the phone has been running with 862 * the given data connection. 863 * 864 * {@hide} 865 */ 866 public abstract long getPhoneDataConnectionTime(int dataType, 867 long batteryRealtime, int which); 868 869 /** 870 * Returns the number of times the phone has entered the given data 871 * connection type. 872 * 873 * {@hide} 874 */ 875 public abstract int getPhoneDataConnectionCount(int dataType, int which); 876 877 public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS 878 = new BitDescription[] { 879 new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged"), 880 new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen"), 881 new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps"), 882 new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call"), 883 new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning"), 884 new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi"), 885 new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running"), 886 new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock"), 887 new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan"), 888 new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast"), 889 new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth"), 890 new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio"), 891 new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video"), 892 new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock"), 893 new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor"), 894 new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK, 895 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", 896 SCREEN_BRIGHTNESS_NAMES), 897 new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK, 898 HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength", 899 SignalStrength.SIGNAL_STRENGTH_NAMES), 900 new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK, 901 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", 902 new String[] {"in", "out", "emergency", "off"}), 903 new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK, 904 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", 905 DATA_CONNECTION_NAMES), 906 }; 907 908 /** 909 * Returns the time in microseconds that wifi has been on while the device was 910 * running on battery. 911 * 912 * {@hide} 913 */ 914 public abstract long getWifiOnTime(long batteryRealtime, int which); 915 916 /** 917 * Returns the time in microseconds that wifi has been on and the driver has 918 * been in the running state while the device was running on battery. 919 * 920 * {@hide} 921 */ 922 public abstract long getGlobalWifiRunningTime(long batteryRealtime, int which); 923 924 /** 925 * Returns the time in microseconds that bluetooth has been on while the device was 926 * running on battery. 927 * 928 * {@hide} 929 */ 930 public abstract long getBluetoothOnTime(long batteryRealtime, int which); 931 932 /** 933 * Return whether we are currently running on battery. 934 */ 935 public abstract boolean getIsOnBattery(); 936 937 /** 938 * Returns a SparseArray containing the statistics for each uid. 939 */ 940 public abstract SparseArray<? extends Uid> getUidStats(); 941 942 /** 943 * Returns the current battery uptime in microseconds. 944 * 945 * @param curTime the amount of elapsed realtime in microseconds. 946 */ 947 public abstract long getBatteryUptime(long curTime); 948 949 /** 950 * @deprecated use getRadioDataUptime 951 */ 952 public long getRadioDataUptimeMs() { 953 return getRadioDataUptime() / 1000; 954 } 955 956 /** 957 * Returns the time that the radio was on for data transfers. 958 * @return the uptime in microseconds while unplugged 959 */ 960 public abstract long getRadioDataUptime(); 961 962 /** 963 * Returns the current battery realtime in microseconds. 964 * 965 * @param curTime the amount of elapsed realtime in microseconds. 966 */ 967 public abstract long getBatteryRealtime(long curTime); 968 969 /** 970 * Returns the battery percentage level at the last time the device was unplugged from power, or 971 * the last time it booted on battery power. 972 */ 973 public abstract int getDischargeStartLevel(); 974 975 /** 976 * Returns the current battery percentage level if we are in a discharge cycle, otherwise 977 * returns the level at the last plug event. 978 */ 979 public abstract int getDischargeCurrentLevel(); 980 981 /** 982 * Get the amount the battery has discharged since the stats were 983 * last reset after charging, as a lower-end approximation. 984 */ 985 public abstract int getLowDischargeAmountSinceCharge(); 986 987 /** 988 * Get the amount the battery has discharged since the stats were 989 * last reset after charging, as an upper-end approximation. 990 */ 991 public abstract int getHighDischargeAmountSinceCharge(); 992 993 /** 994 * Get the amount the battery has discharged while the screen was on, 995 * since the last time power was unplugged. 996 */ 997 public abstract int getDischargeAmountScreenOn(); 998 999 /** 1000 * Get the amount the battery has discharged while the screen was on, 1001 * since the last time the device was charged. 1002 */ 1003 public abstract int getDischargeAmountScreenOnSinceCharge(); 1004 1005 /** 1006 * Get the amount the battery has discharged while the screen was off, 1007 * since the last time power was unplugged. 1008 */ 1009 public abstract int getDischargeAmountScreenOff(); 1010 1011 /** 1012 * Get the amount the battery has discharged while the screen was off, 1013 * since the last time the device was charged. 1014 */ 1015 public abstract int getDischargeAmountScreenOffSinceCharge(); 1016 1017 /** 1018 * Returns the total, last, or current battery uptime in microseconds. 1019 * 1020 * @param curTime the elapsed realtime in microseconds. 1021 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1022 */ 1023 public abstract long computeBatteryUptime(long curTime, int which); 1024 1025 /** 1026 * Returns the total, last, or current battery realtime in microseconds. 1027 * 1028 * @param curTime the current elapsed realtime in microseconds. 1029 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1030 */ 1031 public abstract long computeBatteryRealtime(long curTime, int which); 1032 1033 /** 1034 * Returns the total, last, or current uptime in microseconds. 1035 * 1036 * @param curTime the current elapsed realtime in microseconds. 1037 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1038 */ 1039 public abstract long computeUptime(long curTime, int which); 1040 1041 /** 1042 * Returns the total, last, or current realtime in microseconds. 1043 * * 1044 * @param curTime the current elapsed realtime in microseconds. 1045 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1046 */ 1047 public abstract long computeRealtime(long curTime, int which); 1048 1049 public abstract Map<String, ? extends Timer> getKernelWakelockStats(); 1050 1051 /** Returns the number of different speeds that the CPU can run at */ 1052 public abstract int getCpuSpeedSteps(); 1053 1054 private final static void formatTimeRaw(StringBuilder out, long seconds) { 1055 long days = seconds / (60 * 60 * 24); 1056 if (days != 0) { 1057 out.append(days); 1058 out.append("d "); 1059 } 1060 long used = days * 60 * 60 * 24; 1061 1062 long hours = (seconds - used) / (60 * 60); 1063 if (hours != 0 || used != 0) { 1064 out.append(hours); 1065 out.append("h "); 1066 } 1067 used += hours * 60 * 60; 1068 1069 long mins = (seconds-used) / 60; 1070 if (mins != 0 || used != 0) { 1071 out.append(mins); 1072 out.append("m "); 1073 } 1074 used += mins * 60; 1075 1076 if (seconds != 0 || used != 0) { 1077 out.append(seconds-used); 1078 out.append("s "); 1079 } 1080 } 1081 1082 private final static void formatTime(StringBuilder sb, long time) { 1083 long sec = time / 100; 1084 formatTimeRaw(sb, sec); 1085 sb.append((time - (sec * 100)) * 10); 1086 sb.append("ms "); 1087 } 1088 1089 private final static void formatTimeMs(StringBuilder sb, long time) { 1090 long sec = time / 1000; 1091 formatTimeRaw(sb, sec); 1092 sb.append(time - (sec * 1000)); 1093 sb.append("ms "); 1094 } 1095 1096 private final String formatRatioLocked(long num, long den) { 1097 if (den == 0L) { 1098 return "---%"; 1099 } 1100 float perc = ((float)num) / ((float)den) * 100; 1101 mFormatBuilder.setLength(0); 1102 mFormatter.format("%.1f%%", perc); 1103 return mFormatBuilder.toString(); 1104 } 1105 1106 private final String formatBytesLocked(long bytes) { 1107 mFormatBuilder.setLength(0); 1108 1109 if (bytes < BYTES_PER_KB) { 1110 return bytes + "B"; 1111 } else if (bytes < BYTES_PER_MB) { 1112 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB); 1113 return mFormatBuilder.toString(); 1114 } else if (bytes < BYTES_PER_GB){ 1115 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB); 1116 return mFormatBuilder.toString(); 1117 } else { 1118 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB); 1119 return mFormatBuilder.toString(); 1120 } 1121 } 1122 1123 private static long computeWakeLock(Timer timer, long batteryRealtime, int which) { 1124 if (timer != null) { 1125 // Convert from microseconds to milliseconds with rounding 1126 long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which); 1127 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 1128 return totalTimeMillis; 1129 } 1130 return 0; 1131 } 1132 1133 /** 1134 * 1135 * @param sb a StringBuilder object. 1136 * @param timer a Timer object contining the wakelock times. 1137 * @param batteryRealtime the current on-battery time in microseconds. 1138 * @param name the name of the wakelock. 1139 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1140 * @param linePrefix a String to be prepended to each line of output. 1141 * @return the line prefix 1142 */ 1143 private static final String printWakeLock(StringBuilder sb, Timer timer, 1144 long batteryRealtime, String name, int which, String linePrefix) { 1145 1146 if (timer != null) { 1147 long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which); 1148 1149 int count = timer.getCountLocked(which); 1150 if (totalTimeMillis != 0) { 1151 sb.append(linePrefix); 1152 formatTimeMs(sb, totalTimeMillis); 1153 if (name != null) { 1154 sb.append(name); 1155 sb.append(' '); 1156 } 1157 sb.append('('); 1158 sb.append(count); 1159 sb.append(" times)"); 1160 return ", "; 1161 } 1162 } 1163 return linePrefix; 1164 } 1165 1166 /** 1167 * Checkin version of wakelock printer. Prints simple comma-separated list. 1168 * 1169 * @param sb a StringBuilder object. 1170 * @param timer a Timer object contining the wakelock times. 1171 * @param now the current time in microseconds. 1172 * @param name the name of the wakelock. 1173 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1174 * @param linePrefix a String to be prepended to each line of output. 1175 * @return the line prefix 1176 */ 1177 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now, 1178 String name, int which, String linePrefix) { 1179 long totalTimeMicros = 0; 1180 int count = 0; 1181 if (timer != null) { 1182 totalTimeMicros = timer.getTotalTimeLocked(now, which); 1183 count = timer.getCountLocked(which); 1184 } 1185 sb.append(linePrefix); 1186 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 1187 sb.append(','); 1188 sb.append(name != null ? name + "," : ""); 1189 sb.append(count); 1190 return ","; 1191 } 1192 1193 /** 1194 * Dump a comma-separated line of values for terse checkin mode. 1195 * 1196 * @param pw the PageWriter to dump log to 1197 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 1198 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 1199 * @param args type-dependent data arguments 1200 */ 1201 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 1202 Object... args ) { 1203 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 1204 pw.print(uid); pw.print(','); 1205 pw.print(category); pw.print(','); 1206 pw.print(type); 1207 1208 for (Object arg : args) { 1209 pw.print(','); 1210 pw.print(arg); 1211 } 1212 pw.print('\n'); 1213 } 1214 1215 /** 1216 * Checkin server version of dump to produce more compact, computer-readable log. 1217 * 1218 * NOTE: all times are expressed in 'ms'. 1219 */ 1220 public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) { 1221 final long rawUptime = SystemClock.uptimeMillis() * 1000; 1222 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 1223 final long batteryUptime = getBatteryUptime(rawUptime); 1224 final long batteryRealtime = getBatteryRealtime(rawRealtime); 1225 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 1226 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 1227 final long totalRealtime = computeRealtime(rawRealtime, which); 1228 final long totalUptime = computeUptime(rawUptime, which); 1229 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 1230 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 1231 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 1232 final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which); 1233 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 1234 1235 StringBuilder sb = new StringBuilder(128); 1236 1237 SparseArray<? extends Uid> uidStats = getUidStats(); 1238 final int NU = uidStats.size(); 1239 1240 String category = STAT_NAMES[which]; 1241 1242 // Dump "battery" stat 1243 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 1244 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A", 1245 whichBatteryRealtime / 1000, whichBatteryUptime / 1000, 1246 totalRealtime / 1000, totalUptime / 1000); 1247 1248 // Calculate total network and wakelock times across all uids. 1249 long rxTotal = 0; 1250 long txTotal = 0; 1251 long fullWakeLockTimeTotal = 0; 1252 long partialWakeLockTimeTotal = 0; 1253 1254 for (int iu = 0; iu < NU; iu++) { 1255 Uid u = uidStats.valueAt(iu); 1256 rxTotal += u.getTcpBytesReceived(which); 1257 txTotal += u.getTcpBytesSent(which); 1258 1259 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1260 if (wakelocks.size() > 0) { 1261 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1262 : wakelocks.entrySet()) { 1263 Uid.Wakelock wl = ent.getValue(); 1264 1265 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 1266 if (fullWakeTimer != null) { 1267 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which); 1268 } 1269 1270 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 1271 if (partialWakeTimer != null) { 1272 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked( 1273 batteryRealtime, which); 1274 } 1275 } 1276 } 1277 } 1278 1279 // Dump misc stats 1280 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 1281 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, 1282 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal, 1283 fullWakeLockTimeTotal, partialWakeLockTimeTotal, 1284 getInputEventCount(which)); 1285 1286 // Dump screen brightness stats 1287 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; 1288 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1289 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000; 1290 } 1291 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args); 1292 1293 // Dump signal strength stats 1294 args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 1295 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 1296 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000; 1297 } 1298 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args); 1299 dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA, 1300 getPhoneSignalScanningTime(batteryRealtime, which) / 1000); 1301 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 1302 args[i] = getPhoneSignalStrengthCount(i, which); 1303 } 1304 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args); 1305 1306 // Dump network type stats 1307 args = new Object[NUM_DATA_CONNECTION_TYPES]; 1308 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1309 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000; 1310 } 1311 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args); 1312 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1313 args[i] = getPhoneDataConnectionCount(i, which); 1314 } 1315 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args); 1316 1317 if (which == STATS_SINCE_UNPLUGGED) { 1318 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), 1319 getDischargeCurrentLevel()); 1320 } 1321 1322 if (which == STATS_SINCE_UNPLUGGED) { 1323 dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, 1324 getDischargeStartLevel()-getDischargeCurrentLevel(), 1325 getDischargeStartLevel()-getDischargeCurrentLevel(), 1326 getDischargeAmountScreenOn(), getDischargeAmountScreenOff()); 1327 } else { 1328 dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, 1329 getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(), 1330 getDischargeAmountScreenOn(), getDischargeAmountScreenOff()); 1331 } 1332 1333 if (reqUid < 0) { 1334 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); 1335 if (kernelWakelocks.size() > 0) { 1336 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { 1337 sb.setLength(0); 1338 printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, ""); 1339 1340 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(), 1341 sb.toString()); 1342 } 1343 } 1344 } 1345 1346 for (int iu = 0; iu < NU; iu++) { 1347 final int uid = uidStats.keyAt(iu); 1348 if (reqUid >= 0 && uid != reqUid) { 1349 continue; 1350 } 1351 Uid u = uidStats.valueAt(iu); 1352 // Dump Network stats per uid, if any 1353 long rx = u.getTcpBytesReceived(which); 1354 long tx = u.getTcpBytesSent(which); 1355 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 1356 long wifiScanTime = u.getWifiScanTime(batteryRealtime, which); 1357 long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which); 1358 1359 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx); 1360 1361 if (fullWifiLockOnTime != 0 || wifiScanTime != 0 1362 || uidWifiRunningTime != 0) { 1363 dumpLine(pw, uid, category, WIFI_DATA, 1364 fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime); 1365 } 1366 1367 if (u.hasUserActivity()) { 1368 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES]; 1369 boolean hasData = false; 1370 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 1371 int val = u.getUserActivityCount(i, which); 1372 args[i] = val; 1373 if (val != 0) hasData = true; 1374 } 1375 if (hasData) { 1376 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args); 1377 } 1378 } 1379 1380 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1381 if (wakelocks.size() > 0) { 1382 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1383 : wakelocks.entrySet()) { 1384 Uid.Wakelock wl = ent.getValue(); 1385 String linePrefix = ""; 1386 sb.setLength(0); 1387 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), 1388 batteryRealtime, "f", which, linePrefix); 1389 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), 1390 batteryRealtime, "p", which, linePrefix); 1391 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), 1392 batteryRealtime, "w", which, linePrefix); 1393 1394 // Only log if we had at lease one wakelock... 1395 if (sb.length() > 0) { 1396 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString()); 1397 } 1398 } 1399 } 1400 1401 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1402 if (sensors.size() > 0) { 1403 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1404 : sensors.entrySet()) { 1405 Uid.Sensor se = ent.getValue(); 1406 int sensorNumber = ent.getKey(); 1407 Timer timer = se.getSensorTime(); 1408 if (timer != null) { 1409 // Convert from microseconds to milliseconds with rounding 1410 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; 1411 int count = timer.getCountLocked(which); 1412 if (totalTime != 0) { 1413 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 1414 } 1415 } 1416 } 1417 } 1418 1419 Timer vibTimer = u.getVibratorOnTimer(); 1420 if (vibTimer != null) { 1421 // Convert from microseconds to milliseconds with rounding 1422 long totalTime = (vibTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; 1423 int count = vibTimer.getCountLocked(which); 1424 if (totalTime != 0) { 1425 dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count); 1426 } 1427 } 1428 1429 Timer fgTimer = u.getForegroundActivityTimer(); 1430 if (fgTimer != null) { 1431 // Convert from microseconds to milliseconds with rounding 1432 long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; 1433 int count = fgTimer.getCountLocked(which); 1434 if (totalTime != 0) { 1435 dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count); 1436 } 1437 } 1438 1439 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 1440 if (processStats.size() > 0) { 1441 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 1442 : processStats.entrySet()) { 1443 Uid.Proc ps = ent.getValue(); 1444 1445 final long userMillis = ps.getUserTime(which) * 10; 1446 final long systemMillis = ps.getSystemTime(which) * 10; 1447 final long foregroundMillis = ps.getForegroundTime(which) * 10; 1448 final long starts = ps.getStarts(which); 1449 1450 if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0 1451 || starts != 0) { 1452 dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis, 1453 systemMillis, foregroundMillis, starts); 1454 } 1455 } 1456 } 1457 1458 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 1459 if (packageStats.size() > 0) { 1460 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 1461 : packageStats.entrySet()) { 1462 1463 Uid.Pkg ps = ent.getValue(); 1464 int wakeups = ps.getWakeups(which); 1465 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 1466 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 1467 : serviceStats.entrySet()) { 1468 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 1469 long startTime = ss.getStartTime(batteryUptime, which); 1470 int starts = ss.getStarts(which); 1471 int launches = ss.getLaunches(which); 1472 if (startTime != 0 || starts != 0 || launches != 0) { 1473 dumpLine(pw, uid, category, APK_DATA, 1474 wakeups, // wakeup alarms 1475 ent.getKey(), // Apk 1476 sent.getKey(), // service 1477 startTime / 1000, // time spent started, in ms 1478 starts, 1479 launches); 1480 } 1481 } 1482 } 1483 } 1484 } 1485 } 1486 1487 static final class TimerEntry { 1488 final String mName; 1489 final int mId; 1490 final BatteryStats.Timer mTimer; 1491 final long mTime; 1492 TimerEntry(String name, int id, BatteryStats.Timer timer, long time) { 1493 mName = name; 1494 mId = id; 1495 mTimer = timer; 1496 mTime = time; 1497 } 1498 } 1499 1500 @SuppressWarnings("unused") 1501 public final void dumpLocked(PrintWriter pw, String prefix, final int which, int reqUid) { 1502 final long rawUptime = SystemClock.uptimeMillis() * 1000; 1503 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 1504 final long batteryUptime = getBatteryUptime(rawUptime); 1505 final long batteryRealtime = getBatteryRealtime(rawRealtime); 1506 1507 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 1508 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 1509 final long totalRealtime = computeRealtime(rawRealtime, which); 1510 final long totalUptime = computeUptime(rawUptime, which); 1511 1512 StringBuilder sb = new StringBuilder(128); 1513 1514 SparseArray<? extends Uid> uidStats = getUidStats(); 1515 final int NU = uidStats.size(); 1516 1517 sb.setLength(0); 1518 sb.append(prefix); 1519 sb.append(" Time on battery: "); 1520 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("("); 1521 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime)); 1522 sb.append(") realtime, "); 1523 formatTimeMs(sb, whichBatteryUptime / 1000); 1524 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime)); 1525 sb.append(") uptime"); 1526 pw.println(sb.toString()); 1527 sb.setLength(0); 1528 sb.append(prefix); 1529 sb.append(" Total run time: "); 1530 formatTimeMs(sb, totalRealtime / 1000); 1531 sb.append("realtime, "); 1532 formatTimeMs(sb, totalUptime / 1000); 1533 sb.append("uptime, "); 1534 pw.println(sb.toString()); 1535 1536 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 1537 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 1538 final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which); 1539 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 1540 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 1541 sb.setLength(0); 1542 sb.append(prefix); 1543 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000); 1544 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime)); 1545 sb.append("), Input events: "); sb.append(getInputEventCount(which)); 1546 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000); 1547 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime)); 1548 sb.append(")"); 1549 pw.println(sb.toString()); 1550 sb.setLength(0); 1551 sb.append(prefix); 1552 sb.append(" Screen brightnesses: "); 1553 boolean didOne = false; 1554 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1555 final long time = getScreenBrightnessTime(i, batteryRealtime, which); 1556 if (time == 0) { 1557 continue; 1558 } 1559 if (didOne) sb.append(", "); 1560 didOne = true; 1561 sb.append(SCREEN_BRIGHTNESS_NAMES[i]); 1562 sb.append(" "); 1563 formatTimeMs(sb, time/1000); 1564 sb.append("("); 1565 sb.append(formatRatioLocked(time, screenOnTime)); 1566 sb.append(")"); 1567 } 1568 if (!didOne) sb.append("No activity"); 1569 pw.println(sb.toString()); 1570 1571 // Calculate total network and wakelock times across all uids. 1572 long rxTotal = 0; 1573 long txTotal = 0; 1574 long fullWakeLockTimeTotalMicros = 0; 1575 long partialWakeLockTimeTotalMicros = 0; 1576 1577 final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() { 1578 @Override 1579 public int compare(TimerEntry lhs, TimerEntry rhs) { 1580 long lhsTime = lhs.mTime; 1581 long rhsTime = rhs.mTime; 1582 if (lhsTime < rhsTime) { 1583 return 1; 1584 } 1585 if (lhsTime > rhsTime) { 1586 return -1; 1587 } 1588 return 0; 1589 } 1590 }; 1591 1592 if (reqUid < 0) { 1593 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); 1594 if (kernelWakelocks.size() > 0) { 1595 final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>(); 1596 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { 1597 BatteryStats.Timer timer = ent.getValue(); 1598 long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which); 1599 if (totalTimeMillis > 0) { 1600 timers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis)); 1601 } 1602 } 1603 Collections.sort(timers, timerComparator); 1604 for (int i=0; i<timers.size(); i++) { 1605 TimerEntry timer = timers.get(i); 1606 String linePrefix = ": "; 1607 sb.setLength(0); 1608 sb.append(prefix); 1609 sb.append(" Kernel Wake lock "); 1610 sb.append(timer.mName); 1611 linePrefix = printWakeLock(sb, timer.mTimer, batteryRealtime, null, 1612 which, linePrefix); 1613 if (!linePrefix.equals(": ")) { 1614 sb.append(" realtime"); 1615 // Only print out wake locks that were held 1616 pw.println(sb.toString()); 1617 } 1618 } 1619 } 1620 } 1621 1622 final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>(); 1623 1624 for (int iu = 0; iu < NU; iu++) { 1625 Uid u = uidStats.valueAt(iu); 1626 rxTotal += u.getTcpBytesReceived(which); 1627 txTotal += u.getTcpBytesSent(which); 1628 1629 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1630 if (wakelocks.size() > 0) { 1631 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1632 : wakelocks.entrySet()) { 1633 Uid.Wakelock wl = ent.getValue(); 1634 1635 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 1636 if (fullWakeTimer != null) { 1637 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked( 1638 batteryRealtime, which); 1639 } 1640 1641 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 1642 if (partialWakeTimer != null) { 1643 long totalTimeMicros = partialWakeTimer.getTotalTimeLocked( 1644 batteryRealtime, which); 1645 if (totalTimeMicros > 0) { 1646 if (reqUid < 0) { 1647 // Only show the ordered list of all wake 1648 // locks if the caller is not asking for data 1649 // about a specific uid. 1650 timers.add(new TimerEntry(ent.getKey(), u.getUid(), 1651 partialWakeTimer, totalTimeMicros)); 1652 } 1653 partialWakeLockTimeTotalMicros += totalTimeMicros; 1654 } 1655 } 1656 } 1657 } 1658 } 1659 1660 pw.print(prefix); 1661 pw.print(" Total received: "); pw.print(formatBytesLocked(rxTotal)); 1662 pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal)); 1663 sb.setLength(0); 1664 sb.append(prefix); 1665 sb.append(" Total full wakelock time: "); formatTimeMs(sb, 1666 (fullWakeLockTimeTotalMicros + 500) / 1000); 1667 sb.append(", Total partial wakelock time: "); formatTimeMs(sb, 1668 (partialWakeLockTimeTotalMicros + 500) / 1000); 1669 pw.println(sb.toString()); 1670 1671 sb.setLength(0); 1672 sb.append(prefix); 1673 sb.append(" Signal levels: "); 1674 didOne = false; 1675 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 1676 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which); 1677 if (time == 0) { 1678 continue; 1679 } 1680 if (didOne) sb.append(", "); 1681 didOne = true; 1682 sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]); 1683 sb.append(" "); 1684 formatTimeMs(sb, time/1000); 1685 sb.append("("); 1686 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1687 sb.append(") "); 1688 sb.append(getPhoneSignalStrengthCount(i, which)); 1689 sb.append("x"); 1690 } 1691 if (!didOne) sb.append("No activity"); 1692 pw.println(sb.toString()); 1693 1694 sb.setLength(0); 1695 sb.append(prefix); 1696 sb.append(" Signal scanning time: "); 1697 formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000); 1698 pw.println(sb.toString()); 1699 1700 sb.setLength(0); 1701 sb.append(prefix); 1702 sb.append(" Radio types: "); 1703 didOne = false; 1704 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1705 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which); 1706 if (time == 0) { 1707 continue; 1708 } 1709 if (didOne) sb.append(", "); 1710 didOne = true; 1711 sb.append(DATA_CONNECTION_NAMES[i]); 1712 sb.append(" "); 1713 formatTimeMs(sb, time/1000); 1714 sb.append("("); 1715 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1716 sb.append(") "); 1717 sb.append(getPhoneDataConnectionCount(i, which)); 1718 sb.append("x"); 1719 } 1720 if (!didOne) sb.append("No activity"); 1721 pw.println(sb.toString()); 1722 1723 sb.setLength(0); 1724 sb.append(prefix); 1725 sb.append(" Radio data uptime when unplugged: "); 1726 sb.append(getRadioDataUptime() / 1000); 1727 sb.append(" ms"); 1728 pw.println(sb.toString()); 1729 1730 sb.setLength(0); 1731 sb.append(prefix); 1732 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000); 1733 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime)); 1734 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000); 1735 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime)); 1736 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000); 1737 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)); 1738 sb.append(")"); 1739 pw.println(sb.toString()); 1740 1741 pw.println(" "); 1742 1743 if (which == STATS_SINCE_UNPLUGGED) { 1744 if (getIsOnBattery()) { 1745 pw.print(prefix); pw.println(" Device is currently unplugged"); 1746 pw.print(prefix); pw.print(" Discharge cycle start level: "); 1747 pw.println(getDischargeStartLevel()); 1748 pw.print(prefix); pw.print(" Discharge cycle current level: "); 1749 pw.println(getDischargeCurrentLevel()); 1750 } else { 1751 pw.print(prefix); pw.println(" Device is currently plugged into power"); 1752 pw.print(prefix); pw.print(" Last discharge cycle start level: "); 1753 pw.println(getDischargeStartLevel()); 1754 pw.print(prefix); pw.print(" Last discharge cycle end level: "); 1755 pw.println(getDischargeCurrentLevel()); 1756 } 1757 pw.print(prefix); pw.print(" Amount discharged while screen on: "); 1758 pw.println(getDischargeAmountScreenOn()); 1759 pw.print(prefix); pw.print(" Amount discharged while screen off: "); 1760 pw.println(getDischargeAmountScreenOff()); 1761 pw.println(" "); 1762 } else { 1763 pw.print(prefix); pw.println(" Device battery use since last full charge"); 1764 pw.print(prefix); pw.print(" Amount discharged (lower bound): "); 1765 pw.println(getLowDischargeAmountSinceCharge()); 1766 pw.print(prefix); pw.print(" Amount discharged (upper bound): "); 1767 pw.println(getHighDischargeAmountSinceCharge()); 1768 pw.print(prefix); pw.print(" Amount discharged while screen on: "); 1769 pw.println(getDischargeAmountScreenOnSinceCharge()); 1770 pw.print(prefix); pw.print(" Amount discharged while screen off: "); 1771 pw.println(getDischargeAmountScreenOffSinceCharge()); 1772 pw.println(); 1773 } 1774 1775 if (timers.size() > 0) { 1776 Collections.sort(timers, timerComparator); 1777 pw.print(prefix); pw.println(" All partial wake locks:"); 1778 for (int i=0; i<timers.size(); i++) { 1779 TimerEntry timer = timers.get(i); 1780 sb.setLength(0); 1781 sb.append(" Wake lock #"); 1782 sb.append(timer.mId); 1783 sb.append(" "); 1784 sb.append(timer.mName); 1785 printWakeLock(sb, timer.mTimer, batteryRealtime, null, which, ": "); 1786 sb.append(" realtime"); 1787 pw.println(sb.toString()); 1788 } 1789 timers.clear(); 1790 pw.println(); 1791 } 1792 1793 for (int iu=0; iu<NU; iu++) { 1794 final int uid = uidStats.keyAt(iu); 1795 if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) { 1796 continue; 1797 } 1798 1799 Uid u = uidStats.valueAt(iu); 1800 1801 pw.println(prefix + " #" + uid + ":"); 1802 boolean uidActivity = false; 1803 1804 long tcpReceived = u.getTcpBytesReceived(which); 1805 long tcpSent = u.getTcpBytesSent(which); 1806 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 1807 long wifiScanTime = u.getWifiScanTime(batteryRealtime, which); 1808 long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which); 1809 1810 if (tcpReceived != 0 || tcpSent != 0) { 1811 pw.print(prefix); pw.print(" Network: "); 1812 pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, "); 1813 pw.print(formatBytesLocked(tcpSent)); pw.println(" sent"); 1814 } 1815 1816 if (u.hasUserActivity()) { 1817 boolean hasData = false; 1818 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 1819 int val = u.getUserActivityCount(i, which); 1820 if (val != 0) { 1821 if (!hasData) { 1822 sb.setLength(0); 1823 sb.append(" User activity: "); 1824 hasData = true; 1825 } else { 1826 sb.append(", "); 1827 } 1828 sb.append(val); 1829 sb.append(" "); 1830 sb.append(Uid.USER_ACTIVITY_TYPES[i]); 1831 } 1832 } 1833 if (hasData) { 1834 pw.println(sb.toString()); 1835 } 1836 } 1837 1838 if (fullWifiLockOnTime != 0 || wifiScanTime != 0 1839 || uidWifiRunningTime != 0) { 1840 sb.setLength(0); 1841 sb.append(prefix); sb.append(" Wifi Running: "); 1842 formatTimeMs(sb, uidWifiRunningTime / 1000); 1843 sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime, 1844 whichBatteryRealtime)); sb.append(")\n"); 1845 sb.append(prefix); sb.append(" Full Wifi Lock: "); 1846 formatTimeMs(sb, fullWifiLockOnTime / 1000); 1847 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime, 1848 whichBatteryRealtime)); sb.append(")\n"); 1849 sb.append(prefix); sb.append(" Wifi Scan: "); 1850 formatTimeMs(sb, wifiScanTime / 1000); 1851 sb.append("("); sb.append(formatRatioLocked(wifiScanTime, 1852 whichBatteryRealtime)); sb.append(")"); 1853 pw.println(sb.toString()); 1854 } 1855 1856 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1857 if (wakelocks.size() > 0) { 1858 long totalFull = 0, totalPartial = 0, totalWindow = 0; 1859 int count = 0; 1860 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1861 : wakelocks.entrySet()) { 1862 Uid.Wakelock wl = ent.getValue(); 1863 String linePrefix = ": "; 1864 sb.setLength(0); 1865 sb.append(prefix); 1866 sb.append(" Wake lock "); 1867 sb.append(ent.getKey()); 1868 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 1869 "full", which, linePrefix); 1870 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 1871 "partial", which, linePrefix); 1872 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 1873 "window", which, linePrefix); 1874 if (!linePrefix.equals(": ")) { 1875 sb.append(" realtime"); 1876 // Only print out wake locks that were held 1877 pw.println(sb.toString()); 1878 uidActivity = true; 1879 count++; 1880 } 1881 totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL), 1882 batteryRealtime, which); 1883 totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL), 1884 batteryRealtime, which); 1885 totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW), 1886 batteryRealtime, which); 1887 } 1888 if (count > 1) { 1889 if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) { 1890 sb.setLength(0); 1891 sb.append(prefix); 1892 sb.append(" TOTAL wake: "); 1893 boolean needComma = false; 1894 if (totalFull != 0) { 1895 needComma = true; 1896 formatTimeMs(sb, totalFull); 1897 sb.append("full"); 1898 } 1899 if (totalPartial != 0) { 1900 if (needComma) { 1901 sb.append(", "); 1902 } 1903 needComma = true; 1904 formatTimeMs(sb, totalPartial); 1905 sb.append("partial"); 1906 } 1907 if (totalWindow != 0) { 1908 if (needComma) { 1909 sb.append(", "); 1910 } 1911 needComma = true; 1912 formatTimeMs(sb, totalWindow); 1913 sb.append("window"); 1914 } 1915 sb.append(" realtime"); 1916 pw.println(sb.toString()); 1917 } 1918 } 1919 } 1920 1921 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1922 if (sensors.size() > 0) { 1923 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1924 : sensors.entrySet()) { 1925 Uid.Sensor se = ent.getValue(); 1926 int sensorNumber = ent.getKey(); 1927 sb.setLength(0); 1928 sb.append(prefix); 1929 sb.append(" Sensor "); 1930 int handle = se.getHandle(); 1931 if (handle == Uid.Sensor.GPS) { 1932 sb.append("GPS"); 1933 } else { 1934 sb.append(handle); 1935 } 1936 sb.append(": "); 1937 1938 Timer timer = se.getSensorTime(); 1939 if (timer != null) { 1940 // Convert from microseconds to milliseconds with rounding 1941 long totalTime = (timer.getTotalTimeLocked( 1942 batteryRealtime, which) + 500) / 1000; 1943 int count = timer.getCountLocked(which); 1944 //timer.logState(); 1945 if (totalTime != 0) { 1946 formatTimeMs(sb, totalTime); 1947 sb.append("realtime ("); 1948 sb.append(count); 1949 sb.append(" times)"); 1950 } else { 1951 sb.append("(not used)"); 1952 } 1953 } else { 1954 sb.append("(not used)"); 1955 } 1956 1957 pw.println(sb.toString()); 1958 uidActivity = true; 1959 } 1960 } 1961 1962 Timer vibTimer = u.getVibratorOnTimer(); 1963 if (vibTimer != null) { 1964 // Convert from microseconds to milliseconds with rounding 1965 long totalTime = (vibTimer.getTotalTimeLocked( 1966 batteryRealtime, which) + 500) / 1000; 1967 int count = vibTimer.getCountLocked(which); 1968 //timer.logState(); 1969 if (totalTime != 0) { 1970 sb.setLength(0); 1971 sb.append(prefix); 1972 sb.append(" Vibrator: "); 1973 formatTimeMs(sb, totalTime); 1974 sb.append("realtime ("); 1975 sb.append(count); 1976 sb.append(" times)"); 1977 pw.println(sb.toString()); 1978 uidActivity = true; 1979 } 1980 } 1981 1982 Timer fgTimer = u.getForegroundActivityTimer(); 1983 if (fgTimer != null) { 1984 // Convert from microseconds to milliseconds with rounding 1985 long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; 1986 int count = fgTimer.getCountLocked(which); 1987 if (totalTime != 0) { 1988 sb.setLength(0); 1989 sb.append(prefix); 1990 sb.append(" Foreground activities: "); 1991 formatTimeMs(sb, totalTime); 1992 sb.append("realtime ("); 1993 sb.append(count); 1994 sb.append(" times)"); 1995 pw.println(sb.toString()); 1996 uidActivity = true; 1997 } 1998 } 1999 2000 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 2001 if (processStats.size() > 0) { 2002 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 2003 : processStats.entrySet()) { 2004 Uid.Proc ps = ent.getValue(); 2005 long userTime; 2006 long systemTime; 2007 long foregroundTime; 2008 int starts; 2009 int numExcessive; 2010 2011 userTime = ps.getUserTime(which); 2012 systemTime = ps.getSystemTime(which); 2013 foregroundTime = ps.getForegroundTime(which); 2014 starts = ps.getStarts(which); 2015 numExcessive = which == STATS_SINCE_CHARGED 2016 ? ps.countExcessivePowers() : 0; 2017 2018 if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0 2019 || numExcessive != 0) { 2020 sb.setLength(0); 2021 sb.append(prefix); sb.append(" Proc "); 2022 sb.append(ent.getKey()); sb.append(":\n"); 2023 sb.append(prefix); sb.append(" CPU: "); 2024 formatTime(sb, userTime); sb.append("usr + "); 2025 formatTime(sb, systemTime); sb.append("krn ; "); 2026 formatTime(sb, foregroundTime); sb.append("fg"); 2027 if (starts != 0) { 2028 sb.append("\n"); sb.append(prefix); sb.append(" "); 2029 sb.append(starts); sb.append(" proc starts"); 2030 } 2031 pw.println(sb.toString()); 2032 for (int e=0; e<numExcessive; e++) { 2033 Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e); 2034 if (ew != null) { 2035 pw.print(prefix); pw.print(" * Killed for "); 2036 if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) { 2037 pw.print("wake lock"); 2038 } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) { 2039 pw.print("cpu"); 2040 } else { 2041 pw.print("unknown"); 2042 } 2043 pw.print(" use: "); 2044 TimeUtils.formatDuration(ew.usedTime, pw); 2045 pw.print(" over "); 2046 TimeUtils.formatDuration(ew.overTime, pw); 2047 pw.print(" ("); 2048 pw.print((ew.usedTime*100)/ew.overTime); 2049 pw.println("%)"); 2050 } 2051 } 2052 uidActivity = true; 2053 } 2054 } 2055 } 2056 2057 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 2058 if (packageStats.size() > 0) { 2059 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 2060 : packageStats.entrySet()) { 2061 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":"); 2062 boolean apkActivity = false; 2063 Uid.Pkg ps = ent.getValue(); 2064 int wakeups = ps.getWakeups(which); 2065 if (wakeups != 0) { 2066 pw.print(prefix); pw.print(" "); 2067 pw.print(wakeups); pw.println(" wakeup alarms"); 2068 apkActivity = true; 2069 } 2070 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 2071 if (serviceStats.size() > 0) { 2072 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 2073 : serviceStats.entrySet()) { 2074 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 2075 long startTime = ss.getStartTime(batteryUptime, which); 2076 int starts = ss.getStarts(which); 2077 int launches = ss.getLaunches(which); 2078 if (startTime != 0 || starts != 0 || launches != 0) { 2079 sb.setLength(0); 2080 sb.append(prefix); sb.append(" Service "); 2081 sb.append(sent.getKey()); sb.append(":\n"); 2082 sb.append(prefix); sb.append(" Created for: "); 2083 formatTimeMs(sb, startTime / 1000); 2084 sb.append("uptime\n"); 2085 sb.append(prefix); sb.append(" Starts: "); 2086 sb.append(starts); 2087 sb.append(", launches: "); sb.append(launches); 2088 pw.println(sb.toString()); 2089 apkActivity = true; 2090 } 2091 } 2092 } 2093 if (!apkActivity) { 2094 pw.print(prefix); pw.println(" (nothing executed)"); 2095 } 2096 uidActivity = true; 2097 } 2098 } 2099 if (!uidActivity) { 2100 pw.print(prefix); pw.println(" (nothing executed)"); 2101 } 2102 } 2103 } 2104 2105 static void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) { 2106 int diff = oldval ^ newval; 2107 if (diff == 0) return; 2108 for (int i=0; i<descriptions.length; i++) { 2109 BitDescription bd = descriptions[i]; 2110 if ((diff&bd.mask) != 0) { 2111 if (bd.shift < 0) { 2112 pw.print((newval&bd.mask) != 0 ? " +" : " -"); 2113 pw.print(bd.name); 2114 } else { 2115 pw.print(" "); 2116 pw.print(bd.name); 2117 pw.print("="); 2118 int val = (newval&bd.mask)>>bd.shift; 2119 if (bd.values != null && val >= 0 && val < bd.values.length) { 2120 pw.print(bd.values[val]); 2121 } else { 2122 pw.print(val); 2123 } 2124 } 2125 } 2126 } 2127 } 2128 2129 public void prepareForDumpLocked() { 2130 } 2131 2132 public static class HistoryPrinter { 2133 int oldState = 0; 2134 int oldStatus = -1; 2135 int oldHealth = -1; 2136 int oldPlug = -1; 2137 int oldTemp = -1; 2138 int oldVolt = -1; 2139 2140 public void printNextItem(PrintWriter pw, HistoryItem rec, long now) { 2141 pw.print(" "); 2142 TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN); 2143 pw.print(" "); 2144 if (rec.cmd == HistoryItem.CMD_START) { 2145 pw.println(" START"); 2146 } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) { 2147 pw.println(" *OVERFLOW*"); 2148 } else { 2149 if (rec.batteryLevel < 10) pw.print("00"); 2150 else if (rec.batteryLevel < 100) pw.print("0"); 2151 pw.print(rec.batteryLevel); 2152 pw.print(" "); 2153 if (rec.states < 0x10) pw.print("0000000"); 2154 else if (rec.states < 0x100) pw.print("000000"); 2155 else if (rec.states < 0x1000) pw.print("00000"); 2156 else if (rec.states < 0x10000) pw.print("0000"); 2157 else if (rec.states < 0x100000) pw.print("000"); 2158 else if (rec.states < 0x1000000) pw.print("00"); 2159 else if (rec.states < 0x10000000) pw.print("0"); 2160 pw.print(Integer.toHexString(rec.states)); 2161 if (oldStatus != rec.batteryStatus) { 2162 oldStatus = rec.batteryStatus; 2163 pw.print(" status="); 2164 switch (oldStatus) { 2165 case BatteryManager.BATTERY_STATUS_UNKNOWN: 2166 pw.print("unknown"); 2167 break; 2168 case BatteryManager.BATTERY_STATUS_CHARGING: 2169 pw.print("charging"); 2170 break; 2171 case BatteryManager.BATTERY_STATUS_DISCHARGING: 2172 pw.print("discharging"); 2173 break; 2174 case BatteryManager.BATTERY_STATUS_NOT_CHARGING: 2175 pw.print("not-charging"); 2176 break; 2177 case BatteryManager.BATTERY_STATUS_FULL: 2178 pw.print("full"); 2179 break; 2180 default: 2181 pw.print(oldStatus); 2182 break; 2183 } 2184 } 2185 if (oldHealth != rec.batteryHealth) { 2186 oldHealth = rec.batteryHealth; 2187 pw.print(" health="); 2188 switch (oldHealth) { 2189 case BatteryManager.BATTERY_HEALTH_UNKNOWN: 2190 pw.print("unknown"); 2191 break; 2192 case BatteryManager.BATTERY_HEALTH_GOOD: 2193 pw.print("good"); 2194 break; 2195 case BatteryManager.BATTERY_HEALTH_OVERHEAT: 2196 pw.print("overheat"); 2197 break; 2198 case BatteryManager.BATTERY_HEALTH_DEAD: 2199 pw.print("dead"); 2200 break; 2201 case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: 2202 pw.print("over-voltage"); 2203 break; 2204 case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: 2205 pw.print("failure"); 2206 break; 2207 default: 2208 pw.print(oldHealth); 2209 break; 2210 } 2211 } 2212 if (oldPlug != rec.batteryPlugType) { 2213 oldPlug = rec.batteryPlugType; 2214 pw.print(" plug="); 2215 switch (oldPlug) { 2216 case 0: 2217 pw.print("none"); 2218 break; 2219 case BatteryManager.BATTERY_PLUGGED_AC: 2220 pw.print("ac"); 2221 break; 2222 case BatteryManager.BATTERY_PLUGGED_USB: 2223 pw.print("usb"); 2224 break; 2225 case BatteryManager.BATTERY_PLUGGED_WIRELESS: 2226 pw.print("wireless"); 2227 break; 2228 default: 2229 pw.print(oldPlug); 2230 break; 2231 } 2232 } 2233 if (oldTemp != rec.batteryTemperature) { 2234 oldTemp = rec.batteryTemperature; 2235 pw.print(" temp="); 2236 pw.print(oldTemp); 2237 } 2238 if (oldVolt != rec.batteryVoltage) { 2239 oldVolt = rec.batteryVoltage; 2240 pw.print(" volt="); 2241 pw.print(oldVolt); 2242 } 2243 printBitDescriptions(pw, oldState, rec.states, 2244 HISTORY_STATE_DESCRIPTIONS); 2245 pw.println(); 2246 } 2247 oldState = rec.states; 2248 } 2249 } 2250 2251 /** 2252 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 2253 * 2254 * @param pw a Printer to receive the dump output. 2255 */ 2256 @SuppressWarnings("unused") 2257 public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly) { 2258 prepareForDumpLocked(); 2259 2260 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); 2261 2262 final HistoryItem rec = new HistoryItem(); 2263 if (startIteratingHistoryLocked()) { 2264 pw.println("Battery History:"); 2265 HistoryPrinter hprinter = new HistoryPrinter(); 2266 while (getNextHistoryLocked(rec)) { 2267 hprinter.printNextItem(pw, rec, now); 2268 } 2269 finishIteratingHistoryLocked(); 2270 pw.println(""); 2271 } 2272 2273 if (startIteratingOldHistoryLocked()) { 2274 pw.println("Old battery History:"); 2275 HistoryPrinter hprinter = new HistoryPrinter(); 2276 while (getNextOldHistoryLocked(rec)) { 2277 hprinter.printNextItem(pw, rec, now); 2278 } 2279 finishIteratingOldHistoryLocked(); 2280 pw.println(""); 2281 } 2282 2283 SparseArray<? extends Uid> uidStats = getUidStats(); 2284 final int NU = uidStats.size(); 2285 boolean didPid = false; 2286 long nowRealtime = SystemClock.elapsedRealtime(); 2287 for (int i=0; i<NU; i++) { 2288 Uid uid = uidStats.valueAt(i); 2289 SparseArray<? extends Uid.Pid> pids = uid.getPidStats(); 2290 if (pids != null) { 2291 for (int j=0; j<pids.size(); j++) { 2292 Uid.Pid pid = pids.valueAt(j); 2293 if (!didPid) { 2294 pw.println("Per-PID Stats:"); 2295 didPid = true; 2296 } 2297 long time = pid.mWakeSum + (pid.mWakeStart != 0 2298 ? (nowRealtime - pid.mWakeStart) : 0); 2299 pw.print(" PID "); pw.print(pids.keyAt(j)); 2300 pw.print(" wake time: "); 2301 TimeUtils.formatDuration(time, pw); 2302 pw.println(""); 2303 } 2304 } 2305 } 2306 if (didPid) { 2307 pw.println(""); 2308 } 2309 2310 if (!isUnpluggedOnly) { 2311 pw.println("Statistics since last charge:"); 2312 pw.println(" System starts: " + getStartCount() 2313 + ", currently on battery: " + getIsOnBattery()); 2314 dumpLocked(pw, "", STATS_SINCE_CHARGED, -1); 2315 pw.println(""); 2316 } 2317 pw.println("Statistics since last unplugged:"); 2318 dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, -1); 2319 } 2320 2321 @SuppressWarnings("unused") 2322 public void dumpCheckinLocked( 2323 PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly) { 2324 prepareForDumpLocked(); 2325 2326 if (apps != null) { 2327 SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>(); 2328 for (int i=0; i<apps.size(); i++) { 2329 ApplicationInfo ai = apps.get(i); 2330 ArrayList<String> pkgs = uids.get(ai.uid); 2331 if (pkgs == null) { 2332 pkgs = new ArrayList<String>(); 2333 uids.put(ai.uid, pkgs); 2334 } 2335 pkgs.add(ai.packageName); 2336 } 2337 SparseArray<? extends Uid> uidStats = getUidStats(); 2338 final int NU = uidStats.size(); 2339 String[] lineArgs = new String[2]; 2340 for (int i=0; i<NU; i++) { 2341 int uid = uidStats.keyAt(i); 2342 ArrayList<String> pkgs = uids.get(uid); 2343 if (pkgs != null) { 2344 for (int j=0; j<pkgs.size(); j++) { 2345 lineArgs[0] = Integer.toString(uid); 2346 lineArgs[1] = pkgs.get(j); 2347 dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA, 2348 (Object[])lineArgs); 2349 } 2350 } 2351 } 2352 } 2353 if (isUnpluggedOnly) { 2354 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1); 2355 } 2356 else { 2357 dumpCheckinLocked(pw, STATS_SINCE_CHARGED, -1); 2358 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1); 2359 } 2360 } 2361} 2362