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