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