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