BatteryStats.java revision e9b9b73ab598a912de04fbd5501bca5924ce8f71
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.HashMap; 25import java.util.List; 26import java.util.Map; 27 28import android.content.Context; 29import android.content.pm.ApplicationInfo; 30import android.telephony.SignalStrength; 31import android.text.format.DateFormat; 32import android.util.ArrayMap; 33import android.util.Printer; 34import android.util.SparseArray; 35import android.util.SparseIntArray; 36import android.util.TimeUtils; 37import android.view.Display; 38import com.android.internal.os.BatterySipper; 39import com.android.internal.os.BatteryStatsHelper; 40 41/** 42 * A class providing access to battery usage statistics, including information on 43 * wakelocks, processes, packages, and services. All times are represented in microseconds 44 * except where indicated otherwise. 45 * @hide 46 */ 47public abstract class BatteryStats implements Parcelable { 48 49 private static final boolean LOCAL_LOGV = false; 50 51 /** @hide */ 52 public static final String SERVICE_NAME = "batterystats"; 53 54 /** 55 * A constant indicating a partial wake lock timer. 56 */ 57 public static final int WAKE_TYPE_PARTIAL = 0; 58 59 /** 60 * A constant indicating a full wake lock timer. 61 */ 62 public static final int WAKE_TYPE_FULL = 1; 63 64 /** 65 * A constant indicating a window wake lock timer. 66 */ 67 public static final int WAKE_TYPE_WINDOW = 2; 68 69 /** 70 * A constant indicating a sensor timer. 71 */ 72 public static final int SENSOR = 3; 73 74 /** 75 * A constant indicating a a wifi running timer 76 */ 77 public static final int WIFI_RUNNING = 4; 78 79 /** 80 * A constant indicating a full wifi lock timer 81 */ 82 public static final int FULL_WIFI_LOCK = 5; 83 84 /** 85 * A constant indicating a wifi scan 86 */ 87 public static final int WIFI_SCAN = 6; 88 89 /** 90 * A constant indicating a wifi multicast timer 91 */ 92 public static final int WIFI_MULTICAST_ENABLED = 7; 93 94 /** 95 * A constant indicating a video turn on timer 96 */ 97 public static final int VIDEO_TURNED_ON = 8; 98 99 /** 100 * A constant indicating a vibrator on timer 101 */ 102 public static final int VIBRATOR_ON = 9; 103 104 /** 105 * A constant indicating a foreground activity timer 106 */ 107 public static final int FOREGROUND_ACTIVITY = 10; 108 109 /** 110 * A constant indicating a wifi batched scan is active 111 */ 112 public static final int WIFI_BATCHED_SCAN = 11; 113 114 /** 115 * A constant indicating a process state timer 116 */ 117 public static final int PROCESS_STATE = 12; 118 119 /** 120 * A constant indicating a sync timer 121 */ 122 public static final int SYNC = 13; 123 124 /** 125 * A constant indicating a job timer 126 */ 127 public static final int JOB = 14; 128 129 /** 130 * A constant indicating an audio turn on timer 131 */ 132 public static final int AUDIO_TURNED_ON = 15; 133 134 /** 135 * Include all of the data in the stats, including previously saved data. 136 */ 137 public static final int STATS_SINCE_CHARGED = 0; 138 139 /** 140 * Include only the current run in the stats. 141 */ 142 public static final int STATS_CURRENT = 1; 143 144 /** 145 * Include only the run since the last time the device was unplugged in the stats. 146 */ 147 public static final int STATS_SINCE_UNPLUGGED = 2; 148 149 // NOTE: Update this list if you add/change any stats above. 150 // These characters are supposed to represent "total", "last", "current", 151 // and "unplugged". They were shortened for efficiency sake. 152 private static final String[] STAT_NAMES = { "l", "c", "u" }; 153 154 /** 155 * Bump the version on this if the checkin format changes. 156 */ 157 private static final int BATTERY_STATS_CHECKIN_VERSION = 9; 158 159 private static final long BYTES_PER_KB = 1024; 160 private static final long BYTES_PER_MB = 1048576; // 1024^2 161 private static final long BYTES_PER_GB = 1073741824; //1024^3 162 163 private static final String VERSION_DATA = "vers"; 164 private static final String UID_DATA = "uid"; 165 private static final String APK_DATA = "apk"; 166 private static final String PROCESS_DATA = "pr"; 167 private static final String SENSOR_DATA = "sr"; 168 private static final String VIBRATOR_DATA = "vib"; 169 private static final String FOREGROUND_DATA = "fg"; 170 private static final String STATE_TIME_DATA = "st"; 171 private static final String WAKELOCK_DATA = "wl"; 172 private static final String SYNC_DATA = "sy"; 173 private static final String JOB_DATA = "jb"; 174 private static final String KERNEL_WAKELOCK_DATA = "kwl"; 175 private static final String WAKEUP_REASON_DATA = "wr"; 176 private static final String NETWORK_DATA = "nt"; 177 private static final String USER_ACTIVITY_DATA = "ua"; 178 private static final String BATTERY_DATA = "bt"; 179 private static final String BATTERY_DISCHARGE_DATA = "dc"; 180 private static final String BATTERY_LEVEL_DATA = "lv"; 181 private static final String WIFI_DATA = "wfl"; 182 private static final String MISC_DATA = "m"; 183 private static final String GLOBAL_NETWORK_DATA = "gn"; 184 private static final String HISTORY_STRING_POOL = "hsp"; 185 private static final String HISTORY_DATA = "h"; 186 private static final String SCREEN_BRIGHTNESS_DATA = "br"; 187 private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt"; 188 private static final String SIGNAL_SCANNING_TIME_DATA = "sst"; 189 private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc"; 190 private static final String DATA_CONNECTION_TIME_DATA = "dct"; 191 private static final String DATA_CONNECTION_COUNT_DATA = "dcc"; 192 private static final String WIFI_STATE_TIME_DATA = "wst"; 193 private static final String WIFI_STATE_COUNT_DATA = "wsc"; 194 private static final String WIFI_SUPPL_STATE_TIME_DATA = "wsst"; 195 private static final String WIFI_SUPPL_STATE_COUNT_DATA = "wssc"; 196 private static final String WIFI_SIGNAL_STRENGTH_TIME_DATA = "wsgt"; 197 private static final String WIFI_SIGNAL_STRENGTH_COUNT_DATA = "wsgc"; 198 private static final String BLUETOOTH_STATE_TIME_DATA = "bst"; 199 private static final String BLUETOOTH_STATE_COUNT_DATA = "bsc"; 200 private static final String POWER_USE_SUMMARY_DATA = "pws"; 201 private static final String POWER_USE_ITEM_DATA = "pwi"; 202 private static final String DISCHARGE_STEP_DATA = "dsd"; 203 private static final String CHARGE_STEP_DATA = "csd"; 204 private static final String DISCHARGE_TIME_REMAIN_DATA = "dtr"; 205 private static final String CHARGE_TIME_REMAIN_DATA = "ctr"; 206 207 private final StringBuilder mFormatBuilder = new StringBuilder(32); 208 private final Formatter mFormatter = new Formatter(mFormatBuilder); 209 210 /** 211 * State for keeping track of counting information. 212 */ 213 public static abstract class Counter { 214 215 /** 216 * Returns the count associated with this Counter for the 217 * selected type of statistics. 218 * 219 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT 220 */ 221 public abstract int getCountLocked(int which); 222 223 /** 224 * Temporary for debugging. 225 */ 226 public abstract void logState(Printer pw, String prefix); 227 } 228 229 /** 230 * State for keeping track of long counting information. 231 */ 232 public static abstract class LongCounter { 233 234 /** 235 * Returns the count associated with this Counter for the 236 * selected type of statistics. 237 * 238 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT 239 */ 240 public abstract long getCountLocked(int which); 241 242 /** 243 * Temporary for debugging. 244 */ 245 public abstract void logState(Printer pw, String prefix); 246 } 247 248 /** 249 * State for keeping track of timing information. 250 */ 251 public static abstract class Timer { 252 253 /** 254 * Returns the count associated with this Timer for the 255 * selected type of statistics. 256 * 257 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT 258 */ 259 public abstract int getCountLocked(int which); 260 261 /** 262 * Returns the total time in microseconds associated with this Timer for the 263 * selected type of statistics. 264 * 265 * @param elapsedRealtimeUs current elapsed realtime of system in microseconds 266 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT 267 * @return a time in microseconds 268 */ 269 public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which); 270 271 /** 272 * Temporary for debugging. 273 */ 274 public abstract void logState(Printer pw, String prefix); 275 } 276 277 /** 278 * The statistics associated with a particular uid. 279 */ 280 public static abstract class Uid { 281 282 /** 283 * Returns a mapping containing wakelock statistics. 284 * 285 * @return a Map from Strings to Uid.Wakelock objects. 286 */ 287 public abstract ArrayMap<String, ? extends Wakelock> getWakelockStats(); 288 289 /** 290 * Returns a mapping containing sync statistics. 291 * 292 * @return a Map from Strings to Timer objects. 293 */ 294 public abstract ArrayMap<String, ? extends Timer> getSyncStats(); 295 296 /** 297 * Returns a mapping containing scheduled job statistics. 298 * 299 * @return a Map from Strings to Timer objects. 300 */ 301 public abstract ArrayMap<String, ? extends Timer> getJobStats(); 302 303 /** 304 * The statistics associated with a particular wake lock. 305 */ 306 public static abstract class Wakelock { 307 public abstract Timer getWakeTime(int type); 308 } 309 310 /** 311 * Returns a mapping containing sensor statistics. 312 * 313 * @return a Map from Integer sensor ids to Uid.Sensor objects. 314 */ 315 public abstract SparseArray<? extends Sensor> getSensorStats(); 316 317 /** 318 * Returns a mapping containing active process data. 319 */ 320 public abstract SparseArray<? extends Pid> getPidStats(); 321 322 /** 323 * Returns a mapping containing process statistics. 324 * 325 * @return a Map from Strings to Uid.Proc objects. 326 */ 327 public abstract ArrayMap<String, ? extends Proc> getProcessStats(); 328 329 /** 330 * Returns a mapping containing package statistics. 331 * 332 * @return a Map from Strings to Uid.Pkg objects. 333 */ 334 public abstract ArrayMap<String, ? extends Pkg> getPackageStats(); 335 336 /** 337 * {@hide} 338 */ 339 public abstract int getUid(); 340 341 public abstract void noteWifiRunningLocked(long elapsedRealtime); 342 public abstract void noteWifiStoppedLocked(long elapsedRealtime); 343 public abstract void noteFullWifiLockAcquiredLocked(long elapsedRealtime); 344 public abstract void noteFullWifiLockReleasedLocked(long elapsedRealtime); 345 public abstract void noteWifiScanStartedLocked(long elapsedRealtime); 346 public abstract void noteWifiScanStoppedLocked(long elapsedRealtime); 347 public abstract void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime); 348 public abstract void noteWifiBatchedScanStoppedLocked(long elapsedRealtime); 349 public abstract void noteWifiMulticastEnabledLocked(long elapsedRealtime); 350 public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime); 351 public abstract void noteActivityResumedLocked(long elapsedRealtime); 352 public abstract void noteActivityPausedLocked(long elapsedRealtime); 353 public abstract long getWifiRunningTime(long elapsedRealtimeUs, int which); 354 public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which); 355 public abstract long getWifiScanTime(long elapsedRealtimeUs, int which); 356 public abstract int getWifiScanCount(int which); 357 public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which); 358 public abstract int getWifiBatchedScanCount(int csphBin, int which); 359 public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which); 360 public abstract long getAudioTurnedOnTime(long elapsedRealtimeUs, int which); 361 public abstract long getVideoTurnedOnTime(long elapsedRealtimeUs, int which); 362 public abstract Timer getForegroundActivityTimer(); 363 364 // Time this uid has any processes in foreground state. 365 public static final int PROCESS_STATE_FOREGROUND = 0; 366 // Time this uid has any process in active state (not cached). 367 public static final int PROCESS_STATE_ACTIVE = 1; 368 // Time this uid has any processes running at all. 369 public static final int PROCESS_STATE_RUNNING = 2; 370 // Total number of process states we track. 371 public static final int NUM_PROCESS_STATE = 3; 372 373 static final String[] PROCESS_STATE_NAMES = { 374 "Foreground", "Active", "Running" 375 }; 376 377 public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which); 378 379 public abstract Timer getVibratorOnTimer(); 380 381 public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5; 382 383 /** 384 * Note that these must match the constants in android.os.PowerManager. 385 * Also, if the user activity types change, the BatteryStatsImpl.VERSION must 386 * also be bumped. 387 */ 388 static final String[] USER_ACTIVITY_TYPES = { 389 "other", "button", "touch" 390 }; 391 392 public static final int NUM_USER_ACTIVITY_TYPES = 3; 393 394 public abstract void noteUserActivityLocked(int type); 395 public abstract boolean hasUserActivity(); 396 public abstract int getUserActivityCount(int type, int which); 397 398 public abstract boolean hasNetworkActivity(); 399 public abstract long getNetworkActivityBytes(int type, int which); 400 public abstract long getNetworkActivityPackets(int type, int which); 401 public abstract long getMobileRadioActiveTime(int which); 402 public abstract int getMobileRadioActiveCount(int which); 403 404 public static abstract class Sensor { 405 /* 406 * FIXME: it's not correct to use this magic value because it 407 * could clash with a sensor handle (which are defined by 408 * the sensor HAL, and therefore out of our control 409 */ 410 // Magic sensor number for the GPS. 411 public static final int GPS = -10000; 412 413 public abstract int getHandle(); 414 415 public abstract Timer getSensorTime(); 416 } 417 418 public class Pid { 419 public int mWakeNesting; 420 public long mWakeSumMs; 421 public long mWakeStartMs; 422 } 423 424 /** 425 * The statistics associated with a particular process. 426 */ 427 public static abstract class Proc { 428 429 public static class ExcessivePower { 430 public static final int TYPE_WAKE = 1; 431 public static final int TYPE_CPU = 2; 432 433 public int type; 434 public long overTime; 435 public long usedTime; 436 } 437 438 /** 439 * Returns true if this process is still active in the battery stats. 440 */ 441 public abstract boolean isActive(); 442 443 /** 444 * Returns the total time (in milliseconds) spent executing in user code. 445 * 446 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 447 */ 448 public abstract long getUserTime(int which); 449 450 /** 451 * Returns the total time (in milliseconds) spent executing in system code. 452 * 453 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 454 */ 455 public abstract long getSystemTime(int which); 456 457 /** 458 * Returns the number of times the process has been started. 459 * 460 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 461 */ 462 public abstract int getStarts(int which); 463 464 /** 465 * Returns the number of times the process has crashed. 466 * 467 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 468 */ 469 public abstract int getNumCrashes(int which); 470 471 /** 472 * Returns the number of times the process has ANRed. 473 * 474 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 475 */ 476 public abstract int getNumAnrs(int which); 477 478 /** 479 * Returns the cpu time (milliseconds) spent while the process was in the foreground. 480 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 481 * @return foreground cpu time in microseconds 482 */ 483 public abstract long getForegroundTime(int which); 484 485 /** 486 * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed. 487 * @param speedStep the index of the CPU speed. This is not the actual speed of the 488 * CPU. 489 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 490 * @see BatteryStats#getCpuSpeedSteps() 491 */ 492 public abstract long getTimeAtCpuSpeedStep(int speedStep, int which); 493 494 public abstract int countExcessivePowers(); 495 496 public abstract ExcessivePower getExcessivePower(int i); 497 } 498 499 /** 500 * The statistics associated with a particular package. 501 */ 502 public static abstract class Pkg { 503 504 /** 505 * Returns information about all wakeup alarms that have been triggered for this 506 * package. The mapping keys are tag names for the alarms, the counter contains 507 * the number of times the alarm was triggered while on battery. 508 */ 509 public abstract ArrayMap<String, ? extends Counter> getWakeupAlarmStats(); 510 511 /** 512 * Returns a mapping containing service statistics. 513 */ 514 public abstract ArrayMap<String, ? extends Serv> getServiceStats(); 515 516 /** 517 * The statistics associated with a particular service. 518 */ 519 public abstract class Serv { 520 521 /** 522 * Returns the amount of time spent started. 523 * 524 * @param batteryUptime elapsed uptime on battery in microseconds. 525 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 526 * @return 527 */ 528 public abstract long getStartTime(long batteryUptime, int which); 529 530 /** 531 * Returns the total number of times startService() has been called. 532 * 533 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 534 */ 535 public abstract int getStarts(int which); 536 537 /** 538 * Returns the total number times the service has been launched. 539 * 540 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 541 */ 542 public abstract int getLaunches(int which); 543 } 544 } 545 } 546 547 public static final class LevelStepTracker { 548 public long mLastStepTime = -1; 549 public int mNumStepDurations; 550 public final long[] mStepDurations; 551 552 public LevelStepTracker(int maxLevelSteps) { 553 mStepDurations = new long[maxLevelSteps]; 554 } 555 556 public LevelStepTracker(int numSteps, long[] steps) { 557 mNumStepDurations = numSteps; 558 mStepDurations = new long[numSteps]; 559 System.arraycopy(steps, 0, mStepDurations, 0, numSteps); 560 } 561 562 public long getDurationAt(int index) { 563 return mStepDurations[index] & STEP_LEVEL_TIME_MASK; 564 } 565 566 public int getLevelAt(int index) { 567 return (int)((mStepDurations[index] & STEP_LEVEL_LEVEL_MASK) 568 >> STEP_LEVEL_LEVEL_SHIFT); 569 } 570 571 public int getInitModeAt(int index) { 572 return (int)((mStepDurations[index] & STEP_LEVEL_INITIAL_MODE_MASK) 573 >> STEP_LEVEL_INITIAL_MODE_SHIFT); 574 } 575 576 public int getModModeAt(int index) { 577 return (int)((mStepDurations[index] & STEP_LEVEL_MODIFIED_MODE_MASK) 578 >> STEP_LEVEL_MODIFIED_MODE_SHIFT); 579 } 580 581 private void appendHex(long val, int topOffset, StringBuilder out) { 582 boolean hasData = false; 583 while (topOffset >= 0) { 584 int digit = (int)( (val>>topOffset) & 0xf ); 585 topOffset -= 4; 586 if (!hasData && digit == 0) { 587 continue; 588 } 589 hasData = true; 590 if (digit >= 0 && digit <= 9) { 591 out.append((char)('0' + digit)); 592 } else { 593 out.append((char)('a' + digit - 10)); 594 } 595 } 596 } 597 598 public void encodeEntryAt(int index, StringBuilder out) { 599 long item = mStepDurations[index]; 600 long duration = item & STEP_LEVEL_TIME_MASK; 601 int level = (int)((item & STEP_LEVEL_LEVEL_MASK) 602 >> STEP_LEVEL_LEVEL_SHIFT); 603 int initMode = (int)((item & STEP_LEVEL_INITIAL_MODE_MASK) 604 >> STEP_LEVEL_INITIAL_MODE_SHIFT); 605 int modMode = (int)((item & STEP_LEVEL_MODIFIED_MODE_MASK) 606 >> STEP_LEVEL_MODIFIED_MODE_SHIFT); 607 switch ((initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) { 608 case Display.STATE_OFF: out.append('f'); break; 609 case Display.STATE_ON: out.append('o'); break; 610 case Display.STATE_DOZE: out.append('d'); break; 611 case Display.STATE_DOZE_SUSPEND: out.append('z'); break; 612 } 613 if ((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) { 614 out.append('p'); 615 } 616 if ((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) { 617 out.append('i'); 618 } 619 switch ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) { 620 case Display.STATE_OFF: out.append('F'); break; 621 case Display.STATE_ON: out.append('O'); break; 622 case Display.STATE_DOZE: out.append('D'); break; 623 case Display.STATE_DOZE_SUSPEND: out.append('Z'); break; 624 } 625 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) != 0) { 626 out.append('P'); 627 } 628 if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0) { 629 out.append('I'); 630 } 631 out.append('-'); 632 appendHex(level, 4, out); 633 out.append('-'); 634 appendHex(duration, STEP_LEVEL_LEVEL_SHIFT-4, out); 635 } 636 637 public void decodeEntryAt(int index, String value) { 638 final int N = value.length(); 639 int i = 0; 640 char c; 641 long out = 0; 642 while (i < N && (c=value.charAt(i)) != '-') { 643 i++; 644 switch (c) { 645 case 'f': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT); 646 break; 647 case 'o': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT); 648 break; 649 case 'd': out |= (((long)Display.STATE_DOZE-1)<<STEP_LEVEL_INITIAL_MODE_SHIFT); 650 break; 651 case 'z': out |= (((long)Display.STATE_DOZE_SUSPEND-1) 652 << STEP_LEVEL_INITIAL_MODE_SHIFT); 653 break; 654 case 'p': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE) 655 << STEP_LEVEL_INITIAL_MODE_SHIFT); 656 break; 657 case 'i': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE) 658 << STEP_LEVEL_INITIAL_MODE_SHIFT); 659 break; 660 case 'F': out |= (((long)Display.STATE_OFF-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT); 661 break; 662 case 'O': out |= (((long)Display.STATE_ON-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT); 663 break; 664 case 'D': out |= (((long)Display.STATE_DOZE-1)<<STEP_LEVEL_MODIFIED_MODE_SHIFT); 665 break; 666 case 'Z': out |= (((long)Display.STATE_DOZE_SUSPEND-1) 667 << STEP_LEVEL_MODIFIED_MODE_SHIFT); 668 break; 669 case 'P': out |= (((long)STEP_LEVEL_MODE_POWER_SAVE) 670 << STEP_LEVEL_MODIFIED_MODE_SHIFT); 671 break; 672 case 'I': out |= (((long)STEP_LEVEL_MODE_DEVICE_IDLE) 673 << STEP_LEVEL_MODIFIED_MODE_SHIFT); 674 break; 675 } 676 } 677 i++; 678 long level = 0; 679 while (i < N && (c=value.charAt(i)) != '-') { 680 i++; 681 level <<= 4; 682 if (c >= '0' && c <= '9') { 683 level += c - '0'; 684 } else if (c >= 'a' && c <= 'f') { 685 level += c - 'a' + 10; 686 } else if (c >= 'A' && c <= 'F') { 687 level += c - 'A' + 10; 688 } 689 } 690 i++; 691 out |= (level << STEP_LEVEL_LEVEL_SHIFT) & STEP_LEVEL_LEVEL_MASK; 692 long duration = 0; 693 while (i < N && (c=value.charAt(i)) != '-') { 694 i++; 695 duration <<= 4; 696 if (c >= '0' && c <= '9') { 697 duration += c - '0'; 698 } else if (c >= 'a' && c <= 'f') { 699 duration += c - 'a' + 10; 700 } else if (c >= 'A' && c <= 'F') { 701 duration += c - 'A' + 10; 702 } 703 } 704 mStepDurations[index] = out | (duration & STEP_LEVEL_TIME_MASK); 705 } 706 707 public void init() { 708 mLastStepTime = -1; 709 mNumStepDurations = 0; 710 } 711 712 public void clearTime() { 713 mLastStepTime = -1; 714 } 715 716 public long computeTimePerLevel() { 717 final long[] steps = mStepDurations; 718 final int numSteps = mNumStepDurations; 719 720 // For now we'll do a simple average across all steps. 721 if (numSteps <= 0) { 722 return -1; 723 } 724 long total = 0; 725 for (int i=0; i<numSteps; i++) { 726 total += steps[i] & STEP_LEVEL_TIME_MASK; 727 } 728 return total / numSteps; 729 /* 730 long[] buckets = new long[numSteps]; 731 int numBuckets = 0; 732 int numToAverage = 4; 733 int i = 0; 734 while (i < numSteps) { 735 long totalTime = 0; 736 int num = 0; 737 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 738 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 739 num++; 740 } 741 buckets[numBuckets] = totalTime / num; 742 numBuckets++; 743 numToAverage *= 2; 744 i += num; 745 } 746 if (numBuckets < 1) { 747 return -1; 748 } 749 long averageTime = buckets[numBuckets-1]; 750 for (i=numBuckets-2; i>=0; i--) { 751 averageTime = (averageTime + buckets[i]) / 2; 752 } 753 return averageTime; 754 */ 755 } 756 757 public long computeTimeEstimate(long modesOfInterest, long modeValues, 758 int[] outNumOfInterest) { 759 final long[] steps = mStepDurations; 760 final int count = mNumStepDurations; 761 if (count <= 0) { 762 return -1; 763 } 764 long total = 0; 765 int numOfInterest = 0; 766 for (int i=0; i<count; i++) { 767 long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK) 768 >> STEP_LEVEL_INITIAL_MODE_SHIFT; 769 long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK) 770 >> STEP_LEVEL_MODIFIED_MODE_SHIFT; 771 // If the modes of interest didn't change during this step period... 772 if ((modMode&modesOfInterest) == 0) { 773 // And the mode values during this period match those we are measuring... 774 if ((initMode&modesOfInterest) == modeValues) { 775 // Then this can be used to estimate the total time! 776 numOfInterest++; 777 total += steps[i] & STEP_LEVEL_TIME_MASK; 778 } 779 } 780 } 781 if (numOfInterest <= 0) { 782 return -1; 783 } 784 785 if (outNumOfInterest != null) { 786 outNumOfInterest[0] = numOfInterest; 787 } 788 789 // The estimated time is the average time we spend in each level, multipled 790 // by 100 -- the total number of battery levels 791 return (total / numOfInterest) * 100; 792 } 793 794 public void addLevelSteps(int numStepLevels, long modeBits, long elapsedRealtime) { 795 int stepCount = mNumStepDurations; 796 final long lastStepTime = mLastStepTime; 797 if (lastStepTime >= 0 && numStepLevels > 0) { 798 final long[] steps = mStepDurations; 799 long duration = elapsedRealtime - lastStepTime; 800 for (int i=0; i<numStepLevels; i++) { 801 System.arraycopy(steps, 0, steps, 1, steps.length-1); 802 long thisDuration = duration / (numStepLevels-i); 803 duration -= thisDuration; 804 if (thisDuration > STEP_LEVEL_TIME_MASK) { 805 thisDuration = STEP_LEVEL_TIME_MASK; 806 } 807 steps[0] = thisDuration | modeBits; 808 } 809 stepCount += numStepLevels; 810 if (stepCount > steps.length) { 811 stepCount = steps.length; 812 } 813 } 814 mNumStepDurations = stepCount; 815 mLastStepTime = elapsedRealtime; 816 } 817 818 public void readFromParcel(Parcel in) { 819 final int N = in.readInt(); 820 mNumStepDurations = N; 821 for (int i=0; i<N; i++) { 822 mStepDurations[i] = in.readLong(); 823 } 824 } 825 826 public void writeToParcel(Parcel out) { 827 final int N = mNumStepDurations; 828 out.writeInt(N); 829 for (int i=0; i<N; i++) { 830 out.writeLong(mStepDurations[i]); 831 } 832 } 833 } 834 835 public static final class PackageChange { 836 public String mPackageName; 837 public boolean mUpdate; 838 public int mVersionCode; 839 } 840 841 public static final class DailyItem { 842 public long mStartTime; 843 public long mEndTime; 844 public LevelStepTracker mDischargeSteps; 845 public LevelStepTracker mChargeSteps; 846 public ArrayList<PackageChange> mPackageChanges; 847 } 848 849 public abstract DailyItem getDailyItemLocked(int daysAgo); 850 851 public abstract long getCurrentDailyStartTime(); 852 853 public abstract long getNextMinDailyDeadline(); 854 855 public abstract long getNextMaxDailyDeadline(); 856 857 public final static class HistoryTag { 858 public String string; 859 public int uid; 860 861 public int poolIdx; 862 863 public void setTo(HistoryTag o) { 864 string = o.string; 865 uid = o.uid; 866 poolIdx = o.poolIdx; 867 } 868 869 public void setTo(String _string, int _uid) { 870 string = _string; 871 uid = _uid; 872 poolIdx = -1; 873 } 874 875 public void writeToParcel(Parcel dest, int flags) { 876 dest.writeString(string); 877 dest.writeInt(uid); 878 } 879 880 public void readFromParcel(Parcel src) { 881 string = src.readString(); 882 uid = src.readInt(); 883 poolIdx = -1; 884 } 885 886 @Override 887 public boolean equals(Object o) { 888 if (this == o) return true; 889 if (o == null || getClass() != o.getClass()) return false; 890 891 HistoryTag that = (HistoryTag) o; 892 893 if (uid != that.uid) return false; 894 if (!string.equals(that.string)) return false; 895 896 return true; 897 } 898 899 @Override 900 public int hashCode() { 901 int result = string.hashCode(); 902 result = 31 * result + uid; 903 return result; 904 } 905 } 906 907 /** 908 * Optional detailed information that can go into a history step. This is typically 909 * generated each time the battery level changes. 910 */ 911 public final static class HistoryStepDetails { 912 // Time (in 1/100 second) spent in user space and the kernel since the last step. 913 public int userTime; 914 public int systemTime; 915 916 // Top three apps using CPU in the last step, with times in 1/100 second. 917 public int appCpuUid1; 918 public int appCpuUTime1; 919 public int appCpuSTime1; 920 public int appCpuUid2; 921 public int appCpuUTime2; 922 public int appCpuSTime2; 923 public int appCpuUid3; 924 public int appCpuUTime3; 925 public int appCpuSTime3; 926 927 // Information from /proc/stat 928 public int statUserTime; 929 public int statSystemTime; 930 public int statIOWaitTime; 931 public int statIrqTime; 932 public int statSoftIrqTime; 933 public int statIdlTime; 934 935 public HistoryStepDetails() { 936 clear(); 937 } 938 939 public void clear() { 940 userTime = systemTime = 0; 941 appCpuUid1 = appCpuUid2 = appCpuUid3 = -1; 942 appCpuUTime1 = appCpuSTime1 = appCpuUTime2 = appCpuSTime2 943 = appCpuUTime3 = appCpuSTime3 = 0; 944 } 945 946 public void writeToParcel(Parcel out) { 947 out.writeInt(userTime); 948 out.writeInt(systemTime); 949 out.writeInt(appCpuUid1); 950 out.writeInt(appCpuUTime1); 951 out.writeInt(appCpuSTime1); 952 out.writeInt(appCpuUid2); 953 out.writeInt(appCpuUTime2); 954 out.writeInt(appCpuSTime2); 955 out.writeInt(appCpuUid3); 956 out.writeInt(appCpuUTime3); 957 out.writeInt(appCpuSTime3); 958 out.writeInt(statUserTime); 959 out.writeInt(statSystemTime); 960 out.writeInt(statIOWaitTime); 961 out.writeInt(statIrqTime); 962 out.writeInt(statSoftIrqTime); 963 out.writeInt(statIdlTime); 964 } 965 966 public void readFromParcel(Parcel in) { 967 userTime = in.readInt(); 968 systemTime = in.readInt(); 969 appCpuUid1 = in.readInt(); 970 appCpuUTime1 = in.readInt(); 971 appCpuSTime1 = in.readInt(); 972 appCpuUid2 = in.readInt(); 973 appCpuUTime2 = in.readInt(); 974 appCpuSTime2 = in.readInt(); 975 appCpuUid3 = in.readInt(); 976 appCpuUTime3 = in.readInt(); 977 appCpuSTime3 = in.readInt(); 978 statUserTime = in.readInt(); 979 statSystemTime = in.readInt(); 980 statIOWaitTime = in.readInt(); 981 statIrqTime = in.readInt(); 982 statSoftIrqTime = in.readInt(); 983 statIdlTime = in.readInt(); 984 } 985 } 986 987 public final static class HistoryItem implements Parcelable { 988 public HistoryItem next; 989 990 // The time of this event in milliseconds, as per SystemClock.elapsedRealtime(). 991 public long time; 992 993 public static final byte CMD_UPDATE = 0; // These can be written as deltas 994 public static final byte CMD_NULL = -1; 995 public static final byte CMD_START = 4; 996 public static final byte CMD_CURRENT_TIME = 5; 997 public static final byte CMD_OVERFLOW = 6; 998 public static final byte CMD_RESET = 7; 999 public static final byte CMD_SHUTDOWN = 8; 1000 1001 public byte cmd = CMD_NULL; 1002 1003 /** 1004 * Return whether the command code is a delta data update. 1005 */ 1006 public boolean isDeltaData() { 1007 return cmd == CMD_UPDATE; 1008 } 1009 1010 public byte batteryLevel; 1011 public byte batteryStatus; 1012 public byte batteryHealth; 1013 public byte batteryPlugType; 1014 1015 public short batteryTemperature; 1016 public char batteryVoltage; 1017 1018 // Constants from SCREEN_BRIGHTNESS_* 1019 public static final int STATE_BRIGHTNESS_SHIFT = 0; 1020 public static final int STATE_BRIGHTNESS_MASK = 0x7; 1021 // Constants from SIGNAL_STRENGTH_* 1022 public static final int STATE_PHONE_SIGNAL_STRENGTH_SHIFT = 3; 1023 public static final int STATE_PHONE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_PHONE_SIGNAL_STRENGTH_SHIFT; 1024 // Constants from ServiceState.STATE_* 1025 public static final int STATE_PHONE_STATE_SHIFT = 6; 1026 public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT; 1027 // Constants from DATA_CONNECTION_* 1028 public static final int STATE_DATA_CONNECTION_SHIFT = 9; 1029 public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT; 1030 1031 // These states always appear directly in the first int token 1032 // of a delta change; they should be ones that change relatively 1033 // frequently. 1034 public static final int STATE_CPU_RUNNING_FLAG = 1<<31; 1035 public static final int STATE_WAKE_LOCK_FLAG = 1<<30; 1036 public static final int STATE_GPS_ON_FLAG = 1<<29; 1037 public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28; 1038 public static final int STATE_WIFI_SCAN_FLAG = 1<<27; 1039 public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<26; 1040 public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25; 1041 // These are on the lower bits used for the command; if they change 1042 // we need to write another int of data. 1043 public static final int STATE_SENSOR_ON_FLAG = 1<<23; 1044 public static final int STATE_AUDIO_ON_FLAG = 1<<22; 1045 public static final int STATE_PHONE_SCANNING_FLAG = 1<<21; 1046 public static final int STATE_SCREEN_ON_FLAG = 1<<20; 1047 public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; 1048 public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18; 1049 public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16; 1050 1051 public static final int MOST_INTERESTING_STATES = 1052 STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG 1053 | STATE_PHONE_IN_CALL_FLAG | STATE_BLUETOOTH_ON_FLAG; 1054 1055 public int states; 1056 1057 // Constants from WIFI_SUPPL_STATE_* 1058 public static final int STATE2_WIFI_SUPPL_STATE_SHIFT = 0; 1059 public static final int STATE2_WIFI_SUPPL_STATE_MASK = 0xf; 1060 // Values for NUM_WIFI_SIGNAL_STRENGTH_BINS 1061 public static final int STATE2_WIFI_SIGNAL_STRENGTH_SHIFT = 4; 1062 public static final int STATE2_WIFI_SIGNAL_STRENGTH_MASK = 1063 0x7 << STATE2_WIFI_SIGNAL_STRENGTH_SHIFT; 1064 1065 public static final int STATE2_POWER_SAVE_FLAG = 1<<31; 1066 public static final int STATE2_VIDEO_ON_FLAG = 1<<30; 1067 public static final int STATE2_WIFI_RUNNING_FLAG = 1<<29; 1068 public static final int STATE2_WIFI_ON_FLAG = 1<<28; 1069 public static final int STATE2_FLASHLIGHT_FLAG = 1<<27; 1070 public static final int STATE2_DEVICE_IDLE_FLAG = 1<<26; 1071 1072 public static final int MOST_INTERESTING_STATES2 = 1073 STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_FLAG; 1074 1075 public int states2; 1076 1077 // The wake lock that was acquired at this point. 1078 public HistoryTag wakelockTag; 1079 1080 // Kernel wakeup reason at this point. 1081 public HistoryTag wakeReasonTag; 1082 1083 // Non-null when there is more detailed information at this step. 1084 public HistoryStepDetails stepDetails; 1085 1086 public static final int EVENT_FLAG_START = 0x8000; 1087 public static final int EVENT_FLAG_FINISH = 0x4000; 1088 1089 // No event in this item. 1090 public static final int EVENT_NONE = 0x0000; 1091 // Event is about a process that is running. 1092 public static final int EVENT_PROC = 0x0001; 1093 // Event is about an application package that is in the foreground. 1094 public static final int EVENT_FOREGROUND = 0x0002; 1095 // Event is about an application package that is at the top of the screen. 1096 public static final int EVENT_TOP = 0x0003; 1097 // Event is about active sync operations. 1098 public static final int EVENT_SYNC = 0x0004; 1099 // Events for all additional wake locks aquired/release within a wake block. 1100 // These are not generated by default. 1101 public static final int EVENT_WAKE_LOCK = 0x0005; 1102 // Event is about an application executing a scheduled job. 1103 public static final int EVENT_JOB = 0x0006; 1104 // Events for users running. 1105 public static final int EVENT_USER_RUNNING = 0x0007; 1106 // Events for foreground user. 1107 public static final int EVENT_USER_FOREGROUND = 0x0008; 1108 // Event for connectivity changed. 1109 public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009; 1110 // Event for significant motion taking us out of idle mode. 1111 public static final int EVENT_SIGNIFICANT_MOTION = 0x000a; 1112 // Event for becoming active taking us out of idle mode. 1113 public static final int EVENT_ACTIVE = 0x000b; 1114 // Event for a package being installed. 1115 public static final int EVENT_PACKAGE_INSTALLED = 0x000c; 1116 // Event for a package being uninstalled. 1117 public static final int EVENT_PACKAGE_UNINSTALLED = 0x000d; 1118 // Number of event types. 1119 public static final int EVENT_COUNT = 0x000e; 1120 // Mask to extract out only the type part of the event. 1121 public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH); 1122 1123 public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START; 1124 public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH; 1125 public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START; 1126 public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH; 1127 public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START; 1128 public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH; 1129 public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START; 1130 public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH; 1131 public static final int EVENT_WAKE_LOCK_START = EVENT_WAKE_LOCK | EVENT_FLAG_START; 1132 public static final int EVENT_WAKE_LOCK_FINISH = EVENT_WAKE_LOCK | EVENT_FLAG_FINISH; 1133 public static final int EVENT_JOB_START = EVENT_JOB | EVENT_FLAG_START; 1134 public static final int EVENT_JOB_FINISH = EVENT_JOB | EVENT_FLAG_FINISH; 1135 public static final int EVENT_USER_RUNNING_START = EVENT_USER_RUNNING | EVENT_FLAG_START; 1136 public static final int EVENT_USER_RUNNING_FINISH = EVENT_USER_RUNNING | EVENT_FLAG_FINISH; 1137 public static final int EVENT_USER_FOREGROUND_START = 1138 EVENT_USER_FOREGROUND | EVENT_FLAG_START; 1139 public static final int EVENT_USER_FOREGROUND_FINISH = 1140 EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH; 1141 1142 // For CMD_EVENT. 1143 public int eventCode; 1144 public HistoryTag eventTag; 1145 1146 // Only set for CMD_CURRENT_TIME or CMD_RESET, as per System.currentTimeMillis(). 1147 public long currentTime; 1148 1149 // Meta-data when reading. 1150 public int numReadInts; 1151 1152 // Pre-allocated objects. 1153 public final HistoryTag localWakelockTag = new HistoryTag(); 1154 public final HistoryTag localWakeReasonTag = new HistoryTag(); 1155 public final HistoryTag localEventTag = new HistoryTag(); 1156 1157 public HistoryItem() { 1158 } 1159 1160 public HistoryItem(long time, Parcel src) { 1161 this.time = time; 1162 numReadInts = 2; 1163 readFromParcel(src); 1164 } 1165 1166 public int describeContents() { 1167 return 0; 1168 } 1169 1170 public void writeToParcel(Parcel dest, int flags) { 1171 dest.writeLong(time); 1172 int bat = (((int)cmd)&0xff) 1173 | ((((int)batteryLevel)<<8)&0xff00) 1174 | ((((int)batteryStatus)<<16)&0xf0000) 1175 | ((((int)batteryHealth)<<20)&0xf00000) 1176 | ((((int)batteryPlugType)<<24)&0xf000000) 1177 | (wakelockTag != null ? 0x10000000 : 0) 1178 | (wakeReasonTag != null ? 0x20000000 : 0) 1179 | (eventCode != EVENT_NONE ? 0x40000000 : 0); 1180 dest.writeInt(bat); 1181 bat = (((int)batteryTemperature)&0xffff) 1182 | ((((int)batteryVoltage)<<16)&0xffff0000); 1183 dest.writeInt(bat); 1184 dest.writeInt(states); 1185 dest.writeInt(states2); 1186 if (wakelockTag != null) { 1187 wakelockTag.writeToParcel(dest, flags); 1188 } 1189 if (wakeReasonTag != null) { 1190 wakeReasonTag.writeToParcel(dest, flags); 1191 } 1192 if (eventCode != EVENT_NONE) { 1193 dest.writeInt(eventCode); 1194 eventTag.writeToParcel(dest, flags); 1195 } 1196 if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) { 1197 dest.writeLong(currentTime); 1198 } 1199 } 1200 1201 public void readFromParcel(Parcel src) { 1202 int start = src.dataPosition(); 1203 int bat = src.readInt(); 1204 cmd = (byte)(bat&0xff); 1205 batteryLevel = (byte)((bat>>8)&0xff); 1206 batteryStatus = (byte)((bat>>16)&0xf); 1207 batteryHealth = (byte)((bat>>20)&0xf); 1208 batteryPlugType = (byte)((bat>>24)&0xf); 1209 int bat2 = src.readInt(); 1210 batteryTemperature = (short)(bat2&0xffff); 1211 batteryVoltage = (char)((bat2>>16)&0xffff); 1212 states = src.readInt(); 1213 states2 = src.readInt(); 1214 if ((bat&0x10000000) != 0) { 1215 wakelockTag = localWakelockTag; 1216 wakelockTag.readFromParcel(src); 1217 } else { 1218 wakelockTag = null; 1219 } 1220 if ((bat&0x20000000) != 0) { 1221 wakeReasonTag = localWakeReasonTag; 1222 wakeReasonTag.readFromParcel(src); 1223 } else { 1224 wakeReasonTag = null; 1225 } 1226 if ((bat&0x40000000) != 0) { 1227 eventCode = src.readInt(); 1228 eventTag = localEventTag; 1229 eventTag.readFromParcel(src); 1230 } else { 1231 eventCode = EVENT_NONE; 1232 eventTag = null; 1233 } 1234 if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) { 1235 currentTime = src.readLong(); 1236 } else { 1237 currentTime = 0; 1238 } 1239 numReadInts += (src.dataPosition()-start)/4; 1240 } 1241 1242 public void clear() { 1243 time = 0; 1244 cmd = CMD_NULL; 1245 batteryLevel = 0; 1246 batteryStatus = 0; 1247 batteryHealth = 0; 1248 batteryPlugType = 0; 1249 batteryTemperature = 0; 1250 batteryVoltage = 0; 1251 states = 0; 1252 states2 = 0; 1253 wakelockTag = null; 1254 wakeReasonTag = null; 1255 eventCode = EVENT_NONE; 1256 eventTag = null; 1257 } 1258 1259 public void setTo(HistoryItem o) { 1260 time = o.time; 1261 cmd = o.cmd; 1262 setToCommon(o); 1263 } 1264 1265 public void setTo(long time, byte cmd, HistoryItem o) { 1266 this.time = time; 1267 this.cmd = cmd; 1268 setToCommon(o); 1269 } 1270 1271 private void setToCommon(HistoryItem o) { 1272 batteryLevel = o.batteryLevel; 1273 batteryStatus = o.batteryStatus; 1274 batteryHealth = o.batteryHealth; 1275 batteryPlugType = o.batteryPlugType; 1276 batteryTemperature = o.batteryTemperature; 1277 batteryVoltage = o.batteryVoltage; 1278 states = o.states; 1279 states2 = o.states2; 1280 if (o.wakelockTag != null) { 1281 wakelockTag = localWakelockTag; 1282 wakelockTag.setTo(o.wakelockTag); 1283 } else { 1284 wakelockTag = null; 1285 } 1286 if (o.wakeReasonTag != null) { 1287 wakeReasonTag = localWakeReasonTag; 1288 wakeReasonTag.setTo(o.wakeReasonTag); 1289 } else { 1290 wakeReasonTag = null; 1291 } 1292 eventCode = o.eventCode; 1293 if (o.eventTag != null) { 1294 eventTag = localEventTag; 1295 eventTag.setTo(o.eventTag); 1296 } else { 1297 eventTag = null; 1298 } 1299 currentTime = o.currentTime; 1300 } 1301 1302 public boolean sameNonEvent(HistoryItem o) { 1303 return batteryLevel == o.batteryLevel 1304 && batteryStatus == o.batteryStatus 1305 && batteryHealth == o.batteryHealth 1306 && batteryPlugType == o.batteryPlugType 1307 && batteryTemperature == o.batteryTemperature 1308 && batteryVoltage == o.batteryVoltage 1309 && states == o.states 1310 && states2 == o.states2 1311 && currentTime == o.currentTime; 1312 } 1313 1314 public boolean same(HistoryItem o) { 1315 if (!sameNonEvent(o) || eventCode != o.eventCode) { 1316 return false; 1317 } 1318 if (wakelockTag != o.wakelockTag) { 1319 if (wakelockTag == null || o.wakelockTag == null) { 1320 return false; 1321 } 1322 if (!wakelockTag.equals(o.wakelockTag)) { 1323 return false; 1324 } 1325 } 1326 if (wakeReasonTag != o.wakeReasonTag) { 1327 if (wakeReasonTag == null || o.wakeReasonTag == null) { 1328 return false; 1329 } 1330 if (!wakeReasonTag.equals(o.wakeReasonTag)) { 1331 return false; 1332 } 1333 } 1334 if (eventTag != o.eventTag) { 1335 if (eventTag == null || o.eventTag == null) { 1336 return false; 1337 } 1338 if (!eventTag.equals(o.eventTag)) { 1339 return false; 1340 } 1341 } 1342 return true; 1343 } 1344 } 1345 1346 public final static class HistoryEventTracker { 1347 private final HashMap<String, SparseIntArray>[] mActiveEvents 1348 = (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT]; 1349 1350 public boolean updateState(int code, String name, int uid, int poolIdx) { 1351 if ((code&HistoryItem.EVENT_FLAG_START) != 0) { 1352 int idx = code&HistoryItem.EVENT_TYPE_MASK; 1353 HashMap<String, SparseIntArray> active = mActiveEvents[idx]; 1354 if (active == null) { 1355 active = new HashMap<>(); 1356 mActiveEvents[idx] = active; 1357 } 1358 SparseIntArray uids = active.get(name); 1359 if (uids == null) { 1360 uids = new SparseIntArray(); 1361 active.put(name, uids); 1362 } 1363 if (uids.indexOfKey(uid) >= 0) { 1364 // Already set, nothing to do! 1365 return false; 1366 } 1367 uids.put(uid, poolIdx); 1368 } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) { 1369 int idx = code&HistoryItem.EVENT_TYPE_MASK; 1370 HashMap<String, SparseIntArray> active = mActiveEvents[idx]; 1371 if (active == null) { 1372 // not currently active, nothing to do. 1373 return false; 1374 } 1375 SparseIntArray uids = active.get(name); 1376 if (uids == null) { 1377 // not currently active, nothing to do. 1378 return false; 1379 } 1380 idx = uids.indexOfKey(uid); 1381 if (idx < 0) { 1382 // not currently active, nothing to do. 1383 return false; 1384 } 1385 uids.removeAt(idx); 1386 if (uids.size() <= 0) { 1387 active.remove(name); 1388 } 1389 } 1390 return true; 1391 } 1392 1393 public void removeEvents(int code) { 1394 int idx = code&HistoryItem.EVENT_TYPE_MASK; 1395 mActiveEvents[idx] = null; 1396 } 1397 1398 public HashMap<String, SparseIntArray> getStateForEvent(int code) { 1399 return mActiveEvents[code]; 1400 } 1401 } 1402 1403 public static final class BitDescription { 1404 public final int mask; 1405 public final int shift; 1406 public final String name; 1407 public final String shortName; 1408 public final String[] values; 1409 public final String[] shortValues; 1410 1411 public BitDescription(int mask, String name, String shortName) { 1412 this.mask = mask; 1413 this.shift = -1; 1414 this.name = name; 1415 this.shortName = shortName; 1416 this.values = null; 1417 this.shortValues = null; 1418 } 1419 1420 public BitDescription(int mask, int shift, String name, String shortName, 1421 String[] values, String[] shortValues) { 1422 this.mask = mask; 1423 this.shift = shift; 1424 this.name = name; 1425 this.shortName = shortName; 1426 this.values = values; 1427 this.shortValues = shortValues; 1428 } 1429 } 1430 1431 /** 1432 * Don't allow any more batching in to the current history event. This 1433 * is called when printing partial histories, so to ensure that the next 1434 * history event will go in to a new batch after what was printed in the 1435 * last partial history. 1436 */ 1437 public abstract void commitCurrentHistoryBatchLocked(); 1438 1439 public abstract int getHistoryTotalSize(); 1440 1441 public abstract int getHistoryUsedSize(); 1442 1443 public abstract boolean startIteratingHistoryLocked(); 1444 1445 public abstract int getHistoryStringPoolSize(); 1446 1447 public abstract int getHistoryStringPoolBytes(); 1448 1449 public abstract String getHistoryTagPoolString(int index); 1450 1451 public abstract int getHistoryTagPoolUid(int index); 1452 1453 public abstract boolean getNextHistoryLocked(HistoryItem out); 1454 1455 public abstract void finishIteratingHistoryLocked(); 1456 1457 public abstract boolean startIteratingOldHistoryLocked(); 1458 1459 public abstract boolean getNextOldHistoryLocked(HistoryItem out); 1460 1461 public abstract void finishIteratingOldHistoryLocked(); 1462 1463 /** 1464 * Return the base time offset for the battery history. 1465 */ 1466 public abstract long getHistoryBaseTime(); 1467 1468 /** 1469 * Returns the number of times the device has been started. 1470 */ 1471 public abstract int getStartCount(); 1472 1473 /** 1474 * Returns the time in microseconds that the screen has been on while the device was 1475 * running on battery. 1476 * 1477 * {@hide} 1478 */ 1479 public abstract long getScreenOnTime(long elapsedRealtimeUs, int which); 1480 1481 /** 1482 * Returns the number of times the screen was turned on. 1483 * 1484 * {@hide} 1485 */ 1486 public abstract int getScreenOnCount(int which); 1487 1488 public abstract long getInteractiveTime(long elapsedRealtimeUs, int which); 1489 1490 public static final int SCREEN_BRIGHTNESS_DARK = 0; 1491 public static final int SCREEN_BRIGHTNESS_DIM = 1; 1492 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2; 1493 public static final int SCREEN_BRIGHTNESS_LIGHT = 3; 1494 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4; 1495 1496 static final String[] SCREEN_BRIGHTNESS_NAMES = { 1497 "dark", "dim", "medium", "light", "bright" 1498 }; 1499 1500 static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = { 1501 "0", "1", "2", "3", "4" 1502 }; 1503 1504 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5; 1505 1506 /** 1507 * Returns the time in microseconds that the screen has been on with 1508 * the given brightness 1509 * 1510 * {@hide} 1511 */ 1512 public abstract long getScreenBrightnessTime(int brightnessBin, 1513 long elapsedRealtimeUs, int which); 1514 1515 /** 1516 * Returns the time in microseconds that power save mode has been enabled while the device was 1517 * running on battery. 1518 * 1519 * {@hide} 1520 */ 1521 public abstract long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which); 1522 1523 /** 1524 * Returns the number of times that power save mode was enabled. 1525 * 1526 * {@hide} 1527 */ 1528 public abstract int getPowerSaveModeEnabledCount(int which); 1529 1530 /** 1531 * Returns the time in microseconds that device has been in idle mode while 1532 * running on battery. 1533 * 1534 * {@hide} 1535 */ 1536 public abstract long getDeviceIdleModeEnabledTime(long elapsedRealtimeUs, int which); 1537 1538 /** 1539 * Returns the number of times that the devie has gone in to idle mode. 1540 * 1541 * {@hide} 1542 */ 1543 public abstract int getDeviceIdleModeEnabledCount(int which); 1544 1545 /** 1546 * Returns the time in microseconds that device has been in idling while on 1547 * battery. This is broader than {@link #getDeviceIdleModeEnabledTime} -- it 1548 * counts all of the time that we consider the device to be idle, whether or not 1549 * it is currently in the actual device idle mode. 1550 * 1551 * {@hide} 1552 */ 1553 public abstract long getDeviceIdlingTime(long elapsedRealtimeUs, int which); 1554 1555 /** 1556 * Returns the number of times that the devie has started idling. 1557 * 1558 * {@hide} 1559 */ 1560 public abstract int getDeviceIdlingCount(int which); 1561 1562 /** 1563 * Returns the number of times that connectivity state changed. 1564 * 1565 * {@hide} 1566 */ 1567 public abstract int getNumConnectivityChange(int which); 1568 1569 /** 1570 * Returns the time in microseconds that the phone has been on while the device was 1571 * running on battery. 1572 * 1573 * {@hide} 1574 */ 1575 public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which); 1576 1577 /** 1578 * Returns the number of times a phone call was activated. 1579 * 1580 * {@hide} 1581 */ 1582 public abstract int getPhoneOnCount(int which); 1583 1584 /** 1585 * Returns the time in microseconds that the phone has been running with 1586 * the given signal strength. 1587 * 1588 * {@hide} 1589 */ 1590 public abstract long getPhoneSignalStrengthTime(int strengthBin, 1591 long elapsedRealtimeUs, int which); 1592 1593 /** 1594 * Returns the time in microseconds that the phone has been trying to 1595 * acquire a signal. 1596 * 1597 * {@hide} 1598 */ 1599 public abstract long getPhoneSignalScanningTime( 1600 long elapsedRealtimeUs, int which); 1601 1602 /** 1603 * Returns the number of times the phone has entered the given signal strength. 1604 * 1605 * {@hide} 1606 */ 1607 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which); 1608 1609 /** 1610 * Returns the time in microseconds that the mobile network has been active 1611 * (in a high power state). 1612 * 1613 * {@hide} 1614 */ 1615 public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which); 1616 1617 /** 1618 * Returns the number of times that the mobile network has transitioned to the 1619 * active state. 1620 * 1621 * {@hide} 1622 */ 1623 public abstract int getMobileRadioActiveCount(int which); 1624 1625 /** 1626 * Returns the time in microseconds that is the difference between the mobile radio 1627 * time we saw based on the elapsed timestamp when going down vs. the given time stamp 1628 * from the radio. 1629 * 1630 * {@hide} 1631 */ 1632 public abstract long getMobileRadioActiveAdjustedTime(int which); 1633 1634 /** 1635 * Returns the time in microseconds that the mobile network has been active 1636 * (in a high power state) but not being able to blame on an app. 1637 * 1638 * {@hide} 1639 */ 1640 public abstract long getMobileRadioActiveUnknownTime(int which); 1641 1642 /** 1643 * Return count of number of times radio was up that could not be blamed on apps. 1644 * 1645 * {@hide} 1646 */ 1647 public abstract int getMobileRadioActiveUnknownCount(int which); 1648 1649 public static final int DATA_CONNECTION_NONE = 0; 1650 public static final int DATA_CONNECTION_GPRS = 1; 1651 public static final int DATA_CONNECTION_EDGE = 2; 1652 public static final int DATA_CONNECTION_UMTS = 3; 1653 public static final int DATA_CONNECTION_CDMA = 4; 1654 public static final int DATA_CONNECTION_EVDO_0 = 5; 1655 public static final int DATA_CONNECTION_EVDO_A = 6; 1656 public static final int DATA_CONNECTION_1xRTT = 7; 1657 public static final int DATA_CONNECTION_HSDPA = 8; 1658 public static final int DATA_CONNECTION_HSUPA = 9; 1659 public static final int DATA_CONNECTION_HSPA = 10; 1660 public static final int DATA_CONNECTION_IDEN = 11; 1661 public static final int DATA_CONNECTION_EVDO_B = 12; 1662 public static final int DATA_CONNECTION_LTE = 13; 1663 public static final int DATA_CONNECTION_EHRPD = 14; 1664 public static final int DATA_CONNECTION_HSPAP = 15; 1665 public static final int DATA_CONNECTION_OTHER = 16; 1666 1667 static final String[] DATA_CONNECTION_NAMES = { 1668 "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A", 1669 "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte", 1670 "ehrpd", "hspap", "other" 1671 }; 1672 1673 public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1; 1674 1675 /** 1676 * Returns the time in microseconds that the phone has been running with 1677 * the given data connection. 1678 * 1679 * {@hide} 1680 */ 1681 public abstract long getPhoneDataConnectionTime(int dataType, 1682 long elapsedRealtimeUs, int which); 1683 1684 /** 1685 * Returns the number of times the phone has entered the given data 1686 * connection type. 1687 * 1688 * {@hide} 1689 */ 1690 public abstract int getPhoneDataConnectionCount(int dataType, int which); 1691 1692 public static final int WIFI_SUPPL_STATE_INVALID = 0; 1693 public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1; 1694 public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2; 1695 public static final int WIFI_SUPPL_STATE_INACTIVE = 3; 1696 public static final int WIFI_SUPPL_STATE_SCANNING = 4; 1697 public static final int WIFI_SUPPL_STATE_AUTHENTICATING = 5; 1698 public static final int WIFI_SUPPL_STATE_ASSOCIATING = 6; 1699 public static final int WIFI_SUPPL_STATE_ASSOCIATED = 7; 1700 public static final int WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE = 8; 1701 public static final int WIFI_SUPPL_STATE_GROUP_HANDSHAKE = 9; 1702 public static final int WIFI_SUPPL_STATE_COMPLETED = 10; 1703 public static final int WIFI_SUPPL_STATE_DORMANT = 11; 1704 public static final int WIFI_SUPPL_STATE_UNINITIALIZED = 12; 1705 1706 public static final int NUM_WIFI_SUPPL_STATES = WIFI_SUPPL_STATE_UNINITIALIZED+1; 1707 1708 static final String[] WIFI_SUPPL_STATE_NAMES = { 1709 "invalid", "disconn", "disabled", "inactive", "scanning", 1710 "authenticating", "associating", "associated", "4-way-handshake", 1711 "group-handshake", "completed", "dormant", "uninit" 1712 }; 1713 1714 static final String[] WIFI_SUPPL_STATE_SHORT_NAMES = { 1715 "inv", "dsc", "dis", "inact", "scan", 1716 "auth", "ascing", "asced", "4-way", 1717 "group", "compl", "dorm", "uninit" 1718 }; 1719 1720 public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS 1721 = new BitDescription[] { 1722 new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"), 1723 new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"), 1724 new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"), 1725 new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"), 1726 new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"), 1727 new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"), 1728 new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"), 1729 new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"), 1730 new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"), 1731 new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"), 1732 new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"), 1733 new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"), 1734 new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"), 1735 new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth", "b"), 1736 new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK, 1737 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn", 1738 DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES), 1739 new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK, 1740 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst", 1741 new String[] {"in", "out", "emergency", "off"}, 1742 new String[] {"in", "out", "em", "off"}), 1743 new BitDescription(HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK, 1744 HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT, "phone_signal_strength", "Pss", 1745 SignalStrength.SIGNAL_STRENGTH_NAMES, 1746 new String[] { "0", "1", "2", "3", "4" }), 1747 new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK, 1748 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb", 1749 SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES), 1750 }; 1751 1752 public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS 1753 = new BitDescription[] { 1754 new BitDescription(HistoryItem.STATE2_POWER_SAVE_FLAG, "power_save", "ps"), 1755 new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"), 1756 new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Wr"), 1757 new BitDescription(HistoryItem.STATE2_WIFI_ON_FLAG, "wifi", "W"), 1758 new BitDescription(HistoryItem.STATE2_FLASHLIGHT_FLAG, "flashlight", "fl"), 1759 new BitDescription(HistoryItem.STATE2_DEVICE_IDLE_FLAG, "device_idle", "di"), 1760 new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK, 1761 HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT, "wifi_signal_strength", "Wss", 1762 new String[] { "0", "1", "2", "3", "4" }, 1763 new String[] { "0", "1", "2", "3", "4" }), 1764 new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK, 1765 HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp", 1766 WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES), 1767 }; 1768 1769 public static final String[] HISTORY_EVENT_NAMES = new String[] { 1770 "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn", 1771 "motion", "active", "pkginst", "pkgunin" 1772 }; 1773 1774 public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] { 1775 "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn", 1776 "Esm", "Eac", "Epi", "Epu" 1777 }; 1778 1779 /** 1780 * Returns the time in microseconds that wifi has been on while the device was 1781 * running on battery. 1782 * 1783 * {@hide} 1784 */ 1785 public abstract long getWifiOnTime(long elapsedRealtimeUs, int which); 1786 1787 /** 1788 * Returns the time in microseconds that wifi has been on and the driver has 1789 * been in the running state while the device was running on battery. 1790 * 1791 * {@hide} 1792 */ 1793 public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which); 1794 1795 public static final int WIFI_STATE_OFF = 0; 1796 public static final int WIFI_STATE_OFF_SCANNING = 1; 1797 public static final int WIFI_STATE_ON_NO_NETWORKS = 2; 1798 public static final int WIFI_STATE_ON_DISCONNECTED = 3; 1799 public static final int WIFI_STATE_ON_CONNECTED_STA = 4; 1800 public static final int WIFI_STATE_ON_CONNECTED_P2P = 5; 1801 public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6; 1802 public static final int WIFI_STATE_SOFT_AP = 7; 1803 1804 static final String[] WIFI_STATE_NAMES = { 1805 "off", "scanning", "no_net", "disconn", 1806 "sta", "p2p", "sta_p2p", "soft_ap" 1807 }; 1808 1809 public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1; 1810 1811 /** 1812 * Returns the time in microseconds that WiFi has been running in the given state. 1813 * 1814 * {@hide} 1815 */ 1816 public abstract long getWifiStateTime(int wifiState, 1817 long elapsedRealtimeUs, int which); 1818 1819 /** 1820 * Returns the number of times that WiFi has entered the given state. 1821 * 1822 * {@hide} 1823 */ 1824 public abstract int getWifiStateCount(int wifiState, int which); 1825 1826 /** 1827 * Returns the time in microseconds that the wifi supplicant has been 1828 * in a given state. 1829 * 1830 * {@hide} 1831 */ 1832 public abstract long getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which); 1833 1834 /** 1835 * Returns the number of times that the wifi supplicant has transitioned 1836 * to a given state. 1837 * 1838 * {@hide} 1839 */ 1840 public abstract int getWifiSupplStateCount(int state, int which); 1841 1842 public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5; 1843 1844 /** 1845 * Returns the time in microseconds that WIFI has been running with 1846 * the given signal strength. 1847 * 1848 * {@hide} 1849 */ 1850 public abstract long getWifiSignalStrengthTime(int strengthBin, 1851 long elapsedRealtimeUs, int which); 1852 1853 /** 1854 * Returns the number of times WIFI has entered the given signal strength. 1855 * 1856 * {@hide} 1857 */ 1858 public abstract int getWifiSignalStrengthCount(int strengthBin, int which); 1859 1860 /** 1861 * Returns the time in microseconds that bluetooth has been on while the device was 1862 * running on battery. 1863 * 1864 * {@hide} 1865 */ 1866 public abstract long getBluetoothOnTime(long elapsedRealtimeUs, int which); 1867 1868 public abstract int getBluetoothPingCount(); 1869 1870 public static final int BLUETOOTH_STATE_INACTIVE = 0; 1871 public static final int BLUETOOTH_STATE_LOW = 1; 1872 public static final int BLUETOOTH_STATE_MEDIUM = 2; 1873 public static final int BLUETOOTH_STATE_HIGH = 3; 1874 1875 static final String[] BLUETOOTH_STATE_NAMES = { 1876 "inactive", "low", "med", "high" 1877 }; 1878 1879 public static final int NUM_BLUETOOTH_STATES = BLUETOOTH_STATE_HIGH +1; 1880 1881 /** 1882 * Returns the time in microseconds that Bluetooth has been running in the 1883 * given active state. 1884 * 1885 * {@hide} 1886 */ 1887 public abstract long getBluetoothStateTime(int bluetoothState, 1888 long elapsedRealtimeUs, int which); 1889 1890 /** 1891 * Returns the number of times that Bluetooth has entered the given active state. 1892 * 1893 * {@hide} 1894 */ 1895 public abstract int getBluetoothStateCount(int bluetoothState, int which); 1896 1897 /** 1898 * Returns the time in microseconds that the flashlight has been on while the device was 1899 * running on battery. 1900 * 1901 * {@hide} 1902 */ 1903 public abstract long getFlashlightOnTime(long elapsedRealtimeUs, int which); 1904 1905 /** 1906 * Returns the number of times that the flashlight has been turned on while the device was 1907 * running on battery. 1908 * 1909 * {@hide} 1910 */ 1911 public abstract long getFlashlightOnCount(int which); 1912 1913 public static final int NETWORK_MOBILE_RX_DATA = 0; 1914 public static final int NETWORK_MOBILE_TX_DATA = 1; 1915 public static final int NETWORK_WIFI_RX_DATA = 2; 1916 public static final int NETWORK_WIFI_TX_DATA = 3; 1917 1918 public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1; 1919 1920 public abstract long getNetworkActivityBytes(int type, int which); 1921 public abstract long getNetworkActivityPackets(int type, int which); 1922 1923 public static final int CONTROLLER_IDLE_TIME = 0; 1924 public static final int CONTROLLER_RX_TIME = 1; 1925 public static final int CONTROLLER_TX_TIME = 2; 1926 public static final int CONTROLLER_ENERGY = 3; 1927 public static final int NUM_CONTROLLER_ACTIVITY_TYPES = CONTROLLER_ENERGY + 1; 1928 1929 public abstract long getBluetoothControllerActivity(int type, int which); 1930 public abstract long getWifiControllerActivity(int type, int which); 1931 1932 /** 1933 * Return the wall clock time when battery stats data collection started. 1934 */ 1935 public abstract long getStartClockTime(); 1936 1937 /** 1938 * Return platform version tag that we were running in when the battery stats started. 1939 */ 1940 public abstract String getStartPlatformVersion(); 1941 1942 /** 1943 * Return platform version tag that we were running in when the battery stats ended. 1944 */ 1945 public abstract String getEndPlatformVersion(); 1946 1947 /** 1948 * Return the internal version code of the parcelled format. 1949 */ 1950 public abstract int getParcelVersion(); 1951 1952 /** 1953 * Return whether we are currently running on battery. 1954 */ 1955 public abstract boolean getIsOnBattery(); 1956 1957 /** 1958 * Returns a SparseArray containing the statistics for each uid. 1959 */ 1960 public abstract SparseArray<? extends Uid> getUidStats(); 1961 1962 /** 1963 * Returns the current battery uptime in microseconds. 1964 * 1965 * @param curTime the amount of elapsed realtime in microseconds. 1966 */ 1967 public abstract long getBatteryUptime(long curTime); 1968 1969 /** 1970 * Returns the current battery realtime in microseconds. 1971 * 1972 * @param curTime the amount of elapsed realtime in microseconds. 1973 */ 1974 public abstract long getBatteryRealtime(long curTime); 1975 1976 /** 1977 * Returns the battery percentage level at the last time the device was unplugged from power, or 1978 * the last time it booted on battery power. 1979 */ 1980 public abstract int getDischargeStartLevel(); 1981 1982 /** 1983 * Returns the current battery percentage level if we are in a discharge cycle, otherwise 1984 * returns the level at the last plug event. 1985 */ 1986 public abstract int getDischargeCurrentLevel(); 1987 1988 /** 1989 * Get the amount the battery has discharged since the stats were 1990 * last reset after charging, as a lower-end approximation. 1991 */ 1992 public abstract int getLowDischargeAmountSinceCharge(); 1993 1994 /** 1995 * Get the amount the battery has discharged since the stats were 1996 * last reset after charging, as an upper-end approximation. 1997 */ 1998 public abstract int getHighDischargeAmountSinceCharge(); 1999 2000 /** 2001 * Retrieve the discharge amount over the selected discharge period <var>which</var>. 2002 */ 2003 public abstract int getDischargeAmount(int which); 2004 2005 /** 2006 * Get the amount the battery has discharged while the screen was on, 2007 * since the last time power was unplugged. 2008 */ 2009 public abstract int getDischargeAmountScreenOn(); 2010 2011 /** 2012 * Get the amount the battery has discharged while the screen was on, 2013 * since the last time the device was charged. 2014 */ 2015 public abstract int getDischargeAmountScreenOnSinceCharge(); 2016 2017 /** 2018 * Get the amount the battery has discharged while the screen was off, 2019 * since the last time power was unplugged. 2020 */ 2021 public abstract int getDischargeAmountScreenOff(); 2022 2023 /** 2024 * Get the amount the battery has discharged while the screen was off, 2025 * since the last time the device was charged. 2026 */ 2027 public abstract int getDischargeAmountScreenOffSinceCharge(); 2028 2029 /** 2030 * Returns the total, last, or current battery uptime in microseconds. 2031 * 2032 * @param curTime the elapsed realtime in microseconds. 2033 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 2034 */ 2035 public abstract long computeBatteryUptime(long curTime, int which); 2036 2037 /** 2038 * Returns the total, last, or current battery realtime in microseconds. 2039 * 2040 * @param curTime the current elapsed realtime in microseconds. 2041 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 2042 */ 2043 public abstract long computeBatteryRealtime(long curTime, int which); 2044 2045 /** 2046 * Returns the total, last, or current battery screen off uptime in microseconds. 2047 * 2048 * @param curTime the elapsed realtime in microseconds. 2049 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 2050 */ 2051 public abstract long computeBatteryScreenOffUptime(long curTime, int which); 2052 2053 /** 2054 * Returns the total, last, or current battery screen off realtime in microseconds. 2055 * 2056 * @param curTime the current elapsed realtime in microseconds. 2057 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 2058 */ 2059 public abstract long computeBatteryScreenOffRealtime(long curTime, int which); 2060 2061 /** 2062 * Returns the total, last, or current uptime in microseconds. 2063 * 2064 * @param curTime the current elapsed realtime in microseconds. 2065 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 2066 */ 2067 public abstract long computeUptime(long curTime, int which); 2068 2069 /** 2070 * Returns the total, last, or current realtime in microseconds. 2071 * 2072 * @param curTime the current elapsed realtime in microseconds. 2073 * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 2074 */ 2075 public abstract long computeRealtime(long curTime, int which); 2076 2077 /** 2078 * Compute an approximation for how much run time (in microseconds) is remaining on 2079 * the battery. Returns -1 if no time can be computed: either there is not 2080 * enough current data to make a decision, or the battery is currently 2081 * charging. 2082 * 2083 * @param curTime The current elepsed realtime in microseconds. 2084 */ 2085 public abstract long computeBatteryTimeRemaining(long curTime); 2086 2087 // The part of a step duration that is the actual time. 2088 public static final long STEP_LEVEL_TIME_MASK = 0x000000ffffffffffL; 2089 2090 // Bits in a step duration that are the new battery level we are at. 2091 public static final long STEP_LEVEL_LEVEL_MASK = 0x0000ff0000000000L; 2092 public static final int STEP_LEVEL_LEVEL_SHIFT = 40; 2093 2094 // Bits in a step duration that are the initial mode we were in at that step. 2095 public static final long STEP_LEVEL_INITIAL_MODE_MASK = 0x00ff000000000000L; 2096 public static final int STEP_LEVEL_INITIAL_MODE_SHIFT = 48; 2097 2098 // Bits in a step duration that indicate which modes changed during that step. 2099 public static final long STEP_LEVEL_MODIFIED_MODE_MASK = 0xff00000000000000L; 2100 public static final int STEP_LEVEL_MODIFIED_MODE_SHIFT = 56; 2101 2102 // Step duration mode: the screen is on, off, dozed, etc; value is Display.STATE_* - 1. 2103 public static final int STEP_LEVEL_MODE_SCREEN_STATE = 0x03; 2104 2105 // Step duration mode: power save is on. 2106 public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04; 2107 2108 // Step duration mode: device is currently in idle mode. 2109 public static final int STEP_LEVEL_MODE_DEVICE_IDLE = 0x08; 2110 2111 public static final int[] STEP_LEVEL_MODES_OF_INTEREST = new int[] { 2112 STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, 2113 STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE, 2114 STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE, 2115 STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, 2116 STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, 2117 STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, 2118 STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, 2119 STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE, 2120 STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE|STEP_LEVEL_MODE_DEVICE_IDLE, 2121 STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_DEVICE_IDLE, 2122 }; 2123 public static final int[] STEP_LEVEL_MODE_VALUES = new int[] { 2124 (Display.STATE_OFF-1), 2125 (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE, 2126 (Display.STATE_OFF-1)|STEP_LEVEL_MODE_DEVICE_IDLE, 2127 (Display.STATE_ON-1), 2128 (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE, 2129 (Display.STATE_DOZE-1), 2130 (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE, 2131 (Display.STATE_DOZE_SUSPEND-1), 2132 (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE, 2133 (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_DEVICE_IDLE, 2134 }; 2135 public static final String[] STEP_LEVEL_MODE_LABELS = new String[] { 2136 "screen off", 2137 "screen off power save", 2138 "screen off device idle", 2139 "screen on", 2140 "screen on power save", 2141 "screen doze", 2142 "screen doze power save", 2143 "screen doze-suspend", 2144 "screen doze-suspend power save", 2145 "screen doze-suspend device idle", 2146 }; 2147 2148 /** 2149 * Return the array of discharge step durations. 2150 */ 2151 public abstract LevelStepTracker getDischargeLevelStepTracker(); 2152 2153 /** 2154 * Return the array of daily discharge step durations. 2155 */ 2156 public abstract LevelStepTracker getDailyDischargeLevelStepTracker(); 2157 2158 /** 2159 * Compute an approximation for how much time (in microseconds) remains until the battery 2160 * is fully charged. Returns -1 if no time can be computed: either there is not 2161 * enough current data to make a decision, or the battery is currently 2162 * discharging. 2163 * 2164 * @param curTime The current elepsed realtime in microseconds. 2165 */ 2166 public abstract long computeChargeTimeRemaining(long curTime); 2167 2168 /** 2169 * Return the array of charge step durations. 2170 */ 2171 public abstract LevelStepTracker getChargeLevelStepTracker(); 2172 2173 /** 2174 * Return the array of daily charge step durations. 2175 */ 2176 public abstract LevelStepTracker getDailyChargeLevelStepTracker(); 2177 2178 public abstract ArrayList<PackageChange> getDailyPackageChanges(); 2179 2180 public abstract Map<String, ? extends Timer> getWakeupReasonStats(); 2181 2182 public abstract Map<String, ? extends Timer> getKernelWakelockStats(); 2183 2184 /** Returns the number of different speeds that the CPU can run at */ 2185 public abstract int getCpuSpeedSteps(); 2186 2187 public abstract void writeToParcelWithoutUids(Parcel out, int flags); 2188 2189 private final static void formatTimeRaw(StringBuilder out, long seconds) { 2190 long days = seconds / (60 * 60 * 24); 2191 if (days != 0) { 2192 out.append(days); 2193 out.append("d "); 2194 } 2195 long used = days * 60 * 60 * 24; 2196 2197 long hours = (seconds - used) / (60 * 60); 2198 if (hours != 0 || used != 0) { 2199 out.append(hours); 2200 out.append("h "); 2201 } 2202 used += hours * 60 * 60; 2203 2204 long mins = (seconds-used) / 60; 2205 if (mins != 0 || used != 0) { 2206 out.append(mins); 2207 out.append("m "); 2208 } 2209 used += mins * 60; 2210 2211 if (seconds != 0 || used != 0) { 2212 out.append(seconds-used); 2213 out.append("s "); 2214 } 2215 } 2216 2217 public final static void formatTimeMs(StringBuilder sb, long time) { 2218 long sec = time / 1000; 2219 formatTimeRaw(sb, sec); 2220 sb.append(time - (sec * 1000)); 2221 sb.append("ms "); 2222 } 2223 2224 public final static void formatTimeMsNoSpace(StringBuilder sb, long time) { 2225 long sec = time / 1000; 2226 formatTimeRaw(sb, sec); 2227 sb.append(time - (sec * 1000)); 2228 sb.append("ms"); 2229 } 2230 2231 public final String formatRatioLocked(long num, long den) { 2232 if (den == 0L) { 2233 return "--%"; 2234 } 2235 float perc = ((float)num) / ((float)den) * 100; 2236 mFormatBuilder.setLength(0); 2237 mFormatter.format("%.1f%%", perc); 2238 return mFormatBuilder.toString(); 2239 } 2240 2241 final String formatBytesLocked(long bytes) { 2242 mFormatBuilder.setLength(0); 2243 2244 if (bytes < BYTES_PER_KB) { 2245 return bytes + "B"; 2246 } else if (bytes < BYTES_PER_MB) { 2247 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB); 2248 return mFormatBuilder.toString(); 2249 } else if (bytes < BYTES_PER_GB){ 2250 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB); 2251 return mFormatBuilder.toString(); 2252 } else { 2253 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB); 2254 return mFormatBuilder.toString(); 2255 } 2256 } 2257 2258 private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) { 2259 if (timer != null) { 2260 // Convert from microseconds to milliseconds with rounding 2261 long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which); 2262 long totalTimeMillis = (totalTimeMicros + 500) / 1000; 2263 return totalTimeMillis; 2264 } 2265 return 0; 2266 } 2267 2268 /** 2269 * 2270 * @param sb a StringBuilder object. 2271 * @param timer a Timer object contining the wakelock times. 2272 * @param elapsedRealtimeUs the current on-battery time in microseconds. 2273 * @param name the name of the wakelock. 2274 * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 2275 * @param linePrefix a String to be prepended to each line of output. 2276 * @return the line prefix 2277 */ 2278 private static final String printWakeLock(StringBuilder sb, Timer timer, 2279 long elapsedRealtimeUs, String name, int which, String linePrefix) { 2280 2281 if (timer != null) { 2282 long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which); 2283 2284 int count = timer.getCountLocked(which); 2285 if (totalTimeMillis != 0) { 2286 sb.append(linePrefix); 2287 formatTimeMs(sb, totalTimeMillis); 2288 if (name != null) { 2289 sb.append(name); 2290 sb.append(' '); 2291 } 2292 sb.append('('); 2293 sb.append(count); 2294 sb.append(" times)"); 2295 return ", "; 2296 } 2297 } 2298 return linePrefix; 2299 } 2300 2301 /** 2302 * Checkin version of wakelock printer. Prints simple comma-separated list. 2303 * 2304 * @param sb a StringBuilder object. 2305 * @param timer a Timer object contining the wakelock times. 2306 * @param elapsedRealtimeUs the current time in microseconds. 2307 * @param name the name of the wakelock. 2308 * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. 2309 * @param linePrefix a String to be prepended to each line of output. 2310 * @return the line prefix 2311 */ 2312 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, 2313 long elapsedRealtimeUs, String name, int which, String linePrefix) { 2314 long totalTimeMicros = 0; 2315 int count = 0; 2316 if (timer != null) { 2317 totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which); 2318 count = timer.getCountLocked(which); 2319 } 2320 sb.append(linePrefix); 2321 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding 2322 sb.append(','); 2323 sb.append(name != null ? name + "," : ""); 2324 sb.append(count); 2325 return ","; 2326 } 2327 2328 /** 2329 * Dump a comma-separated line of values for terse checkin mode. 2330 * 2331 * @param pw the PageWriter to dump log to 2332 * @param category category of data (e.g. "total", "last", "unplugged", "current" ) 2333 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network") 2334 * @param args type-dependent data arguments 2335 */ 2336 private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 2337 Object... args ) { 2338 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 2339 pw.print(uid); pw.print(','); 2340 pw.print(category); pw.print(','); 2341 pw.print(type); 2342 2343 for (Object arg : args) { 2344 pw.print(','); 2345 pw.print(arg); 2346 } 2347 pw.println(); 2348 } 2349 2350 /** 2351 * Temporary for settings. 2352 */ 2353 public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) { 2354 dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context)); 2355 } 2356 2357 /** 2358 * Checkin server version of dump to produce more compact, computer-readable log. 2359 * 2360 * NOTE: all times are expressed in 'ms'. 2361 */ 2362 public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid, 2363 boolean wifiOnly) { 2364 final long rawUptime = SystemClock.uptimeMillis() * 1000; 2365 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 2366 final long batteryUptime = getBatteryUptime(rawUptime); 2367 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 2368 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 2369 final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which); 2370 final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime, 2371 which); 2372 final long totalRealtime = computeRealtime(rawRealtime, which); 2373 final long totalUptime = computeUptime(rawUptime, which); 2374 final long screenOnTime = getScreenOnTime(rawRealtime, which); 2375 final long interactiveTime = getInteractiveTime(rawRealtime, which); 2376 final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which); 2377 final long deviceIdleModeEnabledTime = getDeviceIdleModeEnabledTime(rawRealtime, which); 2378 final long deviceIdlingTime = getDeviceIdlingTime(rawRealtime, which); 2379 final int connChanges = getNumConnectivityChange(which); 2380 final long phoneOnTime = getPhoneOnTime(rawRealtime, which); 2381 final long wifiOnTime = getWifiOnTime(rawRealtime, which); 2382 final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which); 2383 final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which); 2384 2385 final StringBuilder sb = new StringBuilder(128); 2386 2387 final SparseArray<? extends Uid> uidStats = getUidStats(); 2388 final int NU = uidStats.size(); 2389 2390 final String category = STAT_NAMES[which]; 2391 2392 // Dump "battery" stat 2393 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 2394 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A", 2395 whichBatteryRealtime / 1000, whichBatteryUptime / 1000, 2396 totalRealtime / 1000, totalUptime / 1000, 2397 getStartClockTime(), 2398 whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000); 2399 2400 // Calculate wakelock times across all uids. 2401 long fullWakeLockTimeTotal = 0; 2402 long partialWakeLockTimeTotal = 0; 2403 2404 for (int iu = 0; iu < NU; iu++) { 2405 final Uid u = uidStats.valueAt(iu); 2406 2407 final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks 2408 = u.getWakelockStats(); 2409 for (int iw=wakelocks.size()-1; iw>=0; iw--) { 2410 final Uid.Wakelock wl = wakelocks.valueAt(iw); 2411 2412 final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 2413 if (fullWakeTimer != null) { 2414 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime, 2415 which); 2416 } 2417 2418 final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 2419 if (partialWakeTimer != null) { 2420 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked( 2421 rawRealtime, which); 2422 } 2423 } 2424 } 2425 2426 final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which); 2427 final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which); 2428 final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which); 2429 final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which); 2430 final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which); 2431 final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which); 2432 final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which); 2433 final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which); 2434 2435 // Dump network stats 2436 dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA, 2437 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes, 2438 mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets); 2439 2440 // Dump misc stats 2441 dumpLine(pw, 0 /* uid */, category, MISC_DATA, 2442 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000, 2443 wifiRunningTime / 1000, bluetoothOnTime / 1000, 2444 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes, 2445 fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000, 2446 0 /*legacy input event count*/, getMobileRadioActiveTime(rawRealtime, which) / 1000, 2447 getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000, 2448 powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeEnabledTime / 1000, 2449 getDeviceIdleModeEnabledCount(which), deviceIdlingTime / 1000, 2450 getDeviceIdlingCount(which)); 2451 2452 // Dump screen brightness stats 2453 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; 2454 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 2455 args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000; 2456 } 2457 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args); 2458 2459 // Dump signal strength stats 2460 args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 2461 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 2462 args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000; 2463 } 2464 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args); 2465 dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA, 2466 getPhoneSignalScanningTime(rawRealtime, which) / 1000); 2467 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 2468 args[i] = getPhoneSignalStrengthCount(i, which); 2469 } 2470 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args); 2471 2472 // Dump network type stats 2473 args = new Object[NUM_DATA_CONNECTION_TYPES]; 2474 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 2475 args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000; 2476 } 2477 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args); 2478 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 2479 args[i] = getPhoneDataConnectionCount(i, which); 2480 } 2481 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args); 2482 2483 // Dump wifi state stats 2484 args = new Object[NUM_WIFI_STATES]; 2485 for (int i=0; i<NUM_WIFI_STATES; i++) { 2486 args[i] = getWifiStateTime(i, rawRealtime, which) / 1000; 2487 } 2488 dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args); 2489 for (int i=0; i<NUM_WIFI_STATES; i++) { 2490 args[i] = getWifiStateCount(i, which); 2491 } 2492 dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args); 2493 2494 // Dump wifi suppl state stats 2495 args = new Object[NUM_WIFI_SUPPL_STATES]; 2496 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 2497 args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000; 2498 } 2499 dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_TIME_DATA, args); 2500 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 2501 args[i] = getWifiSupplStateCount(i, which); 2502 } 2503 dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_COUNT_DATA, args); 2504 2505 // Dump wifi signal strength stats 2506 args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 2507 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 2508 args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000; 2509 } 2510 dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args); 2511 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 2512 args[i] = getWifiSignalStrengthCount(i, which); 2513 } 2514 dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args); 2515 2516 // Dump bluetooth state stats 2517 args = new Object[NUM_BLUETOOTH_STATES]; 2518 for (int i=0; i<NUM_BLUETOOTH_STATES; i++) { 2519 args[i] = getBluetoothStateTime(i, rawRealtime, which) / 1000; 2520 } 2521 dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_TIME_DATA, args); 2522 for (int i=0; i<NUM_BLUETOOTH_STATES; i++) { 2523 args[i] = getBluetoothStateCount(i, which); 2524 } 2525 dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_COUNT_DATA, args); 2526 2527 if (which == STATS_SINCE_UNPLUGGED) { 2528 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), 2529 getDischargeCurrentLevel()); 2530 } 2531 2532 if (which == STATS_SINCE_UNPLUGGED) { 2533 dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, 2534 getDischargeStartLevel()-getDischargeCurrentLevel(), 2535 getDischargeStartLevel()-getDischargeCurrentLevel(), 2536 getDischargeAmountScreenOn(), getDischargeAmountScreenOff()); 2537 } else { 2538 dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, 2539 getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(), 2540 getDischargeAmountScreenOnSinceCharge(), 2541 getDischargeAmountScreenOffSinceCharge()); 2542 } 2543 2544 if (reqUid < 0) { 2545 final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats(); 2546 if (kernelWakelocks.size() > 0) { 2547 for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) { 2548 sb.setLength(0); 2549 printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, ""); 2550 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(), 2551 sb.toString()); 2552 } 2553 } 2554 final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats(); 2555 if (wakeupReasons.size() > 0) { 2556 for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) { 2557 // Not doing the regular wake lock formatting to remain compatible 2558 // with the old checkin format. 2559 long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which); 2560 int count = ent.getValue().getCountLocked(which); 2561 dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA, 2562 "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count); 2563 } 2564 } 2565 } 2566 2567 final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly); 2568 helper.create(this); 2569 helper.refreshStats(which, UserHandle.USER_ALL); 2570 final List<BatterySipper> sippers = helper.getUsageList(); 2571 if (sippers != null && sippers.size() > 0) { 2572 dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA, 2573 BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()), 2574 BatteryStatsHelper.makemAh(helper.getComputedPower()), 2575 BatteryStatsHelper.makemAh(helper.getMinDrainedPower()), 2576 BatteryStatsHelper.makemAh(helper.getMaxDrainedPower())); 2577 for (int i=0; i<sippers.size(); i++) { 2578 final BatterySipper bs = sippers.get(i); 2579 int uid = 0; 2580 String label; 2581 switch (bs.drainType) { 2582 case IDLE: 2583 label="idle"; 2584 break; 2585 case CELL: 2586 label="cell"; 2587 break; 2588 case PHONE: 2589 label="phone"; 2590 break; 2591 case WIFI: 2592 label="wifi"; 2593 break; 2594 case BLUETOOTH: 2595 label="blue"; 2596 break; 2597 case SCREEN: 2598 label="scrn"; 2599 break; 2600 case FLASHLIGHT: 2601 label="flashlight"; 2602 break; 2603 case APP: 2604 uid = bs.uidObj.getUid(); 2605 label = "uid"; 2606 break; 2607 case USER: 2608 uid = UserHandle.getUid(bs.userId, 0); 2609 label = "user"; 2610 break; 2611 case UNACCOUNTED: 2612 label = "unacc"; 2613 break; 2614 case OVERCOUNTED: 2615 label = "over"; 2616 break; 2617 default: 2618 label = "???"; 2619 } 2620 dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label, 2621 BatteryStatsHelper.makemAh(bs.value)); 2622 } 2623 } 2624 2625 for (int iu = 0; iu < NU; iu++) { 2626 final int uid = uidStats.keyAt(iu); 2627 if (reqUid >= 0 && uid != reqUid) { 2628 continue; 2629 } 2630 final Uid u = uidStats.valueAt(iu); 2631 // Dump Network stats per uid, if any 2632 final long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which); 2633 final long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which); 2634 final long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which); 2635 final long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which); 2636 final long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which); 2637 final long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which); 2638 final long mobileActiveTime = u.getMobileRadioActiveTime(which); 2639 final int mobileActiveCount = u.getMobileRadioActiveCount(which); 2640 final long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which); 2641 final long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which); 2642 final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which); 2643 final long wifiScanTime = u.getWifiScanTime(rawRealtime, which); 2644 final int wifiScanCount = u.getWifiScanCount(which); 2645 final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which); 2646 2647 if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0 2648 || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0 2649 || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0) { 2650 dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx, 2651 wifiBytesRx, wifiBytesTx, 2652 mobilePacketsRx, mobilePacketsTx, 2653 wifiPacketsRx, wifiPacketsTx, 2654 mobileActiveTime, mobileActiveCount); 2655 } 2656 2657 if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0 2658 || uidWifiRunningTime != 0) { 2659 dumpLine(pw, uid, category, WIFI_DATA, 2660 fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime, wifiScanCount); 2661 } 2662 2663 if (u.hasUserActivity()) { 2664 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES]; 2665 boolean hasData = false; 2666 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 2667 int val = u.getUserActivityCount(i, which); 2668 args[i] = val; 2669 if (val != 0) hasData = true; 2670 } 2671 if (hasData) { 2672 dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args); 2673 } 2674 } 2675 2676 final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats(); 2677 for (int iw=wakelocks.size()-1; iw>=0; iw--) { 2678 final Uid.Wakelock wl = wakelocks.valueAt(iw); 2679 String linePrefix = ""; 2680 sb.setLength(0); 2681 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), 2682 rawRealtime, "f", which, linePrefix); 2683 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), 2684 rawRealtime, "p", which, linePrefix); 2685 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), 2686 rawRealtime, "w", which, linePrefix); 2687 2688 // Only log if we had at lease one wakelock... 2689 if (sb.length() > 0) { 2690 String name = wakelocks.keyAt(iw); 2691 if (name.indexOf(',') >= 0) { 2692 name = name.replace(',', '_'); 2693 } 2694 dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString()); 2695 } 2696 } 2697 2698 final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats(); 2699 for (int isy=syncs.size()-1; isy>=0; isy--) { 2700 final Timer timer = syncs.valueAt(isy); 2701 // Convert from microseconds to milliseconds with rounding 2702 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; 2703 final int count = timer.getCountLocked(which); 2704 if (totalTime != 0) { 2705 dumpLine(pw, uid, category, SYNC_DATA, syncs.keyAt(isy), totalTime, count); 2706 } 2707 } 2708 2709 final ArrayMap<String, ? extends Timer> jobs = u.getJobStats(); 2710 for (int ij=jobs.size()-1; ij>=0; ij--) { 2711 final Timer timer = jobs.valueAt(ij); 2712 // Convert from microseconds to milliseconds with rounding 2713 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; 2714 final int count = timer.getCountLocked(which); 2715 if (totalTime != 0) { 2716 dumpLine(pw, uid, category, JOB_DATA, jobs.keyAt(ij), totalTime, count); 2717 } 2718 } 2719 2720 final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 2721 final int NSE = sensors.size(); 2722 for (int ise=0; ise<NSE; ise++) { 2723 final Uid.Sensor se = sensors.valueAt(ise); 2724 final int sensorNumber = sensors.keyAt(ise); 2725 final Timer timer = se.getSensorTime(); 2726 if (timer != null) { 2727 // Convert from microseconds to milliseconds with rounding 2728 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) 2729 / 1000; 2730 final int count = timer.getCountLocked(which); 2731 if (totalTime != 0) { 2732 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); 2733 } 2734 } 2735 } 2736 2737 final Timer vibTimer = u.getVibratorOnTimer(); 2738 if (vibTimer != null) { 2739 // Convert from microseconds to milliseconds with rounding 2740 final long totalTime = (vibTimer.getTotalTimeLocked(rawRealtime, which) + 500) 2741 / 1000; 2742 final int count = vibTimer.getCountLocked(which); 2743 if (totalTime != 0) { 2744 dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count); 2745 } 2746 } 2747 2748 final Timer fgTimer = u.getForegroundActivityTimer(); 2749 if (fgTimer != null) { 2750 // Convert from microseconds to milliseconds with rounding 2751 final long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) 2752 / 1000; 2753 final int count = fgTimer.getCountLocked(which); 2754 if (totalTime != 0) { 2755 dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count); 2756 } 2757 } 2758 2759 final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE]; 2760 long totalStateTime = 0; 2761 for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) { 2762 totalStateTime += u.getProcessStateTime(ips, rawRealtime, which); 2763 stateTimes[ips] = (totalStateTime + 500) / 1000; 2764 } 2765 if (totalStateTime > 0) { 2766 dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes); 2767 } 2768 2769 final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats 2770 = u.getProcessStats(); 2771 for (int ipr=processStats.size()-1; ipr>=0; ipr--) { 2772 final Uid.Proc ps = processStats.valueAt(ipr); 2773 2774 final long userMillis = ps.getUserTime(which); 2775 final long systemMillis = ps.getSystemTime(which); 2776 final long foregroundMillis = ps.getForegroundTime(which); 2777 final int starts = ps.getStarts(which); 2778 final int numCrashes = ps.getNumCrashes(which); 2779 final int numAnrs = ps.getNumAnrs(which); 2780 2781 if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0 2782 || starts != 0 || numAnrs != 0 || numCrashes != 0) { 2783 dumpLine(pw, uid, category, PROCESS_DATA, processStats.keyAt(ipr), userMillis, 2784 systemMillis, foregroundMillis, starts, numAnrs, numCrashes); 2785 } 2786 } 2787 2788 final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats 2789 = u.getPackageStats(); 2790 for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) { 2791 final Uid.Pkg ps = packageStats.valueAt(ipkg); 2792 int wakeups = 0; 2793 final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats(); 2794 for (int iwa=alarms.size()-1; iwa>=0; iwa--) { 2795 wakeups += alarms.valueAt(iwa).getCountLocked(which); 2796 } 2797 final ArrayMap<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 2798 for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) { 2799 final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc); 2800 final long startTime = ss.getStartTime(batteryUptime, which); 2801 final int starts = ss.getStarts(which); 2802 final int launches = ss.getLaunches(which); 2803 if (startTime != 0 || starts != 0 || launches != 0) { 2804 dumpLine(pw, uid, category, APK_DATA, 2805 wakeups, // wakeup alarms 2806 packageStats.keyAt(ipkg), // Apk 2807 serviceStats.keyAt(isvc), // service 2808 startTime / 1000, // time spent started, in ms 2809 starts, 2810 launches); 2811 } 2812 } 2813 } 2814 } 2815 } 2816 2817 static final class TimerEntry { 2818 final String mName; 2819 final int mId; 2820 final BatteryStats.Timer mTimer; 2821 final long mTime; 2822 TimerEntry(String name, int id, BatteryStats.Timer timer, long time) { 2823 mName = name; 2824 mId = id; 2825 mTimer = timer; 2826 mTime = time; 2827 } 2828 } 2829 2830 private void printmAh(PrintWriter printer, double power) { 2831 printer.print(BatteryStatsHelper.makemAh(power)); 2832 } 2833 2834 /** 2835 * Temporary for settings. 2836 */ 2837 public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which, 2838 int reqUid) { 2839 dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context)); 2840 } 2841 2842 @SuppressWarnings("unused") 2843 public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which, 2844 int reqUid, boolean wifiOnly) { 2845 final long rawUptime = SystemClock.uptimeMillis() * 1000; 2846 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 2847 final long batteryUptime = getBatteryUptime(rawUptime); 2848 2849 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which); 2850 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which); 2851 final long totalRealtime = computeRealtime(rawRealtime, which); 2852 final long totalUptime = computeUptime(rawUptime, which); 2853 final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which); 2854 final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime, 2855 which); 2856 final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime); 2857 final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime); 2858 2859 final StringBuilder sb = new StringBuilder(128); 2860 2861 final SparseArray<? extends Uid> uidStats = getUidStats(); 2862 final int NU = uidStats.size(); 2863 2864 sb.setLength(0); 2865 sb.append(prefix); 2866 sb.append(" Time on battery: "); 2867 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("("); 2868 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime)); 2869 sb.append(") realtime, "); 2870 formatTimeMs(sb, whichBatteryUptime / 1000); 2871 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime)); 2872 sb.append(") uptime"); 2873 pw.println(sb.toString()); 2874 sb.setLength(0); 2875 sb.append(prefix); 2876 sb.append(" Time on battery screen off: "); 2877 formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("("); 2878 sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime)); 2879 sb.append(") realtime, "); 2880 formatTimeMs(sb, whichBatteryScreenOffUptime / 1000); 2881 sb.append("("); 2882 sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime)); 2883 sb.append(") uptime"); 2884 pw.println(sb.toString()); 2885 sb.setLength(0); 2886 sb.append(prefix); 2887 sb.append(" Total run time: "); 2888 formatTimeMs(sb, totalRealtime / 1000); 2889 sb.append("realtime, "); 2890 formatTimeMs(sb, totalUptime / 1000); 2891 sb.append("uptime"); 2892 pw.println(sb.toString()); 2893 if (batteryTimeRemaining >= 0) { 2894 sb.setLength(0); 2895 sb.append(prefix); 2896 sb.append(" Battery time remaining: "); 2897 formatTimeMs(sb, batteryTimeRemaining / 1000); 2898 pw.println(sb.toString()); 2899 } 2900 if (chargeTimeRemaining >= 0) { 2901 sb.setLength(0); 2902 sb.append(prefix); 2903 sb.append(" Charge time remaining: "); 2904 formatTimeMs(sb, chargeTimeRemaining / 1000); 2905 pw.println(sb.toString()); 2906 } 2907 pw.print(" Start clock time: "); 2908 pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString()); 2909 2910 final long screenOnTime = getScreenOnTime(rawRealtime, which); 2911 final long interactiveTime = getInteractiveTime(rawRealtime, which); 2912 final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which); 2913 final long deviceIdleModeEnabledTime = getDeviceIdleModeEnabledTime(rawRealtime, which); 2914 final long deviceIdlingTime = getDeviceIdlingTime(rawRealtime, which); 2915 final long phoneOnTime = getPhoneOnTime(rawRealtime, which); 2916 final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which); 2917 final long wifiOnTime = getWifiOnTime(rawRealtime, which); 2918 final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which); 2919 sb.setLength(0); 2920 sb.append(prefix); 2921 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000); 2922 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime)); 2923 sb.append(") "); sb.append(getScreenOnCount(which)); 2924 sb.append("x, Interactive: "); formatTimeMs(sb, interactiveTime / 1000); 2925 sb.append("("); sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime)); 2926 sb.append(")"); 2927 pw.println(sb.toString()); 2928 sb.setLength(0); 2929 sb.append(prefix); 2930 sb.append(" Screen brightnesses:"); 2931 boolean didOne = false; 2932 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 2933 final long time = getScreenBrightnessTime(i, rawRealtime, which); 2934 if (time == 0) { 2935 continue; 2936 } 2937 sb.append("\n "); 2938 sb.append(prefix); 2939 didOne = true; 2940 sb.append(SCREEN_BRIGHTNESS_NAMES[i]); 2941 sb.append(" "); 2942 formatTimeMs(sb, time/1000); 2943 sb.append("("); 2944 sb.append(formatRatioLocked(time, screenOnTime)); 2945 sb.append(")"); 2946 } 2947 if (!didOne) sb.append(" (no activity)"); 2948 pw.println(sb.toString()); 2949 if (powerSaveModeEnabledTime != 0) { 2950 sb.setLength(0); 2951 sb.append(prefix); 2952 sb.append(" Power save mode enabled: "); 2953 formatTimeMs(sb, powerSaveModeEnabledTime / 1000); 2954 sb.append("("); 2955 sb.append(formatRatioLocked(powerSaveModeEnabledTime, whichBatteryRealtime)); 2956 sb.append(")"); 2957 pw.println(sb.toString()); 2958 } 2959 if (deviceIdlingTime != 0) { 2960 sb.setLength(0); 2961 sb.append(prefix); 2962 sb.append(" Device idling: "); 2963 formatTimeMs(sb, deviceIdlingTime / 1000); 2964 sb.append("("); 2965 sb.append(formatRatioLocked(deviceIdlingTime, whichBatteryRealtime)); 2966 sb.append(") "); sb.append(getDeviceIdlingCount(which)); 2967 sb.append("x"); 2968 pw.println(sb.toString()); 2969 } 2970 if (deviceIdleModeEnabledTime != 0) { 2971 sb.setLength(0); 2972 sb.append(prefix); 2973 sb.append(" Idle mode time: "); 2974 formatTimeMs(sb, deviceIdleModeEnabledTime / 1000); 2975 sb.append("("); 2976 sb.append(formatRatioLocked(deviceIdleModeEnabledTime, whichBatteryRealtime)); 2977 sb.append(") "); sb.append(getDeviceIdleModeEnabledCount(which)); 2978 sb.append("x"); 2979 pw.println(sb.toString()); 2980 } 2981 if (phoneOnTime != 0) { 2982 sb.setLength(0); 2983 sb.append(prefix); 2984 sb.append(" Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000); 2985 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime)); 2986 sb.append(") "); sb.append(getPhoneOnCount(which)); sb.append("x"); 2987 } 2988 final int connChanges = getNumConnectivityChange(which); 2989 if (connChanges != 0) { 2990 pw.print(prefix); 2991 pw.print(" Connectivity changes: "); pw.println(connChanges); 2992 } 2993 2994 // Calculate wakelock times across all uids. 2995 long fullWakeLockTimeTotalMicros = 0; 2996 long partialWakeLockTimeTotalMicros = 0; 2997 2998 final ArrayList<TimerEntry> timers = new ArrayList<>(); 2999 3000 for (int iu = 0; iu < NU; iu++) { 3001 final Uid u = uidStats.valueAt(iu); 3002 3003 final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks 3004 = u.getWakelockStats(); 3005 for (int iw=wakelocks.size()-1; iw>=0; iw--) { 3006 final Uid.Wakelock wl = wakelocks.valueAt(iw); 3007 3008 final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL); 3009 if (fullWakeTimer != null) { 3010 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked( 3011 rawRealtime, which); 3012 } 3013 3014 final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); 3015 if (partialWakeTimer != null) { 3016 final long totalTimeMicros = partialWakeTimer.getTotalTimeLocked( 3017 rawRealtime, which); 3018 if (totalTimeMicros > 0) { 3019 if (reqUid < 0) { 3020 // Only show the ordered list of all wake 3021 // locks if the caller is not asking for data 3022 // about a specific uid. 3023 timers.add(new TimerEntry(wakelocks.keyAt(iw), u.getUid(), 3024 partialWakeTimer, totalTimeMicros)); 3025 } 3026 partialWakeLockTimeTotalMicros += totalTimeMicros; 3027 } 3028 } 3029 } 3030 } 3031 3032 final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which); 3033 final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which); 3034 final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which); 3035 final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which); 3036 final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which); 3037 final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which); 3038 final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which); 3039 final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which); 3040 3041 if (fullWakeLockTimeTotalMicros != 0) { 3042 sb.setLength(0); 3043 sb.append(prefix); 3044 sb.append(" Total full wakelock time: "); formatTimeMsNoSpace(sb, 3045 (fullWakeLockTimeTotalMicros + 500) / 1000); 3046 pw.println(sb.toString()); 3047 } 3048 3049 if (partialWakeLockTimeTotalMicros != 0) { 3050 sb.setLength(0); 3051 sb.append(prefix); 3052 sb.append(" Total partial wakelock time: "); formatTimeMsNoSpace(sb, 3053 (partialWakeLockTimeTotalMicros + 500) / 1000); 3054 pw.println(sb.toString()); 3055 } 3056 3057 pw.print(prefix); 3058 pw.print(" Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes)); 3059 pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes)); 3060 pw.print(" (packets received "); pw.print(mobileRxTotalPackets); 3061 pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")"); 3062 sb.setLength(0); 3063 sb.append(prefix); 3064 sb.append(" Phone signal levels:"); 3065 didOne = false; 3066 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 3067 final long time = getPhoneSignalStrengthTime(i, rawRealtime, which); 3068 if (time == 0) { 3069 continue; 3070 } 3071 sb.append("\n "); 3072 sb.append(prefix); 3073 didOne = true; 3074 sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]); 3075 sb.append(" "); 3076 formatTimeMs(sb, time/1000); 3077 sb.append("("); 3078 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 3079 sb.append(") "); 3080 sb.append(getPhoneSignalStrengthCount(i, which)); 3081 sb.append("x"); 3082 } 3083 if (!didOne) sb.append(" (no activity)"); 3084 pw.println(sb.toString()); 3085 3086 sb.setLength(0); 3087 sb.append(prefix); 3088 sb.append(" Signal scanning time: "); 3089 formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000); 3090 pw.println(sb.toString()); 3091 3092 sb.setLength(0); 3093 sb.append(prefix); 3094 sb.append(" Radio types:"); 3095 didOne = false; 3096 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 3097 final long time = getPhoneDataConnectionTime(i, rawRealtime, which); 3098 if (time == 0) { 3099 continue; 3100 } 3101 sb.append("\n "); 3102 sb.append(prefix); 3103 didOne = true; 3104 sb.append(DATA_CONNECTION_NAMES[i]); 3105 sb.append(" "); 3106 formatTimeMs(sb, time/1000); 3107 sb.append("("); 3108 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 3109 sb.append(") "); 3110 sb.append(getPhoneDataConnectionCount(i, which)); 3111 sb.append("x"); 3112 } 3113 if (!didOne) sb.append(" (no activity)"); 3114 pw.println(sb.toString()); 3115 3116 sb.setLength(0); 3117 sb.append(prefix); 3118 sb.append(" Mobile radio active time: "); 3119 final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which); 3120 formatTimeMs(sb, mobileActiveTime / 1000); 3121 sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime)); 3122 sb.append(") "); sb.append(getMobileRadioActiveCount(which)); 3123 sb.append("x"); 3124 pw.println(sb.toString()); 3125 3126 final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which); 3127 if (mobileActiveUnknownTime != 0) { 3128 sb.setLength(0); 3129 sb.append(prefix); 3130 sb.append(" Mobile radio active unknown time: "); 3131 formatTimeMs(sb, mobileActiveUnknownTime / 1000); 3132 sb.append("("); 3133 sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime)); 3134 sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which)); 3135 sb.append("x"); 3136 pw.println(sb.toString()); 3137 } 3138 3139 final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which); 3140 if (mobileActiveAdjustedTime != 0) { 3141 sb.setLength(0); 3142 sb.append(prefix); 3143 sb.append(" Mobile radio active adjusted time: "); 3144 formatTimeMs(sb, mobileActiveAdjustedTime / 1000); 3145 sb.append("("); 3146 sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime)); 3147 sb.append(")"); 3148 pw.println(sb.toString()); 3149 } 3150 3151 pw.print(prefix); 3152 pw.print(" Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes)); 3153 pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes)); 3154 pw.print(" (packets received "); pw.print(wifiRxTotalPackets); 3155 pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")"); 3156 sb.setLength(0); 3157 sb.append(prefix); 3158 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000); 3159 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime)); 3160 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000); 3161 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime)); 3162 sb.append(")"); 3163 pw.println(sb.toString()); 3164 3165 sb.setLength(0); 3166 sb.append(prefix); 3167 sb.append(" Wifi states:"); 3168 didOne = false; 3169 for (int i=0; i<NUM_WIFI_STATES; i++) { 3170 final long time = getWifiStateTime(i, rawRealtime, which); 3171 if (time == 0) { 3172 continue; 3173 } 3174 sb.append("\n "); 3175 didOne = true; 3176 sb.append(WIFI_STATE_NAMES[i]); 3177 sb.append(" "); 3178 formatTimeMs(sb, time/1000); 3179 sb.append("("); 3180 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 3181 sb.append(") "); 3182 sb.append(getWifiStateCount(i, which)); 3183 sb.append("x"); 3184 } 3185 if (!didOne) sb.append(" (no activity)"); 3186 pw.println(sb.toString()); 3187 3188 sb.setLength(0); 3189 sb.append(prefix); 3190 sb.append(" Wifi supplicant states:"); 3191 didOne = false; 3192 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 3193 final long time = getWifiSupplStateTime(i, rawRealtime, which); 3194 if (time == 0) { 3195 continue; 3196 } 3197 sb.append("\n "); 3198 didOne = true; 3199 sb.append(WIFI_SUPPL_STATE_NAMES[i]); 3200 sb.append(" "); 3201 formatTimeMs(sb, time/1000); 3202 sb.append("("); 3203 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 3204 sb.append(") "); 3205 sb.append(getWifiSupplStateCount(i, which)); 3206 sb.append("x"); 3207 } 3208 if (!didOne) sb.append(" (no activity)"); 3209 pw.println(sb.toString()); 3210 3211 sb.setLength(0); 3212 sb.append(prefix); 3213 sb.append(" Wifi signal levels:"); 3214 didOne = false; 3215 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 3216 final long time = getWifiSignalStrengthTime(i, rawRealtime, which); 3217 if (time == 0) { 3218 continue; 3219 } 3220 sb.append("\n "); 3221 sb.append(prefix); 3222 didOne = true; 3223 sb.append("level("); 3224 sb.append(i); 3225 sb.append(") "); 3226 formatTimeMs(sb, time/1000); 3227 sb.append("("); 3228 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 3229 sb.append(") "); 3230 sb.append(getWifiSignalStrengthCount(i, which)); 3231 sb.append("x"); 3232 } 3233 if (!didOne) sb.append(" (no activity)"); 3234 pw.println(sb.toString()); 3235 3236 final long wifiIdleTimeMs = getWifiControllerActivity(CONTROLLER_IDLE_TIME, which); 3237 final long wifiRxTimeMs = getWifiControllerActivity(CONTROLLER_RX_TIME, which); 3238 final long wifiTxTimeMs = getWifiControllerActivity(CONTROLLER_TX_TIME, which); 3239 final long wifiTotalTimeMs = wifiIdleTimeMs + wifiRxTimeMs + wifiTxTimeMs; 3240 3241 sb.setLength(0); 3242 sb.append(prefix); 3243 sb.append(" WiFi Idle time: "); formatTimeMs(sb, wifiIdleTimeMs); 3244 sb.append(" ("); 3245 sb.append(formatRatioLocked(wifiIdleTimeMs, wifiTotalTimeMs)); 3246 sb.append(")"); 3247 pw.println(sb.toString()); 3248 3249 sb.setLength(0); 3250 sb.append(prefix); 3251 sb.append(" WiFi Rx time: "); formatTimeMs(sb, wifiRxTimeMs); 3252 sb.append(" ("); 3253 sb.append(formatRatioLocked(wifiRxTimeMs, wifiTotalTimeMs)); 3254 sb.append(")"); 3255 pw.println(sb.toString()); 3256 3257 sb.setLength(0); 3258 sb.append(prefix); 3259 sb.append(" WiFi Tx time: "); formatTimeMs(sb, wifiTxTimeMs); 3260 sb.append(" ("); 3261 sb.append(formatRatioLocked(wifiTxTimeMs, wifiTotalTimeMs)); 3262 sb.append(")"); 3263 pw.println(sb.toString()); 3264 3265 sb.setLength(0); 3266 sb.append(prefix); 3267 sb.append(" Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000); 3268 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime)); 3269 sb.append(")"); 3270 pw.println(sb.toString()); 3271 3272 sb.setLength(0); 3273 sb.append(prefix); 3274 sb.append(" Bluetooth states:"); 3275 didOne = false; 3276 for (int i=0; i<NUM_BLUETOOTH_STATES; i++) { 3277 final long time = getBluetoothStateTime(i, rawRealtime, which); 3278 if (time == 0) { 3279 continue; 3280 } 3281 sb.append("\n "); 3282 didOne = true; 3283 sb.append(BLUETOOTH_STATE_NAMES[i]); 3284 sb.append(" "); 3285 formatTimeMs(sb, time/1000); 3286 sb.append("("); 3287 sb.append(formatRatioLocked(time, whichBatteryRealtime)); 3288 sb.append(") "); 3289 sb.append(getPhoneDataConnectionCount(i, which)); 3290 sb.append("x"); 3291 } 3292 3293 if (!didOne) sb.append(" (no activity)"); 3294 pw.println(sb.toString()); 3295 3296 final long bluetoothIdleTimeMs = 3297 getBluetoothControllerActivity(CONTROLLER_IDLE_TIME, which); 3298 final long bluetoothRxTimeMs = getBluetoothControllerActivity(CONTROLLER_RX_TIME, which); 3299 final long bluetoothTxTimeMs = getBluetoothControllerActivity(CONTROLLER_TX_TIME, which); 3300 final long bluetoothTotalTimeMs = bluetoothIdleTimeMs + bluetoothRxTimeMs + 3301 bluetoothTxTimeMs; 3302 3303 sb.setLength(0); 3304 sb.append(prefix); 3305 sb.append(" Bluetooth Idle time: "); formatTimeMs(sb, bluetoothIdleTimeMs); 3306 sb.append(" ("); 3307 sb.append(formatRatioLocked(bluetoothIdleTimeMs, bluetoothTotalTimeMs)); 3308 sb.append(")"); 3309 pw.println(sb.toString()); 3310 3311 sb.setLength(0); 3312 sb.append(prefix); 3313 sb.append(" Bluetooth Rx time: "); formatTimeMs(sb, bluetoothRxTimeMs); 3314 sb.append(" ("); 3315 sb.append(formatRatioLocked(bluetoothRxTimeMs, bluetoothTotalTimeMs)); 3316 sb.append(")"); 3317 pw.println(sb.toString()); 3318 3319 sb.setLength(0); 3320 sb.append(prefix); 3321 sb.append(" Bluetooth Tx time: "); formatTimeMs(sb, bluetoothTxTimeMs); 3322 sb.append(" ("); 3323 sb.append(formatRatioLocked(bluetoothTxTimeMs, bluetoothTotalTimeMs)); 3324 sb.append(")"); 3325 pw.println(sb.toString()); 3326 3327 pw.println(); 3328 3329 if (which == STATS_SINCE_UNPLUGGED) { 3330 if (getIsOnBattery()) { 3331 pw.print(prefix); pw.println(" Device is currently unplugged"); 3332 pw.print(prefix); pw.print(" Discharge cycle start level: "); 3333 pw.println(getDischargeStartLevel()); 3334 pw.print(prefix); pw.print(" Discharge cycle current level: "); 3335 pw.println(getDischargeCurrentLevel()); 3336 } else { 3337 pw.print(prefix); pw.println(" Device is currently plugged into power"); 3338 pw.print(prefix); pw.print(" Last discharge cycle start level: "); 3339 pw.println(getDischargeStartLevel()); 3340 pw.print(prefix); pw.print(" Last discharge cycle end level: "); 3341 pw.println(getDischargeCurrentLevel()); 3342 } 3343 pw.print(prefix); pw.print(" Amount discharged while screen on: "); 3344 pw.println(getDischargeAmountScreenOn()); 3345 pw.print(prefix); pw.print(" Amount discharged while screen off: "); 3346 pw.println(getDischargeAmountScreenOff()); 3347 pw.println(" "); 3348 } else { 3349 pw.print(prefix); pw.println(" Device battery use since last full charge"); 3350 pw.print(prefix); pw.print(" Amount discharged (lower bound): "); 3351 pw.println(getLowDischargeAmountSinceCharge()); 3352 pw.print(prefix); pw.print(" Amount discharged (upper bound): "); 3353 pw.println(getHighDischargeAmountSinceCharge()); 3354 pw.print(prefix); pw.print(" Amount discharged while screen on: "); 3355 pw.println(getDischargeAmountScreenOnSinceCharge()); 3356 pw.print(prefix); pw.print(" Amount discharged while screen off: "); 3357 pw.println(getDischargeAmountScreenOffSinceCharge()); 3358 pw.println(); 3359 } 3360 3361 final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly); 3362 helper.create(this); 3363 helper.refreshStats(which, UserHandle.USER_ALL); 3364 List<BatterySipper> sippers = helper.getUsageList(); 3365 if (sippers != null && sippers.size() > 0) { 3366 pw.print(prefix); pw.println(" Estimated power use (mAh):"); 3367 pw.print(prefix); pw.print(" Capacity: "); 3368 printmAh(pw, helper.getPowerProfile().getBatteryCapacity()); 3369 pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower()); 3370 pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower()); 3371 if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) { 3372 pw.print("-"); printmAh(pw, helper.getMaxDrainedPower()); 3373 } 3374 pw.println(); 3375 for (int i=0; i<sippers.size(); i++) { 3376 final BatterySipper bs = sippers.get(i); 3377 switch (bs.drainType) { 3378 case IDLE: 3379 pw.print(prefix); pw.print(" Idle: "); printmAh(pw, bs.value); 3380 pw.println(); 3381 break; 3382 case CELL: 3383 pw.print(prefix); pw.print(" Cell standby: "); printmAh(pw, bs.value); 3384 pw.println(); 3385 break; 3386 case PHONE: 3387 pw.print(prefix); pw.print(" Phone calls: "); printmAh(pw, bs.value); 3388 pw.println(); 3389 break; 3390 case WIFI: 3391 pw.print(prefix); pw.print(" Wifi: "); printmAh(pw, bs.value); 3392 pw.println(); 3393 break; 3394 case BLUETOOTH: 3395 pw.print(prefix); pw.print(" Bluetooth: "); printmAh(pw, bs.value); 3396 pw.println(); 3397 break; 3398 case SCREEN: 3399 pw.print(prefix); pw.print(" Screen: "); printmAh(pw, bs.value); 3400 pw.println(); 3401 break; 3402 case FLASHLIGHT: 3403 pw.print(prefix); pw.print(" Flashlight: "); printmAh(pw, bs.value); 3404 pw.println(); 3405 break; 3406 case APP: 3407 pw.print(prefix); pw.print(" Uid "); 3408 UserHandle.formatUid(pw, bs.uidObj.getUid()); 3409 pw.print(": "); printmAh(pw, bs.value); pw.println(); 3410 break; 3411 case USER: 3412 pw.print(prefix); pw.print(" User "); pw.print(bs.userId); 3413 pw.print(": "); printmAh(pw, bs.value); pw.println(); 3414 break; 3415 case UNACCOUNTED: 3416 pw.print(prefix); pw.print(" Unaccounted: "); printmAh(pw, bs.value); 3417 pw.println(); 3418 break; 3419 case OVERCOUNTED: 3420 pw.print(prefix); pw.print(" Over-counted: "); printmAh(pw, bs.value); 3421 pw.println(); 3422 break; 3423 } 3424 } 3425 pw.println(); 3426 } 3427 3428 sippers = helper.getMobilemsppList(); 3429 if (sippers != null && sippers.size() > 0) { 3430 pw.print(prefix); pw.println(" Per-app mobile ms per packet:"); 3431 long totalTime = 0; 3432 for (int i=0; i<sippers.size(); i++) { 3433 final BatterySipper bs = sippers.get(i); 3434 sb.setLength(0); 3435 sb.append(prefix); sb.append(" Uid "); 3436 UserHandle.formatUid(sb, bs.uidObj.getUid()); 3437 sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp)); 3438 sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets); 3439 sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive); 3440 sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x"); 3441 pw.println(sb.toString()); 3442 totalTime += bs.mobileActive; 3443 } 3444 sb.setLength(0); 3445 sb.append(prefix); 3446 sb.append(" TOTAL TIME: "); 3447 formatTimeMs(sb, totalTime); 3448 sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime)); 3449 sb.append(")"); 3450 pw.println(sb.toString()); 3451 pw.println(); 3452 } 3453 3454 final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() { 3455 @Override 3456 public int compare(TimerEntry lhs, TimerEntry rhs) { 3457 long lhsTime = lhs.mTime; 3458 long rhsTime = rhs.mTime; 3459 if (lhsTime < rhsTime) { 3460 return 1; 3461 } 3462 if (lhsTime > rhsTime) { 3463 return -1; 3464 } 3465 return 0; 3466 } 3467 }; 3468 3469 if (reqUid < 0) { 3470 final Map<String, ? extends BatteryStats.Timer> kernelWakelocks 3471 = getKernelWakelockStats(); 3472 if (kernelWakelocks.size() > 0) { 3473 final ArrayList<TimerEntry> ktimers = new ArrayList<>(); 3474 for (Map.Entry<String, ? extends BatteryStats.Timer> ent 3475 : kernelWakelocks.entrySet()) { 3476 final BatteryStats.Timer timer = ent.getValue(); 3477 final long totalTimeMillis = computeWakeLock(timer, rawRealtime, which); 3478 if (totalTimeMillis > 0) { 3479 ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis)); 3480 } 3481 } 3482 if (ktimers.size() > 0) { 3483 Collections.sort(ktimers, timerComparator); 3484 pw.print(prefix); pw.println(" All kernel wake locks:"); 3485 for (int i=0; i<ktimers.size(); i++) { 3486 final TimerEntry timer = ktimers.get(i); 3487 String linePrefix = ": "; 3488 sb.setLength(0); 3489 sb.append(prefix); 3490 sb.append(" Kernel Wake lock "); 3491 sb.append(timer.mName); 3492 linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null, 3493 which, linePrefix); 3494 if (!linePrefix.equals(": ")) { 3495 sb.append(" realtime"); 3496 // Only print out wake locks that were held 3497 pw.println(sb.toString()); 3498 } 3499 } 3500 pw.println(); 3501 } 3502 } 3503 3504 if (timers.size() > 0) { 3505 Collections.sort(timers, timerComparator); 3506 pw.print(prefix); pw.println(" All partial wake locks:"); 3507 for (int i=0; i<timers.size(); i++) { 3508 TimerEntry timer = timers.get(i); 3509 sb.setLength(0); 3510 sb.append(" Wake lock "); 3511 UserHandle.formatUid(sb, timer.mId); 3512 sb.append(" "); 3513 sb.append(timer.mName); 3514 printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": "); 3515 sb.append(" realtime"); 3516 pw.println(sb.toString()); 3517 } 3518 timers.clear(); 3519 pw.println(); 3520 } 3521 3522 final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats(); 3523 if (wakeupReasons.size() > 0) { 3524 pw.print(prefix); pw.println(" All wakeup reasons:"); 3525 final ArrayList<TimerEntry> reasons = new ArrayList<>(); 3526 for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) { 3527 final Timer timer = ent.getValue(); 3528 reasons.add(new TimerEntry(ent.getKey(), 0, timer, 3529 timer.getCountLocked(which))); 3530 } 3531 Collections.sort(reasons, timerComparator); 3532 for (int i=0; i<reasons.size(); i++) { 3533 TimerEntry timer = reasons.get(i); 3534 String linePrefix = ": "; 3535 sb.setLength(0); 3536 sb.append(prefix); 3537 sb.append(" Wakeup reason "); 3538 sb.append(timer.mName); 3539 printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": "); 3540 sb.append(" realtime"); 3541 pw.println(sb.toString()); 3542 } 3543 pw.println(); 3544 } 3545 } 3546 3547 for (int iu=0; iu<NU; iu++) { 3548 final int uid = uidStats.keyAt(iu); 3549 if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) { 3550 continue; 3551 } 3552 3553 final Uid u = uidStats.valueAt(iu); 3554 3555 pw.print(prefix); 3556 pw.print(" "); 3557 UserHandle.formatUid(pw, uid); 3558 pw.println(":"); 3559 boolean uidActivity = false; 3560 3561 final long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which); 3562 final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which); 3563 final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which); 3564 final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which); 3565 final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which); 3566 final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which); 3567 final long uidMobileActiveTime = u.getMobileRadioActiveTime(which); 3568 final int uidMobileActiveCount = u.getMobileRadioActiveCount(which); 3569 final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which); 3570 final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which); 3571 final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which); 3572 final long wifiScanTime = u.getWifiScanTime(rawRealtime, which); 3573 final int wifiScanCount = u.getWifiScanCount(which); 3574 final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which); 3575 3576 if (mobileRxBytes > 0 || mobileTxBytes > 0 3577 || mobileRxPackets > 0 || mobileTxPackets > 0) { 3578 pw.print(prefix); pw.print(" Mobile network: "); 3579 pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, "); 3580 pw.print(formatBytesLocked(mobileTxBytes)); 3581 pw.print(" sent (packets "); pw.print(mobileRxPackets); 3582 pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)"); 3583 } 3584 if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) { 3585 sb.setLength(0); 3586 sb.append(prefix); sb.append(" Mobile radio active: "); 3587 formatTimeMs(sb, uidMobileActiveTime / 1000); 3588 sb.append("("); 3589 sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime)); 3590 sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x"); 3591 long packets = mobileRxPackets + mobileTxPackets; 3592 if (packets == 0) { 3593 packets = 1; 3594 } 3595 sb.append(" @ "); 3596 sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets)); 3597 sb.append(" mspp"); 3598 pw.println(sb.toString()); 3599 } 3600 3601 if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) { 3602 pw.print(prefix); pw.print(" Wi-Fi network: "); 3603 pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, "); 3604 pw.print(formatBytesLocked(wifiTxBytes)); 3605 pw.print(" sent (packets "); pw.print(wifiRxPackets); 3606 pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)"); 3607 } 3608 3609 if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0 3610 || uidWifiRunningTime != 0) { 3611 sb.setLength(0); 3612 sb.append(prefix); sb.append(" Wifi Running: "); 3613 formatTimeMs(sb, uidWifiRunningTime / 1000); 3614 sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime, 3615 whichBatteryRealtime)); sb.append(")\n"); 3616 sb.append(prefix); sb.append(" Full Wifi Lock: "); 3617 formatTimeMs(sb, fullWifiLockOnTime / 1000); 3618 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime, 3619 whichBatteryRealtime)); sb.append(")\n"); 3620 sb.append(prefix); sb.append(" Wifi Scan: "); 3621 formatTimeMs(sb, wifiScanTime / 1000); 3622 sb.append("("); sb.append(formatRatioLocked(wifiScanTime, 3623 whichBatteryRealtime)); sb.append(") "); 3624 sb.append(wifiScanCount); 3625 sb.append("x"); 3626 pw.println(sb.toString()); 3627 } 3628 3629 if (u.hasUserActivity()) { 3630 boolean hasData = false; 3631 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 3632 final int val = u.getUserActivityCount(i, which); 3633 if (val != 0) { 3634 if (!hasData) { 3635 sb.setLength(0); 3636 sb.append(" User activity: "); 3637 hasData = true; 3638 } else { 3639 sb.append(", "); 3640 } 3641 sb.append(val); 3642 sb.append(" "); 3643 sb.append(Uid.USER_ACTIVITY_TYPES[i]); 3644 } 3645 } 3646 if (hasData) { 3647 pw.println(sb.toString()); 3648 } 3649 } 3650 3651 final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks 3652 = u.getWakelockStats(); 3653 long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0; 3654 int countWakelock = 0; 3655 for (int iw=wakelocks.size()-1; iw>=0; iw--) { 3656 final Uid.Wakelock wl = wakelocks.valueAt(iw); 3657 String linePrefix = ": "; 3658 sb.setLength(0); 3659 sb.append(prefix); 3660 sb.append(" Wake lock "); 3661 sb.append(wakelocks.keyAt(iw)); 3662 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, 3663 "full", which, linePrefix); 3664 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime, 3665 "partial", which, linePrefix); 3666 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, 3667 "window", which, linePrefix); 3668 if (true || !linePrefix.equals(": ")) { 3669 sb.append(" realtime"); 3670 // Only print out wake locks that were held 3671 pw.println(sb.toString()); 3672 uidActivity = true; 3673 countWakelock++; 3674 } 3675 totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL), 3676 rawRealtime, which); 3677 totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL), 3678 rawRealtime, which); 3679 totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW), 3680 rawRealtime, which); 3681 } 3682 if (countWakelock > 1) { 3683 if (totalFullWakelock != 0 || totalPartialWakelock != 0 3684 || totalWindowWakelock != 0) { 3685 sb.setLength(0); 3686 sb.append(prefix); 3687 sb.append(" TOTAL wake: "); 3688 boolean needComma = false; 3689 if (totalFullWakelock != 0) { 3690 needComma = true; 3691 formatTimeMs(sb, totalFullWakelock); 3692 sb.append("full"); 3693 } 3694 if (totalPartialWakelock != 0) { 3695 if (needComma) { 3696 sb.append(", "); 3697 } 3698 needComma = true; 3699 formatTimeMs(sb, totalPartialWakelock); 3700 sb.append("partial"); 3701 } 3702 if (totalWindowWakelock != 0) { 3703 if (needComma) { 3704 sb.append(", "); 3705 } 3706 needComma = true; 3707 formatTimeMs(sb, totalWindowWakelock); 3708 sb.append("window"); 3709 } 3710 sb.append(" realtime"); 3711 pw.println(sb.toString()); 3712 } 3713 } 3714 3715 final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats(); 3716 for (int isy=syncs.size()-1; isy>=0; isy--) { 3717 final Timer timer = syncs.valueAt(isy); 3718 // Convert from microseconds to milliseconds with rounding 3719 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; 3720 final int count = timer.getCountLocked(which); 3721 sb.setLength(0); 3722 sb.append(prefix); 3723 sb.append(" Sync "); 3724 sb.append(syncs.keyAt(isy)); 3725 sb.append(": "); 3726 if (totalTime != 0) { 3727 formatTimeMs(sb, totalTime); 3728 sb.append("realtime ("); 3729 sb.append(count); 3730 sb.append(" times)"); 3731 } else { 3732 sb.append("(not used)"); 3733 } 3734 pw.println(sb.toString()); 3735 uidActivity = true; 3736 } 3737 3738 final ArrayMap<String, ? extends Timer> jobs = u.getJobStats(); 3739 for (int ij=jobs.size()-1; ij>=0; ij--) { 3740 final Timer timer = jobs.valueAt(ij); 3741 // Convert from microseconds to milliseconds with rounding 3742 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; 3743 final int count = timer.getCountLocked(which); 3744 sb.setLength(0); 3745 sb.append(prefix); 3746 sb.append(" Job "); 3747 sb.append(jobs.keyAt(ij)); 3748 sb.append(": "); 3749 if (totalTime != 0) { 3750 formatTimeMs(sb, totalTime); 3751 sb.append("realtime ("); 3752 sb.append(count); 3753 sb.append(" times)"); 3754 } else { 3755 sb.append("(not used)"); 3756 } 3757 pw.println(sb.toString()); 3758 uidActivity = true; 3759 } 3760 3761 final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); 3762 final int NSE = sensors.size(); 3763 for (int ise=0; ise<NSE; ise++) { 3764 final Uid.Sensor se = sensors.valueAt(ise); 3765 final int sensorNumber = sensors.keyAt(ise); 3766 sb.setLength(0); 3767 sb.append(prefix); 3768 sb.append(" Sensor "); 3769 int handle = se.getHandle(); 3770 if (handle == Uid.Sensor.GPS) { 3771 sb.append("GPS"); 3772 } else { 3773 sb.append(handle); 3774 } 3775 sb.append(": "); 3776 3777 final Timer timer = se.getSensorTime(); 3778 if (timer != null) { 3779 // Convert from microseconds to milliseconds with rounding 3780 final long totalTime = (timer.getTotalTimeLocked( 3781 rawRealtime, which) + 500) / 1000; 3782 final int count = timer.getCountLocked(which); 3783 //timer.logState(); 3784 if (totalTime != 0) { 3785 formatTimeMs(sb, totalTime); 3786 sb.append("realtime ("); 3787 sb.append(count); 3788 sb.append(" times)"); 3789 } else { 3790 sb.append("(not used)"); 3791 } 3792 } else { 3793 sb.append("(not used)"); 3794 } 3795 3796 pw.println(sb.toString()); 3797 uidActivity = true; 3798 } 3799 3800 final Timer vibTimer = u.getVibratorOnTimer(); 3801 if (vibTimer != null) { 3802 // Convert from microseconds to milliseconds with rounding 3803 final long totalTime = (vibTimer.getTotalTimeLocked( 3804 rawRealtime, which) + 500) / 1000; 3805 final int count = vibTimer.getCountLocked(which); 3806 //timer.logState(); 3807 if (totalTime != 0) { 3808 sb.setLength(0); 3809 sb.append(prefix); 3810 sb.append(" Vibrator: "); 3811 formatTimeMs(sb, totalTime); 3812 sb.append("realtime ("); 3813 sb.append(count); 3814 sb.append(" times)"); 3815 pw.println(sb.toString()); 3816 uidActivity = true; 3817 } 3818 } 3819 3820 final Timer fgTimer = u.getForegroundActivityTimer(); 3821 if (fgTimer != null) { 3822 // Convert from microseconds to milliseconds with rounding 3823 final long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) 3824 / 1000; 3825 final int count = fgTimer.getCountLocked(which); 3826 if (totalTime != 0) { 3827 sb.setLength(0); 3828 sb.append(prefix); 3829 sb.append(" Foreground activities: "); 3830 formatTimeMs(sb, totalTime); 3831 sb.append("realtime ("); 3832 sb.append(count); 3833 sb.append(" times)"); 3834 pw.println(sb.toString()); 3835 uidActivity = true; 3836 } 3837 } 3838 3839 long totalStateTime = 0; 3840 for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) { 3841 long time = u.getProcessStateTime(ips, rawRealtime, which); 3842 if (time > 0) { 3843 totalStateTime += time; 3844 sb.setLength(0); 3845 sb.append(prefix); 3846 sb.append(" "); 3847 sb.append(Uid.PROCESS_STATE_NAMES[ips]); 3848 sb.append(" for: "); 3849 formatTimeMs(sb, (totalStateTime + 500) / 1000); 3850 pw.println(sb.toString()); 3851 uidActivity = true; 3852 } 3853 } 3854 3855 final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats 3856 = u.getProcessStats(); 3857 for (int ipr=processStats.size()-1; ipr>=0; ipr--) { 3858 final Uid.Proc ps = processStats.valueAt(ipr); 3859 long userTime; 3860 long systemTime; 3861 long foregroundTime; 3862 int starts; 3863 int numExcessive; 3864 3865 userTime = ps.getUserTime(which); 3866 systemTime = ps.getSystemTime(which); 3867 foregroundTime = ps.getForegroundTime(which); 3868 starts = ps.getStarts(which); 3869 final int numCrashes = ps.getNumCrashes(which); 3870 final int numAnrs = ps.getNumAnrs(which); 3871 numExcessive = which == STATS_SINCE_CHARGED 3872 ? ps.countExcessivePowers() : 0; 3873 3874 if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0 3875 || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) { 3876 sb.setLength(0); 3877 sb.append(prefix); sb.append(" Proc "); 3878 sb.append(processStats.keyAt(ipr)); sb.append(":\n"); 3879 sb.append(prefix); sb.append(" CPU: "); 3880 formatTimeMs(sb, userTime); sb.append("usr + "); 3881 formatTimeMs(sb, systemTime); sb.append("krn ; "); 3882 formatTimeMs(sb, foregroundTime); sb.append("fg"); 3883 if (starts != 0 || numCrashes != 0 || numAnrs != 0) { 3884 sb.append("\n"); sb.append(prefix); sb.append(" "); 3885 boolean hasOne = false; 3886 if (starts != 0) { 3887 hasOne = true; 3888 sb.append(starts); sb.append(" starts"); 3889 } 3890 if (numCrashes != 0) { 3891 if (hasOne) { 3892 sb.append(", "); 3893 } 3894 hasOne = true; 3895 sb.append(numCrashes); sb.append(" crashes"); 3896 } 3897 if (numAnrs != 0) { 3898 if (hasOne) { 3899 sb.append(", "); 3900 } 3901 sb.append(numAnrs); sb.append(" anrs"); 3902 } 3903 } 3904 pw.println(sb.toString()); 3905 for (int e=0; e<numExcessive; e++) { 3906 Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e); 3907 if (ew != null) { 3908 pw.print(prefix); pw.print(" * Killed for "); 3909 if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) { 3910 pw.print("wake lock"); 3911 } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) { 3912 pw.print("cpu"); 3913 } else { 3914 pw.print("unknown"); 3915 } 3916 pw.print(" use: "); 3917 TimeUtils.formatDuration(ew.usedTime, pw); 3918 pw.print(" over "); 3919 TimeUtils.formatDuration(ew.overTime, pw); 3920 if (ew.overTime != 0) { 3921 pw.print(" ("); 3922 pw.print((ew.usedTime*100)/ew.overTime); 3923 pw.println("%)"); 3924 } 3925 } 3926 } 3927 uidActivity = true; 3928 } 3929 } 3930 3931 final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats 3932 = u.getPackageStats(); 3933 for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) { 3934 pw.print(prefix); pw.print(" Apk "); pw.print(packageStats.keyAt(ipkg)); 3935 pw.println(":"); 3936 boolean apkActivity = false; 3937 final Uid.Pkg ps = packageStats.valueAt(ipkg); 3938 final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats(); 3939 for (int iwa=alarms.size()-1; iwa>=0; iwa--) { 3940 pw.print(prefix); pw.print(" Wakeup alarm "); 3941 pw.print(alarms.keyAt(iwa)); pw.print(": "); 3942 pw.print(alarms.valueAt(iwa).getCountLocked(which)); 3943 pw.println(" times"); 3944 apkActivity = true; 3945 } 3946 final ArrayMap<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats(); 3947 for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) { 3948 final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc); 3949 final long startTime = ss.getStartTime(batteryUptime, which); 3950 final int starts = ss.getStarts(which); 3951 final int launches = ss.getLaunches(which); 3952 if (startTime != 0 || starts != 0 || launches != 0) { 3953 sb.setLength(0); 3954 sb.append(prefix); sb.append(" Service "); 3955 sb.append(serviceStats.keyAt(isvc)); sb.append(":\n"); 3956 sb.append(prefix); sb.append(" Created for: "); 3957 formatTimeMs(sb, startTime / 1000); 3958 sb.append("uptime\n"); 3959 sb.append(prefix); sb.append(" Starts: "); 3960 sb.append(starts); 3961 sb.append(", launches: "); sb.append(launches); 3962 pw.println(sb.toString()); 3963 apkActivity = true; 3964 } 3965 } 3966 if (!apkActivity) { 3967 pw.print(prefix); pw.println(" (nothing executed)"); 3968 } 3969 uidActivity = true; 3970 } 3971 if (!uidActivity) { 3972 pw.print(prefix); pw.println(" (nothing executed)"); 3973 } 3974 } 3975 } 3976 3977 static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag, 3978 BitDescription[] descriptions, boolean longNames) { 3979 int diff = oldval ^ newval; 3980 if (diff == 0) return; 3981 boolean didWake = false; 3982 for (int i=0; i<descriptions.length; i++) { 3983 BitDescription bd = descriptions[i]; 3984 if ((diff&bd.mask) != 0) { 3985 pw.print(longNames ? " " : ","); 3986 if (bd.shift < 0) { 3987 pw.print((newval&bd.mask) != 0 ? "+" : "-"); 3988 pw.print(longNames ? bd.name : bd.shortName); 3989 if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) { 3990 didWake = true; 3991 pw.print("="); 3992 if (longNames) { 3993 UserHandle.formatUid(pw, wakelockTag.uid); 3994 pw.print(":\""); 3995 pw.print(wakelockTag.string); 3996 pw.print("\""); 3997 } else { 3998 pw.print(wakelockTag.poolIdx); 3999 } 4000 } 4001 } else { 4002 pw.print(longNames ? bd.name : bd.shortName); 4003 pw.print("="); 4004 int val = (newval&bd.mask)>>bd.shift; 4005 if (bd.values != null && val >= 0 && val < bd.values.length) { 4006 pw.print(longNames? bd.values[val] : bd.shortValues[val]); 4007 } else { 4008 pw.print(val); 4009 } 4010 } 4011 } 4012 } 4013 if (!didWake && wakelockTag != null) { 4014 pw.print(longNames ? " wake_lock=" : ",w="); 4015 if (longNames) { 4016 UserHandle.formatUid(pw, wakelockTag.uid); 4017 pw.print(":\""); 4018 pw.print(wakelockTag.string); 4019 pw.print("\""); 4020 } else { 4021 pw.print(wakelockTag.poolIdx); 4022 } 4023 } 4024 } 4025 4026 public void prepareForDumpLocked() { 4027 } 4028 4029 public static class HistoryPrinter { 4030 int oldState = 0; 4031 int oldState2 = 0; 4032 int oldLevel = -1; 4033 int oldStatus = -1; 4034 int oldHealth = -1; 4035 int oldPlug = -1; 4036 int oldTemp = -1; 4037 int oldVolt = -1; 4038 long lastTime = -1; 4039 4040 void reset() { 4041 oldState = oldState2 = 0; 4042 oldLevel = -1; 4043 oldStatus = -1; 4044 oldHealth = -1; 4045 oldPlug = -1; 4046 oldTemp = -1; 4047 oldVolt = -1; 4048 } 4049 4050 public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin, 4051 boolean verbose) { 4052 if (!checkin) { 4053 pw.print(" "); 4054 TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN); 4055 pw.print(" ("); 4056 pw.print(rec.numReadInts); 4057 pw.print(") "); 4058 } else { 4059 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 4060 pw.print(HISTORY_DATA); pw.print(','); 4061 if (lastTime < 0) { 4062 pw.print(rec.time - baseTime); 4063 } else { 4064 pw.print(rec.time - lastTime); 4065 } 4066 lastTime = rec.time; 4067 } 4068 if (rec.cmd == HistoryItem.CMD_START) { 4069 if (checkin) { 4070 pw.print(":"); 4071 } 4072 pw.println("START"); 4073 reset(); 4074 } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME 4075 || rec.cmd == HistoryItem.CMD_RESET) { 4076 if (checkin) { 4077 pw.print(":"); 4078 } 4079 if (rec.cmd == HistoryItem.CMD_RESET) { 4080 pw.print("RESET:"); 4081 reset(); 4082 } 4083 pw.print("TIME:"); 4084 if (checkin) { 4085 pw.println(rec.currentTime); 4086 } else { 4087 pw.print(" "); 4088 pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", 4089 rec.currentTime).toString()); 4090 } 4091 } else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) { 4092 if (checkin) { 4093 pw.print(":"); 4094 } 4095 pw.println("SHUTDOWN"); 4096 } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) { 4097 if (checkin) { 4098 pw.print(":"); 4099 } 4100 pw.println("*OVERFLOW*"); 4101 } else { 4102 if (!checkin) { 4103 if (rec.batteryLevel < 10) pw.print("00"); 4104 else if (rec.batteryLevel < 100) pw.print("0"); 4105 pw.print(rec.batteryLevel); 4106 if (verbose) { 4107 pw.print(" "); 4108 if (rec.states < 0) ; 4109 else if (rec.states < 0x10) pw.print("0000000"); 4110 else if (rec.states < 0x100) pw.print("000000"); 4111 else if (rec.states < 0x1000) pw.print("00000"); 4112 else if (rec.states < 0x10000) pw.print("0000"); 4113 else if (rec.states < 0x100000) pw.print("000"); 4114 else if (rec.states < 0x1000000) pw.print("00"); 4115 else if (rec.states < 0x10000000) pw.print("0"); 4116 pw.print(Integer.toHexString(rec.states)); 4117 } 4118 } else { 4119 if (oldLevel != rec.batteryLevel) { 4120 oldLevel = rec.batteryLevel; 4121 pw.print(",Bl="); pw.print(rec.batteryLevel); 4122 } 4123 } 4124 if (oldStatus != rec.batteryStatus) { 4125 oldStatus = rec.batteryStatus; 4126 pw.print(checkin ? ",Bs=" : " status="); 4127 switch (oldStatus) { 4128 case BatteryManager.BATTERY_STATUS_UNKNOWN: 4129 pw.print(checkin ? "?" : "unknown"); 4130 break; 4131 case BatteryManager.BATTERY_STATUS_CHARGING: 4132 pw.print(checkin ? "c" : "charging"); 4133 break; 4134 case BatteryManager.BATTERY_STATUS_DISCHARGING: 4135 pw.print(checkin ? "d" : "discharging"); 4136 break; 4137 case BatteryManager.BATTERY_STATUS_NOT_CHARGING: 4138 pw.print(checkin ? "n" : "not-charging"); 4139 break; 4140 case BatteryManager.BATTERY_STATUS_FULL: 4141 pw.print(checkin ? "f" : "full"); 4142 break; 4143 default: 4144 pw.print(oldStatus); 4145 break; 4146 } 4147 } 4148 if (oldHealth != rec.batteryHealth) { 4149 oldHealth = rec.batteryHealth; 4150 pw.print(checkin ? ",Bh=" : " health="); 4151 switch (oldHealth) { 4152 case BatteryManager.BATTERY_HEALTH_UNKNOWN: 4153 pw.print(checkin ? "?" : "unknown"); 4154 break; 4155 case BatteryManager.BATTERY_HEALTH_GOOD: 4156 pw.print(checkin ? "g" : "good"); 4157 break; 4158 case BatteryManager.BATTERY_HEALTH_OVERHEAT: 4159 pw.print(checkin ? "h" : "overheat"); 4160 break; 4161 case BatteryManager.BATTERY_HEALTH_DEAD: 4162 pw.print(checkin ? "d" : "dead"); 4163 break; 4164 case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: 4165 pw.print(checkin ? "v" : "over-voltage"); 4166 break; 4167 case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: 4168 pw.print(checkin ? "f" : "failure"); 4169 break; 4170 case BatteryManager.BATTERY_HEALTH_COLD: 4171 pw.print(checkin ? "c" : "cold"); 4172 break; 4173 default: 4174 pw.print(oldHealth); 4175 break; 4176 } 4177 } 4178 if (oldPlug != rec.batteryPlugType) { 4179 oldPlug = rec.batteryPlugType; 4180 pw.print(checkin ? ",Bp=" : " plug="); 4181 switch (oldPlug) { 4182 case 0: 4183 pw.print(checkin ? "n" : "none"); 4184 break; 4185 case BatteryManager.BATTERY_PLUGGED_AC: 4186 pw.print(checkin ? "a" : "ac"); 4187 break; 4188 case BatteryManager.BATTERY_PLUGGED_USB: 4189 pw.print(checkin ? "u" : "usb"); 4190 break; 4191 case BatteryManager.BATTERY_PLUGGED_WIRELESS: 4192 pw.print(checkin ? "w" : "wireless"); 4193 break; 4194 default: 4195 pw.print(oldPlug); 4196 break; 4197 } 4198 } 4199 if (oldTemp != rec.batteryTemperature) { 4200 oldTemp = rec.batteryTemperature; 4201 pw.print(checkin ? ",Bt=" : " temp="); 4202 pw.print(oldTemp); 4203 } 4204 if (oldVolt != rec.batteryVoltage) { 4205 oldVolt = rec.batteryVoltage; 4206 pw.print(checkin ? ",Bv=" : " volt="); 4207 pw.print(oldVolt); 4208 } 4209 printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag, 4210 HISTORY_STATE_DESCRIPTIONS, !checkin); 4211 printBitDescriptions(pw, oldState2, rec.states2, null, 4212 HISTORY_STATE2_DESCRIPTIONS, !checkin); 4213 if (rec.wakeReasonTag != null) { 4214 if (checkin) { 4215 pw.print(",wr="); 4216 pw.print(rec.wakeReasonTag.poolIdx); 4217 } else { 4218 pw.print(" wake_reason="); 4219 pw.print(rec.wakeReasonTag.uid); 4220 pw.print(":\""); 4221 pw.print(rec.wakeReasonTag.string); 4222 pw.print("\""); 4223 } 4224 } 4225 if (rec.eventCode != HistoryItem.EVENT_NONE) { 4226 pw.print(checkin ? "," : " "); 4227 if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) { 4228 pw.print("+"); 4229 } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) { 4230 pw.print("-"); 4231 } 4232 String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES 4233 : HISTORY_EVENT_NAMES; 4234 int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START 4235 | HistoryItem.EVENT_FLAG_FINISH); 4236 if (idx >= 0 && idx < eventNames.length) { 4237 pw.print(eventNames[idx]); 4238 } else { 4239 pw.print(checkin ? "Ev" : "event"); 4240 pw.print(idx); 4241 } 4242 pw.print("="); 4243 if (checkin) { 4244 pw.print(rec.eventTag.poolIdx); 4245 } else { 4246 UserHandle.formatUid(pw, rec.eventTag.uid); 4247 pw.print(":\""); 4248 pw.print(rec.eventTag.string); 4249 pw.print("\""); 4250 } 4251 } 4252 pw.println(); 4253 if (rec.stepDetails != null) { 4254 if (!checkin) { 4255 pw.print(" Details: cpu="); 4256 pw.print(rec.stepDetails.userTime); 4257 pw.print("u+"); 4258 pw.print(rec.stepDetails.systemTime); 4259 pw.print("s"); 4260 if (rec.stepDetails.appCpuUid1 >= 0) { 4261 pw.print(" ("); 4262 printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid1, 4263 rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1); 4264 if (rec.stepDetails.appCpuUid2 >= 0) { 4265 pw.print(", "); 4266 printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid2, 4267 rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2); 4268 } 4269 if (rec.stepDetails.appCpuUid3 >= 0) { 4270 pw.print(", "); 4271 printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid3, 4272 rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3); 4273 } 4274 pw.print(')'); 4275 } 4276 pw.println(); 4277 pw.print(" /proc/stat="); 4278 pw.print(rec.stepDetails.statUserTime); 4279 pw.print(" usr, "); 4280 pw.print(rec.stepDetails.statSystemTime); 4281 pw.print(" sys, "); 4282 pw.print(rec.stepDetails.statIOWaitTime); 4283 pw.print(" io, "); 4284 pw.print(rec.stepDetails.statIrqTime); 4285 pw.print(" irq, "); 4286 pw.print(rec.stepDetails.statSoftIrqTime); 4287 pw.print(" sirq, "); 4288 pw.print(rec.stepDetails.statIdlTime); 4289 pw.print(" idle"); 4290 int totalRun = rec.stepDetails.statUserTime + rec.stepDetails.statSystemTime 4291 + rec.stepDetails.statIOWaitTime + rec.stepDetails.statIrqTime 4292 + rec.stepDetails.statSoftIrqTime; 4293 int total = totalRun + rec.stepDetails.statIdlTime; 4294 if (total > 0) { 4295 pw.print(" ("); 4296 float perc = ((float)totalRun) / ((float)total) * 100; 4297 pw.print(String.format("%.1f%%", perc)); 4298 pw.print(" of "); 4299 StringBuilder sb = new StringBuilder(64); 4300 formatTimeMsNoSpace(sb, total*10); 4301 pw.print(sb); 4302 pw.print(")"); 4303 } 4304 pw.println(); 4305 } else { 4306 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 4307 pw.print(HISTORY_DATA); pw.print(",0,Dcpu="); 4308 pw.print(rec.stepDetails.userTime); 4309 pw.print(":"); 4310 pw.print(rec.stepDetails.systemTime); 4311 if (rec.stepDetails.appCpuUid1 >= 0) { 4312 printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid1, 4313 rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1); 4314 if (rec.stepDetails.appCpuUid2 >= 0) { 4315 printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid2, 4316 rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2); 4317 } 4318 if (rec.stepDetails.appCpuUid3 >= 0) { 4319 printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid3, 4320 rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3); 4321 } 4322 } 4323 pw.println(); 4324 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 4325 pw.print(HISTORY_DATA); pw.print(",0,Dpst="); 4326 pw.print(rec.stepDetails.statUserTime); 4327 pw.print(','); 4328 pw.print(rec.stepDetails.statSystemTime); 4329 pw.print(','); 4330 pw.print(rec.stepDetails.statIOWaitTime); 4331 pw.print(','); 4332 pw.print(rec.stepDetails.statIrqTime); 4333 pw.print(','); 4334 pw.print(rec.stepDetails.statSoftIrqTime); 4335 pw.print(','); 4336 pw.print(rec.stepDetails.statIdlTime); 4337 pw.println(); 4338 } 4339 } 4340 oldState = rec.states; 4341 oldState2 = rec.states2; 4342 } 4343 } 4344 4345 private void printStepCpuUidDetails(PrintWriter pw, int uid, int utime, int stime) { 4346 UserHandle.formatUid(pw, uid); 4347 pw.print("="); 4348 pw.print(utime); 4349 pw.print("u+"); 4350 pw.print(stime); 4351 pw.print("s"); 4352 } 4353 4354 private void printStepCpuUidCheckinDetails(PrintWriter pw, int uid, int utime, int stime) { 4355 pw.print('/'); 4356 pw.print(uid); 4357 pw.print(":"); 4358 pw.print(utime); 4359 pw.print(":"); 4360 pw.print(stime); 4361 } 4362 } 4363 4364 private void printSizeValue(PrintWriter pw, long size) { 4365 float result = size; 4366 String suffix = ""; 4367 if (result >= 10*1024) { 4368 suffix = "KB"; 4369 result = result / 1024; 4370 } 4371 if (result >= 10*1024) { 4372 suffix = "MB"; 4373 result = result / 1024; 4374 } 4375 if (result >= 10*1024) { 4376 suffix = "GB"; 4377 result = result / 1024; 4378 } 4379 if (result >= 10*1024) { 4380 suffix = "TB"; 4381 result = result / 1024; 4382 } 4383 if (result >= 10*1024) { 4384 suffix = "PB"; 4385 result = result / 1024; 4386 } 4387 pw.print((int)result); 4388 pw.print(suffix); 4389 } 4390 4391 private static boolean dumpTimeEstimate(PrintWriter pw, String label1, String label2, 4392 String label3, long estimatedTime) { 4393 if (estimatedTime < 0) { 4394 return false; 4395 } 4396 pw.print(label1); 4397 pw.print(label2); 4398 pw.print(label3); 4399 StringBuilder sb = new StringBuilder(64); 4400 formatTimeMs(sb, estimatedTime); 4401 pw.print(sb); 4402 pw.println(); 4403 return true; 4404 } 4405 4406 private static boolean dumpDurationSteps(PrintWriter pw, String prefix, String header, 4407 LevelStepTracker steps, boolean checkin) { 4408 if (steps == null) { 4409 return false; 4410 } 4411 int count = steps.mNumStepDurations; 4412 if (count <= 0) { 4413 return false; 4414 } 4415 if (!checkin) { 4416 pw.println(header); 4417 } 4418 String[] lineArgs = new String[5]; 4419 for (int i=0; i<count; i++) { 4420 long duration = steps.getDurationAt(i); 4421 int level = steps.getLevelAt(i); 4422 long initMode = steps.getInitModeAt(i); 4423 long modMode = steps.getModModeAt(i); 4424 if (checkin) { 4425 lineArgs[0] = Long.toString(duration); 4426 lineArgs[1] = Integer.toString(level); 4427 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) { 4428 switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) { 4429 case Display.STATE_OFF: lineArgs[2] = "s-"; break; 4430 case Display.STATE_ON: lineArgs[2] = "s+"; break; 4431 case Display.STATE_DOZE: lineArgs[2] = "sd"; break; 4432 case Display.STATE_DOZE_SUSPEND: lineArgs[2] = "sds"; break; 4433 default: lineArgs[2] = "?"; break; 4434 } 4435 } else { 4436 lineArgs[2] = ""; 4437 } 4438 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) { 4439 lineArgs[3] = (initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 ? "p+" : "p-"; 4440 } else { 4441 lineArgs[3] = ""; 4442 } 4443 if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) { 4444 lineArgs[4] = (initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0 ? "i+" : "i-"; 4445 } else { 4446 lineArgs[4] = ""; 4447 } 4448 dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs); 4449 } else { 4450 pw.print(prefix); 4451 pw.print("#"); pw.print(i); pw.print(": "); 4452 TimeUtils.formatDuration(duration, pw); 4453 pw.print(" to "); pw.print(level); 4454 boolean haveModes = false; 4455 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) { 4456 pw.print(" ("); 4457 switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) { 4458 case Display.STATE_OFF: pw.print("screen-off"); break; 4459 case Display.STATE_ON: pw.print("screen-on"); break; 4460 case Display.STATE_DOZE: pw.print("screen-doze"); break; 4461 case Display.STATE_DOZE_SUSPEND: pw.print("screen-doze-suspend"); break; 4462 default: pw.print("screen-?"); break; 4463 } 4464 haveModes = true; 4465 } 4466 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) { 4467 pw.print(haveModes ? ", " : " ("); 4468 pw.print((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 4469 ? "power-save-on" : "power-save-off"); 4470 haveModes = true; 4471 } 4472 if ((modMode&STEP_LEVEL_MODE_DEVICE_IDLE) == 0) { 4473 pw.print(haveModes ? ", " : " ("); 4474 pw.print((initMode&STEP_LEVEL_MODE_DEVICE_IDLE) != 0 4475 ? "device-idle-on" : "device-idle-off"); 4476 haveModes = true; 4477 } 4478 if (haveModes) { 4479 pw.print(")"); 4480 } 4481 pw.println(); 4482 } 4483 } 4484 return true; 4485 } 4486 4487 public static final int DUMP_CHARGED_ONLY = 1<<1; 4488 public static final int DUMP_DAILY_ONLY = 1<<2; 4489 public static final int DUMP_HISTORY_ONLY = 1<<3; 4490 public static final int DUMP_INCLUDE_HISTORY = 1<<4; 4491 public static final int DUMP_VERBOSE = 1<<5; 4492 public static final int DUMP_DEVICE_WIFI_ONLY = 1<<6; 4493 4494 private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) { 4495 final HistoryPrinter hprinter = new HistoryPrinter(); 4496 final HistoryItem rec = new HistoryItem(); 4497 long lastTime = -1; 4498 long baseTime = -1; 4499 boolean printed = false; 4500 HistoryEventTracker tracker = null; 4501 while (getNextHistoryLocked(rec)) { 4502 lastTime = rec.time; 4503 if (baseTime < 0) { 4504 baseTime = lastTime; 4505 } 4506 if (rec.time >= histStart) { 4507 if (histStart >= 0 && !printed) { 4508 if (rec.cmd == HistoryItem.CMD_CURRENT_TIME 4509 || rec.cmd == HistoryItem.CMD_RESET 4510 || rec.cmd == HistoryItem.CMD_START 4511 || rec.cmd == HistoryItem.CMD_SHUTDOWN) { 4512 printed = true; 4513 hprinter.printNextItem(pw, rec, baseTime, checkin, 4514 (flags&DUMP_VERBOSE) != 0); 4515 rec.cmd = HistoryItem.CMD_UPDATE; 4516 } else if (rec.currentTime != 0) { 4517 printed = true; 4518 byte cmd = rec.cmd; 4519 rec.cmd = HistoryItem.CMD_CURRENT_TIME; 4520 hprinter.printNextItem(pw, rec, baseTime, checkin, 4521 (flags&DUMP_VERBOSE) != 0); 4522 rec.cmd = cmd; 4523 } 4524 if (tracker != null) { 4525 if (rec.cmd != HistoryItem.CMD_UPDATE) { 4526 hprinter.printNextItem(pw, rec, baseTime, checkin, 4527 (flags&DUMP_VERBOSE) != 0); 4528 rec.cmd = HistoryItem.CMD_UPDATE; 4529 } 4530 int oldEventCode = rec.eventCode; 4531 HistoryTag oldEventTag = rec.eventTag; 4532 rec.eventTag = new HistoryTag(); 4533 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 4534 HashMap<String, SparseIntArray> active 4535 = tracker.getStateForEvent(i); 4536 if (active == null) { 4537 continue; 4538 } 4539 for (HashMap.Entry<String, SparseIntArray> ent 4540 : active.entrySet()) { 4541 SparseIntArray uids = ent.getValue(); 4542 for (int j=0; j<uids.size(); j++) { 4543 rec.eventCode = i; 4544 rec.eventTag.string = ent.getKey(); 4545 rec.eventTag.uid = uids.keyAt(j); 4546 rec.eventTag.poolIdx = uids.valueAt(j); 4547 hprinter.printNextItem(pw, rec, baseTime, checkin, 4548 (flags&DUMP_VERBOSE) != 0); 4549 rec.wakeReasonTag = null; 4550 rec.wakelockTag = null; 4551 } 4552 } 4553 } 4554 rec.eventCode = oldEventCode; 4555 rec.eventTag = oldEventTag; 4556 tracker = null; 4557 } 4558 } 4559 hprinter.printNextItem(pw, rec, baseTime, checkin, 4560 (flags&DUMP_VERBOSE) != 0); 4561 } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) { 4562 // This is an attempt to aggregate the previous state and generate 4563 // fake events to reflect that state at the point where we start 4564 // printing real events. It doesn't really work right, so is turned off. 4565 if (tracker == null) { 4566 tracker = new HistoryEventTracker(); 4567 } 4568 tracker.updateState(rec.eventCode, rec.eventTag.string, 4569 rec.eventTag.uid, rec.eventTag.poolIdx); 4570 } 4571 } 4572 if (histStart >= 0) { 4573 commitCurrentHistoryBatchLocked(); 4574 pw.print(checkin ? "NEXT: " : " NEXT: "); pw.println(lastTime+1); 4575 } 4576 } 4577 4578 private void dumpDailyLevelStepSummary(PrintWriter pw, String prefix, String label, 4579 LevelStepTracker steps, StringBuilder tmpSb, int[] tmpOutInt) { 4580 if (steps == null) { 4581 return; 4582 } 4583 long timeRemaining = steps.computeTimeEstimate(0, 0, tmpOutInt); 4584 if (timeRemaining >= 0) { 4585 pw.print(prefix); pw.print(label); pw.print(" total time: "); 4586 tmpSb.setLength(0); 4587 formatTimeMs(tmpSb, timeRemaining); 4588 pw.print(tmpSb); 4589 pw.print(" (from "); pw.print(tmpOutInt[0]); 4590 pw.println(" steps)"); 4591 } 4592 for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) { 4593 long estimatedTime = steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i], 4594 STEP_LEVEL_MODE_VALUES[i], tmpOutInt); 4595 if (estimatedTime > 0) { 4596 pw.print(prefix); pw.print(label); pw.print(" "); 4597 pw.print(STEP_LEVEL_MODE_LABELS[i]); 4598 pw.print(" time: "); 4599 tmpSb.setLength(0); 4600 formatTimeMs(tmpSb, estimatedTime); 4601 pw.print(tmpSb); 4602 pw.print(" (from "); pw.print(tmpOutInt[0]); 4603 pw.println(" steps)"); 4604 } 4605 } 4606 } 4607 4608 private void dumpDailyPackageChanges(PrintWriter pw, String prefix, 4609 ArrayList<PackageChange> changes) { 4610 if (changes == null) { 4611 return; 4612 } 4613 pw.print(prefix); pw.println("Package changes:"); 4614 for (int i=0; i<changes.size(); i++) { 4615 PackageChange pc = changes.get(i); 4616 if (pc.mUpdate) { 4617 pw.print(prefix); pw.print(" Update "); pw.print(pc.mPackageName); 4618 pw.print(" vers="); pw.println(pc.mVersionCode); 4619 } else { 4620 pw.print(prefix); pw.print(" Uninstall "); pw.println(pc.mPackageName); 4621 } 4622 } 4623 } 4624 4625 /** 4626 * Dumps a human-readable summary of the battery statistics to the given PrintWriter. 4627 * 4628 * @param pw a Printer to receive the dump output. 4629 */ 4630 @SuppressWarnings("unused") 4631 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 4632 prepareForDumpLocked(); 4633 4634 final boolean filtering = (flags 4635 & (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0; 4636 4637 if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) { 4638 final long historyTotalSize = getHistoryTotalSize(); 4639 final long historyUsedSize = getHistoryUsedSize(); 4640 if (startIteratingHistoryLocked()) { 4641 try { 4642 pw.print("Battery History ("); 4643 pw.print((100*historyUsedSize)/historyTotalSize); 4644 pw.print("% used, "); 4645 printSizeValue(pw, historyUsedSize); 4646 pw.print(" used of "); 4647 printSizeValue(pw, historyTotalSize); 4648 pw.print(", "); 4649 pw.print(getHistoryStringPoolSize()); 4650 pw.print(" strings using "); 4651 printSizeValue(pw, getHistoryStringPoolBytes()); 4652 pw.println("):"); 4653 dumpHistoryLocked(pw, flags, histStart, false); 4654 pw.println(); 4655 } finally { 4656 finishIteratingHistoryLocked(); 4657 } 4658 } 4659 4660 if (startIteratingOldHistoryLocked()) { 4661 try { 4662 final HistoryItem rec = new HistoryItem(); 4663 pw.println("Old battery History:"); 4664 HistoryPrinter hprinter = new HistoryPrinter(); 4665 long baseTime = -1; 4666 while (getNextOldHistoryLocked(rec)) { 4667 if (baseTime < 0) { 4668 baseTime = rec.time; 4669 } 4670 hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0); 4671 } 4672 pw.println(); 4673 } finally { 4674 finishIteratingOldHistoryLocked(); 4675 } 4676 } 4677 } 4678 4679 if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) { 4680 return; 4681 } 4682 4683 if (!filtering) { 4684 SparseArray<? extends Uid> uidStats = getUidStats(); 4685 final int NU = uidStats.size(); 4686 boolean didPid = false; 4687 long nowRealtime = SystemClock.elapsedRealtime(); 4688 for (int i=0; i<NU; i++) { 4689 Uid uid = uidStats.valueAt(i); 4690 SparseArray<? extends Uid.Pid> pids = uid.getPidStats(); 4691 if (pids != null) { 4692 for (int j=0; j<pids.size(); j++) { 4693 Uid.Pid pid = pids.valueAt(j); 4694 if (!didPid) { 4695 pw.println("Per-PID Stats:"); 4696 didPid = true; 4697 } 4698 long time = pid.mWakeSumMs + (pid.mWakeNesting > 0 4699 ? (nowRealtime - pid.mWakeStartMs) : 0); 4700 pw.print(" PID "); pw.print(pids.keyAt(j)); 4701 pw.print(" wake time: "); 4702 TimeUtils.formatDuration(time, pw); 4703 pw.println(""); 4704 } 4705 } 4706 } 4707 if (didPid) { 4708 pw.println(); 4709 } 4710 } 4711 4712 if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) { 4713 if (dumpDurationSteps(pw, " ", "Discharge step durations:", 4714 getDischargeLevelStepTracker(), false)) { 4715 long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime()); 4716 if (timeRemaining >= 0) { 4717 pw.print(" Estimated discharge time remaining: "); 4718 TimeUtils.formatDuration(timeRemaining / 1000, pw); 4719 pw.println(); 4720 } 4721 final LevelStepTracker steps = getDischargeLevelStepTracker(); 4722 for (int i=0; i< STEP_LEVEL_MODES_OF_INTEREST.length; i++) { 4723 dumpTimeEstimate(pw, " Estimated ", STEP_LEVEL_MODE_LABELS[i], " time: ", 4724 steps.computeTimeEstimate(STEP_LEVEL_MODES_OF_INTEREST[i], 4725 STEP_LEVEL_MODE_VALUES[i], null)); 4726 } 4727 pw.println(); 4728 } 4729 if (dumpDurationSteps(pw, " ", "Charge step durations:", 4730 getChargeLevelStepTracker(), false)) { 4731 long timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime()); 4732 if (timeRemaining >= 0) { 4733 pw.print(" Estimated charge time remaining: "); 4734 TimeUtils.formatDuration(timeRemaining / 1000, pw); 4735 pw.println(); 4736 } 4737 pw.println(); 4738 } 4739 } 4740 if (!filtering || (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0) { 4741 pw.println("Daily stats:"); 4742 pw.print(" Current start time: "); 4743 pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", 4744 getCurrentDailyStartTime()).toString()); 4745 pw.print(" Next min deadline: "); 4746 pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", 4747 getNextMinDailyDeadline()).toString()); 4748 pw.print(" Next max deadline: "); 4749 pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", 4750 getNextMaxDailyDeadline()).toString()); 4751 StringBuilder sb = new StringBuilder(64); 4752 int[] outInt = new int[1]; 4753 LevelStepTracker dsteps = getDailyDischargeLevelStepTracker(); 4754 LevelStepTracker csteps = getDailyChargeLevelStepTracker(); 4755 ArrayList<PackageChange> pkgc = getDailyPackageChanges(); 4756 if (dsteps.mNumStepDurations > 0 || csteps.mNumStepDurations > 0 || pkgc != null) { 4757 if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) { 4758 if (dumpDurationSteps(pw, " ", " Current daily discharge step durations:", 4759 dsteps, false)) { 4760 dumpDailyLevelStepSummary(pw, " ", "Discharge", dsteps, 4761 sb, outInt); 4762 } 4763 if (dumpDurationSteps(pw, " ", " Current daily charge step durations:", 4764 csteps, false)) { 4765 dumpDailyLevelStepSummary(pw, " ", "Charge", csteps, 4766 sb, outInt); 4767 } 4768 dumpDailyPackageChanges(pw, " ", pkgc); 4769 } else { 4770 pw.println(" Current daily steps:"); 4771 dumpDailyLevelStepSummary(pw, " ", "Discharge", dsteps, 4772 sb, outInt); 4773 dumpDailyLevelStepSummary(pw, " ", "Charge", csteps, 4774 sb, outInt); 4775 } 4776 } 4777 DailyItem dit; 4778 int curIndex = 0; 4779 while ((dit=getDailyItemLocked(curIndex)) != null) { 4780 curIndex++; 4781 if ((flags&DUMP_DAILY_ONLY) != 0) { 4782 pw.println(); 4783 } 4784 pw.print(" Daily from "); 4785 pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mStartTime).toString()); 4786 pw.print(" to "); 4787 pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mEndTime).toString()); 4788 pw.println(":"); 4789 if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) { 4790 if (dumpDurationSteps(pw, " ", 4791 " Discharge step durations:", dit.mDischargeSteps, false)) { 4792 dumpDailyLevelStepSummary(pw, " ", "Discharge", dit.mDischargeSteps, 4793 sb, outInt); 4794 } 4795 if (dumpDurationSteps(pw, " ", 4796 " Charge step durations:", dit.mChargeSteps, false)) { 4797 dumpDailyLevelStepSummary(pw, " ", "Charge", dit.mChargeSteps, 4798 sb, outInt); 4799 } 4800 dumpDailyPackageChanges(pw, " ", dit.mPackageChanges); 4801 } else { 4802 dumpDailyLevelStepSummary(pw, " ", "Discharge", dit.mDischargeSteps, 4803 sb, outInt); 4804 dumpDailyLevelStepSummary(pw, " ", "Charge", dit.mChargeSteps, 4805 sb, outInt); 4806 } 4807 } 4808 pw.println(); 4809 } 4810 if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) { 4811 pw.println("Statistics since last charge:"); 4812 pw.println(" System starts: " + getStartCount() 4813 + ", currently on battery: " + getIsOnBattery()); 4814 dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid, 4815 (flags&DUMP_DEVICE_WIFI_ONLY) != 0); 4816 pw.println(); 4817 } 4818 } 4819 4820 @SuppressWarnings("unused") 4821 public void dumpCheckinLocked(Context context, PrintWriter pw, 4822 List<ApplicationInfo> apps, int flags, long histStart) { 4823 prepareForDumpLocked(); 4824 4825 dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA, 4826 "13", getParcelVersion(), getStartPlatformVersion(), getEndPlatformVersion()); 4827 4828 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); 4829 4830 final boolean filtering = (flags & 4831 (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0; 4832 4833 if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) { 4834 if (startIteratingHistoryLocked()) { 4835 try { 4836 for (int i=0; i<getHistoryStringPoolSize(); i++) { 4837 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); 4838 pw.print(HISTORY_STRING_POOL); pw.print(','); 4839 pw.print(i); 4840 pw.print(","); 4841 pw.print(getHistoryTagPoolUid(i)); 4842 pw.print(",\""); 4843 String str = getHistoryTagPoolString(i); 4844 str = str.replace("\\", "\\\\"); 4845 str = str.replace("\"", "\\\""); 4846 pw.print(str); 4847 pw.print("\""); 4848 pw.println(); 4849 } 4850 dumpHistoryLocked(pw, flags, histStart, true); 4851 } finally { 4852 finishIteratingHistoryLocked(); 4853 } 4854 } 4855 } 4856 4857 if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) { 4858 return; 4859 } 4860 4861 if (apps != null) { 4862 SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>(); 4863 for (int i=0; i<apps.size(); i++) { 4864 ApplicationInfo ai = apps.get(i); 4865 ArrayList<String> pkgs = uids.get(ai.uid); 4866 if (pkgs == null) { 4867 pkgs = new ArrayList<String>(); 4868 uids.put(ai.uid, pkgs); 4869 } 4870 pkgs.add(ai.packageName); 4871 } 4872 SparseArray<? extends Uid> uidStats = getUidStats(); 4873 final int NU = uidStats.size(); 4874 String[] lineArgs = new String[2]; 4875 for (int i=0; i<NU; i++) { 4876 int uid = uidStats.keyAt(i); 4877 ArrayList<String> pkgs = uids.get(uid); 4878 if (pkgs != null) { 4879 for (int j=0; j<pkgs.size(); j++) { 4880 lineArgs[0] = Integer.toString(uid); 4881 lineArgs[1] = pkgs.get(j); 4882 dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA, 4883 (Object[])lineArgs); 4884 } 4885 } 4886 } 4887 } 4888 if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) { 4889 dumpDurationSteps(pw, "", DISCHARGE_STEP_DATA, getDischargeLevelStepTracker(), true); 4890 String[] lineArgs = new String[1]; 4891 long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime()); 4892 if (timeRemaining >= 0) { 4893 lineArgs[0] = Long.toString(timeRemaining); 4894 dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA, 4895 (Object[])lineArgs); 4896 } 4897 dumpDurationSteps(pw, "", CHARGE_STEP_DATA, getChargeLevelStepTracker(), true); 4898 timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime()); 4899 if (timeRemaining >= 0) { 4900 lineArgs[0] = Long.toString(timeRemaining); 4901 dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA, 4902 (Object[])lineArgs); 4903 } 4904 dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1, 4905 (flags&DUMP_DEVICE_WIFI_ONLY) != 0); 4906 } 4907 } 4908} 4909