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