BatteryStats.java revision bffcf1c2dae4fcfb8b7ee7d1ee7ff8951ad04d88
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.Context; 28import android.content.pm.ApplicationInfo; 29import android.telephony.SignalStrength; 30import android.text.format.DateFormat; 31import android.util.Printer; 32import android.util.SparseArray; 33import android.util.TimeUtils; 34import com.android.internal.os.BatterySipper; 35import com.android.internal.os.BatteryStatsHelper; 36 37/** 38 * A class providing access to battery usage statistics, including information on 39 * wakelocks, processes, packages, and services. All times are represented in microseconds 40 * except where indicated otherwise. 41 * @hide 42 */ 43public abstract class BatteryStats implements Parcelable { 44 45 private static final boolean LOCAL_LOGV = false; 46 47 /** @hide */ 48 public static final String SERVICE_NAME = "batterystats"; 49 50 /** 51 * A constant indicating a partial wake lock timer. 52 */ 53 public static final int WAKE_TYPE_PARTIAL = 0; 54 55 /** 56 * A constant indicating a full wake lock timer. 57 */ 58 public static final int WAKE_TYPE_FULL = 1; 59 60 /** 61 * A constant indicating a window wake lock timer. 62 */ 63 public static final int WAKE_TYPE_WINDOW = 2; 64 65 /** 66 * A constant indicating a sensor timer. 67 */ 68 public static final int SENSOR = 3; 69 70 /** 71 * A constant indicating a a wifi running timer 72 */ 73 public static final int WIFI_RUNNING = 4; 74 75 /** 76 * A constant indicating a full wifi lock timer 77 */ 78 public static final int FULL_WIFI_LOCK = 5; 79 80 /** 81 * A constant indicating a wifi scan 82 */ 83 public static final int WIFI_SCAN = 6; 84 85 /** 86 * A constant indicating a wifi multicast timer 87 */ 88 public static final int WIFI_MULTICAST_ENABLED = 7; 89 90 /** 91 * A constant indicating an audio turn on timer 92 */ 93 public static final int AUDIO_TURNED_ON = 7; 94 95 /** 96 * A constant indicating a video turn on timer 97 */ 98 public static final int VIDEO_TURNED_ON = 8; 99 100 /** 101 * A constant indicating a vibrator on timer 102 */ 103 public static final int VIBRATOR_ON = 9; 104 105 /** 106 * A constant indicating a foreground activity timer 107 */ 108 public static final int FOREGROUND_ACTIVITY = 10; 109 110 /** 111 * A constant indicating a wifi batched scan is active 112 */ 113 public static final int WIFI_BATCHED_SCAN = 11; 114 115 /** 116 * Include all of the data in the stats, including previously saved data. 117 */ 118 public static final int STATS_SINCE_CHARGED = 0; 119 120 /** 121 * Include only the current run in the stats. 122 */ 123 public static final int STATS_CURRENT = 1; 124 125 /** 126 * Include only the run since the last time the device was unplugged in the stats. 127 */ 128 public static final int STATS_SINCE_UNPLUGGED = 2; 129 130 // NOTE: Update this list if you add/change any stats above. 131 // These characters are supposed to represent "total", "last", "current", 132 // and "unplugged". They were shortened for efficiency sake. 133 private static final String[] STAT_NAMES = { "l", "c", "u" }; 134 135 /** 136 * Bump the version on this if the checkin format changes. 137 */ 138 private static final int BATTERY_STATS_CHECKIN_VERSION = 8; 139 140 private static final long BYTES_PER_KB = 1024; 141 private static final long BYTES_PER_MB = 1048576; // 1024^2 142 private static final long BYTES_PER_GB = 1073741824; //1024^3 143 144 145 private static final String UID_DATA = "uid"; 146 private static final String APK_DATA = "apk"; 147 private static final String PROCESS_DATA = "pr"; 148 private static final String SENSOR_DATA = "sr"; 149 private static final String VIBRATOR_DATA = "vib"; 150 private static final String FOREGROUND_DATA = "fg"; 151 private static final String WAKELOCK_DATA = "wl"; 152 private static final String KERNEL_WAKELOCK_DATA = "kwl"; 153 private static final String WAKEUP_REASON_DATA = "wr"; 154 private static final String NETWORK_DATA = "nt"; 155 private static final String USER_ACTIVITY_DATA = "ua"; 156 private static final String BATTERY_DATA = "bt"; 157 private static final String BATTERY_DISCHARGE_DATA = "dc"; 158 private static final String BATTERY_LEVEL_DATA = "lv"; 159 private static final String WIFI_DATA = "wfl"; 160 private static final String MISC_DATA = "m"; 161 private static final String GLOBAL_NETWORK_DATA = "gn"; 162 private static final String HISTORY_STRING_POOL = "hsp"; 163 private static final String HISTORY_DATA = "h"; 164 private static final String SCREEN_BRIGHTNESS_DATA = "br"; 165 private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt"; 166 private static final String SIGNAL_SCANNING_TIME_DATA = "sst"; 167 private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc"; 168 private static final String DATA_CONNECTION_TIME_DATA = "dct"; 169 private static final String DATA_CONNECTION_COUNT_DATA = "dcc"; 170 private static final String WIFI_STATE_TIME_DATA = "wst"; 171 private static final String WIFI_STATE_COUNT_DATA = "wsc"; 172 private static final String BLUETOOTH_STATE_TIME_DATA = "bst"; 173 private static final String BLUETOOTH_STATE_COUNT_DATA = "bsc"; 174 private static final String POWER_USE_SUMMARY_DATA = "pws"; 175 private static final String POWER_USE_ITEM_DATA = "pwi"; 176 private static final String DISCHARGE_STEP_DATA = "dsd"; 177 private static final String CHARGE_STEP_DATA = "csd"; 178 private static final String DISCHARGE_TIME_REMAIN_DATA = "dtr"; 179 private static final String CHARGE_TIME_REMAIN_DATA = "ctr"; 180 181 private final StringBuilder mFormatBuilder = new StringBuilder(32); 182 private final Formatter mFormatter = new Formatter(mFormatBuilder); 183 184 /** 185 * State for keeping track of counting information. 186 */ 187 public static abstract class Counter { 188 189 /** 190 * Returns the count associated with this Counter for the 191 * selected type of statistics. 192 * 193 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT 194 */ 195 public abstract int getCountLocked(int which); 196 197 /** 198 * Temporary for debugging. 199 */ 200 public abstract void logState(Printer pw, String prefix); 201 } 202 203 /** 204 * State for keeping track of long counting information. 205 */ 206 public static abstract class LongCounter { 207 208 /** 209 * Returns the count associated with this Counter for the 210 * selected type of statistics. 211 * 212 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT 213 */ 214 public abstract long getCountLocked(int which); 215 216 /** 217 * Temporary for debugging. 218 */ 219 public abstract void logState(Printer pw, String prefix); 220 } 221 222 /** 223 * State for keeping track of timing information. 224 */ 225 public static abstract class Timer { 226 227 /** 228 * Returns the count associated with this Timer for the 229 * selected type of statistics. 230 * 231 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT 232 */ 233 public abstract int getCountLocked(int which); 234 235 /** 236 * Returns the total time in microseconds associated with this Timer for the 237 * selected type of statistics. 238 * 239 * @param elapsedRealtimeUs current elapsed realtime of system in microseconds 240 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT 241 * @return a time in microseconds 242 */ 243 public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which); 244 245 /** 246 * Temporary for debugging. 247 */ 248 public abstract void logState(Printer pw, String prefix); 249 } 250 251 /** 252 * The statistics associated with a particular uid. 253 */ 254 public static abstract class Uid { 255 256 /** 257 * Returns a mapping containing wakelock statistics. 258 * 259 * @return a Map from Strings to Uid.Wakelock objects. 260 */ 261 public abstract Map<String, ? extends Wakelock> getWakelockStats(); 262 263 /** 264 * The statistics associated with a particular wake lock. 265 */ 266 public static abstract class Wakelock { 267 public abstract Timer getWakeTime(int type); 268 } 269 270 /** 271 * Returns a mapping containing sensor statistics. 272 * 273 * @return a Map from Integer sensor ids to Uid.Sensor objects. 274 */ 275 public abstract Map<Integer, ? extends Sensor> getSensorStats(); 276 277 /** 278 * Returns a mapping containing active process data. 279 */ 280 public abstract SparseArray<? extends Pid> getPidStats(); 281 282 /** 283 * Returns a mapping containing process statistics. 284 * 285 * @return a Map from Strings to Uid.Proc objects. 286 */ 287 public abstract Map<String, ? extends Proc> getProcessStats(); 288 289 /** 290 * Returns a mapping containing package statistics. 291 * 292 * @return a Map from Strings to Uid.Pkg objects. 293 */ 294 public abstract Map<String, ? extends Pkg> getPackageStats(); 295 296 /** 297 * {@hide} 298 */ 299 public abstract int getUid(); 300 301 public abstract void noteWifiRunningLocked(long elapsedRealtime); 302 public abstract void noteWifiStoppedLocked(long elapsedRealtime); 303 public abstract void noteFullWifiLockAcquiredLocked(long elapsedRealtime); 304 public abstract void noteFullWifiLockReleasedLocked(long elapsedRealtime); 305 public abstract void noteWifiScanStartedLocked(long elapsedRealtime); 306 public abstract void noteWifiScanStoppedLocked(long elapsedRealtime); 307 public abstract void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime); 308 public abstract void noteWifiBatchedScanStoppedLocked(long elapsedRealtime); 309 public abstract void noteWifiMulticastEnabledLocked(long elapsedRealtime); 310 public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime); 311 public abstract void noteAudioTurnedOnLocked(long elapsedRealtime); 312 public abstract void noteAudioTurnedOffLocked(long elapsedRealtime); 313 public abstract void noteVideoTurnedOnLocked(long elapsedRealtime); 314 public abstract void noteVideoTurnedOffLocked(long elapsedRealtime); 315 public abstract void noteActivityResumedLocked(long elapsedRealtime); 316 public abstract void noteActivityPausedLocked(long elapsedRealtime); 317 public abstract long getWifiRunningTime(long elapsedRealtimeUs, int which); 318 public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which); 319 public abstract long getWifiScanTime(long elapsedRealtimeUs, int which); 320 public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which); 321 public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which); 322 public abstract long getAudioTurnedOnTime(long elapsedRealtimeUs, int which); 323 public abstract long getVideoTurnedOnTime(long elapsedRealtimeUs, int which); 324 public abstract Timer getForegroundActivityTimer(); 325 public abstract Timer getVibratorOnTimer(); 326 327 public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5; 328 329 /** 330 * Note that these must match the constants in android.os.PowerManager. 331 * Also, if the user activity types change, the BatteryStatsImpl.VERSION must 332 * also be bumped. 333 */ 334 static final String[] USER_ACTIVITY_TYPES = { 335 "other", "button", "touch" 336 }; 337 338 public static final int NUM_USER_ACTIVITY_TYPES = 3; 339 340 public abstract void noteUserActivityLocked(int type); 341 public abstract boolean hasUserActivity(); 342 public abstract int getUserActivityCount(int type, int which); 343 344 public abstract boolean hasNetworkActivity(); 345 public abstract long getNetworkActivityBytes(int type, int which); 346 public abstract long getNetworkActivityPackets(int type, int which); 347 public abstract long getMobileRadioActiveTime(int which); 348 public abstract int getMobileRadioActiveCount(int which); 349 350 public static abstract class Sensor { 351 /* 352 * FIXME: it's not correct to use this magic value because it 353 * could clash with a sensor handle (which are defined by 354 * the sensor HAL, and therefore out of our control 355 */ 356 // Magic sensor number for the GPS. 357 public static final int GPS = -10000; 358 359 public abstract int getHandle(); 360 361 public abstract Timer getSensorTime(); 362 } 363 364 public class Pid { 365 public int mWakeNesting; 366 public long mWakeSumMs; 367 public long mWakeStartMs; 368 } 369 370 /** 371 * The statistics associated with a particular process. 372 */ 373 public static abstract class Proc { 374 375 public static class ExcessivePower { 376 public static final int TYPE_WAKE = 1; 377 public static final int TYPE_CPU = 2; 378 379 public int type; 380 public long overTime; 381 public long usedTime; 382 } 383 384 /** 385 * Returns true if this process is still active in the battery stats. 386 */ 387 public abstract boolean isActive(); 388 389 /** 390 * Returns the total time (in 1/100 sec) spent executing in user code. 391 * 392 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 393 */ 394 public abstract long getUserTime(int which); 395 396 /** 397 * Returns the total time (in 1/100 sec) spent executing in system code. 398 * 399 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 400 */ 401 public abstract long getSystemTime(int which); 402 403 /** 404 * Returns the number of times the process has been started. 405 * 406 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 407 */ 408 public abstract int getStarts(int which); 409 410 /** 411 * Returns the cpu time spent in microseconds while the process was in the foreground. 412 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 413 * @return foreground cpu time in microseconds 414 */ 415 public abstract long getForegroundTime(int which); 416 417 /** 418 * Returns the approximate cpu time spent in microseconds, at a certain CPU speed. 419 * @param speedStep the index of the CPU speed. This is not the actual speed of the 420 * CPU. 421 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 422 * @see BatteryStats#getCpuSpeedSteps() 423 */ 424 public abstract long getTimeAtCpuSpeedStep(int speedStep, int which); 425 426 public abstract int countExcessivePowers(); 427 428 public abstract ExcessivePower getExcessivePower(int i); 429 } 430 431 /** 432 * The statistics associated with a particular package. 433 */ 434 public static abstract class Pkg { 435 436 /** 437 * Returns the number of times this package has done something that could wake up the 438 * device from sleep. 439 * 440 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 441 */ 442 public abstract int getWakeups(int which); 443 444 /** 445 * Returns a mapping containing service statistics. 446 */ 447 public abstract Map<String, ? extends Serv> getServiceStats(); 448 449 /** 450 * The statistics associated with a particular service. 451 */ 452 public abstract class Serv { 453 454 /** 455 * Returns the amount of time spent started. 456 * 457 * @param batteryUptime elapsed uptime on battery in microseconds. 458 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 459 * @return 460 */ 461 public abstract long getStartTime(long batteryUptime, int which); 462 463 /** 464 * Returns the total number of times startService() has been called. 465 * 466 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 467 */ 468 public abstract int getStarts(int which); 469 470 /** 471 * Returns the total number times the service has been launched. 472 * 473 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 474 */ 475 public abstract int getLaunches(int which); 476 } 477 } 478 } 479 480 public final static class HistoryTag { 481 public String string; 482 public int uid; 483 484 public int poolIdx; 485 486 public void setTo(HistoryTag o) { 487 string = o.string; 488 uid = o.uid; 489 poolIdx = o.poolIdx; 490 } 491 492 public void setTo(String _string, int _uid) { 493 string = _string; 494 uid = _uid; 495 poolIdx = -1; 496 } 497 498 public void writeToParcel(Parcel dest, int flags) { 499 dest.writeString(string); 500 dest.writeInt(uid); 501 } 502 503 public void readFromParcel(Parcel src) { 504 string = src.readString(); 505 uid = src.readInt(); 506 poolIdx = -1; 507 } 508 509 @Override 510 public boolean equals(Object o) { 511 if (this == o) return true; 512 if (o == null || getClass() != o.getClass()) return false; 513 514 HistoryTag that = (HistoryTag) o; 515 516 if (uid != that.uid) return false; 517 if (!string.equals(that.string)) return false; 518 519 return true; 520 } 521 522 @Override 523 public int hashCode() { 524 int result = string.hashCode(); 525 result = 31 * result + uid; 526 return result; 527 } 528 } 529 530 public final static class HistoryItem implements Parcelable { 531 public HistoryItem next; 532 533 public long time; 534 535 public static final byte CMD_UPDATE = 0; // These can be written as deltas 536 public static final byte CMD_NULL = -1; 537 public static final byte CMD_START = 4; 538 public static final byte CMD_CURRENT_TIME = 5; 539 public static final byte CMD_OVERFLOW = 6; 540 541 public byte cmd = CMD_NULL; 542 543 /** 544 * Return whether the command code is a delta data update. 545 */ 546 public boolean isDeltaData() { 547 return cmd == CMD_UPDATE; 548 } 549 550 public byte batteryLevel; 551 public byte batteryStatus; 552 public byte batteryHealth; 553 public byte batteryPlugType; 554 555 public short batteryTemperature; 556 public char batteryVoltage; 557 558 // Constants from SCREEN_BRIGHTNESS_* 559 public static final int STATE_BRIGHTNESS_SHIFT = 0; 560 public static final int STATE_BRIGHTNESS_MASK = 0x7; 561 // Constants from SIGNAL_STRENGTH_* 562 public static final int STATE_SIGNAL_STRENGTH_SHIFT = 3; 563 public static final int STATE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_SIGNAL_STRENGTH_SHIFT; 564 // Constants from ServiceState.STATE_* 565 public static final int STATE_PHONE_STATE_SHIFT = 6; 566 public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT; 567 // Constants from DATA_CONNECTION_* 568 public static final int STATE_DATA_CONNECTION_SHIFT = 9; 569 public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT; 570 571 // These states always appear directly in the first int token 572 // of a delta change; they should be ones that change relatively 573 // frequently. 574 public static final int STATE_CPU_RUNNING_FLAG = 1<<31; 575 public static final int STATE_WAKE_LOCK_FLAG = 1<<30; 576 public static final int STATE_GPS_ON_FLAG = 1<<29; 577 public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28; 578 public static final int STATE_WIFI_SCAN_FLAG = 1<<27; 579 public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<26; 580 public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25; 581 public static final int STATE_WIFI_RUNNING_FLAG = 1<<24; 582 // These are on the lower bits used for the command; if they change 583 // we need to write another int of data. 584 public static final int STATE_SENSOR_ON_FLAG = 1<<23; 585 public static final int STATE_AUDIO_ON_FLAG = 1<<22; 586 public static final int STATE_PHONE_SCANNING_FLAG = 1<<21; 587 public static final int STATE_SCREEN_ON_FLAG = 1<<20; 588 public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; 589 public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18; 590 public static final int STATE_WIFI_ON_FLAG = 1<<17; 591 public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16; 592 593 public static final int MOST_INTERESTING_STATES = 594 STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG 595 | STATE_GPS_ON_FLAG | STATE_PHONE_IN_CALL_FLAG; 596 597 public int states; 598 599 public static final int STATE2_VIDEO_ON_FLAG = 1<<0; 600 public int states2; 601 602 // The wake lock that was acquired at this point. 603 public HistoryTag wakelockTag; 604 605 // Kernel wakeup reason at this point. 606 public HistoryTag wakeReasonTag; 607 608 public static final int EVENT_FLAG_START = 0x8000; 609 public static final int EVENT_FLAG_FINISH = 0x4000; 610 611 // No event in this item. 612 public static final int EVENT_NONE = 0x0000; 613 // Event is about a process that is running. 614 public static final int EVENT_PROC = 0x0001; 615 // Event is about an application package that is in the foreground. 616 public static final int EVENT_FOREGROUND = 0x0002; 617 // Event is about an application package that is at the top of the screen. 618 public static final int EVENT_TOP = 0x0003; 619 // Event is about an application package that is at the top of the screen. 620 public static final int EVENT_SYNC = 0x0004; 621 // Number of event types. 622 public static final int EVENT_COUNT = 0x0005; 623 624 public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START; 625 public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH; 626 public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START; 627 public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH; 628 public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START; 629 public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH; 630 public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START; 631 public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH; 632 633 // For CMD_EVENT. 634 public int eventCode; 635 public HistoryTag eventTag; 636 637 // Only set for CMD_CURRENT_TIME. 638 public long currentTime; 639 640 // Meta-data when reading. 641 public int numReadInts; 642 643 // Pre-allocated objects. 644 public final HistoryTag localWakelockTag = new HistoryTag(); 645 public final HistoryTag localWakeReasonTag = new HistoryTag(); 646 public final HistoryTag localEventTag = new HistoryTag(); 647 648 public HistoryItem() { 649 } 650 651 public HistoryItem(long time, Parcel src) { 652 this.time = time; 653 numReadInts = 2; 654 readFromParcel(src); 655 } 656 657 public int describeContents() { 658 return 0; 659 } 660 661 public void writeToParcel(Parcel dest, int flags) { 662 dest.writeLong(time); 663 int bat = (((int)cmd)&0xff) 664 | ((((int)batteryLevel)<<8)&0xff00) 665 | ((((int)batteryStatus)<<16)&0xf0000) 666 | ((((int)batteryHealth)<<20)&0xf00000) 667 | ((((int)batteryPlugType)<<24)&0xf000000) 668 | (wakelockTag != null ? 0x10000000 : 0) 669 | (wakeReasonTag != null ? 0x20000000 : 0) 670 | (eventCode != EVENT_NONE ? 0x40000000 : 0); 671 dest.writeInt(bat); 672 bat = (((int)batteryTemperature)&0xffff) 673 | ((((int)batteryVoltage)<<16)&0xffff0000); 674 dest.writeInt(bat); 675 dest.writeInt(states); 676 dest.writeInt(states2); 677 if (wakelockTag != null) { 678 wakelockTag.writeToParcel(dest, flags); 679 } 680 if (wakeReasonTag != null) { 681 wakeReasonTag.writeToParcel(dest, flags); 682 } 683 if (eventCode != EVENT_NONE) { 684 dest.writeInt(eventCode); 685 eventTag.writeToParcel(dest, flags); 686 } 687 if (cmd == CMD_CURRENT_TIME) { 688 dest.writeLong(currentTime); 689 } 690 } 691 692 public void readFromParcel(Parcel src) { 693 int start = src.dataPosition(); 694 int bat = src.readInt(); 695 cmd = (byte)(bat&0xff); 696 batteryLevel = (byte)((bat>>8)&0xff); 697 batteryStatus = (byte)((bat>>16)&0xf); 698 batteryHealth = (byte)((bat>>20)&0xf); 699 batteryPlugType = (byte)((bat>>24)&0xf); 700 int bat2 = src.readInt(); 701 batteryTemperature = (short)(bat2&0xffff); 702 batteryVoltage = (char)((bat2>>16)&0xffff); 703 states = src.readInt(); 704 states2 = src.readInt(); 705 if ((bat&0x10000000) != 0) { 706 wakelockTag = localWakelockTag; 707 wakelockTag.readFromParcel(src); 708 } else { 709 wakelockTag = null; 710 } 711 if ((bat&0x20000000) != 0) { 712 wakeReasonTag = localWakeReasonTag; 713 wakeReasonTag.readFromParcel(src); 714 } else { 715 wakeReasonTag = null; 716 } 717 if ((bat&0x40000000) != 0) { 718 eventCode = src.readInt(); 719 eventTag = localEventTag; 720 eventTag.readFromParcel(src); 721 } else { 722 eventCode = EVENT_NONE; 723 eventTag = null; 724 } 725 if (cmd == CMD_CURRENT_TIME) { 726 currentTime = src.readLong(); 727 } else { 728 currentTime = 0; 729 } 730 numReadInts += (src.dataPosition()-start)/4; 731 } 732 733 public void clear() { 734 time = 0; 735 cmd = CMD_NULL; 736 batteryLevel = 0; 737 batteryStatus = 0; 738 batteryHealth = 0; 739 batteryPlugType = 0; 740 batteryTemperature = 0; 741 batteryVoltage = 0; 742 states = 0; 743 states2 = 0; 744 wakelockTag = null; 745 wakeReasonTag = null; 746 eventCode = EVENT_NONE; 747 eventTag = null; 748 } 749 750 public void setTo(HistoryItem o) { 751 time = o.time; 752 cmd = o.cmd; 753 setToCommon(o); 754 } 755 756 public void setTo(long time, byte cmd, HistoryItem o) { 757 this.time = time; 758 this.cmd = cmd; 759 setToCommon(o); 760 } 761 762 private void setToCommon(HistoryItem o) { 763 batteryLevel = o.batteryLevel; 764 batteryStatus = o.batteryStatus; 765 batteryHealth = o.batteryHealth; 766 batteryPlugType = o.batteryPlugType; 767 batteryTemperature = o.batteryTemperature; 768 batteryVoltage = o.batteryVoltage; 769 states = o.states; 770 states2 = o.states2; 771 if (o.wakelockTag != null) { 772 wakelockTag = localWakelockTag; 773 wakelockTag.setTo(o.wakelockTag); 774 } else { 775 wakelockTag = null; 776 } 777 if (o.wakeReasonTag != null) { 778 wakeReasonTag = localWakeReasonTag; 779 wakeReasonTag.setTo(o.wakeReasonTag); 780 } else { 781 wakeReasonTag = null; 782 } 783 eventCode = o.eventCode; 784 if (o.eventTag != null) { 785 eventTag = localEventTag; 786 eventTag.setTo(o.eventTag); 787 } else { 788 eventTag = null; 789 } 790 currentTime = o.currentTime; 791 } 792 793 public boolean sameNonEvent(HistoryItem o) { 794 return batteryLevel == o.batteryLevel 795 && batteryStatus == o.batteryStatus 796 && batteryHealth == o.batteryHealth 797 && batteryPlugType == o.batteryPlugType 798 && batteryTemperature == o.batteryTemperature 799 && batteryVoltage == o.batteryVoltage 800 && states == o.states 801 && states2 == o.states2 802 && currentTime == o.currentTime; 803 } 804 805 public boolean same(HistoryItem o) { 806 if (!sameNonEvent(o) || eventCode != o.eventCode) { 807 return false; 808 } 809 if (wakelockTag != o.wakelockTag) { 810 if (wakelockTag == null || o.wakelockTag == null) { 811 return false; 812 } 813 if (!wakelockTag.equals(o.wakelockTag)) { 814 return false; 815 } 816 } 817 if (wakeReasonTag != o.wakeReasonTag) { 818 if (wakeReasonTag == null || o.wakeReasonTag == null) { 819 return false; 820 } 821 if (!wakeReasonTag.equals(o.wakeReasonTag)) { 822 return false; 823 } 824 } 825 if (eventTag != o.eventTag) { 826 if (eventTag == null || o.eventTag == null) { 827 return false; 828 } 829 if (!eventTag.equals(o.eventTag)) { 830 return false; 831 } 832 } 833 return true; 834 } 835 } 836 837 public static final class BitDescription { 838 public final int mask; 839 public final int shift; 840 public final String name; 841 public final String shortName; 842 public final String[] values; 843 public final String[] shortValues; 844 845 public BitDescription(int mask, String name, String shortName) { 846 this.mask = mask; 847 this.shift = -1; 848 this.name = name; 849 this.shortName = shortName; 850 this.values = null; 851 this.shortValues = null; 852 } 853 854 public BitDescription(int mask, int shift, String name, String shortName, 855 String[] values, String[] shortValues) { 856 this.mask = mask; 857 this.shift = shift; 858 this.name = name; 859 this.shortName = shortName; 860 this.values = values; 861 this.shortValues = shortValues; 862 } 863 } 864 865 public abstract int getHistoryTotalSize(); 866 867 public abstract int getHistoryUsedSize(); 868 869 public abstract boolean startIteratingHistoryLocked(); 870 871 public abstract int getHistoryStringPoolSize(); 872 873 public abstract int getHistoryStringPoolBytes(); 874 875 public abstract String getHistoryTagPoolString(int index); 876 877 public abstract int getHistoryTagPoolUid(int index); 878 879 public abstract boolean getNextHistoryLocked(HistoryItem out); 880 881 public abstract void finishIteratingHistoryLocked(); 882 883 public abstract boolean startIteratingOldHistoryLocked(); 884 885 public abstract boolean getNextOldHistoryLocked(HistoryItem out); 886 887 public abstract void finishIteratingOldHistoryLocked(); 888 889 /** 890 * Return the base time offset for the battery history. 891 */ 892 public abstract long getHistoryBaseTime(); 893 894 /** 895 * Returns the number of times the device has been started. 896 */ 897 public abstract int getStartCount(); 898 899 /** 900 * Returns the time in microseconds that the screen has been on while the device was 901 * running on battery. 902 * 903 * {@hide} 904 */ 905 public abstract long getScreenOnTime(long elapsedRealtimeUs, int which); 906 907 /** 908 * Returns the number of times the screen was turned on. 909 * 910 * {@hide} 911 */ 912 public abstract int getScreenOnCount(int which); 913 914 public abstract long getInteractiveTime(long elapsedRealtimeUs, int which); 915 916 public static final int SCREEN_BRIGHTNESS_DARK = 0; 917 public static final int SCREEN_BRIGHTNESS_DIM = 1; 918 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2; 919 public static final int SCREEN_BRIGHTNESS_LIGHT = 3; 920 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4; 921 922 static final String[] SCREEN_BRIGHTNESS_NAMES = { 923 "dark", "dim", "medium", "light", "bright" 924 }; 925 926 static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = { 927 "0", "1", "2", "3", "4" 928 }; 929 930 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5; 931 932 /** 933 * Returns the time in microseconds that the screen has been on with 934 * the given brightness 935 * 936 * {@hide} 937 */ 938 public abstract long getScreenBrightnessTime(int brightnessBin, 939 long elapsedRealtimeUs, int which); 940 941 /** 942 * Returns the time in microseconds that the phone has been on while the device was 943 * running on battery. 944 * 945 * {@hide} 946 */ 947 public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which); 948 949 /** 950 * Returns the number of times a phone call was activated. 951 * 952 * {@hide} 953 */ 954 public abstract int getPhoneOnCount(int which); 955 956 /** 957 * Returns the time in microseconds that the phone has been running with 958 * the given signal strength. 959 * 960 * {@hide} 961 */ 962 public abstract long getPhoneSignalStrengthTime(int strengthBin, 963 long elapsedRealtimeUs, int which); 964 965 /** 966 * Returns the time in microseconds that the phone has been trying to 967 * acquire a signal. 968 * 969 * {@hide} 970 */ 971 public abstract long getPhoneSignalScanningTime( 972 long elapsedRealtimeUs, int which); 973 974 /** 975 * Returns the number of times the phone has entered the given signal strength. 976 * 977 * {@hide} 978 */ 979 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which); 980 981 /** 982 * Returns the time in microseconds that the mobile network has been active 983 * (in a high power state). 984 * 985 * {@hide} 986 */ 987 public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which); 988 989 /** 990 * Returns the number of times that the mobile network has transitioned to the 991 * active state. 992 * 993 * {@hide} 994 */ 995 public abstract int getMobileRadioActiveCount(int which); 996 997 /** 998 * Returns the time in microseconds that is the difference between the mobile radio 999 * time we saw based on the elapsed timestamp when going down vs. the given time stamp 1000 * from the radio. 1001 * 1002 * {@hide} 1003 */ 1004 public abstract long getMobileRadioActiveAdjustedTime(int which); 1005 1006 /** 1007 * Returns the time in microseconds that the mobile network has been active 1008 * (in a high power state) but not being able to blame on an app. 1009 * 1010 * {@hide} 1011 */ 1012 public abstract long getMobileRadioActiveUnknownTime(int which); 1013 1014 /** 1015 * Return count of number of times radio was up that could not be blamed on apps. 1016 * 1017 * {@hide} 1018 */ 1019 public abstract int getMobileRadioActiveUnknownCount(int which); 1020 1021 public static final int DATA_CONNECTION_NONE = 0; 1022 public static final int DATA_CONNECTION_GPRS = 1; 1023 public static final int DATA_CONNECTION_EDGE = 2; 1024 public static final int DATA_CONNECTION_UMTS = 3; 1025 public static final int DATA_CONNECTION_CDMA = 4; 1026 public static final int DATA_CONNECTION_EVDO_0 = 5; 1027 public static final int DATA_CONNECTION_EVDO_A = 6; 1028 public static final int DATA_CONNECTION_1xRTT = 7; 1029 public static final int DATA_CONNECTION_HSDPA = 8; 1030 public static final int DATA_CONNECTION_HSUPA = 9; 1031 public static final int DATA_CONNECTION_HSPA = 10; 1032 public static final int DATA_CONNECTION_IDEN = 11; 1033 public static final int DATA_CONNECTION_EVDO_B = 12; 1034 public static final int DATA_CONNECTION_LTE = 13; 1035 public static final int DATA_CONNECTION_EHRPD = 14; 1036 public static final int DATA_CONNECTION_HSPAP = 15; 1037 public static final int DATA_CONNECTION_OTHER = 16; 1038 1039 static final String[] DATA_CONNECTION_NAMES = { 1040 "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A", 1041 "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte", 1042 "ehrpd", "hspap", "other" 1043 }; 1044 1045 public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1; 1046 1047 /** 1048 * Returns the time in microseconds that the phone has been running with 1049 * the given data connection. 1050 * 1051 * {@hide} 1052 */ 1053 public abstract long getPhoneDataConnectionTime(int dataType, 1054 long elapsedRealtimeUs, int which); 1055 1056 /** 1057 * Returns the number of times the phone has entered the given data 1058 * connection type. 1059 * 1060 * {@hide} 1061 */ 1062 public abstract int getPhoneDataConnectionCount(int dataType, int which); 1063 1064 public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS 1065 = new BitDescription[] { 1066 new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"), 1067 new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"), 1068 new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"), 1069 new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"), 1070 new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"), 1071 new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"), 1072 new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"), 1073 new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"), 1074 new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running", "Wr"), 1075 new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"), 1076 new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"), 1077 new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"), 1078 new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"), 1079 new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"), 1080 new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi", "W"), 1081 new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth", "b"), 1082 new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK, 1083 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn", 1084 DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES), 1085 new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK, 1086 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst", 1087 new String[] {"in", "out", "emergency", "off"}, 1088 new String[] {"in", "out", "em", "off"}), 1089 new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK, 1090 HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength", "Pss", 1091 SignalStrength.SIGNAL_STRENGTH_NAMES, new String[] { 1092 "0", "1", "2", "3", "4" 1093 }), 1094 new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK, 1095 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb", 1096 SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES), 1097 }; 1098 1099 public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS 1100 = new BitDescription[] { 1101 new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"), 1102 }; 1103 1104 public static final String[] HISTORY_EVENT_NAMES = new String[] { 1105 "null", "proc", "fg", "top", "sync" 1106 }; 1107 1108 public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] { 1109 "Enl", "Epr", "Efg", "Etp", "Esy" 1110 }; 1111 1112 /** 1113 * Returns the time in microseconds that wifi has been on while the device was 1114 * running on battery. 1115 * 1116 * {@hide} 1117 */ 1118 public abstract long getWifiOnTime(long elapsedRealtimeUs, int which); 1119 1120 /** 1121 * Returns the time in microseconds that wifi has been on and the driver has 1122 * been in the running state while the device was running on battery. 1123 * 1124 * {@hide} 1125 */ 1126 public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which); 1127 1128 public static final int WIFI_STATE_OFF = 0; 1129 public static final int WIFI_STATE_OFF_SCANNING = 1; 1130 public static final int WIFI_STATE_ON_NO_NETWORKS = 2; 1131 public static final int WIFI_STATE_ON_DISCONNECTED = 3; 1132 public static final int WIFI_STATE_ON_CONNECTED_STA = 4; 1133 public static final int WIFI_STATE_ON_CONNECTED_P2P = 5; 1134 public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6; 1135 public static final int WIFI_STATE_SOFT_AP = 7; 1136 1137 static final String[] WIFI_STATE_NAMES = { 1138 "off", "scanning", "no_net", "disconn", 1139 "sta", "p2p", "sta_p2p", "soft_ap" 1140 }; 1141 1142 public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1; 1143 1144 /** 1145 * Returns the time in microseconds that WiFi has been running in the given state. 1146 * 1147 * {@hide} 1148 */ 1149 public abstract long getWifiStateTime(int wifiState, 1150 long elapsedRealtimeUs, int which); 1151 1152 /** 1153 * Returns the number of times that WiFi has entered the given state. 1154 * 1155 * {@hide} 1156 */ 1157 public abstract int getWifiStateCount(int wifiState, int which); 1158 1159 /** 1160 * Returns the time in microseconds that bluetooth has been on while the device was 1161 * running on battery. 1162 * 1163 * {@hide} 1164 */ 1165 public abstract long getBluetoothOnTime(long elapsedRealtimeUs, int which); 1166 1167 public abstract int getBluetoothPingCount(); 1168 1169 public static final int BLUETOOTH_STATE_INACTIVE = 0; 1170 public static final int BLUETOOTH_STATE_LOW = 1; 1171 public static final int BLUETOOTH_STATE_MEDIUM = 2; 1172 public static final int BLUETOOTH_STATE_HIGH = 3; 1173 1174 static final String[] BLUETOOTH_STATE_NAMES = { 1175 "inactive", "low", "med", "high" 1176 }; 1177 1178 public static final int NUM_BLUETOOTH_STATES = BLUETOOTH_STATE_HIGH +1; 1179 1180 /** 1181 * Returns the time in microseconds that Bluetooth has been running in the 1182 * given active state. 1183 * 1184 * {@hide} 1185 */ 1186 public abstract long getBluetoothStateTime(int bluetoothState, 1187 long elapsedRealtimeUs, int which); 1188 1189 /** 1190 * Returns the number of times that Bluetooth has entered the given active state. 1191 * 1192 * {@hide} 1193 */ 1194 public abstract int getBluetoothStateCount(int bluetoothState, int which); 1195 1196 public static final int NETWORK_MOBILE_RX_DATA = 0; 1197 public static final int NETWORK_MOBILE_TX_DATA = 1; 1198 public static final int NETWORK_WIFI_RX_DATA = 2; 1199 public static final int NETWORK_WIFI_TX_DATA = 3; 1200 1201 public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1; 1202 1203 public abstract long getNetworkActivityBytes(int type, int which); 1204 public abstract long getNetworkActivityPackets(int type, int which); 1205 1206 /** 1207 * Return the wall clock time when battery stats data collection started. 1208 */ 1209 public abstract long getStartClockTime(); 1210 1211 /** 1212 * Return whether we are currently running on battery. 1213 */ 1214 public abstract boolean getIsOnBattery(); 1215 1216 /** 1217 * Returns a SparseArray containing the statistics for each uid. 1218 */ 1219 public abstract SparseArray<? extends Uid> getUidStats(); 1220 1221 /** 1222 * Returns the current battery uptime in microseconds. 1223 * 1224 * @param curTime the amount of elapsed realtime in microseconds. 1225 */ 1226 public abstract long getBatteryUptime(long curTime); 1227 1228 /** 1229 * Returns the current battery realtime in microseconds. 1230 * 1231 * @param curTime the amount of elapsed realtime in microseconds. 1232 */ 1233 public abstract long getBatteryRealtime(long curTime); 1234 1235 /** 1236 * Returns the battery percentage level at the last time the device was unplugged from power, or 1237 * the last time it booted on battery power. 1238 */ 1239 public abstract int getDischargeStartLevel(); 1240 1241 /** 1242 * Returns the current battery percentage level if we are in a discharge cycle, otherwise 1243 * returns the level at the last plug event. 1244 */ 1245 public abstract int getDischargeCurrentLevel(); 1246 1247 /** 1248 * Get the amount the battery has discharged since the stats were 1249 * last reset after charging, as a lower-end approximation. 1250 */ 1251 public abstract int getLowDischargeAmountSinceCharge(); 1252 1253 /** 1254 * Get the amount the battery has discharged since the stats were 1255 * last reset after charging, as an upper-end approximation. 1256 */ 1257 public abstract int getHighDischargeAmountSinceCharge(); 1258 1259 /** 1260 * Retrieve the discharge amount over the selected discharge period <var>which</var>. 1261 */ 1262 public abstract int getDischargeAmount(int which); 1263 1264 /** 1265 * Get the amount the battery has discharged while the screen was on, 1266 * since the last time power was unplugged. 1267 */ 1268 public abstract int getDischargeAmountScreenOn(); 1269 1270 /** 1271 * Get the amount the battery has discharged while the screen was on, 1272 * since the last time the device was charged. 1273 */ 1274 public abstract int getDischargeAmountScreenOnSinceCharge(); 1275 1276 /** 1277 * Get the amount the battery has discharged while the screen was off, 1278 * since the last time power was unplugged. 1279 */ 1280 public abstract int getDischargeAmountScreenOff(); 1281 1282 /** 1283 * Get the amount the battery has discharged while the screen was off, 1284 * since the last time the device was charged. 1285 */ 1286 public abstract int getDischargeAmountScreenOffSinceCharge(); 1287 1288 /** 1289 * Returns the total, last, or current battery uptime in microseconds. 1290 * 1291 * @param curTime the elapsed realtime in microseconds. 1292 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 1293 */ 1294 public abstract long computeBatteryUptime(long curTime, int which); 1295 1296 /** 1297 * Returns the total, last, or current battery realtime in microseconds. 1298 * 1299 * @param curTime the current elapsed realtime in microseconds. 1300 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 1301 */ 1302 public abstract long computeBatteryRealtime(long curTime, int which); 1303 1304 /** 1305 * Returns the total, last, or current battery screen off uptime in microseconds. 1306 * 1307 * @param curTime the elapsed realtime in microseconds. 1308 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 1309 */ 1310 public abstract long computeBatteryScreenOffUptime(long curTime, int which); 1311 1312 /** 1313 * Returns the total, last, or current battery screen off realtime in microseconds. 1314 * 1315 * @param curTime the current elapsed realtime in microseconds. 1316 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 1317 */ 1318 public abstract long computeBatteryScreenOffRealtime(long curTime, int which); 1319 1320 /** 1321 * Returns the total, last, or current uptime in microseconds. 1322 * 1323 * @param curTime the current elapsed realtime in microseconds. 1324 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 1325 */ 1326 public abstract long computeUptime(long curTime, int which); 1327 1328 /** 1329 * Returns the total, last, or current realtime in microseconds. 1330 * 1331 * @param curTime the current elapsed realtime in microseconds. 1332 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 1333 */ 1334 public abstract long computeRealtime(long curTime, int which); 1335 1336 /** 1337 * Compute an approximation for how much run time (in microseconds) is remaining on 1338 * the battery. Returns -1 if no time can be computed: either there is not 1339 * enough current data to make a decision, or the battery is currently 1340 * charging. 1341 * 1342 * @param curTime The current elepsed realtime in microseconds. 1343 */ 1344 public abstract long computeBatteryTimeRemaining(long curTime); 1345 1346 /** 1347 * Return the historical number of discharge steps we currently have. 1348 */ 1349 public abstract int getNumDischargeStepDurations(); 1350 1351 /** 1352 * Return the array of discharge step durations; the number of valid 1353 * items in it is returned by {@link #getNumDischargeStepDurations()}. 1354 * These values are in milliseconds. 1355 */ 1356 public abstract long[] getDischargeStepDurationsArray(); 1357 1358 /** 1359 * Compute an approximation for how much time (in microseconds) remains until the battery 1360 * is fully charged. Returns -1 if no time can be computed: either there is not 1361 * enough current data to make a decision, or the battery is currently 1362 * discharging. 1363 * 1364 * @param curTime The current elepsed realtime in microseconds. 1365 */ 1366 public abstract long computeChargeTimeRemaining(long curTime); 1367 1368 /** 1369 * Return the historical number of charge steps we currently have. 1370 */ 1371 public abstract int getNumChargeStepDurations(); 1372 1373 /** 1374 * Return the array of charge step durations; the number of valid 1375 * items in it is returned by {@link #getNumChargeStepDurations()}. 1376 * These values are in milliseconds. 1377 */ 1378 public abstract long[] getChargeStepDurationsArray(); 1379 1380 public abstract Map<String, ? extends LongCounter> getWakeupReasonStats(); 1381 1382 public abstract Map<String, ? extends Timer> getKernelWakelockStats(); 1383 1384 /** Returns the number of different speeds that the CPU can run at */ 1385 public abstract int getCpuSpeedSteps(); 1386 1387 public abstract void writeToParcelWithoutUids(Parcel out, int flags); 1388 1389 private final static void formatTimeRaw(StringBuilder out, long seconds) { 1390 long days = seconds / (60 * 60 * 24); 1391 if (days != 0) { 1392 out.append(days); 1393 out.append("d "); 1394 } 1395 long used = days * 60 * 60 * 24; 1396 1397 long hours = (seconds - used) / (60 * 60); 1398 if (hours != 0 || used != 0) { 1399 out.append(hours); 1400 out.append("h "); 1401 } 1402 used += hours * 60 * 60; 1403 1404 long mins = (seconds-used) / 60; 1405 if (mins != 0 || used != 0) { 1406 out.append(mins); 1407 out.append("m "); 1408 } 1409 used += mins * 60; 1410 1411 if (seconds != 0 || used != 0) { 1412 out.append(seconds-used); 1413 out.append("s "); 1414 } 1415 } 1416 1417 public final static void formatTime(StringBuilder sb, long time) { 1418 long sec = time / 100; 1419 formatTimeRaw(sb, sec); 1420 sb.append((time - (sec * 100)) * 10); 1421 sb.append("ms "); 1422 } 1423 1424 public final static void formatTimeMs(StringBuilder sb, long time) { 1425 long sec = time / 1000; 1426 formatTimeRaw(sb, sec); 1427 sb.append(time - (sec * 1000)); 1428 sb.append("ms "); 1429 } 1430 1431 public final static void formatTimeMsNoSpace(StringBuilder sb, long time) { 1432 long sec = time / 1000; 1433 formatTimeRaw(sb, sec); 1434 sb.append(time - (sec * 1000)); 1435 sb.append("ms"); 1436 } 1437 1438 public final String formatRatioLocked(long num, long den) { 1439 if (den == 0L) { 1440 return "--%"; 1441 } 1442 float perc = ((float)num) / ((float)den) * 100; 1443 mFormatBuilder.setLength(0); 1444 mFormatter.format("%.1f%%", perc); 1445 return mFormatBuilder.toString(); 1446 } 1447 1448 final String formatBytesLocked(long bytes) { 1449 mFormatBuilder.setLength(0); 1450 1451 if (bytes < BYTES_PER_KB) { 1452 return bytes + "B"; 1453 } else if (bytes < BYTES_PER_MB) { 1454 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB); 1455 return mFormatBuilder.toString(); 1456 } else if (bytes < BYTES_PER_GB){ 1457 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB); 1458 return mFormatBuilder.toString(); 1459 } else { 1460 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB); 1461 return mFormatBuilder.toString(); 1462 } 1463 } 1464 1465 private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) { 1466 if (timer != null) { 1467 // Convert from microseconds to milliseconds with rounding 1468 long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which); 1469 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 1470 return totalTimeMillis; 1471 } 1472 return 0; 1473 } 1474 1475 /** 1476 * 1477 * @param sb a StringBuilder object. 1478 * @param timer a Timer object contining the wakelock times. 1479 * @param elapsedRealtimeUs the current on-battery time in microseconds. 1480 * @param name the name of the wakelock. 1481 * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 1482 * @param linePrefix a String to be prepended to each line of output. 1483 * @return the line prefix 1484 */ 1485 private static final String printWakeLock(StringBuilder sb, Timer timer, 1486 long elapsedRealtimeUs, String name, int which, String linePrefix) { 1487 1488 if (timer != null) { 1489 long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which); 1490 1491 int count = timer.getCountLocked(which); 1492 if (totalTimeMillis != 0) { 1493 sb.append(linePrefix); 1494 formatTimeMs(sb, totalTimeMillis); 1495 if (name != null) { 1496 sb.append(name); 1497 sb.append(' '); 1498 } 1499 sb.append('('); 1500 sb.append(count); 1501 sb.append(" times)"); 1502 return ", "; 1503 } 1504 } 1505 return linePrefix; 1506 } 1507 1508 /** 1509 * Checkin version of wakelock printer. Prints simple comma-separated list. 1510 * 1511 * @param sb a StringBuilder object. 1512 * @param timer a Timer object contining the wakelock times. 1513 * @param elapsedRealtimeUs the current time in microseconds. 1514 * @param name the name of the wakelock. 1515 * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 1516 * @param linePrefix a String to be prepended to each line of output. 1517 * @return the line prefix 1518 */ 1519 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, 1520 long elapsedRealtimeUs, String name, int which, String linePrefix) { 1521 long totalTimeMicros = 0; 1522 int count = 0; 1523 if (timer != null) { 1524 totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which); 1525 count = timer.getCountLocked(which); 1526 } 1527 sb.append(linePrefix); 1528 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 1529 sb.append(','); 1530 sb.append(name != null ? name + "," : ""); 1531 sb.append(count); 1532 return ","; 1533 } 1534 1535 /** 1536 * Dump a comma-separated line of values for terse checkin mode. 1537 * 1538 * @param pw the PageWriter to dump log to 1539 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 1540 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 1541 * @param args type-dependent data arguments 1542 */ 1543 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 1544 Object... args ) { 1545 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 1546 pw.print(uid); pw.print(','); 1547 pw.print(category); pw.print(','); 1548 pw.print(type); 1549 1550 for (Object arg : args) { 1551 pw.print(','); 1552 pw.print(arg); 1553 } 1554 pw.println(); 1555 } 1556 1557 /** 1558 * Checkin server version of dump to produce more compact, computer-readable log. 1559 * 1560 * NOTE: all times are expressed in 'ms'. 1561 */ 1562 public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) { 1563 final long rawUptime = SystemClock.uptimeMillis() * 1000; 1564 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 1565 final long batteryUptime = getBatteryUptime(rawUptime); 1566 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 1567 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 1568 final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which); 1569 final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime, 1570 which); 1571 final long totalRealtime = computeRealtime(rawRealtime, which); 1572 final long totalUptime = computeUptime(rawUptime, which); 1573 final long screenOnTime = getScreenOnTime(rawRealtime, which); 1574 final long interactiveTime = getInteractiveTime(rawRealtime, which); 1575 final long phoneOnTime = getPhoneOnTime(rawRealtime, which); 1576 final long wifiOnTime = getWifiOnTime(rawRealtime, which); 1577 final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which); 1578 final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which); 1579 1580 StringBuilder sb = new StringBuilder(128); 1581 1582 SparseArray<? extends Uid> uidStats = getUidStats(); 1583 final int NU = uidStats.size(); 1584 1585 String category = STAT_NAMES[which]; 1586 1587 // Dump "battery" stat 1588 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 1589 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A", 1590 whichBatteryRealtime / 1000, whichBatteryUptime / 1000, 1591 totalRealtime / 1000, totalUptime / 1000, 1592 getStartClockTime(), 1593 whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000); 1594 1595 // Calculate wakelock times across all uids. 1596 long fullWakeLockTimeTotal = 0; 1597 long partialWakeLockTimeTotal = 0; 1598 1599 for (int iu = 0; iu < NU; iu++) { 1600 Uid u = uidStats.valueAt(iu); 1601 1602 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1603 if (wakelocks.size() > 0) { 1604 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1605 : wakelocks.entrySet()) { 1606 Uid.Wakelock wl = ent.getValue(); 1607 1608 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 1609 if (fullWakeTimer != null) { 1610 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime, 1611 which); 1612 } 1613 1614 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 1615 if (partialWakeTimer != null) { 1616 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked( 1617 rawRealtime, which); 1618 } 1619 } 1620 } 1621 } 1622 1623 long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which); 1624 long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which); 1625 long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which); 1626 long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which); 1627 long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which); 1628 long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which); 1629 long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which); 1630 long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which); 1631 1632 // Dump network stats 1633 dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA, 1634 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes, 1635 mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets); 1636 1637 // Dump misc stats 1638 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 1639 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, 1640 wifiRunningTime / 1000, bluetoothOnTime / 1000, 1641 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes, 1642 fullWakeLockTimeTotal, partialWakeLockTimeTotal, 1643 0 /*legacy input event count*/, getMobileRadioActiveTime(rawRealtime, which), 1644 getMobileRadioActiveAdjustedTime(which), interactiveTime / 1000); 1645 1646 // Dump screen brightness stats 1647 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; 1648 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1649 args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000; 1650 } 1651 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args); 1652 1653 // Dump signal strength stats 1654 args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 1655 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 1656 args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000; 1657 } 1658 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args); 1659 dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA, 1660 getPhoneSignalScanningTime(rawRealtime, which) / 1000); 1661 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 1662 args[i] = getPhoneSignalStrengthCount(i, which); 1663 } 1664 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args); 1665 1666 // Dump network type stats 1667 args = new Object[NUM_DATA_CONNECTION_TYPES]; 1668 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1669 args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000; 1670 } 1671 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args); 1672 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 1673 args[i] = getPhoneDataConnectionCount(i, which); 1674 } 1675 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args); 1676 1677 // Dump wifi state stats 1678 args = new Object[NUM_WIFI_STATES]; 1679 for (int i=0; i<NUM_WIFI_STATES; i++) { 1680 args[i] = getWifiStateTime(i, rawRealtime, which) / 1000; 1681 } 1682 dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args); 1683 for (int i=0; i<NUM_WIFI_STATES; i++) { 1684 args[i] = getWifiStateCount(i, which); 1685 } 1686 dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args); 1687 1688 // Dump bluetooth state stats 1689 args = new Object[NUM_BLUETOOTH_STATES]; 1690 for (int i=0; i<NUM_BLUETOOTH_STATES; i++) { 1691 args[i] = getBluetoothStateTime(i, rawRealtime, which) / 1000; 1692 } 1693 dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_TIME_DATA, args); 1694 for (int i=0; i<NUM_BLUETOOTH_STATES; i++) { 1695 args[i] = getBluetoothStateCount(i, which); 1696 } 1697 dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_COUNT_DATA, args); 1698 1699 if (which == STATS_SINCE_UNPLUGGED) { 1700 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), 1701 getDischargeCurrentLevel()); 1702 } 1703 1704 if (which == STATS_SINCE_UNPLUGGED) { 1705 dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, 1706 getDischargeStartLevel()-getDischargeCurrentLevel(), 1707 getDischargeStartLevel()-getDischargeCurrentLevel(), 1708 getDischargeAmountScreenOn(), getDischargeAmountScreenOff()); 1709 } else { 1710 dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, 1711 getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(), 1712 getDischargeAmountScreenOn(), getDischargeAmountScreenOff()); 1713 } 1714 1715 if (reqUid < 0) { 1716 Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats(); 1717 if (kernelWakelocks.size() > 0) { 1718 for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) { 1719 sb.setLength(0); 1720 printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, ""); 1721 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(), 1722 sb.toString()); 1723 } 1724 } 1725 Map<String, ? extends LongCounter> wakeupReasons = getWakeupReasonStats(); 1726 if (wakeupReasons.size() > 0) { 1727 for (Map.Entry<String, ? extends LongCounter> ent : wakeupReasons.entrySet()) { 1728 dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA, 1729 "\"" + ent.getKey() + "\"", ent.getValue().getCountLocked(which)); 1730 } 1731 } 1732 } 1733 1734 BatteryStatsHelper helper = new BatteryStatsHelper(context, false); 1735 helper.create(this); 1736 helper.refreshStats(which, UserHandle.USER_ALL); 1737 List<BatterySipper> sippers = helper.getUsageList(); 1738 if (sippers != null && sippers.size() > 0) { 1739 dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA, 1740 BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()), 1741 BatteryStatsHelper.makemAh(helper.getComputedPower()), 1742 BatteryStatsHelper.makemAh(helper.getMinDrainedPower()), 1743 BatteryStatsHelper.makemAh(helper.getMaxDrainedPower())); 1744 for (int i=0; i<sippers.size(); i++) { 1745 BatterySipper bs = sippers.get(i); 1746 int uid = 0; 1747 String label; 1748 switch (bs.drainType) { 1749 case IDLE: 1750 label="idle"; 1751 break; 1752 case CELL: 1753 label="cell"; 1754 break; 1755 case PHONE: 1756 label="phone"; 1757 break; 1758 case WIFI: 1759 label="wifi"; 1760 break; 1761 case BLUETOOTH: 1762 label="blue"; 1763 break; 1764 case SCREEN: 1765 label="scrn"; 1766 break; 1767 case APP: 1768 uid = bs.uidObj.getUid(); 1769 label = "uid"; 1770 break; 1771 case USER: 1772 uid = UserHandle.getUid(bs.userId, 0); 1773 label = "user"; 1774 break; 1775 case UNACCOUNTED: 1776 label = "unacc"; 1777 break; 1778 case OVERCOUNTED: 1779 label = "over"; 1780 break; 1781 default: 1782 label = "???"; 1783 } 1784 dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label, 1785 BatteryStatsHelper.makemAh(bs.value)); 1786 } 1787 } 1788 1789 for (int iu = 0; iu < NU; iu++) { 1790 final int uid = uidStats.keyAt(iu); 1791 if (reqUid >= 0 && uid != reqUid) { 1792 continue; 1793 } 1794 Uid u = uidStats.valueAt(iu); 1795 // Dump Network stats per uid, if any 1796 long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which); 1797 long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which); 1798 long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which); 1799 long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which); 1800 long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which); 1801 long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which); 1802 long mobileActiveTime = u.getMobileRadioActiveTime(which); 1803 int mobileActiveCount = u.getMobileRadioActiveCount(which); 1804 long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which); 1805 long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which); 1806 long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which); 1807 long wifiScanTime = u.getWifiScanTime(rawRealtime, which); 1808 long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which); 1809 1810 if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0 1811 || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0 1812 || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0) { 1813 dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx, 1814 wifiBytesRx, wifiBytesTx, 1815 mobilePacketsRx, mobilePacketsTx, 1816 wifiPacketsRx, wifiPacketsTx, 1817 mobileActiveTime, mobileActiveCount); 1818 } 1819 1820 if (fullWifiLockOnTime != 0 || wifiScanTime != 0 1821 || uidWifiRunningTime != 0) { 1822 dumpLine(pw, uid, category, WIFI_DATA, 1823 fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime); 1824 } 1825 1826 if (u.hasUserActivity()) { 1827 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES]; 1828 boolean hasData = false; 1829 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 1830 int val = u.getUserActivityCount(i, which); 1831 args[i] = val; 1832 if (val != 0) hasData = true; 1833 } 1834 if (hasData) { 1835 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args); 1836 } 1837 } 1838 1839 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 1840 if (wakelocks.size() > 0) { 1841 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 1842 : wakelocks.entrySet()) { 1843 Uid.Wakelock wl = ent.getValue(); 1844 String linePrefix = ""; 1845 sb.setLength(0); 1846 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), 1847 rawRealtime, "f", which, linePrefix); 1848 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), 1849 rawRealtime, "p", which, linePrefix); 1850 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), 1851 rawRealtime, "w", which, linePrefix); 1852 1853 // Only log if we had at lease one wakelock... 1854 if (sb.length() > 0) { 1855 String name = ent.getKey(); 1856 if (name.indexOf(',') >= 0) { 1857 name = name.replace(',', '_'); 1858 } 1859 dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString()); 1860 } 1861 } 1862 } 1863 1864 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 1865 if (sensors.size() > 0) { 1866 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 1867 : sensors.entrySet()) { 1868 Uid.Sensor se = ent.getValue(); 1869 int sensorNumber = ent.getKey(); 1870 Timer timer = se.getSensorTime(); 1871 if (timer != null) { 1872 // Convert from microseconds to milliseconds with rounding 1873 long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; 1874 int count = timer.getCountLocked(which); 1875 if (totalTime != 0) { 1876 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 1877 } 1878 } 1879 } 1880 } 1881 1882 Timer vibTimer = u.getVibratorOnTimer(); 1883 if (vibTimer != null) { 1884 // Convert from microseconds to milliseconds with rounding 1885 long totalTime = (vibTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; 1886 int count = vibTimer.getCountLocked(which); 1887 if (totalTime != 0) { 1888 dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count); 1889 } 1890 } 1891 1892 Timer fgTimer = u.getForegroundActivityTimer(); 1893 if (fgTimer != null) { 1894 // Convert from microseconds to milliseconds with rounding 1895 long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; 1896 int count = fgTimer.getCountLocked(which); 1897 if (totalTime != 0) { 1898 dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count); 1899 } 1900 } 1901 1902 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 1903 if (processStats.size() > 0) { 1904 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 1905 : processStats.entrySet()) { 1906 Uid.Proc ps = ent.getValue(); 1907 1908 final long userMillis = ps.getUserTime(which) * 10; 1909 final long systemMillis = ps.getSystemTime(which) * 10; 1910 final long foregroundMillis = ps.getForegroundTime(which) * 10; 1911 final long starts = ps.getStarts(which); 1912 1913 if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0 1914 || starts != 0) { 1915 dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis, 1916 systemMillis, foregroundMillis, starts); 1917 } 1918 } 1919 } 1920 1921 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 1922 if (packageStats.size() > 0) { 1923 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 1924 : packageStats.entrySet()) { 1925 1926 Uid.Pkg ps = ent.getValue(); 1927 int wakeups = ps.getWakeups(which); 1928 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 1929 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 1930 : serviceStats.entrySet()) { 1931 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 1932 long startTime = ss.getStartTime(batteryUptime, which); 1933 int starts = ss.getStarts(which); 1934 int launches = ss.getLaunches(which); 1935 if (startTime != 0 || starts != 0 || launches != 0) { 1936 dumpLine(pw, uid, category, APK_DATA, 1937 wakeups, // wakeup alarms 1938 ent.getKey(), // Apk 1939 sent.getKey(), // service 1940 startTime / 1000, // time spent started, in ms 1941 starts, 1942 launches); 1943 } 1944 } 1945 } 1946 } 1947 } 1948 } 1949 1950 static final class TimerEntry { 1951 final String mName; 1952 final int mId; 1953 final BatteryStats.Timer mTimer; 1954 final long mTime; 1955 TimerEntry(String name, int id, BatteryStats.Timer timer, long time) { 1956 mName = name; 1957 mId = id; 1958 mTimer = timer; 1959 mTime = time; 1960 } 1961 } 1962 1963 private void printmAh(PrintWriter printer, double power) { 1964 printer.print(BatteryStatsHelper.makemAh(power)); 1965 } 1966 1967 @SuppressWarnings("unused") 1968 public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which, 1969 int reqUid) { 1970 final long rawUptime = SystemClock.uptimeMillis() * 1000; 1971 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 1972 final long batteryUptime = getBatteryUptime(rawUptime); 1973 1974 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 1975 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 1976 final long totalRealtime = computeRealtime(rawRealtime, which); 1977 final long totalUptime = computeUptime(rawUptime, which); 1978 final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which); 1979 final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime, 1980 which); 1981 final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime); 1982 final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime); 1983 1984 StringBuilder sb = new StringBuilder(128); 1985 1986 SparseArray<? extends Uid> uidStats = getUidStats(); 1987 final int NU = uidStats.size(); 1988 1989 sb.setLength(0); 1990 sb.append(prefix); 1991 sb.append(" Time on battery: "); 1992 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("("); 1993 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime)); 1994 sb.append(") realtime, "); 1995 formatTimeMs(sb, whichBatteryUptime / 1000); 1996 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime)); 1997 sb.append(") uptime"); 1998 pw.println(sb.toString()); 1999 sb.setLength(0); 2000 sb.append(prefix); 2001 sb.append(" Time on battery screen off: "); 2002 formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("("); 2003 sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime)); 2004 sb.append(") realtime, "); 2005 formatTimeMs(sb, whichBatteryScreenOffUptime / 1000); 2006 sb.append("("); 2007 sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime)); 2008 sb.append(") uptime"); 2009 pw.println(sb.toString()); 2010 sb.setLength(0); 2011 sb.append(prefix); 2012 sb.append(" Total run time: "); 2013 formatTimeMs(sb, totalRealtime / 1000); 2014 sb.append("realtime, "); 2015 formatTimeMs(sb, totalUptime / 1000); 2016 sb.append("uptime"); 2017 pw.println(sb.toString()); 2018 if (batteryTimeRemaining >= 0) { 2019 sb.setLength(0); 2020 sb.append(prefix); 2021 sb.append(" Battery time remaining: "); 2022 formatTimeMs(sb, batteryTimeRemaining / 1000); 2023 pw.println(sb.toString()); 2024 } 2025 if (chargeTimeRemaining >= 0) { 2026 sb.setLength(0); 2027 sb.append(prefix); 2028 sb.append(" Charge time remaining: "); 2029 formatTimeMs(sb, chargeTimeRemaining / 1000); 2030 pw.println(sb.toString()); 2031 } 2032 pw.print(" Start clock time: "); 2033 pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString()); 2034 2035 final long screenOnTime = getScreenOnTime(rawRealtime, which); 2036 final long interactiveTime = getInteractiveTime(rawRealtime, which); 2037 final long phoneOnTime = getPhoneOnTime(rawRealtime, which); 2038 final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which); 2039 final long wifiOnTime = getWifiOnTime(rawRealtime, which); 2040 final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which); 2041 sb.setLength(0); 2042 sb.append(prefix); 2043 sb.append(" Interactive: "); formatTimeMs(sb, interactiveTime / 1000); 2044 sb.append("("); sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime)); 2045 sb.append(")"); 2046 pw.println(sb.toString()); 2047 sb.setLength(0); 2048 sb.append(prefix); 2049 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000); 2050 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime)); 2051 sb.append(") "); sb.append(getScreenOnCount(which)); 2052 sb.append("x, Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000); 2053 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime)); 2054 sb.append(")"); 2055 pw.println(sb.toString()); 2056 if (phoneOnTime != 0) { 2057 sb.setLength(0); 2058 sb.append(prefix); 2059 sb.append(" Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000); 2060 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime)); 2061 sb.append(") "); sb.append(getPhoneOnCount(which)); 2062 } 2063 sb.setLength(0); 2064 sb.append(prefix); 2065 sb.append(" Screen brightnesses:"); 2066 boolean didOne = false; 2067 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 2068 final long time = getScreenBrightnessTime(i, rawRealtime, which); 2069 if (time == 0) { 2070 continue; 2071 } 2072 sb.append("\n "); 2073 sb.append(prefix); 2074 didOne = true; 2075 sb.append(SCREEN_BRIGHTNESS_NAMES[i]); 2076 sb.append(" "); 2077 formatTimeMs(sb, time/1000); 2078 sb.append("("); 2079 sb.append(formatRatioLocked(time, screenOnTime)); 2080 sb.append(")"); 2081 } 2082 if (!didOne) sb.append(" (no activity)"); 2083 pw.println(sb.toString()); 2084 2085 // Calculate wakelock times across all uids. 2086 long fullWakeLockTimeTotalMicros = 0; 2087 long partialWakeLockTimeTotalMicros = 0; 2088 2089 final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>(); 2090 2091 for (int iu = 0; iu < NU; iu++) { 2092 Uid u = uidStats.valueAt(iu); 2093 2094 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 2095 if (wakelocks.size() > 0) { 2096 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 2097 : wakelocks.entrySet()) { 2098 Uid.Wakelock wl = ent.getValue(); 2099 2100 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 2101 if (fullWakeTimer != null) { 2102 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked( 2103 rawRealtime, which); 2104 } 2105 2106 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 2107 if (partialWakeTimer != null) { 2108 long totalTimeMicros = partialWakeTimer.getTotalTimeLocked( 2109 rawRealtime, which); 2110 if (totalTimeMicros > 0) { 2111 if (reqUid < 0) { 2112 // Only show the ordered list of all wake 2113 // locks if the caller is not asking for data 2114 // about a specific uid. 2115 timers.add(new TimerEntry(ent.getKey(), u.getUid(), 2116 partialWakeTimer, totalTimeMicros)); 2117 } 2118 partialWakeLockTimeTotalMicros += totalTimeMicros; 2119 } 2120 } 2121 } 2122 } 2123 } 2124 2125 long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which); 2126 long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which); 2127 long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which); 2128 long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which); 2129 long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which); 2130 long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which); 2131 long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which); 2132 long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which); 2133 2134 if (fullWakeLockTimeTotalMicros != 0) { 2135 sb.setLength(0); 2136 sb.append(prefix); 2137 sb.append(" Total full wakelock time: "); formatTimeMsNoSpace(sb, 2138 (fullWakeLockTimeTotalMicros + 500) / 1000); 2139 pw.println(sb.toString()); 2140 } 2141 2142 if (partialWakeLockTimeTotalMicros != 0) { 2143 sb.setLength(0); 2144 sb.append(prefix); 2145 sb.append(" Total partial wakelock time: "); formatTimeMsNoSpace(sb, 2146 (partialWakeLockTimeTotalMicros + 500) / 1000); 2147 pw.println(sb.toString()); 2148 } 2149 2150 pw.print(prefix); 2151 pw.print(" Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes)); 2152 pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes)); 2153 pw.print(" (packets received "); pw.print(mobileRxTotalPackets); 2154 pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")"); 2155 sb.setLength(0); 2156 sb.append(prefix); 2157 sb.append(" Signal levels:"); 2158 didOne = false; 2159 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 2160 final long time = getPhoneSignalStrengthTime(i, rawRealtime, which); 2161 if (time == 0) { 2162 continue; 2163 } 2164 sb.append("\n "); 2165 sb.append(prefix); 2166 didOne = true; 2167 sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]); 2168 sb.append(" "); 2169 formatTimeMs(sb, time/1000); 2170 sb.append("("); 2171 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 2172 sb.append(") "); 2173 sb.append(getPhoneSignalStrengthCount(i, which)); 2174 sb.append("x"); 2175 } 2176 if (!didOne) sb.append(" (no activity)"); 2177 pw.println(sb.toString()); 2178 2179 sb.setLength(0); 2180 sb.append(prefix); 2181 sb.append(" Signal scanning time: "); 2182 formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000); 2183 pw.println(sb.toString()); 2184 2185 sb.setLength(0); 2186 sb.append(prefix); 2187 sb.append(" Radio types:"); 2188 didOne = false; 2189 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 2190 final long time = getPhoneDataConnectionTime(i, rawRealtime, which); 2191 if (time == 0) { 2192 continue; 2193 } 2194 sb.append("\n "); 2195 sb.append(prefix); 2196 didOne = true; 2197 sb.append(DATA_CONNECTION_NAMES[i]); 2198 sb.append(" "); 2199 formatTimeMs(sb, time/1000); 2200 sb.append("("); 2201 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 2202 sb.append(") "); 2203 sb.append(getPhoneDataConnectionCount(i, which)); 2204 sb.append("x"); 2205 } 2206 if (!didOne) sb.append(" (no activity)"); 2207 pw.println(sb.toString()); 2208 2209 sb.setLength(0); 2210 sb.append(prefix); 2211 sb.append(" Mobile radio active time: "); 2212 final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which); 2213 formatTimeMs(sb, mobileActiveTime / 1000); 2214 sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime)); 2215 sb.append(") "); sb.append(getMobileRadioActiveCount(which)); 2216 sb.append("x"); 2217 pw.println(sb.toString()); 2218 2219 final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which); 2220 if (mobileActiveUnknownTime != 0) { 2221 sb.setLength(0); 2222 sb.append(prefix); 2223 sb.append(" Mobile radio active unknown time: "); 2224 formatTimeMs(sb, mobileActiveUnknownTime / 1000); 2225 sb.append("("); 2226 sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime)); 2227 sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which)); 2228 sb.append("x"); 2229 pw.println(sb.toString()); 2230 } 2231 2232 final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which); 2233 if (mobileActiveAdjustedTime != 0) { 2234 sb.setLength(0); 2235 sb.append(prefix); 2236 sb.append(" Mobile radio active adjusted time: "); 2237 formatTimeMs(sb, mobileActiveAdjustedTime / 1000); 2238 sb.append("("); 2239 sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime)); 2240 sb.append(")"); 2241 pw.println(sb.toString()); 2242 } 2243 2244 pw.print(prefix); 2245 pw.print(" Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes)); 2246 pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes)); 2247 pw.print(" (packets received "); pw.print(wifiRxTotalPackets); 2248 pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")"); 2249 sb.setLength(0); 2250 sb.append(prefix); 2251 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000); 2252 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime)); 2253 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000); 2254 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime)); 2255 sb.append(")"); 2256 pw.println(sb.toString()); 2257 2258 sb.setLength(0); 2259 sb.append(prefix); 2260 sb.append(" Wifi states:"); 2261 didOne = false; 2262 for (int i=0; i<NUM_WIFI_STATES; i++) { 2263 final long time = getWifiStateTime(i, rawRealtime, which); 2264 if (time == 0) { 2265 continue; 2266 } 2267 sb.append("\n "); 2268 didOne = true; 2269 sb.append(WIFI_STATE_NAMES[i]); 2270 sb.append(" "); 2271 formatTimeMs(sb, time/1000); 2272 sb.append("("); 2273 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 2274 sb.append(") "); 2275 sb.append(getPhoneDataConnectionCount(i, which)); 2276 sb.append("x"); 2277 } 2278 if (!didOne) sb.append(" (no activity)"); 2279 pw.println(sb.toString()); 2280 2281 sb.setLength(0); 2282 sb.append(prefix); 2283 sb.append(" Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000); 2284 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)); 2285 sb.append(")"); 2286 pw.println(sb.toString()); 2287 2288 sb.setLength(0); 2289 sb.append(prefix); 2290 sb.append(" Bluetooth states:"); 2291 didOne = false; 2292 for (int i=0; i<NUM_BLUETOOTH_STATES; i++) { 2293 final long time = getBluetoothStateTime(i, rawRealtime, which); 2294 if (time == 0) { 2295 continue; 2296 } 2297 sb.append("\n "); 2298 didOne = true; 2299 sb.append(BLUETOOTH_STATE_NAMES[i]); 2300 sb.append(" "); 2301 formatTimeMs(sb, time/1000); 2302 sb.append("("); 2303 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 2304 sb.append(") "); 2305 sb.append(getPhoneDataConnectionCount(i, which)); 2306 sb.append("x"); 2307 } 2308 if (!didOne) sb.append(" (no activity)"); 2309 pw.println(sb.toString()); 2310 2311 pw.println(); 2312 2313 if (which == STATS_SINCE_UNPLUGGED) { 2314 if (getIsOnBattery()) { 2315 pw.print(prefix); pw.println(" Device is currently unplugged"); 2316 pw.print(prefix); pw.print(" Discharge cycle start level: "); 2317 pw.println(getDischargeStartLevel()); 2318 pw.print(prefix); pw.print(" Discharge cycle current level: "); 2319 pw.println(getDischargeCurrentLevel()); 2320 } else { 2321 pw.print(prefix); pw.println(" Device is currently plugged into power"); 2322 pw.print(prefix); pw.print(" Last discharge cycle start level: "); 2323 pw.println(getDischargeStartLevel()); 2324 pw.print(prefix); pw.print(" Last discharge cycle end level: "); 2325 pw.println(getDischargeCurrentLevel()); 2326 } 2327 pw.print(prefix); pw.print(" Amount discharged while screen on: "); 2328 pw.println(getDischargeAmountScreenOn()); 2329 pw.print(prefix); pw.print(" Amount discharged while screen off: "); 2330 pw.println(getDischargeAmountScreenOff()); 2331 pw.println(" "); 2332 } else { 2333 pw.print(prefix); pw.println(" Device battery use since last full charge"); 2334 pw.print(prefix); pw.print(" Amount discharged (lower bound): "); 2335 pw.println(getLowDischargeAmountSinceCharge()); 2336 pw.print(prefix); pw.print(" Amount discharged (upper bound): "); 2337 pw.println(getHighDischargeAmountSinceCharge()); 2338 pw.print(prefix); pw.print(" Amount discharged while screen on: "); 2339 pw.println(getDischargeAmountScreenOnSinceCharge()); 2340 pw.print(prefix); pw.print(" Amount discharged while screen off: "); 2341 pw.println(getDischargeAmountScreenOffSinceCharge()); 2342 pw.println(); 2343 } 2344 2345 BatteryStatsHelper helper = new BatteryStatsHelper(context, false); 2346 helper.create(this); 2347 helper.refreshStats(which, UserHandle.USER_ALL); 2348 List<BatterySipper> sippers = helper.getUsageList(); 2349 if (sippers != null && sippers.size() > 0) { 2350 pw.print(prefix); pw.println(" Estimated power use (mAh):"); 2351 pw.print(prefix); pw.print(" Capacity: "); 2352 printmAh(pw, helper.getPowerProfile().getBatteryCapacity()); 2353 pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower()); 2354 pw.print(", Min drain: "); printmAh(pw, helper.getMinDrainedPower()); 2355 pw.print(", Max drain: "); printmAh(pw, helper.getMaxDrainedPower()); 2356 pw.println(); 2357 for (int i=0; i<sippers.size(); i++) { 2358 BatterySipper bs = sippers.get(i); 2359 switch (bs.drainType) { 2360 case IDLE: 2361 pw.print(prefix); pw.print(" Idle: "); printmAh(pw, bs.value); 2362 pw.println(); 2363 break; 2364 case CELL: 2365 pw.print(prefix); pw.print(" Cell standby: "); printmAh(pw, bs.value); 2366 pw.println(); 2367 break; 2368 case PHONE: 2369 pw.print(prefix); pw.print(" Phone calls: "); printmAh(pw, bs.value); 2370 pw.println(); 2371 break; 2372 case WIFI: 2373 pw.print(prefix); pw.print(" Wifi: "); printmAh(pw, bs.value); 2374 pw.println(); 2375 break; 2376 case BLUETOOTH: 2377 pw.print(prefix); pw.print(" Bluetooth: "); printmAh(pw, bs.value); 2378 pw.println(); 2379 break; 2380 case SCREEN: 2381 pw.print(prefix); pw.print(" Screen: "); printmAh(pw, bs.value); 2382 pw.println(); 2383 break; 2384 case APP: 2385 pw.print(prefix); pw.print(" Uid "); 2386 UserHandle.formatUid(pw, bs.uidObj.getUid()); 2387 pw.print(": "); printmAh(pw, bs.value); pw.println(); 2388 break; 2389 case USER: 2390 pw.print(prefix); pw.print(" User "); pw.print(bs.userId); 2391 pw.print(": "); printmAh(pw, bs.value); pw.println(); 2392 break; 2393 case UNACCOUNTED: 2394 pw.print(prefix); pw.print(" Unaccounted: "); printmAh(pw, bs.value); 2395 pw.println(); 2396 break; 2397 case OVERCOUNTED: 2398 pw.print(prefix); pw.print(" Over-counted: "); printmAh(pw, bs.value); 2399 pw.println(); 2400 break; 2401 } 2402 } 2403 pw.println(); 2404 } 2405 2406 sippers = helper.getMobilemsppList(); 2407 if (sippers != null && sippers.size() > 0) { 2408 pw.print(prefix); pw.println(" Per-app mobile ms per packet:"); 2409 long totalTime = 0; 2410 for (int i=0; i<sippers.size(); i++) { 2411 BatterySipper bs = sippers.get(i); 2412 sb.setLength(0); 2413 sb.append(prefix); sb.append(" Uid "); 2414 UserHandle.formatUid(sb, bs.uidObj.getUid()); 2415 sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp)); 2416 sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets); 2417 sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive); 2418 sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x"); 2419 pw.println(sb.toString()); 2420 totalTime += bs.mobileActive; 2421 } 2422 sb.setLength(0); 2423 sb.append(prefix); 2424 sb.append(" TOTAL TIME: "); 2425 formatTimeMs(sb, totalTime); 2426 sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime)); 2427 sb.append(")"); 2428 pw.println(sb.toString()); 2429 pw.println(); 2430 } 2431 2432 final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() { 2433 @Override 2434 public int compare(TimerEntry lhs, TimerEntry rhs) { 2435 long lhsTime = lhs.mTime; 2436 long rhsTime = rhs.mTime; 2437 if (lhsTime < rhsTime) { 2438 return 1; 2439 } 2440 if (lhsTime > rhsTime) { 2441 return -1; 2442 } 2443 return 0; 2444 } 2445 }; 2446 2447 if (reqUid < 0) { 2448 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); 2449 if (kernelWakelocks.size() > 0) { 2450 final ArrayList<TimerEntry> ktimers = new ArrayList<TimerEntry>(); 2451 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { 2452 BatteryStats.Timer timer = ent.getValue(); 2453 long totalTimeMillis = computeWakeLock(timer, rawRealtime, which); 2454 if (totalTimeMillis > 0) { 2455 ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis)); 2456 } 2457 } 2458 if (ktimers.size() > 0) { 2459 Collections.sort(ktimers, timerComparator); 2460 pw.print(prefix); pw.println(" All kernel wake locks:"); 2461 for (int i=0; i<ktimers.size(); i++) { 2462 TimerEntry timer = ktimers.get(i); 2463 String linePrefix = ": "; 2464 sb.setLength(0); 2465 sb.append(prefix); 2466 sb.append(" Kernel Wake lock "); 2467 sb.append(timer.mName); 2468 linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null, 2469 which, linePrefix); 2470 if (!linePrefix.equals(": ")) { 2471 sb.append(" realtime"); 2472 // Only print out wake locks that were held 2473 pw.println(sb.toString()); 2474 } 2475 } 2476 pw.println(); 2477 } 2478 } 2479 2480 if (timers.size() > 0) { 2481 Collections.sort(timers, timerComparator); 2482 pw.print(prefix); pw.println(" All partial wake locks:"); 2483 for (int i=0; i<timers.size(); i++) { 2484 TimerEntry timer = timers.get(i); 2485 sb.setLength(0); 2486 sb.append(" Wake lock "); 2487 UserHandle.formatUid(sb, timer.mId); 2488 sb.append(" "); 2489 sb.append(timer.mName); 2490 printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": "); 2491 sb.append(" realtime"); 2492 pw.println(sb.toString()); 2493 } 2494 timers.clear(); 2495 pw.println(); 2496 } 2497 2498 Map<String, ? extends LongCounter> wakeupReasons = getWakeupReasonStats(); 2499 if (wakeupReasons.size() > 0) { 2500 pw.print(prefix); pw.println(" All wakeup reasons:"); 2501 final ArrayList<TimerEntry> reasons = new ArrayList<TimerEntry>(); 2502 for (Map.Entry<String, ? extends LongCounter> ent : wakeupReasons.entrySet()) { 2503 BatteryStats.LongCounter counter = ent.getValue(); 2504 reasons.add(new TimerEntry(ent.getKey(), 0, null, 2505 ent.getValue().getCountLocked(which))); 2506 } 2507 Collections.sort(reasons, timerComparator); 2508 for (int i=0; i<reasons.size(); i++) { 2509 TimerEntry timer = reasons.get(i); 2510 String linePrefix = ": "; 2511 sb.setLength(0); 2512 sb.append(prefix); 2513 sb.append(" Wakeup reason "); 2514 sb.append(timer.mName); 2515 sb.append(": "); 2516 formatTimeMs(sb, timer.mTime); 2517 sb.append("realtime"); 2518 pw.println(sb.toString()); 2519 } 2520 pw.println(); 2521 } 2522 } 2523 2524 for (int iu=0; iu<NU; iu++) { 2525 final int uid = uidStats.keyAt(iu); 2526 if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) { 2527 continue; 2528 } 2529 2530 Uid u = uidStats.valueAt(iu); 2531 2532 pw.print(prefix); 2533 pw.print(" "); 2534 UserHandle.formatUid(pw, uid); 2535 pw.println(":"); 2536 boolean uidActivity = false; 2537 2538 long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which); 2539 long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which); 2540 long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which); 2541 long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which); 2542 long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which); 2543 long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which); 2544 long uidMobileActiveTime = u.getMobileRadioActiveTime(which); 2545 int uidMobileActiveCount = u.getMobileRadioActiveCount(which); 2546 long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which); 2547 long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which); 2548 long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which); 2549 long wifiScanTime = u.getWifiScanTime(rawRealtime, which); 2550 long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which); 2551 2552 if (mobileRxBytes > 0 || mobileTxBytes > 0 2553 || mobileRxPackets > 0 || mobileTxPackets > 0) { 2554 pw.print(prefix); pw.print(" Mobile network: "); 2555 pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, "); 2556 pw.print(formatBytesLocked(mobileTxBytes)); 2557 pw.print(" sent (packets "); pw.print(mobileRxPackets); 2558 pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)"); 2559 } 2560 if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) { 2561 sb.setLength(0); 2562 sb.append(prefix); sb.append(" Mobile radio active: "); 2563 formatTimeMs(sb, uidMobileActiveTime / 1000); 2564 sb.append("("); 2565 sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime)); 2566 sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x"); 2567 long packets = mobileRxPackets + mobileTxPackets; 2568 if (packets == 0) { 2569 packets = 1; 2570 } 2571 sb.append(" @ "); 2572 sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets)); 2573 sb.append(" mspp"); 2574 pw.println(sb.toString()); 2575 } 2576 2577 if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) { 2578 pw.print(prefix); pw.print(" Wi-Fi network: "); 2579 pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, "); 2580 pw.print(formatBytesLocked(wifiTxBytes)); 2581 pw.print(" sent (packets "); pw.print(wifiRxPackets); 2582 pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)"); 2583 } 2584 2585 if (fullWifiLockOnTime != 0 || wifiScanTime != 0 2586 || uidWifiRunningTime != 0) { 2587 sb.setLength(0); 2588 sb.append(prefix); sb.append(" Wifi Running: "); 2589 formatTimeMs(sb, uidWifiRunningTime / 1000); 2590 sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime, 2591 whichBatteryRealtime)); sb.append(")\n"); 2592 sb.append(prefix); sb.append(" Full Wifi Lock: "); 2593 formatTimeMs(sb, fullWifiLockOnTime / 1000); 2594 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime, 2595 whichBatteryRealtime)); sb.append(")\n"); 2596 sb.append(prefix); sb.append(" Wifi Scan: "); 2597 formatTimeMs(sb, wifiScanTime / 1000); 2598 sb.append("("); sb.append(formatRatioLocked(wifiScanTime, 2599 whichBatteryRealtime)); sb.append(")"); 2600 pw.println(sb.toString()); 2601 } 2602 2603 if (u.hasUserActivity()) { 2604 boolean hasData = false; 2605 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 2606 int val = u.getUserActivityCount(i, which); 2607 if (val != 0) { 2608 if (!hasData) { 2609 sb.setLength(0); 2610 sb.append(" User activity: "); 2611 hasData = true; 2612 } else { 2613 sb.append(", "); 2614 } 2615 sb.append(val); 2616 sb.append(" "); 2617 sb.append(Uid.USER_ACTIVITY_TYPES[i]); 2618 } 2619 } 2620 if (hasData) { 2621 pw.println(sb.toString()); 2622 } 2623 } 2624 2625 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); 2626 if (wakelocks.size() > 0) { 2627 long totalFull = 0, totalPartial = 0, totalWindow = 0; 2628 int count = 0; 2629 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 2630 : wakelocks.entrySet()) { 2631 Uid.Wakelock wl = ent.getValue(); 2632 String linePrefix = ": "; 2633 sb.setLength(0); 2634 sb.append(prefix); 2635 sb.append(" Wake lock "); 2636 sb.append(ent.getKey()); 2637 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, 2638 "full", which, linePrefix); 2639 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime, 2640 "partial", which, linePrefix); 2641 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, 2642 "window", which, linePrefix); 2643 if (!linePrefix.equals(": ")) { 2644 sb.append(" realtime"); 2645 // Only print out wake locks that were held 2646 pw.println(sb.toString()); 2647 uidActivity = true; 2648 count++; 2649 } 2650 totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL), 2651 rawRealtime, which); 2652 totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL), 2653 rawRealtime, which); 2654 totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW), 2655 rawRealtime, which); 2656 } 2657 if (count > 1) { 2658 if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) { 2659 sb.setLength(0); 2660 sb.append(prefix); 2661 sb.append(" TOTAL wake: "); 2662 boolean needComma = false; 2663 if (totalFull != 0) { 2664 needComma = true; 2665 formatTimeMs(sb, totalFull); 2666 sb.append("full"); 2667 } 2668 if (totalPartial != 0) { 2669 if (needComma) { 2670 sb.append(", "); 2671 } 2672 needComma = true; 2673 formatTimeMs(sb, totalPartial); 2674 sb.append("partial"); 2675 } 2676 if (totalWindow != 0) { 2677 if (needComma) { 2678 sb.append(", "); 2679 } 2680 needComma = true; 2681 formatTimeMs(sb, totalWindow); 2682 sb.append("window"); 2683 } 2684 sb.append(" realtime"); 2685 pw.println(sb.toString()); 2686 } 2687 } 2688 } 2689 2690 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 2691 if (sensors.size() > 0) { 2692 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent 2693 : sensors.entrySet()) { 2694 Uid.Sensor se = ent.getValue(); 2695 int sensorNumber = ent.getKey(); 2696 sb.setLength(0); 2697 sb.append(prefix); 2698 sb.append(" Sensor "); 2699 int handle = se.getHandle(); 2700 if (handle == Uid.Sensor.GPS) { 2701 sb.append("GPS"); 2702 } else { 2703 sb.append(handle); 2704 } 2705 sb.append(": "); 2706 2707 Timer timer = se.getSensorTime(); 2708 if (timer != null) { 2709 // Convert from microseconds to milliseconds with rounding 2710 long totalTime = (timer.getTotalTimeLocked( 2711 rawRealtime, which) + 500) / 1000; 2712 int count = timer.getCountLocked(which); 2713 //timer.logState(); 2714 if (totalTime != 0) { 2715 formatTimeMs(sb, totalTime); 2716 sb.append("realtime ("); 2717 sb.append(count); 2718 sb.append(" times)"); 2719 } else { 2720 sb.append("(not used)"); 2721 } 2722 } else { 2723 sb.append("(not used)"); 2724 } 2725 2726 pw.println(sb.toString()); 2727 uidActivity = true; 2728 } 2729 } 2730 2731 Timer vibTimer = u.getVibratorOnTimer(); 2732 if (vibTimer != null) { 2733 // Convert from microseconds to milliseconds with rounding 2734 long totalTime = (vibTimer.getTotalTimeLocked( 2735 rawRealtime, which) + 500) / 1000; 2736 int count = vibTimer.getCountLocked(which); 2737 //timer.logState(); 2738 if (totalTime != 0) { 2739 sb.setLength(0); 2740 sb.append(prefix); 2741 sb.append(" Vibrator: "); 2742 formatTimeMs(sb, totalTime); 2743 sb.append("realtime ("); 2744 sb.append(count); 2745 sb.append(" times)"); 2746 pw.println(sb.toString()); 2747 uidActivity = true; 2748 } 2749 } 2750 2751 Timer fgTimer = u.getForegroundActivityTimer(); 2752 if (fgTimer != null) { 2753 // Convert from microseconds to milliseconds with rounding 2754 long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; 2755 int count = fgTimer.getCountLocked(which); 2756 if (totalTime != 0) { 2757 sb.setLength(0); 2758 sb.append(prefix); 2759 sb.append(" Foreground activities: "); 2760 formatTimeMs(sb, totalTime); 2761 sb.append("realtime ("); 2762 sb.append(count); 2763 sb.append(" times)"); 2764 pw.println(sb.toString()); 2765 uidActivity = true; 2766 } 2767 } 2768 2769 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 2770 if (processStats.size() > 0) { 2771 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 2772 : processStats.entrySet()) { 2773 Uid.Proc ps = ent.getValue(); 2774 long userTime; 2775 long systemTime; 2776 long foregroundTime; 2777 int starts; 2778 int numExcessive; 2779 2780 userTime = ps.getUserTime(which); 2781 systemTime = ps.getSystemTime(which); 2782 foregroundTime = ps.getForegroundTime(which); 2783 starts = ps.getStarts(which); 2784 numExcessive = which == STATS_SINCE_CHARGED 2785 ? ps.countExcessivePowers() : 0; 2786 2787 if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0 2788 || numExcessive != 0) { 2789 sb.setLength(0); 2790 sb.append(prefix); sb.append(" Proc "); 2791 sb.append(ent.getKey()); sb.append(":\n"); 2792 sb.append(prefix); sb.append(" CPU: "); 2793 formatTime(sb, userTime); sb.append("usr + "); 2794 formatTime(sb, systemTime); sb.append("krn ; "); 2795 formatTime(sb, foregroundTime); sb.append("fg"); 2796 if (starts != 0) { 2797 sb.append("\n"); sb.append(prefix); sb.append(" "); 2798 sb.append(starts); sb.append(" proc starts"); 2799 } 2800 pw.println(sb.toString()); 2801 for (int e=0; e<numExcessive; e++) { 2802 Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e); 2803 if (ew != null) { 2804 pw.print(prefix); pw.print(" * Killed for "); 2805 if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) { 2806 pw.print("wake lock"); 2807 } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) { 2808 pw.print("cpu"); 2809 } else { 2810 pw.print("unknown"); 2811 } 2812 pw.print(" use: "); 2813 TimeUtils.formatDuration(ew.usedTime, pw); 2814 pw.print(" over "); 2815 TimeUtils.formatDuration(ew.overTime, pw); 2816 if (ew.overTime != 0) { 2817 pw.print(" ("); 2818 pw.print((ew.usedTime*100)/ew.overTime); 2819 pw.println("%)"); 2820 } 2821 } 2822 } 2823 uidActivity = true; 2824 } 2825 } 2826 } 2827 2828 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats(); 2829 if (packageStats.size() > 0) { 2830 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent 2831 : packageStats.entrySet()) { 2832 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":"); 2833 boolean apkActivity = false; 2834 Uid.Pkg ps = ent.getValue(); 2835 int wakeups = ps.getWakeups(which); 2836 if (wakeups != 0) { 2837 pw.print(prefix); pw.print(" "); 2838 pw.print(wakeups); pw.println(" wakeup alarms"); 2839 apkActivity = true; 2840 } 2841 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 2842 if (serviceStats.size() > 0) { 2843 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent 2844 : serviceStats.entrySet()) { 2845 BatteryStats.Uid.Pkg.Serv ss = sent.getValue(); 2846 long startTime = ss.getStartTime(batteryUptime, which); 2847 int starts = ss.getStarts(which); 2848 int launches = ss.getLaunches(which); 2849 if (startTime != 0 || starts != 0 || launches != 0) { 2850 sb.setLength(0); 2851 sb.append(prefix); sb.append(" Service "); 2852 sb.append(sent.getKey()); sb.append(":\n"); 2853 sb.append(prefix); sb.append(" Created for: "); 2854 formatTimeMs(sb, startTime / 1000); 2855 sb.append("uptime\n"); 2856 sb.append(prefix); sb.append(" Starts: "); 2857 sb.append(starts); 2858 sb.append(", launches: "); sb.append(launches); 2859 pw.println(sb.toString()); 2860 apkActivity = true; 2861 } 2862 } 2863 } 2864 if (!apkActivity) { 2865 pw.print(prefix); pw.println(" (nothing executed)"); 2866 } 2867 uidActivity = true; 2868 } 2869 } 2870 if (!uidActivity) { 2871 pw.print(prefix); pw.println(" (nothing executed)"); 2872 } 2873 } 2874 } 2875 2876 static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag, 2877 BitDescription[] descriptions, boolean longNames) { 2878 int diff = oldval ^ newval; 2879 if (diff == 0) return; 2880 boolean didWake = false; 2881 for (int i=0; i<descriptions.length; i++) { 2882 BitDescription bd = descriptions[i]; 2883 if ((diff&bd.mask) != 0) { 2884 pw.print(longNames ? " " : ","); 2885 if (bd.shift < 0) { 2886 pw.print((newval&bd.mask) != 0 ? "+" : "-"); 2887 pw.print(longNames ? bd.name : bd.shortName); 2888 if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) { 2889 didWake = true; 2890 pw.print("="); 2891 if (longNames) { 2892 UserHandle.formatUid(pw, wakelockTag.uid); 2893 pw.print(":\""); 2894 pw.print(wakelockTag.string); 2895 pw.print("\""); 2896 } else { 2897 pw.print(wakelockTag.poolIdx); 2898 } 2899 } 2900 } else { 2901 pw.print(longNames ? bd.name : bd.shortName); 2902 pw.print("="); 2903 int val = (newval&bd.mask)>>bd.shift; 2904 if (bd.values != null && val >= 0 && val < bd.values.length) { 2905 pw.print(longNames? bd.values[val] : bd.shortValues[val]); 2906 } else { 2907 pw.print(val); 2908 } 2909 } 2910 } 2911 } 2912 if (!didWake && wakelockTag != null) { 2913 pw.print(longNames ? " wake_lock=" : ",w="); 2914 if (longNames) { 2915 UserHandle.formatUid(pw, wakelockTag.uid); 2916 pw.print(":\""); 2917 pw.print(wakelockTag.string); 2918 pw.print("\""); 2919 } else { 2920 pw.print(wakelockTag.poolIdx); 2921 } 2922 } 2923 } 2924 2925 public void prepareForDumpLocked() { 2926 } 2927 2928 public static class HistoryPrinter { 2929 int oldState = 0; 2930 int oldState2 = 0; 2931 int oldLevel = -1; 2932 int oldStatus = -1; 2933 int oldHealth = -1; 2934 int oldPlug = -1; 2935 int oldTemp = -1; 2936 int oldVolt = -1; 2937 long lastTime = -1; 2938 long firstTime = -1; 2939 2940 public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin, 2941 boolean verbose) { 2942 if (!checkin) { 2943 pw.print(" "); 2944 TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN); 2945 pw.print(" ("); 2946 pw.print(rec.numReadInts); 2947 pw.print(") "); 2948 } else { 2949 if (lastTime < 0) { 2950 pw.print(rec.time - baseTime); 2951 } else { 2952 pw.print(rec.time - lastTime); 2953 } 2954 lastTime = rec.time; 2955 } 2956 if (rec.cmd == HistoryItem.CMD_START) { 2957 if (checkin) { 2958 pw.print(":"); 2959 } 2960 pw.println("START"); 2961 } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) { 2962 if (checkin) { 2963 pw.print(":"); 2964 } 2965 pw.print("TIME:"); 2966 if (checkin) { 2967 pw.println(rec.currentTime); 2968 } else { 2969 pw.print(" "); 2970 pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", 2971 rec.currentTime).toString()); 2972 } 2973 } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) { 2974 if (checkin) { 2975 pw.print(":"); 2976 } 2977 pw.println("*OVERFLOW*"); 2978 } else { 2979 if (!checkin) { 2980 if (rec.batteryLevel < 10) pw.print("00"); 2981 else if (rec.batteryLevel < 100) pw.print("0"); 2982 pw.print(rec.batteryLevel); 2983 if (verbose) { 2984 pw.print(" "); 2985 if (rec.states < 0) ; 2986 else if (rec.states < 0x10) pw.print("0000000"); 2987 else if (rec.states < 0x100) pw.print("000000"); 2988 else if (rec.states < 0x1000) pw.print("00000"); 2989 else if (rec.states < 0x10000) pw.print("0000"); 2990 else if (rec.states < 0x100000) pw.print("000"); 2991 else if (rec.states < 0x1000000) pw.print("00"); 2992 else if (rec.states < 0x10000000) pw.print("0"); 2993 pw.print(Integer.toHexString(rec.states)); 2994 } 2995 } else { 2996 if (oldLevel != rec.batteryLevel) { 2997 oldLevel = rec.batteryLevel; 2998 pw.print(",Bl="); pw.print(rec.batteryLevel); 2999 } 3000 } 3001 if (oldStatus != rec.batteryStatus) { 3002 oldStatus = rec.batteryStatus; 3003 pw.print(checkin ? ",Bs=" : " status="); 3004 switch (oldStatus) { 3005 case BatteryManager.BATTERY_STATUS_UNKNOWN: 3006 pw.print(checkin ? "?" : "unknown"); 3007 break; 3008 case BatteryManager.BATTERY_STATUS_CHARGING: 3009 pw.print(checkin ? "c" : "charging"); 3010 break; 3011 case BatteryManager.BATTERY_STATUS_DISCHARGING: 3012 pw.print(checkin ? "d" : "discharging"); 3013 break; 3014 case BatteryManager.BATTERY_STATUS_NOT_CHARGING: 3015 pw.print(checkin ? "n" : "not-charging"); 3016 break; 3017 case BatteryManager.BATTERY_STATUS_FULL: 3018 pw.print(checkin ? "f" : "full"); 3019 break; 3020 default: 3021 pw.print(oldStatus); 3022 break; 3023 } 3024 } 3025 if (oldHealth != rec.batteryHealth) { 3026 oldHealth = rec.batteryHealth; 3027 pw.print(checkin ? ",Bh=" : " health="); 3028 switch (oldHealth) { 3029 case BatteryManager.BATTERY_HEALTH_UNKNOWN: 3030 pw.print(checkin ? "?" : "unknown"); 3031 break; 3032 case BatteryManager.BATTERY_HEALTH_GOOD: 3033 pw.print(checkin ? "g" : "good"); 3034 break; 3035 case BatteryManager.BATTERY_HEALTH_OVERHEAT: 3036 pw.print(checkin ? "h" : "overheat"); 3037 break; 3038 case BatteryManager.BATTERY_HEALTH_DEAD: 3039 pw.print(checkin ? "d" : "dead"); 3040 break; 3041 case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: 3042 pw.print(checkin ? "v" : "over-voltage"); 3043 break; 3044 case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: 3045 pw.print(checkin ? "f" : "failure"); 3046 break; 3047 case BatteryManager.BATTERY_HEALTH_COLD: 3048 pw.print(checkin ? "c" : "cold"); 3049 break; 3050 default: 3051 pw.print(oldHealth); 3052 break; 3053 } 3054 } 3055 if (oldPlug != rec.batteryPlugType) { 3056 oldPlug = rec.batteryPlugType; 3057 pw.print(checkin ? ",Bp=" : " plug="); 3058 switch (oldPlug) { 3059 case 0: 3060 pw.print(checkin ? "n" : "none"); 3061 break; 3062 case BatteryManager.BATTERY_PLUGGED_AC: 3063 pw.print(checkin ? "a" : "ac"); 3064 break; 3065 case BatteryManager.BATTERY_PLUGGED_USB: 3066 pw.print(checkin ? "u" : "usb"); 3067 break; 3068 case BatteryManager.BATTERY_PLUGGED_WIRELESS: 3069 pw.print(checkin ? "w" : "wireless"); 3070 break; 3071 default: 3072 pw.print(oldPlug); 3073 break; 3074 } 3075 } 3076 if (oldTemp != rec.batteryTemperature) { 3077 oldTemp = rec.batteryTemperature; 3078 pw.print(checkin ? ",Bt=" : " temp="); 3079 pw.print(oldTemp); 3080 } 3081 if (oldVolt != rec.batteryVoltage) { 3082 oldVolt = rec.batteryVoltage; 3083 pw.print(checkin ? ",Bv=" : " volt="); 3084 pw.print(oldVolt); 3085 } 3086 printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag, 3087 HISTORY_STATE_DESCRIPTIONS, !checkin); 3088 printBitDescriptions(pw, oldState2, rec.states2, null, 3089 HISTORY_STATE2_DESCRIPTIONS, !checkin); 3090 if (rec.wakeReasonTag != null) { 3091 if (checkin) { 3092 pw.print(",wr="); 3093 pw.print(rec.wakeReasonTag.poolIdx); 3094 } else { 3095 pw.print(" wake_reason="); 3096 pw.print(rec.wakeReasonTag.uid); 3097 pw.print(":\""); 3098 pw.print(rec.wakeReasonTag.string); 3099 pw.print("\""); 3100 } 3101 } 3102 if (rec.eventCode != HistoryItem.EVENT_NONE) { 3103 pw.print(checkin ? "," : " "); 3104 if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) { 3105 pw.print("+"); 3106 } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) { 3107 pw.print("-"); 3108 } 3109 String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES 3110 : HISTORY_EVENT_NAMES; 3111 int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START 3112 | HistoryItem.EVENT_FLAG_FINISH); 3113 if (idx >= 0 && idx < eventNames.length) { 3114 pw.print(eventNames[idx]); 3115 } else { 3116 pw.print(checkin ? "Ev" : "event"); 3117 pw.print(idx); 3118 } 3119 pw.print("="); 3120 if (checkin) { 3121 pw.print(rec.eventTag.poolIdx); 3122 } else { 3123 UserHandle.formatUid(pw, rec.eventTag.uid); 3124 pw.print(":\""); 3125 pw.print(rec.eventTag.string); 3126 pw.print("\""); 3127 } 3128 } 3129 pw.println(); 3130 oldState = rec.states; 3131 } 3132 } 3133 } 3134 3135 private void printSizeValue(PrintWriter pw, long size) { 3136 float result = size; 3137 String suffix = ""; 3138 if (result >= 10*1024) { 3139 suffix = "KB"; 3140 result = result / 1024; 3141 } 3142 if (result >= 10*1024) { 3143 suffix = "MB"; 3144 result = result / 1024; 3145 } 3146 if (result >= 10*1024) { 3147 suffix = "GB"; 3148 result = result / 1024; 3149 } 3150 if (result >= 10*1024) { 3151 suffix = "TB"; 3152 result = result / 1024; 3153 } 3154 if (result >= 10*1024) { 3155 suffix = "PB"; 3156 result = result / 1024; 3157 } 3158 pw.print((int)result); 3159 pw.print(suffix); 3160 } 3161 3162 private static boolean dumpDurationSteps(PrintWriter pw, String header, long[] steps, 3163 int count, boolean checkin) { 3164 if (count <= 0) { 3165 return false; 3166 } 3167 if (!checkin) { 3168 pw.println(header); 3169 } 3170 String[] lineArgs = new String[1]; 3171 for (int i=0; i<count; i++) { 3172 if (checkin) { 3173 lineArgs[0] = Long.toString(steps[i]); 3174 dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs); 3175 } else { 3176 pw.print(" #"); pw.print(i); pw.print(": "); 3177 TimeUtils.formatDuration(steps[i], pw); 3178 pw.println(); 3179 } 3180 } 3181 return true; 3182 } 3183 3184 public static final int DUMP_UNPLUGGED_ONLY = 1<<0; 3185 public static final int DUMP_CHARGED_ONLY = 1<<1; 3186 public static final int DUMP_HISTORY_ONLY = 1<<2; 3187 public static final int DUMP_INCLUDE_HISTORY = 1<<3; 3188 public static final int DUMP_VERBOSE = 1<<4; 3189 3190 /** 3191 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 3192 * 3193 * @param pw a Printer to receive the dump output. 3194 */ 3195 @SuppressWarnings("unused") 3196 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 3197 prepareForDumpLocked(); 3198 3199 final boolean filtering = 3200 (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0; 3201 3202 if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) { 3203 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); 3204 3205 final HistoryItem rec = new HistoryItem(); 3206 final long historyTotalSize = getHistoryTotalSize(); 3207 final long historyUsedSize = getHistoryUsedSize(); 3208 if (startIteratingHistoryLocked()) { 3209 try { 3210 pw.print("Battery History ("); 3211 pw.print((100*historyUsedSize)/historyTotalSize); 3212 pw.print("% used, "); 3213 printSizeValue(pw, historyUsedSize); 3214 pw.print(" used of "); 3215 printSizeValue(pw, historyTotalSize); 3216 pw.print(", "); 3217 pw.print(getHistoryStringPoolSize()); 3218 pw.print(" strings using "); 3219 printSizeValue(pw, getHistoryStringPoolBytes()); 3220 pw.println("):"); 3221 HistoryPrinter hprinter = new HistoryPrinter(); 3222 long lastTime = -1; 3223 long baseTime = -1; 3224 boolean printed = false; 3225 while (getNextHistoryLocked(rec)) { 3226 lastTime = rec.time; 3227 if (baseTime < 0) { 3228 baseTime = lastTime; 3229 } 3230 if (rec.time >= histStart) { 3231 if (histStart >= 0 && !printed) { 3232 if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) { 3233 printed = true; 3234 } else if (rec.currentTime != 0) { 3235 printed = true; 3236 byte cmd = rec.cmd; 3237 rec.cmd = HistoryItem.CMD_CURRENT_TIME; 3238 hprinter.printNextItem(pw, rec, baseTime, false, 3239 (flags&DUMP_VERBOSE) != 0); 3240 rec.cmd = cmd; 3241 } 3242 } 3243 hprinter.printNextItem(pw, rec, baseTime, false, 3244 (flags&DUMP_VERBOSE) != 0); 3245 } 3246 } 3247 if (histStart >= 0) { 3248 pw.print(" NEXT: "); pw.println(lastTime+1); 3249 } 3250 pw.println(); 3251 } finally { 3252 finishIteratingHistoryLocked(); 3253 } 3254 } 3255 3256 if (startIteratingOldHistoryLocked()) { 3257 try { 3258 pw.println("Old battery History:"); 3259 HistoryPrinter hprinter = new HistoryPrinter(); 3260 long baseTime = -1; 3261 while (getNextOldHistoryLocked(rec)) { 3262 if (baseTime < 0) { 3263 baseTime = rec.time; 3264 } 3265 hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0); 3266 } 3267 pw.println(); 3268 } finally { 3269 finishIteratingOldHistoryLocked(); 3270 } 3271 } 3272 } 3273 3274 if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) { 3275 return; 3276 } 3277 3278 if (!filtering) { 3279 SparseArray<? extends Uid> uidStats = getUidStats(); 3280 final int NU = uidStats.size(); 3281 boolean didPid = false; 3282 long nowRealtime = SystemClock.elapsedRealtime(); 3283 for (int i=0; i<NU; i++) { 3284 Uid uid = uidStats.valueAt(i); 3285 SparseArray<? extends Uid.Pid> pids = uid.getPidStats(); 3286 if (pids != null) { 3287 for (int j=0; j<pids.size(); j++) { 3288 Uid.Pid pid = pids.valueAt(j); 3289 if (!didPid) { 3290 pw.println("Per-PID Stats:"); 3291 didPid = true; 3292 } 3293 long time = pid.mWakeSumMs + (pid.mWakeNesting > 0 3294 ? (nowRealtime - pid.mWakeStartMs) : 0); 3295 pw.print(" PID "); pw.print(pids.keyAt(j)); 3296 pw.print(" wake time: "); 3297 TimeUtils.formatDuration(time, pw); 3298 pw.println(""); 3299 } 3300 } 3301 } 3302 if (didPid) { 3303 pw.println(); 3304 } 3305 if (dumpDurationSteps(pw, "Discharge step durations:", getDischargeStepDurationsArray(), 3306 getNumDischargeStepDurations(), false)) { 3307 long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime()); 3308 if (timeRemaining >= 0) { 3309 pw.print(" Estimated discharge time remaining: "); 3310 TimeUtils.formatDuration(timeRemaining / 1000, pw); 3311 pw.println(); 3312 } 3313 pw.println(); 3314 } 3315 if (dumpDurationSteps(pw, "Charge step durations:", getChargeStepDurationsArray(), 3316 getNumChargeStepDurations(), false)) { 3317 long timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime()); 3318 if (timeRemaining >= 0) { 3319 pw.print(" Estimated charge time remaining: "); 3320 TimeUtils.formatDuration(timeRemaining / 1000, pw); 3321 pw.println(); 3322 } 3323 pw.println(); 3324 } 3325 } 3326 3327 if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) { 3328 pw.println("Statistics since last charge:"); 3329 pw.println(" System starts: " + getStartCount() 3330 + ", currently on battery: " + getIsOnBattery()); 3331 dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid); 3332 pw.println(); 3333 } 3334 if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) { 3335 pw.println("Statistics since last unplugged:"); 3336 dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid); 3337 } 3338 } 3339 3340 @SuppressWarnings("unused") 3341 public void dumpCheckinLocked(Context context, PrintWriter pw, 3342 List<ApplicationInfo> apps, int flags, long histStart) { 3343 prepareForDumpLocked(); 3344 3345 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); 3346 3347 final boolean filtering = 3348 (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0; 3349 3350 if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) { 3351 final HistoryItem rec = new HistoryItem(); 3352 if (startIteratingHistoryLocked()) { 3353 try { 3354 for (int i=0; i<getHistoryStringPoolSize(); i++) { 3355 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 3356 pw.print(HISTORY_STRING_POOL); pw.print(','); 3357 pw.print(i); 3358 pw.print(","); 3359 pw.print(getHistoryTagPoolUid(i)); 3360 pw.print(",\""); 3361 String str = getHistoryTagPoolString(i); 3362 str = str.replace("\\", "\\\\"); 3363 str = str.replace("\"", "\\\""); 3364 pw.print(str); 3365 pw.print("\""); 3366 pw.println(); 3367 } 3368 HistoryPrinter hprinter = new HistoryPrinter(); 3369 long lastTime = -1; 3370 long baseTime = -1; 3371 boolean printed = false; 3372 while (getNextHistoryLocked(rec)) { 3373 lastTime = rec.time; 3374 if (baseTime < 0) { 3375 baseTime = lastTime; 3376 } 3377 if (rec.time >= histStart) { 3378 if (histStart >= 0 && !printed) { 3379 if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) { 3380 printed = true; 3381 } else if (rec.currentTime != 0) { 3382 printed = true; 3383 byte cmd = rec.cmd; 3384 rec.cmd = HistoryItem.CMD_CURRENT_TIME; 3385 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 3386 pw.print(HISTORY_DATA); pw.print(','); 3387 hprinter.printNextItem(pw, rec, baseTime, true, false); 3388 rec.cmd = cmd; 3389 } 3390 } 3391 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 3392 pw.print(HISTORY_DATA); pw.print(','); 3393 hprinter.printNextItem(pw, rec, baseTime, true, false); 3394 } 3395 } 3396 if (histStart >= 0) { 3397 pw.print("NEXT: "); pw.println(lastTime+1); 3398 } 3399 } finally { 3400 finishIteratingHistoryLocked(); 3401 } 3402 } 3403 } 3404 3405 if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) { 3406 return; 3407 } 3408 3409 if (apps != null) { 3410 SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>(); 3411 for (int i=0; i<apps.size(); i++) { 3412 ApplicationInfo ai = apps.get(i); 3413 ArrayList<String> pkgs = uids.get(ai.uid); 3414 if (pkgs == null) { 3415 pkgs = new ArrayList<String>(); 3416 uids.put(ai.uid, pkgs); 3417 } 3418 pkgs.add(ai.packageName); 3419 } 3420 SparseArray<? extends Uid> uidStats = getUidStats(); 3421 final int NU = uidStats.size(); 3422 String[] lineArgs = new String[2]; 3423 for (int i=0; i<NU; i++) { 3424 int uid = uidStats.keyAt(i); 3425 ArrayList<String> pkgs = uids.get(uid); 3426 if (pkgs != null) { 3427 for (int j=0; j<pkgs.size(); j++) { 3428 lineArgs[0] = Integer.toString(uid); 3429 lineArgs[1] = pkgs.get(j); 3430 dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA, 3431 (Object[])lineArgs); 3432 } 3433 } 3434 } 3435 } 3436 if (!filtering) { 3437 dumpDurationSteps(pw, DISCHARGE_STEP_DATA, getDischargeStepDurationsArray(), 3438 getNumDischargeStepDurations(), true); 3439 String[] lineArgs = new String[1]; 3440 long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime()); 3441 if (timeRemaining >= 0) { 3442 lineArgs[0] = Long.toString(timeRemaining); 3443 dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA, 3444 (Object[])lineArgs); 3445 } 3446 dumpDurationSteps(pw, CHARGE_STEP_DATA, getChargeStepDurationsArray(), 3447 getNumChargeStepDurations(), true); 3448 timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime()); 3449 if (timeRemaining >= 0) { 3450 lineArgs[0] = Long.toString(timeRemaining); 3451 dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA, 3452 (Object[])lineArgs); 3453 } 3454 } 3455 if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) { 3456 dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1); 3457 } 3458 if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) { 3459 dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1); 3460 } 3461 } 3462} 3463