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