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