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