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