BatteryStats.java revision b71703cfdfbac35a6e5afaa437d073cf835c25db
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 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_HSPAP = 15; 848 public static final int DATA_CONNECTION_OTHER = 16; 849 850 static final String[] DATA_CONNECTION_NAMES = { 851 "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A", 852 "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte", 853 "ehrpd", "hspap", "other" 854 }; 855 856 public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1; 857 858 /** 859 * Returns the time in microseconds that the phone has been running with 860 * the given data connection. 861 * 862 * {@hide} 863 */ 864 public abstract long getPhoneDataConnectionTime(int dataType, 865 long batteryRealtime, int which); 866 867 /** 868 * Returns the number of times the phone has entered the given data 869 * connection type. 870 * 871 * {@hide} 872 */ 873 public abstract int getPhoneDataConnectionCount(int dataType, int which); 874 875 public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS 876 = new BitDescription[] { 877 new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged"), 878 new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen"), 879 new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps"), 880 new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call"), 881 new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning"), 882 new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi"), 883 new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running"), 884 new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock"), 885 new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan"), 886 new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast"), 887 new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth"), 888 new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio"), 889 new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video"), 890 new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock"), 891 new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor"), 892 new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK, 893 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", 894 SCREEN_BRIGHTNESS_NAMES), 895 new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK, 896 HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength", 897 SignalStrength.SIGNAL_STRENGTH_NAMES), 898 new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK, 899 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", 900 new String[] {"in", "out", "emergency", "off"}), 901 new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK, 902 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", 903 DATA_CONNECTION_NAMES), 904 }; 905 906 /** 907 * Returns the time in microseconds that wifi has been on while the device was 908 * running on battery. 909 * 910 * {@hide} 911 */ 912 public abstract long getWifiOnTime(long batteryRealtime, int which); 913 914 /** 915 * Returns the time in microseconds that wifi has been on and the driver has 916 * been in the running state while the device was running on battery. 917 * 918 * {@hide} 919 */ 920 public abstract long getGlobalWifiRunningTime(long batteryRealtime, int which); 921 922 /** 923 * Returns the time in microseconds that bluetooth has been on while the device was 924 * running on battery. 925 * 926 * {@hide} 927 */ 928 public abstract long getBluetoothOnTime(long batteryRealtime, int which); 929 930 public static final int NETWORK_MOBILE_RX_BYTES = 0; 931 public static final int NETWORK_MOBILE_TX_BYTES = 1; 932 public static final int NETWORK_WIFI_RX_BYTES = 2; 933 public static final int NETWORK_WIFI_TX_BYTES = 3; 934 935 public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_BYTES + 1; 936 937 public abstract long getNetworkActivityCount(int type, int which); 938 939 /** 940 * Return whether we are currently running on battery. 941 */ 942 public abstract boolean getIsOnBattery(); 943 944 /** 945 * Returns a SparseArray containing the statistics for each uid. 946 */ 947 public abstract SparseArray<? extends Uid> getUidStats(); 948 949 /** 950 * Returns the current battery uptime in microseconds. 951 * 952 * @param curTime the amount of elapsed realtime in microseconds. 953 */ 954 public abstract long getBatteryUptime(long curTime); 955 956 /** 957 * @deprecated use getRadioDataUptime 958 */ 959 public long getRadioDataUptimeMs() { 960 return getRadioDataUptime() / 1000; 961 } 962 963 /** 964 * Returns the time that the radio was on for data transfers. 965 * @return the uptime in microseconds while unplugged 966 */ 967 public abstract long getRadioDataUptime(); 968 969 /** 970 * Returns the current battery realtime in microseconds. 971 * 972 * @param curTime the amount of elapsed realtime in microseconds. 973 */ 974 public abstract long getBatteryRealtime(long curTime); 975 976 /** 977 * Returns the battery percentage level at the last time the device was unplugged from power, or 978 * the last time it booted on battery power. 979 */ 980 public abstract int getDischargeStartLevel(); 981 982 /** 983 * Returns the current battery percentage level if we are in a discharge cycle, otherwise 984 * returns the level at the last plug event. 985 */ 986 public abstract int getDischargeCurrentLevel(); 987 988 /** 989 * Get the amount the battery has discharged since the stats were 990 * last reset after charging, as a lower-end approximation. 991 */ 992 public abstract int getLowDischargeAmountSinceCharge(); 993 994 /** 995 * Get the amount the battery has discharged since the stats were 996 * last reset after charging, as an upper-end approximation. 997 */ 998 public abstract int getHighDischargeAmountSinceCharge(); 999 1000 /** 1001 * Get the amount the battery has discharged while the screen was on, 1002 * since the last time power was unplugged. 1003 */ 1004 public abstract int getDischargeAmountScreenOn(); 1005 1006 /** 1007 * Get the amount the battery has discharged while the screen was on, 1008 * since the last time the device was charged. 1009 */ 1010 public abstract int getDischargeAmountScreenOnSinceCharge(); 1011 1012 /** 1013 * Get the amount the battery has discharged while the screen was off, 1014 * since the last time power was unplugged. 1015 */ 1016 public abstract int getDischargeAmountScreenOff(); 1017 1018 /** 1019 * Get the amount the battery has discharged while the screen was off, 1020 * since the last time the device was charged. 1021 */ 1022 public abstract int getDischargeAmountScreenOffSinceCharge(); 1023 1024 /** 1025 * Returns the total, last, or current battery uptime in microseconds. 1026 * 1027 * @param curTime the elapsed realtime in microseconds. 1028 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1029 */ 1030 public abstract long computeBatteryUptime(long curTime, int which); 1031 1032 /** 1033 * Returns the total, last, or current battery realtime in microseconds. 1034 * 1035 * @param curTime the current elapsed realtime in microseconds. 1036 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1037 */ 1038 public abstract long computeBatteryRealtime(long curTime, int which); 1039 1040 /** 1041 * Returns the total, last, or current uptime in microseconds. 1042 * 1043 * @param curTime the current elapsed realtime in microseconds. 1044 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1045 */ 1046 public abstract long computeUptime(long curTime, int which); 1047 1048 /** 1049 * Returns the total, last, or current realtime in microseconds. 1050 * * 1051 * @param curTime the current elapsed realtime in microseconds. 1052 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1053 */ 1054 public abstract long computeRealtime(long curTime, int which); 1055 1056 public abstract Map<String, ? extends Timer> getKernelWakelockStats(); 1057 1058 /** Returns the number of different speeds that the CPU can run at */ 1059 public abstract int getCpuSpeedSteps(); 1060 1061 private final static void formatTimeRaw(StringBuilder out, long seconds) { 1062 long days = seconds / (60 * 60 * 24); 1063 if (days != 0) { 1064 out.append(days); 1065 out.append("d "); 1066 } 1067 long used = days * 60 * 60 * 24; 1068 1069 long hours = (seconds - used) / (60 * 60); 1070 if (hours != 0 || used != 0) { 1071 out.append(hours); 1072 out.append("h "); 1073 } 1074 used += hours * 60 * 60; 1075 1076 long mins = (seconds-used) / 60; 1077 if (mins != 0 || used != 0) { 1078 out.append(mins); 1079 out.append("m "); 1080 } 1081 used += mins * 60; 1082 1083 if (seconds != 0 || used != 0) { 1084 out.append(seconds-used); 1085 out.append("s "); 1086 } 1087 } 1088 1089 private final static void formatTime(StringBuilder sb, long time) { 1090 long sec = time / 100; 1091 formatTimeRaw(sb, sec); 1092 sb.append((time - (sec * 100)) * 10); 1093 sb.append("ms "); 1094 } 1095 1096 private final static void formatTimeMs(StringBuilder sb, long time) { 1097 long sec = time / 1000; 1098 formatTimeRaw(sb, sec); 1099 sb.append(time - (sec * 1000)); 1100 sb.append("ms "); 1101 } 1102 1103 private final String formatRatioLocked(long num, long den) { 1104 if (den == 0L) { 1105 return "---%"; 1106 } 1107 float perc = ((float)num) / ((float)den) * 100; 1108 mFormatBuilder.setLength(0); 1109 mFormatter.format("%.1f%%", perc); 1110 return mFormatBuilder.toString(); 1111 } 1112 1113 private final String formatBytesLocked(long bytes) { 1114 mFormatBuilder.setLength(0); 1115 1116 if (bytes < BYTES_PER_KB) { 1117 return bytes + "B"; 1118 } else if (bytes < BYTES_PER_MB) { 1119 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB); 1120 return mFormatBuilder.toString(); 1121 } else if (bytes < BYTES_PER_GB){ 1122 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB); 1123 return mFormatBuilder.toString(); 1124 } else { 1125 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB); 1126 return mFormatBuilder.toString(); 1127 } 1128 } 1129 1130 private static long computeWakeLock(Timer timer, long batteryRealtime, int which) { 1131 if (timer != null) { 1132 // Convert from microseconds to milliseconds with rounding 1133 long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which); 1134 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 1135 return totalTimeMillis; 1136 } 1137 return 0; 1138 } 1139 1140 /** 1141 * 1142 * @param sb a StringBuilder object. 1143 * @param timer a Timer object contining the wakelock times. 1144 * @param batteryRealtime the current on-battery time in microseconds. 1145 * @param name the name of the wakelock. 1146 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1147 * @param linePrefix a String to be prepended to each line of output. 1148 * @return the line prefix 1149 */ 1150 private static final String printWakeLock(StringBuilder sb, Timer timer, 1151 long batteryRealtime, String name, int which, String linePrefix) { 1152 1153 if (timer != null) { 1154 long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which); 1155 1156 int count = timer.getCountLocked(which); 1157 if (totalTimeMillis != 0) { 1158 sb.append(linePrefix); 1159 formatTimeMs(sb, totalTimeMillis); 1160 if (name != null) { 1161 sb.append(name); 1162 sb.append(' '); 1163 } 1164 sb.append('('); 1165 sb.append(count); 1166 sb.append(" times)"); 1167 return ", "; 1168 } 1169 } 1170 return linePrefix; 1171 } 1172 1173 /** 1174 * Checkin version of wakelock printer. Prints simple comma-separated list. 1175 * 1176 * @param sb a StringBuilder object. 1177 * @param timer a Timer object contining the wakelock times. 1178 * @param now the current time in microseconds. 1179 * @param name the name of the wakelock. 1180 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT. 1181 * @param linePrefix a String to be prepended to each line of output. 1182 * @return the line prefix 1183 */ 1184 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now, 1185 String name, int which, String linePrefix) { 1186 long totalTimeMicros = 0; 1187 int count = 0; 1188 if (timer != null) { 1189 totalTimeMicros = timer.getTotalTimeLocked(now, which); 1190 count = timer.getCountLocked(which); 1191 } 1192 sb.append(linePrefix); 1193 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 1194 sb.append(','); 1195 sb.append(name != null ? name + "," : ""); 1196 sb.append(count); 1197 return ","; 1198 } 1199 1200 /** 1201 * Dump a comma-separated line of values for terse checkin mode. 1202 * 1203 * @param pw the PageWriter to dump log to 1204 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 1205 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 1206 * @param args type-dependent data arguments 1207 */ 1208 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 1209 Object... args ) { 1210 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 1211 pw.print(uid); pw.print(','); 1212 pw.print(category); pw.print(','); 1213 pw.print(type); 1214 1215 for (Object arg : args) { 1216 pw.print(','); 1217 pw.print(arg); 1218 } 1219 pw.println(); 1220 } 1221 1222 /** 1223 * Checkin server version of dump to produce more compact, computer-readable log. 1224 * 1225 * NOTE: all times are expressed in 'ms'. 1226 */ 1227 public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) { 1228 final long rawUptime = SystemClock.uptimeMillis() * 1000; 1229 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 1230 final long batteryUptime = getBatteryUptime(rawUptime); 1231 final long batteryRealtime = getBatteryRealtime(rawRealtime); 1232 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 1233 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 1234 final long totalRealtime = computeRealtime(rawRealtime, which); 1235 final long totalUptime = computeUptime(rawUptime, which); 1236 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 1237 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 1238 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 1239 final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which); 1240 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 1241 1242 StringBuilder sb = new StringBuilder(128); 1243 1244 SparseArray<? extends Uid> uidStats = getUidStats(); 1245 final int NU = uidStats.size(); 1246 1247 String category = STAT_NAMES[which]; 1248 1249 // Dump "battery" stat 1250 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 1251 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A", 1252 whichBatteryRealtime / 1000, whichBatteryUptime / 1000, 1253 totalRealtime / 1000, totalUptime / 1000); 1254 1255 // Calculate total network and wakelock times across all uids. 1256 long mobileRxTotal = 0; 1257 long mobileTxTotal = 0; 1258 long wifiRxTotal = 0; 1259 long wifiTxTotal = 0; 1260 long fullWakeLockTimeTotal = 0; 1261 long partialWakeLockTimeTotal = 0; 1262 1263 for (int iu = 0; iu < NU; iu++) { 1264 Uid u = uidStats.valueAt(iu); 1265 mobileRxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which); 1266 mobileTxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which); 1267 wifiRxTotal += u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which); 1268 wifiTxTotal += u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which); 1269 1270 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1271 if (wakelocks.size() > 0) { 1272 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1273 : wakelocks.entrySet()) { 1274 Uid.Wakelock wl = ent.getValue(); 1275 1276 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 1277 if (fullWakeTimer != null) { 1278 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which); 1279 } 1280 1281 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 1282 if (partialWakeTimer != null) { 1283 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked( 1284 batteryRealtime, which); 1285 } 1286 } 1287 } 1288 } 1289 1290 // Dump misc stats 1291 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 1292 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, 1293 wifiRunningTime / 1000, bluetoothOnTime / 1000, 1294 mobileRxTotal, mobileTxTotal, wifiRxTotal, wifiTxTotal, 1295 fullWakeLockTimeTotal, partialWakeLockTimeTotal, 1296 getInputEventCount(which)); 1297 1298 // Dump screen brightness stats 1299 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; 1300 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1301 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000; 1302 } 1303 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args); 1304 1305 // Dump signal strength stats 1306 args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 1307 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 1308 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000; 1309 } 1310 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args); 1311 dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA, 1312 getPhoneSignalScanningTime(batteryRealtime, which) / 1000); 1313 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 1314 args[i] = getPhoneSignalStrengthCount(i, which); 1315 } 1316 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args); 1317 1318 // Dump network type stats 1319 args = new Object[NUM_DATA_CONNECTION_TYPES]; 1320 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1321 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000; 1322 } 1323 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args); 1324 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1325 args[i] = getPhoneDataConnectionCount(i, which); 1326 } 1327 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args); 1328 1329 if (which == STATS_SINCE_UNPLUGGED) { 1330 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), 1331 getDischargeCurrentLevel()); 1332 } 1333 1334 if (which == STATS_SINCE_UNPLUGGED) { 1335 dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, 1336 getDischargeStartLevel()-getDischargeCurrentLevel(), 1337 getDischargeStartLevel()-getDischargeCurrentLevel(), 1338 getDischargeAmountScreenOn(), getDischargeAmountScreenOff()); 1339 } else { 1340 dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, 1341 getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(), 1342 getDischargeAmountScreenOn(), getDischargeAmountScreenOff()); 1343 } 1344 1345 if (reqUid < 0) { 1346 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); 1347 if (kernelWakelocks.size() > 0) { 1348 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { 1349 sb.setLength(0); 1350 printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, ""); 1351 1352 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(), 1353 sb.toString()); 1354 } 1355 } 1356 } 1357 1358 for (int iu = 0; iu < NU; iu++) { 1359 final int uid = uidStats.keyAt(iu); 1360 if (reqUid >= 0 && uid != reqUid) { 1361 continue; 1362 } 1363 Uid u = uidStats.valueAt(iu); 1364 // Dump Network stats per uid, if any 1365 long mobileRx = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which); 1366 long mobileTx = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which); 1367 long wifiRx = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which); 1368 long wifiTx = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which); 1369 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 1370 long wifiScanTime = u.getWifiScanTime(batteryRealtime, which); 1371 long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which); 1372 1373 if (mobileRx > 0 || mobileTx > 0 || wifiRx > 0 || wifiTx > 0) { 1374 dumpLine(pw, uid, category, NETWORK_DATA, mobileRx, mobileTx, wifiRx, wifiTx); 1375 } 1376 1377 if (fullWifiLockOnTime != 0 || wifiScanTime != 0 1378 || uidWifiRunningTime != 0) { 1379 dumpLine(pw, uid, category, WIFI_DATA, 1380 fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime); 1381 } 1382 1383 if (u.hasUserActivity()) { 1384 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES]; 1385 boolean hasData = false; 1386 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 1387 int val = u.getUserActivityCount(i, which); 1388 args[i] = val; 1389 if (val != 0) hasData = true; 1390 } 1391 if (hasData) { 1392 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args); 1393 } 1394 } 1395 1396 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1397 if (wakelocks.size() > 0) { 1398 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1399 : wakelocks.entrySet()) { 1400 Uid.Wakelock wl = ent.getValue(); 1401 String linePrefix = ""; 1402 sb.setLength(0); 1403 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), 1404 batteryRealtime, "f", which, linePrefix); 1405 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), 1406 batteryRealtime, "p", which, linePrefix); 1407 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), 1408 batteryRealtime, "w", which, linePrefix); 1409 1410 // Only log if we had at lease one wakelock... 1411 if (sb.length() > 0) { 1412 String name = ent.getKey(); 1413 if (name.indexOf(',') >= 0) { 1414 name = name.replace(',', '_'); 1415 } 1416 dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString()); 1417 } 1418 } 1419 } 1420 1421 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1422 if (sensors.size() > 0) { 1423 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1424 : sensors.entrySet()) { 1425 Uid.Sensor se = ent.getValue(); 1426 int sensorNumber = ent.getKey(); 1427 Timer timer = se.getSensorTime(); 1428 if (timer != null) { 1429 // Convert from microseconds to milliseconds with rounding 1430 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; 1431 int count = timer.getCountLocked(which); 1432 if (totalTime != 0) { 1433 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 1434 } 1435 } 1436 } 1437 } 1438 1439 Timer vibTimer = u.getVibratorOnTimer(); 1440 if (vibTimer != null) { 1441 // Convert from microseconds to milliseconds with rounding 1442 long totalTime = (vibTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; 1443 int count = vibTimer.getCountLocked(which); 1444 if (totalTime != 0) { 1445 dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count); 1446 } 1447 } 1448 1449 Timer fgTimer = u.getForegroundActivityTimer(); 1450 if (fgTimer != null) { 1451 // Convert from microseconds to milliseconds with rounding 1452 long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; 1453 int count = fgTimer.getCountLocked(which); 1454 if (totalTime != 0) { 1455 dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count); 1456 } 1457 } 1458 1459 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 1460 if (processStats.size() > 0) { 1461 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 1462 : processStats.entrySet()) { 1463 Uid.Proc ps = ent.getValue(); 1464 1465 final long userMillis = ps.getUserTime(which) * 10; 1466 final long systemMillis = ps.getSystemTime(which) * 10; 1467 final long foregroundMillis = ps.getForegroundTime(which) * 10; 1468 final long starts = ps.getStarts(which); 1469 1470 if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0 1471 || starts != 0) { 1472 dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis, 1473 systemMillis, foregroundMillis, starts); 1474 } 1475 } 1476 } 1477 1478 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 1479 if (packageStats.size() > 0) { 1480 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 1481 : packageStats.entrySet()) { 1482 1483 Uid.Pkg ps = ent.getValue(); 1484 int wakeups = ps.getWakeups(which); 1485 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 1486 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 1487 : serviceStats.entrySet()) { 1488 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 1489 long startTime = ss.getStartTime(batteryUptime, which); 1490 int starts = ss.getStarts(which); 1491 int launches = ss.getLaunches(which); 1492 if (startTime != 0 || starts != 0 || launches != 0) { 1493 dumpLine(pw, uid, category, APK_DATA, 1494 wakeups, // wakeup alarms 1495 ent.getKey(), // Apk 1496 sent.getKey(), // service 1497 startTime / 1000, // time spent started, in ms 1498 starts, 1499 launches); 1500 } 1501 } 1502 } 1503 } 1504 } 1505 } 1506 1507 static final class TimerEntry { 1508 final String mName; 1509 final int mId; 1510 final BatteryStats.Timer mTimer; 1511 final long mTime; 1512 TimerEntry(String name, int id, BatteryStats.Timer timer, long time) { 1513 mName = name; 1514 mId = id; 1515 mTimer = timer; 1516 mTime = time; 1517 } 1518 } 1519 1520 @SuppressWarnings("unused") 1521 public final void dumpLocked(PrintWriter pw, String prefix, final int which, int reqUid) { 1522 final long rawUptime = SystemClock.uptimeMillis() * 1000; 1523 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 1524 final long batteryUptime = getBatteryUptime(rawUptime); 1525 final long batteryRealtime = getBatteryRealtime(rawRealtime); 1526 1527 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 1528 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 1529 final long totalRealtime = computeRealtime(rawRealtime, which); 1530 final long totalUptime = computeUptime(rawUptime, which); 1531 1532 StringBuilder sb = new StringBuilder(128); 1533 1534 SparseArray<? extends Uid> uidStats = getUidStats(); 1535 final int NU = uidStats.size(); 1536 1537 sb.setLength(0); 1538 sb.append(prefix); 1539 sb.append(" Time on battery: "); 1540 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("("); 1541 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime)); 1542 sb.append(") realtime, "); 1543 formatTimeMs(sb, whichBatteryUptime / 1000); 1544 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime)); 1545 sb.append(") uptime"); 1546 pw.println(sb.toString()); 1547 sb.setLength(0); 1548 sb.append(prefix); 1549 sb.append(" Total run time: "); 1550 formatTimeMs(sb, totalRealtime / 1000); 1551 sb.append("realtime, "); 1552 formatTimeMs(sb, totalUptime / 1000); 1553 sb.append("uptime, "); 1554 pw.println(sb.toString()); 1555 1556 final long screenOnTime = getScreenOnTime(batteryRealtime, which); 1557 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which); 1558 final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which); 1559 final long wifiOnTime = getWifiOnTime(batteryRealtime, which); 1560 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which); 1561 sb.setLength(0); 1562 sb.append(prefix); 1563 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000); 1564 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime)); 1565 sb.append("), Input events: "); sb.append(getInputEventCount(which)); 1566 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000); 1567 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime)); 1568 sb.append(")"); 1569 pw.println(sb.toString()); 1570 sb.setLength(0); 1571 sb.append(prefix); 1572 sb.append(" Screen brightnesses: "); 1573 boolean didOne = false; 1574 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1575 final long time = getScreenBrightnessTime(i, batteryRealtime, which); 1576 if (time == 0) { 1577 continue; 1578 } 1579 if (didOne) sb.append(", "); 1580 didOne = true; 1581 sb.append(SCREEN_BRIGHTNESS_NAMES[i]); 1582 sb.append(" "); 1583 formatTimeMs(sb, time/1000); 1584 sb.append("("); 1585 sb.append(formatRatioLocked(time, screenOnTime)); 1586 sb.append(")"); 1587 } 1588 if (!didOne) sb.append("No activity"); 1589 pw.println(sb.toString()); 1590 1591 // Calculate total network and wakelock times across all uids. 1592 long mobileRxTotal = 0; 1593 long mobileTxTotal = 0; 1594 long wifiRxTotal = 0; 1595 long wifiTxTotal = 0; 1596 long fullWakeLockTimeTotalMicros = 0; 1597 long partialWakeLockTimeTotalMicros = 0; 1598 1599 final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() { 1600 @Override 1601 public int compare(TimerEntry lhs, TimerEntry rhs) { 1602 long lhsTime = lhs.mTime; 1603 long rhsTime = rhs.mTime; 1604 if (lhsTime < rhsTime) { 1605 return 1; 1606 } 1607 if (lhsTime > rhsTime) { 1608 return -1; 1609 } 1610 return 0; 1611 } 1612 }; 1613 1614 if (reqUid < 0) { 1615 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); 1616 if (kernelWakelocks.size() > 0) { 1617 final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>(); 1618 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { 1619 BatteryStats.Timer timer = ent.getValue(); 1620 long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which); 1621 if (totalTimeMillis > 0) { 1622 timers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis)); 1623 } 1624 } 1625 Collections.sort(timers, timerComparator); 1626 for (int i=0; i<timers.size(); i++) { 1627 TimerEntry timer = timers.get(i); 1628 String linePrefix = ": "; 1629 sb.setLength(0); 1630 sb.append(prefix); 1631 sb.append(" Kernel Wake lock "); 1632 sb.append(timer.mName); 1633 linePrefix = printWakeLock(sb, timer.mTimer, batteryRealtime, null, 1634 which, linePrefix); 1635 if (!linePrefix.equals(": ")) { 1636 sb.append(" realtime"); 1637 // Only print out wake locks that were held 1638 pw.println(sb.toString()); 1639 } 1640 } 1641 } 1642 } 1643 1644 final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>(); 1645 1646 for (int iu = 0; iu < NU; iu++) { 1647 Uid u = uidStats.valueAt(iu); 1648 mobileRxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which); 1649 mobileTxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which); 1650 wifiRxTotal += u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which); 1651 wifiTxTotal += u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which); 1652 1653 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1654 if (wakelocks.size() > 0) { 1655 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1656 : wakelocks.entrySet()) { 1657 Uid.Wakelock wl = ent.getValue(); 1658 1659 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 1660 if (fullWakeTimer != null) { 1661 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked( 1662 batteryRealtime, which); 1663 } 1664 1665 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 1666 if (partialWakeTimer != null) { 1667 long totalTimeMicros = partialWakeTimer.getTotalTimeLocked( 1668 batteryRealtime, which); 1669 if (totalTimeMicros > 0) { 1670 if (reqUid < 0) { 1671 // Only show the ordered list of all wake 1672 // locks if the caller is not asking for data 1673 // about a specific uid. 1674 timers.add(new TimerEntry(ent.getKey(), u.getUid(), 1675 partialWakeTimer, totalTimeMicros)); 1676 } 1677 partialWakeLockTimeTotalMicros += totalTimeMicros; 1678 } 1679 } 1680 } 1681 } 1682 } 1683 1684 pw.print(prefix); 1685 pw.print(" Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotal)); 1686 pw.print(", Total sent: "); pw.println(formatBytesLocked(mobileTxTotal)); 1687 pw.print(prefix); 1688 pw.print(" Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotal)); 1689 pw.print(", Total sent: "); pw.println(formatBytesLocked(wifiTxTotal)); 1690 sb.setLength(0); 1691 sb.append(prefix); 1692 sb.append(" Total full wakelock time: "); formatTimeMs(sb, 1693 (fullWakeLockTimeTotalMicros + 500) / 1000); 1694 sb.append(", Total partial wakelock time: "); formatTimeMs(sb, 1695 (partialWakeLockTimeTotalMicros + 500) / 1000); 1696 pw.println(sb.toString()); 1697 1698 sb.setLength(0); 1699 sb.append(prefix); 1700 sb.append(" Signal levels: "); 1701 didOne = false; 1702 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 1703 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which); 1704 if (time == 0) { 1705 continue; 1706 } 1707 if (didOne) sb.append(", "); 1708 didOne = true; 1709 sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]); 1710 sb.append(" "); 1711 formatTimeMs(sb, time/1000); 1712 sb.append("("); 1713 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1714 sb.append(") "); 1715 sb.append(getPhoneSignalStrengthCount(i, which)); 1716 sb.append("x"); 1717 } 1718 if (!didOne) sb.append("No activity"); 1719 pw.println(sb.toString()); 1720 1721 sb.setLength(0); 1722 sb.append(prefix); 1723 sb.append(" Signal scanning time: "); 1724 formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000); 1725 pw.println(sb.toString()); 1726 1727 sb.setLength(0); 1728 sb.append(prefix); 1729 sb.append(" Radio types: "); 1730 didOne = false; 1731 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1732 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which); 1733 if (time == 0) { 1734 continue; 1735 } 1736 if (didOne) sb.append(", "); 1737 didOne = true; 1738 sb.append(DATA_CONNECTION_NAMES[i]); 1739 sb.append(" "); 1740 formatTimeMs(sb, time/1000); 1741 sb.append("("); 1742 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 1743 sb.append(") "); 1744 sb.append(getPhoneDataConnectionCount(i, which)); 1745 sb.append("x"); 1746 } 1747 if (!didOne) sb.append("No activity"); 1748 pw.println(sb.toString()); 1749 1750 sb.setLength(0); 1751 sb.append(prefix); 1752 sb.append(" Radio data uptime when unplugged: "); 1753 sb.append(getRadioDataUptime() / 1000); 1754 sb.append(" ms"); 1755 pw.println(sb.toString()); 1756 1757 sb.setLength(0); 1758 sb.append(prefix); 1759 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000); 1760 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime)); 1761 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000); 1762 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime)); 1763 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000); 1764 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)); 1765 sb.append(")"); 1766 pw.println(sb.toString()); 1767 1768 pw.println(" "); 1769 1770 if (which == STATS_SINCE_UNPLUGGED) { 1771 if (getIsOnBattery()) { 1772 pw.print(prefix); pw.println(" Device is currently unplugged"); 1773 pw.print(prefix); pw.print(" Discharge cycle start level: "); 1774 pw.println(getDischargeStartLevel()); 1775 pw.print(prefix); pw.print(" Discharge cycle current level: "); 1776 pw.println(getDischargeCurrentLevel()); 1777 } else { 1778 pw.print(prefix); pw.println(" Device is currently plugged into power"); 1779 pw.print(prefix); pw.print(" Last discharge cycle start level: "); 1780 pw.println(getDischargeStartLevel()); 1781 pw.print(prefix); pw.print(" Last discharge cycle end level: "); 1782 pw.println(getDischargeCurrentLevel()); 1783 } 1784 pw.print(prefix); pw.print(" Amount discharged while screen on: "); 1785 pw.println(getDischargeAmountScreenOn()); 1786 pw.print(prefix); pw.print(" Amount discharged while screen off: "); 1787 pw.println(getDischargeAmountScreenOff()); 1788 pw.println(" "); 1789 } else { 1790 pw.print(prefix); pw.println(" Device battery use since last full charge"); 1791 pw.print(prefix); pw.print(" Amount discharged (lower bound): "); 1792 pw.println(getLowDischargeAmountSinceCharge()); 1793 pw.print(prefix); pw.print(" Amount discharged (upper bound): "); 1794 pw.println(getHighDischargeAmountSinceCharge()); 1795 pw.print(prefix); pw.print(" Amount discharged while screen on: "); 1796 pw.println(getDischargeAmountScreenOnSinceCharge()); 1797 pw.print(prefix); pw.print(" Amount discharged while screen off: "); 1798 pw.println(getDischargeAmountScreenOffSinceCharge()); 1799 pw.println(); 1800 } 1801 1802 if (timers.size() > 0) { 1803 Collections.sort(timers, timerComparator); 1804 pw.print(prefix); pw.println(" All partial wake locks:"); 1805 for (int i=0; i<timers.size(); i++) { 1806 TimerEntry timer = timers.get(i); 1807 sb.setLength(0); 1808 sb.append(" Wake lock "); 1809 UserHandle.formatUid(sb, timer.mId); 1810 sb.append(" "); 1811 sb.append(timer.mName); 1812 printWakeLock(sb, timer.mTimer, batteryRealtime, null, which, ": "); 1813 sb.append(" realtime"); 1814 pw.println(sb.toString()); 1815 } 1816 timers.clear(); 1817 pw.println(); 1818 } 1819 1820 for (int iu=0; iu<NU; iu++) { 1821 final int uid = uidStats.keyAt(iu); 1822 if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) { 1823 continue; 1824 } 1825 1826 Uid u = uidStats.valueAt(iu); 1827 1828 pw.print(prefix); 1829 pw.print(" "); 1830 UserHandle.formatUid(pw, uid); 1831 pw.println(":"); 1832 boolean uidActivity = false; 1833 1834 long mobileRxBytes = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which); 1835 long mobileTxBytes = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which); 1836 long wifiRxBytes = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which); 1837 long wifiTxBytes = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which); 1838 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which); 1839 long wifiScanTime = u.getWifiScanTime(batteryRealtime, which); 1840 long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which); 1841 1842 if (mobileRxBytes > 0 || mobileTxBytes > 0) { 1843 pw.print(prefix); pw.print(" Mobile network: "); 1844 pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, "); 1845 pw.print(formatBytesLocked(mobileTxBytes)); pw.println(" sent"); 1846 } 1847 if (wifiRxBytes > 0 || wifiTxBytes > 0) { 1848 pw.print(prefix); pw.print(" Wi-Fi network: "); 1849 pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, "); 1850 pw.print(formatBytesLocked(wifiTxBytes)); pw.println(" sent"); 1851 } 1852 1853 if (u.hasUserActivity()) { 1854 boolean hasData = false; 1855 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 1856 int val = u.getUserActivityCount(i, which); 1857 if (val != 0) { 1858 if (!hasData) { 1859 sb.setLength(0); 1860 sb.append(" User activity: "); 1861 hasData = true; 1862 } else { 1863 sb.append(", "); 1864 } 1865 sb.append(val); 1866 sb.append(" "); 1867 sb.append(Uid.USER_ACTIVITY_TYPES[i]); 1868 } 1869 } 1870 if (hasData) { 1871 pw.println(sb.toString()); 1872 } 1873 } 1874 1875 if (fullWifiLockOnTime != 0 || wifiScanTime != 0 1876 || uidWifiRunningTime != 0) { 1877 sb.setLength(0); 1878 sb.append(prefix); sb.append(" Wifi Running: "); 1879 formatTimeMs(sb, uidWifiRunningTime / 1000); 1880 sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime, 1881 whichBatteryRealtime)); sb.append(")\n"); 1882 sb.append(prefix); sb.append(" Full Wifi Lock: "); 1883 formatTimeMs(sb, fullWifiLockOnTime / 1000); 1884 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime, 1885 whichBatteryRealtime)); sb.append(")\n"); 1886 sb.append(prefix); sb.append(" Wifi Scan: "); 1887 formatTimeMs(sb, wifiScanTime / 1000); 1888 sb.append("("); sb.append(formatRatioLocked(wifiScanTime, 1889 whichBatteryRealtime)); sb.append(")"); 1890 pw.println(sb.toString()); 1891 } 1892 1893 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1894 if (wakelocks.size() > 0) { 1895 long totalFull = 0, totalPartial = 0, totalWindow = 0; 1896 int count = 0; 1897 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1898 : wakelocks.entrySet()) { 1899 Uid.Wakelock wl = ent.getValue(); 1900 String linePrefix = ": "; 1901 sb.setLength(0); 1902 sb.append(prefix); 1903 sb.append(" Wake lock "); 1904 sb.append(ent.getKey()); 1905 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime, 1906 "full", which, linePrefix); 1907 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime, 1908 "partial", which, linePrefix); 1909 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime, 1910 "window", which, linePrefix); 1911 if (!linePrefix.equals(": ")) { 1912 sb.append(" realtime"); 1913 // Only print out wake locks that were held 1914 pw.println(sb.toString()); 1915 uidActivity = true; 1916 count++; 1917 } 1918 totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL), 1919 batteryRealtime, which); 1920 totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL), 1921 batteryRealtime, which); 1922 totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW), 1923 batteryRealtime, which); 1924 } 1925 if (count > 1) { 1926 if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) { 1927 sb.setLength(0); 1928 sb.append(prefix); 1929 sb.append(" TOTAL wake: "); 1930 boolean needComma = false; 1931 if (totalFull != 0) { 1932 needComma = true; 1933 formatTimeMs(sb, totalFull); 1934 sb.append("full"); 1935 } 1936 if (totalPartial != 0) { 1937 if (needComma) { 1938 sb.append(", "); 1939 } 1940 needComma = true; 1941 formatTimeMs(sb, totalPartial); 1942 sb.append("partial"); 1943 } 1944 if (totalWindow != 0) { 1945 if (needComma) { 1946 sb.append(", "); 1947 } 1948 needComma = true; 1949 formatTimeMs(sb, totalWindow); 1950 sb.append("window"); 1951 } 1952 sb.append(" realtime"); 1953 pw.println(sb.toString()); 1954 } 1955 } 1956 } 1957 1958 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1959 if (sensors.size() > 0) { 1960 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1961 : sensors.entrySet()) { 1962 Uid.Sensor se = ent.getValue(); 1963 int sensorNumber = ent.getKey(); 1964 sb.setLength(0); 1965 sb.append(prefix); 1966 sb.append(" Sensor "); 1967 int handle = se.getHandle(); 1968 if (handle == Uid.Sensor.GPS) { 1969 sb.append("GPS"); 1970 } else { 1971 sb.append(handle); 1972 } 1973 sb.append(": "); 1974 1975 Timer timer = se.getSensorTime(); 1976 if (timer != null) { 1977 // Convert from microseconds to milliseconds with rounding 1978 long totalTime = (timer.getTotalTimeLocked( 1979 batteryRealtime, which) + 500) / 1000; 1980 int count = timer.getCountLocked(which); 1981 //timer.logState(); 1982 if (totalTime != 0) { 1983 formatTimeMs(sb, totalTime); 1984 sb.append("realtime ("); 1985 sb.append(count); 1986 sb.append(" times)"); 1987 } else { 1988 sb.append("(not used)"); 1989 } 1990 } else { 1991 sb.append("(not used)"); 1992 } 1993 1994 pw.println(sb.toString()); 1995 uidActivity = true; 1996 } 1997 } 1998 1999 Timer vibTimer = u.getVibratorOnTimer(); 2000 if (vibTimer != null) { 2001 // Convert from microseconds to milliseconds with rounding 2002 long totalTime = (vibTimer.getTotalTimeLocked( 2003 batteryRealtime, which) + 500) / 1000; 2004 int count = vibTimer.getCountLocked(which); 2005 //timer.logState(); 2006 if (totalTime != 0) { 2007 sb.setLength(0); 2008 sb.append(prefix); 2009 sb.append(" Vibrator: "); 2010 formatTimeMs(sb, totalTime); 2011 sb.append("realtime ("); 2012 sb.append(count); 2013 sb.append(" times)"); 2014 pw.println(sb.toString()); 2015 uidActivity = true; 2016 } 2017 } 2018 2019 Timer fgTimer = u.getForegroundActivityTimer(); 2020 if (fgTimer != null) { 2021 // Convert from microseconds to milliseconds with rounding 2022 long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000; 2023 int count = fgTimer.getCountLocked(which); 2024 if (totalTime != 0) { 2025 sb.setLength(0); 2026 sb.append(prefix); 2027 sb.append(" Foreground activities: "); 2028 formatTimeMs(sb, totalTime); 2029 sb.append("realtime ("); 2030 sb.append(count); 2031 sb.append(" times)"); 2032 pw.println(sb.toString()); 2033 uidActivity = true; 2034 } 2035 } 2036 2037 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 2038 if (processStats.size() > 0) { 2039 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 2040 : processStats.entrySet()) { 2041 Uid.Proc ps = ent.getValue(); 2042 long userTime; 2043 long systemTime; 2044 long foregroundTime; 2045 int starts; 2046 int numExcessive; 2047 2048 userTime = ps.getUserTime(which); 2049 systemTime = ps.getSystemTime(which); 2050 foregroundTime = ps.getForegroundTime(which); 2051 starts = ps.getStarts(which); 2052 numExcessive = which == STATS_SINCE_CHARGED 2053 ? ps.countExcessivePowers() : 0; 2054 2055 if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0 2056 || numExcessive != 0) { 2057 sb.setLength(0); 2058 sb.append(prefix); sb.append(" Proc "); 2059 sb.append(ent.getKey()); sb.append(":\n"); 2060 sb.append(prefix); sb.append(" CPU: "); 2061 formatTime(sb, userTime); sb.append("usr + "); 2062 formatTime(sb, systemTime); sb.append("krn ; "); 2063 formatTime(sb, foregroundTime); sb.append("fg"); 2064 if (starts != 0) { 2065 sb.append("\n"); sb.append(prefix); sb.append(" "); 2066 sb.append(starts); sb.append(" proc starts"); 2067 } 2068 pw.println(sb.toString()); 2069 for (int e=0; e<numExcessive; e++) { 2070 Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e); 2071 if (ew != null) { 2072 pw.print(prefix); pw.print(" * Killed for "); 2073 if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) { 2074 pw.print("wake lock"); 2075 } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) { 2076 pw.print("cpu"); 2077 } else { 2078 pw.print("unknown"); 2079 } 2080 pw.print(" use: "); 2081 TimeUtils.formatDuration(ew.usedTime, pw); 2082 pw.print(" over "); 2083 TimeUtils.formatDuration(ew.overTime, pw); 2084 pw.print(" ("); 2085 pw.print((ew.usedTime*100)/ew.overTime); 2086 pw.println("%)"); 2087 } 2088 } 2089 uidActivity = true; 2090 } 2091 } 2092 } 2093 2094 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 2095 if (packageStats.size() > 0) { 2096 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 2097 : packageStats.entrySet()) { 2098 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":"); 2099 boolean apkActivity = false; 2100 Uid.Pkg ps = ent.getValue(); 2101 int wakeups = ps.getWakeups(which); 2102 if (wakeups != 0) { 2103 pw.print(prefix); pw.print(" "); 2104 pw.print(wakeups); pw.println(" wakeup alarms"); 2105 apkActivity = true; 2106 } 2107 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 2108 if (serviceStats.size() > 0) { 2109 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 2110 : serviceStats.entrySet()) { 2111 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 2112 long startTime = ss.getStartTime(batteryUptime, which); 2113 int starts = ss.getStarts(which); 2114 int launches = ss.getLaunches(which); 2115 if (startTime != 0 || starts != 0 || launches != 0) { 2116 sb.setLength(0); 2117 sb.append(prefix); sb.append(" Service "); 2118 sb.append(sent.getKey()); sb.append(":\n"); 2119 sb.append(prefix); sb.append(" Created for: "); 2120 formatTimeMs(sb, startTime / 1000); 2121 sb.append("uptime\n"); 2122 sb.append(prefix); sb.append(" Starts: "); 2123 sb.append(starts); 2124 sb.append(", launches: "); sb.append(launches); 2125 pw.println(sb.toString()); 2126 apkActivity = true; 2127 } 2128 } 2129 } 2130 if (!apkActivity) { 2131 pw.print(prefix); pw.println(" (nothing executed)"); 2132 } 2133 uidActivity = true; 2134 } 2135 } 2136 if (!uidActivity) { 2137 pw.print(prefix); pw.println(" (nothing executed)"); 2138 } 2139 } 2140 } 2141 2142 static void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) { 2143 int diff = oldval ^ newval; 2144 if (diff == 0) return; 2145 for (int i=0; i<descriptions.length; i++) { 2146 BitDescription bd = descriptions[i]; 2147 if ((diff&bd.mask) != 0) { 2148 if (bd.shift < 0) { 2149 pw.print((newval&bd.mask) != 0 ? " +" : " -"); 2150 pw.print(bd.name); 2151 } else { 2152 pw.print(" "); 2153 pw.print(bd.name); 2154 pw.print("="); 2155 int val = (newval&bd.mask)>>bd.shift; 2156 if (bd.values != null && val >= 0 && val < bd.values.length) { 2157 pw.print(bd.values[val]); 2158 } else { 2159 pw.print(val); 2160 } 2161 } 2162 } 2163 } 2164 } 2165 2166 public void prepareForDumpLocked() { 2167 } 2168 2169 public static class HistoryPrinter { 2170 int oldState = 0; 2171 int oldStatus = -1; 2172 int oldHealth = -1; 2173 int oldPlug = -1; 2174 int oldTemp = -1; 2175 int oldVolt = -1; 2176 2177 public void printNextItem(PrintWriter pw, HistoryItem rec, long now) { 2178 pw.print(" "); 2179 TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN); 2180 pw.print(" "); 2181 if (rec.cmd == HistoryItem.CMD_START) { 2182 pw.println(" START"); 2183 } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) { 2184 pw.println(" *OVERFLOW*"); 2185 } else { 2186 if (rec.batteryLevel < 10) pw.print("00"); 2187 else if (rec.batteryLevel < 100) pw.print("0"); 2188 pw.print(rec.batteryLevel); 2189 pw.print(" "); 2190 if (rec.states < 0x10) pw.print("0000000"); 2191 else if (rec.states < 0x100) pw.print("000000"); 2192 else if (rec.states < 0x1000) pw.print("00000"); 2193 else if (rec.states < 0x10000) pw.print("0000"); 2194 else if (rec.states < 0x100000) pw.print("000"); 2195 else if (rec.states < 0x1000000) pw.print("00"); 2196 else if (rec.states < 0x10000000) pw.print("0"); 2197 pw.print(Integer.toHexString(rec.states)); 2198 if (oldStatus != rec.batteryStatus) { 2199 oldStatus = rec.batteryStatus; 2200 pw.print(" status="); 2201 switch (oldStatus) { 2202 case BatteryManager.BATTERY_STATUS_UNKNOWN: 2203 pw.print("unknown"); 2204 break; 2205 case BatteryManager.BATTERY_STATUS_CHARGING: 2206 pw.print("charging"); 2207 break; 2208 case BatteryManager.BATTERY_STATUS_DISCHARGING: 2209 pw.print("discharging"); 2210 break; 2211 case BatteryManager.BATTERY_STATUS_NOT_CHARGING: 2212 pw.print("not-charging"); 2213 break; 2214 case BatteryManager.BATTERY_STATUS_FULL: 2215 pw.print("full"); 2216 break; 2217 default: 2218 pw.print(oldStatus); 2219 break; 2220 } 2221 } 2222 if (oldHealth != rec.batteryHealth) { 2223 oldHealth = rec.batteryHealth; 2224 pw.print(" health="); 2225 switch (oldHealth) { 2226 case BatteryManager.BATTERY_HEALTH_UNKNOWN: 2227 pw.print("unknown"); 2228 break; 2229 case BatteryManager.BATTERY_HEALTH_GOOD: 2230 pw.print("good"); 2231 break; 2232 case BatteryManager.BATTERY_HEALTH_OVERHEAT: 2233 pw.print("overheat"); 2234 break; 2235 case BatteryManager.BATTERY_HEALTH_DEAD: 2236 pw.print("dead"); 2237 break; 2238 case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: 2239 pw.print("over-voltage"); 2240 break; 2241 case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: 2242 pw.print("failure"); 2243 break; 2244 default: 2245 pw.print(oldHealth); 2246 break; 2247 } 2248 } 2249 if (oldPlug != rec.batteryPlugType) { 2250 oldPlug = rec.batteryPlugType; 2251 pw.print(" plug="); 2252 switch (oldPlug) { 2253 case 0: 2254 pw.print("none"); 2255 break; 2256 case BatteryManager.BATTERY_PLUGGED_AC: 2257 pw.print("ac"); 2258 break; 2259 case BatteryManager.BATTERY_PLUGGED_USB: 2260 pw.print("usb"); 2261 break; 2262 case BatteryManager.BATTERY_PLUGGED_WIRELESS: 2263 pw.print("wireless"); 2264 break; 2265 default: 2266 pw.print(oldPlug); 2267 break; 2268 } 2269 } 2270 if (oldTemp != rec.batteryTemperature) { 2271 oldTemp = rec.batteryTemperature; 2272 pw.print(" temp="); 2273 pw.print(oldTemp); 2274 } 2275 if (oldVolt != rec.batteryVoltage) { 2276 oldVolt = rec.batteryVoltage; 2277 pw.print(" volt="); 2278 pw.print(oldVolt); 2279 } 2280 printBitDescriptions(pw, oldState, rec.states, 2281 HISTORY_STATE_DESCRIPTIONS); 2282 pw.println(); 2283 } 2284 oldState = rec.states; 2285 } 2286 2287 public void printNextItemCheckin(PrintWriter pw, HistoryItem rec, long now) { 2288 pw.print(rec.time-now); 2289 pw.print(","); 2290 if (rec.cmd == HistoryItem.CMD_START) { 2291 pw.print("start"); 2292 } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) { 2293 pw.print("overflow"); 2294 } else { 2295 pw.print(rec.batteryLevel); 2296 pw.print(","); 2297 pw.print(rec.states); 2298 pw.print(","); 2299 pw.print(rec.batteryStatus); 2300 pw.print(","); 2301 pw.print(rec.batteryHealth); 2302 pw.print(","); 2303 pw.print(rec.batteryPlugType); 2304 pw.print(","); 2305 pw.print((int)rec.batteryTemperature); 2306 pw.print(","); 2307 pw.print((int)rec.batteryVoltage); 2308 } 2309 } 2310 } 2311 2312 /** 2313 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 2314 * 2315 * @param pw a Printer to receive the dump output. 2316 */ 2317 @SuppressWarnings("unused") 2318 public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) { 2319 prepareForDumpLocked(); 2320 2321 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); 2322 2323 final HistoryItem rec = new HistoryItem(); 2324 if (startIteratingHistoryLocked()) { 2325 pw.println("Battery History:"); 2326 HistoryPrinter hprinter = new HistoryPrinter(); 2327 while (getNextHistoryLocked(rec)) { 2328 hprinter.printNextItem(pw, rec, now); 2329 } 2330 finishIteratingHistoryLocked(); 2331 pw.println(""); 2332 } 2333 2334 if (startIteratingOldHistoryLocked()) { 2335 pw.println("Old battery History:"); 2336 HistoryPrinter hprinter = new HistoryPrinter(); 2337 while (getNextOldHistoryLocked(rec)) { 2338 hprinter.printNextItem(pw, rec, now); 2339 } 2340 finishIteratingOldHistoryLocked(); 2341 pw.println(""); 2342 } 2343 2344 SparseArray<? extends Uid> uidStats = getUidStats(); 2345 final int NU = uidStats.size(); 2346 boolean didPid = false; 2347 long nowRealtime = SystemClock.elapsedRealtime(); 2348 for (int i=0; i<NU; i++) { 2349 Uid uid = uidStats.valueAt(i); 2350 SparseArray<? extends Uid.Pid> pids = uid.getPidStats(); 2351 if (pids != null) { 2352 for (int j=0; j<pids.size(); j++) { 2353 Uid.Pid pid = pids.valueAt(j); 2354 if (!didPid) { 2355 pw.println("Per-PID Stats:"); 2356 didPid = true; 2357 } 2358 long time = pid.mWakeSum + (pid.mWakeStart != 0 2359 ? (nowRealtime - pid.mWakeStart) : 0); 2360 pw.print(" PID "); pw.print(pids.keyAt(j)); 2361 pw.print(" wake time: "); 2362 TimeUtils.formatDuration(time, pw); 2363 pw.println(""); 2364 } 2365 } 2366 } 2367 if (didPid) { 2368 pw.println(""); 2369 } 2370 2371 if (!isUnpluggedOnly) { 2372 pw.println("Statistics since last charge:"); 2373 pw.println(" System starts: " + getStartCount() 2374 + ", currently on battery: " + getIsOnBattery()); 2375 dumpLocked(pw, "", STATS_SINCE_CHARGED, reqUid); 2376 pw.println(""); 2377 } 2378 pw.println("Statistics since last unplugged:"); 2379 dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, reqUid); 2380 } 2381 2382 @SuppressWarnings("unused") 2383 public void dumpCheckinLocked( 2384 PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly, 2385 boolean includeHistory) { 2386 prepareForDumpLocked(); 2387 2388 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); 2389 2390 if (includeHistory) { 2391 final HistoryItem rec = new HistoryItem(); 2392 if (startIteratingHistoryLocked()) { 2393 HistoryPrinter hprinter = new HistoryPrinter(); 2394 while (getNextHistoryLocked(rec)) { 2395 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 2396 pw.print(0); pw.print(','); 2397 pw.print(HISTORY_DATA); pw.print(','); 2398 hprinter.printNextItemCheckin(pw, rec, now); 2399 pw.println(); 2400 } 2401 finishIteratingHistoryLocked(); 2402 } 2403 } 2404 2405 if (apps != null) { 2406 SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>(); 2407 for (int i=0; i<apps.size(); i++) { 2408 ApplicationInfo ai = apps.get(i); 2409 ArrayList<String> pkgs = uids.get(ai.uid); 2410 if (pkgs == null) { 2411 pkgs = new ArrayList<String>(); 2412 uids.put(ai.uid, pkgs); 2413 } 2414 pkgs.add(ai.packageName); 2415 } 2416 SparseArray<? extends Uid> uidStats = getUidStats(); 2417 final int NU = uidStats.size(); 2418 String[] lineArgs = new String[2]; 2419 for (int i=0; i<NU; i++) { 2420 int uid = uidStats.keyAt(i); 2421 ArrayList<String> pkgs = uids.get(uid); 2422 if (pkgs != null) { 2423 for (int j=0; j<pkgs.size(); j++) { 2424 lineArgs[0] = Integer.toString(uid); 2425 lineArgs[1] = pkgs.get(j); 2426 dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA, 2427 (Object[])lineArgs); 2428 } 2429 } 2430 } 2431 } 2432 if (isUnpluggedOnly) { 2433 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1); 2434 } 2435 else { 2436 dumpCheckinLocked(pw, STATS_SINCE_CHARGED, -1); 2437 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1); 2438 } 2439 } 2440} 2441