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