1 /* 2 * Copyright (C) 2006-2007 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 17 package com.android.internal.os; 18 19 import android.annotation.Nullable; 20 import android.app.ActivityManager; 21 import android.bluetooth.BluetoothActivityEnergyInfo; 22 import android.bluetooth.UidTraffic; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.net.ConnectivityManager; 26 import android.net.NetworkStats; 27 import android.net.wifi.WifiActivityEnergyInfo; 28 import android.net.wifi.WifiManager; 29 import android.os.BatteryManager; 30 import android.os.BatteryStats; 31 import android.os.Build; 32 import android.os.FileUtils; 33 import android.os.Handler; 34 import android.os.Looper; 35 import android.os.Message; 36 import android.os.Parcel; 37 import android.os.ParcelFormatException; 38 import android.os.Parcelable; 39 import android.os.Process; 40 import android.os.SystemClock; 41 import android.os.SystemProperties; 42 import android.os.WorkSource; 43 import android.telephony.DataConnectionRealTimeInfo; 44 import android.telephony.ModemActivityInfo; 45 import android.telephony.ServiceState; 46 import android.telephony.SignalStrength; 47 import android.telephony.TelephonyManager; 48 import android.text.TextUtils; 49 import android.util.ArrayMap; 50 import android.util.Log; 51 import android.util.LogWriter; 52 import android.util.MutableInt; 53 import android.util.PrintWriterPrinter; 54 import android.util.Printer; 55 import android.util.Slog; 56 import android.util.SparseArray; 57 import android.util.SparseIntArray; 58 import android.util.SparseLongArray; 59 import android.util.TimeUtils; 60 import android.util.Xml; 61 import android.view.Display; 62 63 import com.android.internal.annotations.VisibleForTesting; 64 import com.android.internal.net.NetworkStatsFactory; 65 import com.android.internal.util.ArrayUtils; 66 import com.android.internal.util.FastPrintWriter; 67 import com.android.internal.util.FastXmlSerializer; 68 import com.android.internal.util.JournaledFile; 69 import com.android.internal.util.XmlUtils; 70 import com.android.server.NetworkManagementSocketTagger; 71 import libcore.util.EmptyArray; 72 import org.xmlpull.v1.XmlPullParser; 73 import org.xmlpull.v1.XmlPullParserException; 74 import org.xmlpull.v1.XmlSerializer; 75 76 import java.io.ByteArrayOutputStream; 77 import java.io.File; 78 import java.io.FileInputStream; 79 import java.io.FileNotFoundException; 80 import java.io.FileOutputStream; 81 import java.io.IOException; 82 import java.io.PrintWriter; 83 import java.nio.charset.StandardCharsets; 84 import java.util.ArrayList; 85 import java.util.Calendar; 86 import java.util.HashMap; 87 import java.util.Iterator; 88 import java.util.Map; 89 import java.util.concurrent.atomic.AtomicInteger; 90 import java.util.concurrent.locks.ReentrantLock; 91 92 /** 93 * All information we are collecting about things that can happen that impact 94 * battery life. All times are represented in microseconds except where indicated 95 * otherwise. 96 */ 97 public class BatteryStatsImpl extends BatteryStats { 98 private static final String TAG = "BatteryStatsImpl"; 99 private static final boolean DEBUG = false; 100 public static final boolean DEBUG_ENERGY = false; 101 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 102 private static final boolean DEBUG_HISTORY = false; 103 private static final boolean USE_OLD_HISTORY = false; // for debugging. 104 105 // TODO: remove "tcp" from network methods, since we measure total stats. 106 107 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 108 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 109 110 // Current on-disk Parcel version 111 private static final int VERSION = 147 + (USE_OLD_HISTORY ? 1000 : 0); 112 113 // Maximum number of items we will record in the history. 114 private static final int MAX_HISTORY_ITEMS = 2000; 115 116 // No, really, THIS is the maximum number of items we will record in the history. 117 private static final int MAX_MAX_HISTORY_ITEMS = 3000; 118 119 // The maximum number of names wakelocks we will keep track of 120 // per uid; once the limit is reached, we batch the remaining wakelocks 121 // in to one common name. 122 private static final int MAX_WAKELOCKS_PER_UID = 100; 123 124 // Number of transmit power states the Wifi controller can be in. 125 private static final int NUM_WIFI_TX_LEVELS = 1; 126 127 // Number of transmit power states the Bluetooth controller can be in. 128 private static final int NUM_BT_TX_LEVELS = 1; 129 130 protected Clocks mClocks; 131 132 private final JournaledFile mFile; 133 public final AtomicFile mCheckinFile; 134 public final AtomicFile mDailyFile; 135 136 static final int MSG_UPDATE_WAKELOCKS = 1; 137 static final int MSG_REPORT_POWER_CHANGE = 2; 138 static final int MSG_REPORT_CHARGING = 3; 139 static final long DELAY_UPDATE_WAKELOCKS = 5*1000; 140 141 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); 142 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 143 144 private final KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader(); 145 private KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 146 147 public interface BatteryCallback { batteryNeedsCpuUpdate()148 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)149 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)150 public void batterySendBroadcast(Intent intent); 151 } 152 153 public interface PlatformIdleStateCallback { getPlatformLowPowerStats()154 public String getPlatformLowPowerStats(); 155 } 156 157 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 158 159 160 final class MyHandler extends Handler { MyHandler(Looper looper)161 public MyHandler(Looper looper) { 162 super(looper, null, true); 163 } 164 165 @Override handleMessage(Message msg)166 public void handleMessage(Message msg) { 167 BatteryCallback cb = mCallback; 168 switch (msg.what) { 169 case MSG_UPDATE_WAKELOCKS: 170 synchronized (BatteryStatsImpl.this) { 171 updateCpuTimeLocked(); 172 } 173 if (cb != null) { 174 cb.batteryNeedsCpuUpdate(); 175 } 176 break; 177 case MSG_REPORT_POWER_CHANGE: 178 if (cb != null) { 179 cb.batteryPowerChanged(msg.arg1 != 0); 180 } 181 break; 182 case MSG_REPORT_CHARGING: 183 if (cb != null) { 184 final String action; 185 synchronized (BatteryStatsImpl.this) { 186 action = mCharging ? BatteryManager.ACTION_CHARGING 187 : BatteryManager.ACTION_DISCHARGING; 188 } 189 Intent intent = new Intent(action); 190 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 191 cb.batterySendBroadcast(intent); 192 } 193 break; 194 } 195 } 196 } 197 198 public interface Clocks { elapsedRealtime()199 public long elapsedRealtime(); uptimeMillis()200 public long uptimeMillis(); 201 } 202 203 public static class SystemClocks implements Clocks { elapsedRealtime()204 public long elapsedRealtime() { 205 return SystemClock.elapsedRealtime(); 206 } 207 uptimeMillis()208 public long uptimeMillis() { 209 return SystemClock.uptimeMillis(); 210 } 211 } 212 213 public interface ExternalStatsSync { 214 public static final int UPDATE_CPU = 0x01; 215 public static final int UPDATE_WIFI = 0x02; 216 public static final int UPDATE_RADIO = 0x04; 217 public static final int UPDATE_BT = 0x08; 218 public static final int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT; 219 scheduleSync(String reason, int flags)220 void scheduleSync(String reason, int flags); scheduleCpuSyncDueToRemovedUid(int uid)221 void scheduleCpuSyncDueToRemovedUid(int uid); 222 } 223 224 public final MyHandler mHandler; 225 private final ExternalStatsSync mExternalSync; 226 227 private BatteryCallback mCallback; 228 229 /** 230 * Mapping isolated uids to the actual owning app uid. 231 */ 232 final SparseIntArray mIsolatedUids = new SparseIntArray(); 233 234 /** 235 * The statistics we have collected organized by uids. 236 */ 237 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 238 239 // A set of pools of currently active timers. When a timer is queried, we will divide the 240 // elapsed time by the number of active timers to arrive at that timer's share of the time. 241 // In order to do this, we must refresh each timer whenever the number of active timers 242 // changes. 243 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 244 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 245 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 246 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 247 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 248 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 249 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 250 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 251 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 252 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>(); 253 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 254 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 255 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 256 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 257 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 258 259 // Last partial timers we use for distributing CPU usage. 260 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 261 262 // These are the objects that will want to do something when the device 263 // is unplugged from power. 264 protected final TimeBase mOnBatteryTimeBase = new TimeBase(); 265 266 // These are the objects that will want to do something when the device 267 // is unplugged from power *and* the screen is off. 268 final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(); 269 270 // Set to true when we want to distribute CPU across wakelocks for the next 271 // CPU update, even if we aren't currently running wake locks. 272 boolean mDistributeWakelockCpu; 273 274 boolean mShuttingDown; 275 276 final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 277 278 long mHistoryBaseTime; 279 boolean mHaveBatteryLevel = false; 280 boolean mRecordingHistory = false; 281 int mNumHistoryItems; 282 283 static final int MAX_HISTORY_BUFFER = 256*1024; // 256KB 284 static final int MAX_MAX_HISTORY_BUFFER = 320*1024; // 320KB 285 final Parcel mHistoryBuffer = Parcel.obtain(); 286 final HistoryItem mHistoryLastWritten = new HistoryItem(); 287 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 288 final HistoryItem mHistoryReadTmp = new HistoryItem(); 289 final HistoryItem mHistoryAddTmp = new HistoryItem(); 290 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); 291 String[] mReadHistoryStrings; 292 int[] mReadHistoryUids; 293 int mReadHistoryChars; 294 int mNextHistoryTagIdx = 0; 295 int mNumHistoryTagChars = 0; 296 int mHistoryBufferLastPos = -1; 297 boolean mHistoryOverflow = false; 298 int mActiveHistoryStates = 0xffffffff; 299 int mActiveHistoryStates2 = 0xffffffff; 300 long mLastHistoryElapsedRealtime = 0; 301 long mTrackRunningHistoryElapsedRealtime = 0; 302 long mTrackRunningHistoryUptime = 0; 303 304 final HistoryItem mHistoryCur = new HistoryItem(); 305 306 HistoryItem mHistory; 307 HistoryItem mHistoryEnd; 308 HistoryItem mHistoryLastEnd; 309 HistoryItem mHistoryCache; 310 311 // Used by computeHistoryStepDetails 312 HistoryStepDetails mLastHistoryStepDetails = null; 313 byte mLastHistoryStepLevel = 0; 314 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); 315 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); 316 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); 317 318 /** 319 * Total time (in milliseconds) spent executing in user code. 320 */ 321 long mLastStepCpuUserTime; 322 long mCurStepCpuUserTime; 323 /** 324 * Total time (in milliseconds) spent executing in kernel code. 325 */ 326 long mLastStepCpuSystemTime; 327 long mCurStepCpuSystemTime; 328 /** 329 * Times from /proc/stat (but measured in milliseconds). 330 */ 331 long mLastStepStatUserTime; 332 long mLastStepStatSystemTime; 333 long mLastStepStatIOWaitTime; 334 long mLastStepStatIrqTime; 335 long mLastStepStatSoftIrqTime; 336 long mLastStepStatIdleTime; 337 long mCurStepStatUserTime; 338 long mCurStepStatSystemTime; 339 long mCurStepStatIOWaitTime; 340 long mCurStepStatIrqTime; 341 long mCurStepStatSoftIrqTime; 342 long mCurStepStatIdleTime; 343 344 private HistoryItem mHistoryIterator; 345 private boolean mReadOverflow; 346 private boolean mIteratingHistory; 347 348 int mStartCount; 349 350 long mStartClockTime; 351 String mStartPlatformVersion; 352 String mEndPlatformVersion; 353 354 long mUptime; 355 long mUptimeStart; 356 long mRealtime; 357 long mRealtimeStart; 358 359 int mWakeLockNesting; 360 boolean mWakeLockImportant; 361 public boolean mRecordAllHistory; 362 boolean mNoAutoReset; 363 364 int mScreenState = Display.STATE_UNKNOWN; 365 StopwatchTimer mScreenOnTimer; 366 367 int mScreenBrightnessBin = -1; 368 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 369 370 boolean mInteractive; 371 StopwatchTimer mInteractiveTimer; 372 373 boolean mPowerSaveModeEnabled; 374 StopwatchTimer mPowerSaveModeEnabledTimer; 375 376 boolean mDeviceIdling; 377 StopwatchTimer mDeviceIdlingTimer; 378 379 boolean mDeviceLightIdling; 380 StopwatchTimer mDeviceLightIdlingTimer; 381 382 int mDeviceIdleMode; 383 long mLastIdleTimeStart; 384 long mLongestLightIdleTime; 385 long mLongestFullIdleTime; 386 StopwatchTimer mDeviceIdleModeLightTimer; 387 StopwatchTimer mDeviceIdleModeFullTimer; 388 389 boolean mPhoneOn; 390 StopwatchTimer mPhoneOnTimer; 391 392 int mAudioOnNesting; 393 StopwatchTimer mAudioOnTimer; 394 395 int mVideoOnNesting; 396 StopwatchTimer mVideoOnTimer; 397 398 int mFlashlightOnNesting; 399 StopwatchTimer mFlashlightOnTimer; 400 401 int mCameraOnNesting; 402 StopwatchTimer mCameraOnTimer; 403 404 int mPhoneSignalStrengthBin = -1; 405 int mPhoneSignalStrengthBinRaw = -1; 406 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 407 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 408 409 StopwatchTimer mPhoneSignalScanningTimer; 410 411 int mPhoneDataConnectionType = -1; 412 final StopwatchTimer[] mPhoneDataConnectionsTimer = 413 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 414 415 final LongSamplingCounter[] mNetworkByteActivityCounters = 416 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 417 final LongSamplingCounter[] mNetworkPacketActivityCounters = 418 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 419 420 /** 421 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 422 */ 423 ControllerActivityCounterImpl mWifiActivity; 424 425 /** 426 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 427 */ 428 ControllerActivityCounterImpl mBluetoothActivity; 429 430 /** 431 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 432 */ 433 ControllerActivityCounterImpl mModemActivity; 434 435 /** 436 * Whether the device supports WiFi controller energy reporting. This is set to true on 437 * the first WiFi energy report. See {@link #mWifiActivity}. 438 */ 439 boolean mHasWifiReporting = false; 440 441 /** 442 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 443 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 444 */ 445 boolean mHasBluetoothReporting = false; 446 447 /** 448 * Whether the device supports Modem controller energy reporting. This is set to true on 449 * the first Modem energy report. See {@link #mModemActivity}. 450 */ 451 boolean mHasModemReporting = false; 452 453 boolean mWifiOn; 454 StopwatchTimer mWifiOnTimer; 455 456 boolean mGlobalWifiRunning; 457 StopwatchTimer mGlobalWifiRunningTimer; 458 459 int mWifiState = -1; 460 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 461 462 int mWifiSupplState = -1; 463 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 464 465 int mWifiSignalStrengthBin = -1; 466 final StopwatchTimer[] mWifiSignalStrengthsTimer = 467 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 468 469 int mBluetoothScanNesting; 470 StopwatchTimer mBluetoothScanTimer; 471 472 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 473 long mMobileRadioActiveStartTime; 474 StopwatchTimer mMobileRadioActiveTimer; 475 StopwatchTimer mMobileRadioActivePerAppTimer; 476 LongSamplingCounter mMobileRadioActiveAdjustedTime; 477 LongSamplingCounter mMobileRadioActiveUnknownTime; 478 LongSamplingCounter mMobileRadioActiveUnknownCount; 479 480 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 481 482 /** 483 * These provide time bases that discount the time the device is plugged 484 * in to power. 485 */ 486 boolean mOnBattery; 487 boolean mOnBatteryInternal; 488 489 /** 490 * External reporting of whether the device is actually charging. 491 */ 492 boolean mCharging = true; 493 int mLastChargingStateLevel; 494 495 /* 496 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 497 */ 498 int mDischargeStartLevel; 499 int mDischargeUnplugLevel; 500 int mDischargePlugLevel; 501 int mDischargeCurrentLevel; 502 int mCurrentBatteryLevel; 503 int mLowDischargeAmountSinceCharge; 504 int mHighDischargeAmountSinceCharge; 505 int mDischargeScreenOnUnplugLevel; 506 int mDischargeScreenOffUnplugLevel; 507 int mDischargeAmountScreenOn; 508 int mDischargeAmountScreenOnSinceCharge; 509 int mDischargeAmountScreenOff; 510 int mDischargeAmountScreenOffSinceCharge; 511 512 private LongSamplingCounter mDischargeScreenOffCounter; 513 private LongSamplingCounter mDischargeCounter; 514 515 static final int MAX_LEVEL_STEPS = 200; 516 517 int mInitStepMode = 0; 518 int mCurStepMode = 0; 519 int mModStepMode = 0; 520 521 int mLastDischargeStepLevel; 522 int mMinDischargeStepLevel; 523 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 524 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 525 ArrayList<PackageChange> mDailyPackageChanges; 526 527 int mLastChargeStepLevel; 528 int mMaxChargeStepLevel; 529 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 530 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 531 532 static final int MAX_DAILY_ITEMS = 10; 533 534 long mDailyStartTime = 0; 535 long mNextMinDailyDeadline = 0; 536 long mNextMaxDailyDeadline = 0; 537 538 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 539 540 long mLastWriteTime = 0; // Milliseconds 541 542 private int mPhoneServiceState = -1; 543 private int mPhoneServiceStateRaw = -1; 544 private int mPhoneSimStateRaw = -1; 545 546 private int mNumConnectivityChange; 547 private int mLoadedNumConnectivityChange; 548 private int mUnpluggedNumConnectivityChange; 549 550 private int mEstimatedBatteryCapacity = -1; 551 552 private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry(); 553 554 private PowerProfile mPowerProfile; 555 556 /* 557 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 558 */ 559 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 560 getKernelWakelockStats()561 public Map<String, ? extends Timer> getKernelWakelockStats() { 562 return mKernelWakelockStats; 563 } 564 565 String mLastWakeupReason = null; 566 long mLastWakeupUptimeMs = 0; 567 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 568 getWakeupReasonStats()569 public Map<String, ? extends Timer> getWakeupReasonStats() { 570 return mWakeupReasonStats; 571 } 572 573 @Override getDischargeScreenOffCoulombCounter()574 public LongCounter getDischargeScreenOffCoulombCounter() { 575 return mDischargeScreenOffCounter; 576 } 577 578 @Override getDischargeCoulombCounter()579 public LongCounter getDischargeCoulombCounter() { 580 return mDischargeCounter; 581 } 582 583 @Override getEstimatedBatteryCapacity()584 public int getEstimatedBatteryCapacity() { 585 return mEstimatedBatteryCapacity; 586 } 587 BatteryStatsImpl()588 public BatteryStatsImpl() { 589 this(new SystemClocks()); 590 } 591 BatteryStatsImpl(Clocks clocks)592 public BatteryStatsImpl(Clocks clocks) { 593 init(clocks); 594 mFile = null; 595 mCheckinFile = null; 596 mDailyFile = null; 597 mHandler = null; 598 mExternalSync = null; 599 mPlatformIdleStateCallback = null; 600 clearHistoryLocked(); 601 } 602 init(Clocks clocks)603 private void init(Clocks clocks) { 604 mClocks = clocks; 605 mMobileNetworkStats = new NetworkStats[] { 606 new NetworkStats(mClocks.elapsedRealtime(), 50), 607 new NetworkStats(mClocks.elapsedRealtime(), 50), 608 new NetworkStats(mClocks.elapsedRealtime(), 50) 609 }; 610 mWifiNetworkStats = new NetworkStats[] { 611 new NetworkStats(mClocks.elapsedRealtime(), 50), 612 new NetworkStats(mClocks.elapsedRealtime(), 50), 613 new NetworkStats(mClocks.elapsedRealtime(), 50) 614 }; 615 } 616 617 public static interface TimeBaseObs { onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)618 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime); onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)619 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime); 620 } 621 622 // methods are protected not private to be VisibleForTesting 623 public static class TimeBase { 624 protected final ArrayList<TimeBaseObs> mObservers = new ArrayList<>(); 625 626 protected long mUptime; 627 protected long mRealtime; 628 629 protected boolean mRunning; 630 631 protected long mPastUptime; 632 protected long mUptimeStart; 633 protected long mPastRealtime; 634 protected long mRealtimeStart; 635 protected long mUnpluggedUptime; 636 protected long mUnpluggedRealtime; 637 dump(PrintWriter pw, String prefix)638 public void dump(PrintWriter pw, String prefix) { 639 StringBuilder sb = new StringBuilder(128); 640 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 641 sb.setLength(0); 642 sb.append(prefix); 643 sb.append("mUptime="); 644 formatTimeMs(sb, mUptime / 1000); 645 pw.println(sb.toString()); 646 sb.setLength(0); 647 sb.append(prefix); 648 sb.append("mRealtime="); 649 formatTimeMs(sb, mRealtime / 1000); 650 pw.println(sb.toString()); 651 sb.setLength(0); 652 sb.append(prefix); 653 sb.append("mPastUptime="); 654 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart="); 655 formatTimeMs(sb, mUptimeStart / 1000); 656 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000); 657 pw.println(sb.toString()); 658 sb.setLength(0); 659 sb.append(prefix); 660 sb.append("mPastRealtime="); 661 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart="); 662 formatTimeMs(sb, mRealtimeStart / 1000); 663 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000); 664 pw.println(sb.toString()); 665 } 666 add(TimeBaseObs observer)667 public void add(TimeBaseObs observer) { 668 mObservers.add(observer); 669 } 670 remove(TimeBaseObs observer)671 public void remove(TimeBaseObs observer) { 672 if (!mObservers.remove(observer)) { 673 Slog.wtf(TAG, "Removed unknown observer: " + observer); 674 } 675 } 676 hasObserver(TimeBaseObs observer)677 public boolean hasObserver(TimeBaseObs observer) { 678 return mObservers.contains(observer); 679 } 680 init(long uptime, long realtime)681 public void init(long uptime, long realtime) { 682 mRealtime = 0; 683 mUptime = 0; 684 mPastUptime = 0; 685 mPastRealtime = 0; 686 mUptimeStart = uptime; 687 mRealtimeStart = realtime; 688 mUnpluggedUptime = getUptime(mUptimeStart); 689 mUnpluggedRealtime = getRealtime(mRealtimeStart); 690 } 691 reset(long uptime, long realtime)692 public void reset(long uptime, long realtime) { 693 if (!mRunning) { 694 mPastUptime = 0; 695 mPastRealtime = 0; 696 } else { 697 mUptimeStart = uptime; 698 mRealtimeStart = realtime; 699 // TODO: Since mUptimeStart was just reset and we are running, getUptime will 700 // just return mPastUptime. Also, are we sure we don't want to reset that? 701 mUnpluggedUptime = getUptime(uptime); 702 // TODO: likewise. 703 mUnpluggedRealtime = getRealtime(realtime); 704 } 705 } 706 computeUptime(long curTime, int which)707 public long computeUptime(long curTime, int which) { 708 switch (which) { 709 case STATS_SINCE_CHARGED: 710 return mUptime + getUptime(curTime); 711 case STATS_CURRENT: 712 return getUptime(curTime); 713 case STATS_SINCE_UNPLUGGED: 714 return getUptime(curTime) - mUnpluggedUptime; 715 } 716 return 0; 717 } 718 computeRealtime(long curTime, int which)719 public long computeRealtime(long curTime, int which) { 720 switch (which) { 721 case STATS_SINCE_CHARGED: 722 return mRealtime + getRealtime(curTime); 723 case STATS_CURRENT: 724 return getRealtime(curTime); 725 case STATS_SINCE_UNPLUGGED: 726 return getRealtime(curTime) - mUnpluggedRealtime; 727 } 728 return 0; 729 } 730 getUptime(long curTime)731 public long getUptime(long curTime) { 732 long time = mPastUptime; 733 if (mRunning) { 734 time += curTime - mUptimeStart; 735 } 736 return time; 737 } 738 getRealtime(long curTime)739 public long getRealtime(long curTime) { 740 long time = mPastRealtime; 741 if (mRunning) { 742 time += curTime - mRealtimeStart; 743 } 744 return time; 745 } 746 getUptimeStart()747 public long getUptimeStart() { 748 return mUptimeStart; 749 } 750 getRealtimeStart()751 public long getRealtimeStart() { 752 return mRealtimeStart; 753 } 754 isRunning()755 public boolean isRunning() { 756 return mRunning; 757 } 758 setRunning(boolean running, long uptime, long realtime)759 public boolean setRunning(boolean running, long uptime, long realtime) { 760 if (mRunning != running) { 761 mRunning = running; 762 if (running) { 763 mUptimeStart = uptime; 764 mRealtimeStart = realtime; 765 long batteryUptime = mUnpluggedUptime = getUptime(uptime); 766 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime); 767 768 for (int i = mObservers.size() - 1; i >= 0; i--) { 769 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime); 770 } 771 } else { 772 mPastUptime += uptime - mUptimeStart; 773 mPastRealtime += realtime - mRealtimeStart; 774 775 long batteryUptime = getUptime(uptime); 776 long batteryRealtime = getRealtime(realtime); 777 778 for (int i = mObservers.size() - 1; i >= 0; i--) { 779 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime); 780 } 781 } 782 return true; 783 } 784 return false; 785 } 786 readSummaryFromParcel(Parcel in)787 public void readSummaryFromParcel(Parcel in) { 788 mUptime = in.readLong(); 789 mRealtime = in.readLong(); 790 } 791 writeSummaryToParcel(Parcel out, long uptime, long realtime)792 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) { 793 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED)); 794 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED)); 795 } 796 readFromParcel(Parcel in)797 public void readFromParcel(Parcel in) { 798 mRunning = false; 799 mUptime = in.readLong(); 800 mPastUptime = in.readLong(); 801 mUptimeStart = in.readLong(); 802 mRealtime = in.readLong(); 803 mPastRealtime = in.readLong(); 804 mRealtimeStart = in.readLong(); 805 mUnpluggedUptime = in.readLong(); 806 mUnpluggedRealtime = in.readLong(); 807 } 808 writeToParcel(Parcel out, long uptime, long realtime)809 public void writeToParcel(Parcel out, long uptime, long realtime) { 810 final long runningUptime = getUptime(uptime); 811 final long runningRealtime = getRealtime(realtime); 812 out.writeLong(mUptime); 813 out.writeLong(runningUptime); 814 out.writeLong(mUptimeStart); 815 out.writeLong(mRealtime); 816 out.writeLong(runningRealtime); 817 out.writeLong(mRealtimeStart); 818 out.writeLong(mUnpluggedUptime); 819 out.writeLong(mUnpluggedRealtime); 820 } 821 } 822 823 /** 824 * State for keeping track of counting information. 825 */ 826 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 827 final AtomicInteger mCount = new AtomicInteger(); 828 final TimeBase mTimeBase; 829 int mLoadedCount; 830 int mLastCount; 831 int mUnpluggedCount; 832 int mPluggedCount; 833 Counter(TimeBase timeBase, Parcel in)834 Counter(TimeBase timeBase, Parcel in) { 835 mTimeBase = timeBase; 836 mPluggedCount = in.readInt(); 837 mCount.set(mPluggedCount); 838 mLoadedCount = in.readInt(); 839 mLastCount = 0; 840 mUnpluggedCount = in.readInt(); 841 timeBase.add(this); 842 } 843 Counter(TimeBase timeBase)844 Counter(TimeBase timeBase) { 845 mTimeBase = timeBase; 846 timeBase.add(this); 847 } 848 writeToParcel(Parcel out)849 public void writeToParcel(Parcel out) { 850 out.writeInt(mCount.get()); 851 out.writeInt(mLoadedCount); 852 out.writeInt(mUnpluggedCount); 853 } 854 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)855 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 856 mUnpluggedCount = mPluggedCount; 857 mCount.set(mPluggedCount); 858 } 859 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)860 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 861 mPluggedCount = mCount.get(); 862 } 863 864 /** 865 * Writes a possibly null Counter to a Parcel. 866 * 867 * @param out the Parcel to be written to. 868 * @param counter a Counter, or null. 869 */ writeCounterToParcel(Parcel out, Counter counter)870 public static void writeCounterToParcel(Parcel out, Counter counter) { 871 if (counter == null) { 872 out.writeInt(0); // indicates null 873 return; 874 } 875 out.writeInt(1); // indicates non-null 876 877 counter.writeToParcel(out); 878 } 879 880 @Override getCountLocked(int which)881 public int getCountLocked(int which) { 882 int val = mCount.get(); 883 if (which == STATS_SINCE_UNPLUGGED) { 884 val -= mUnpluggedCount; 885 } else if (which != STATS_SINCE_CHARGED) { 886 val -= mLoadedCount; 887 } 888 889 return val; 890 } 891 logState(Printer pw, String prefix)892 public void logState(Printer pw, String prefix) { 893 pw.println(prefix + "mCount=" + mCount.get() 894 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 895 + " mUnpluggedCount=" + mUnpluggedCount 896 + " mPluggedCount=" + mPluggedCount); 897 } 898 stepAtomic()899 void stepAtomic() { 900 mCount.incrementAndGet(); 901 } 902 903 /** 904 * Clear state of this counter. 905 */ reset(boolean detachIfReset)906 void reset(boolean detachIfReset) { 907 mCount.set(0); 908 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0; 909 if (detachIfReset) { 910 detach(); 911 } 912 } 913 detach()914 void detach() { 915 mTimeBase.remove(this); 916 } 917 writeSummaryFromParcelLocked(Parcel out)918 void writeSummaryFromParcelLocked(Parcel out) { 919 int count = mCount.get(); 920 out.writeInt(count); 921 } 922 readSummaryFromParcelLocked(Parcel in)923 void readSummaryFromParcelLocked(Parcel in) { 924 mLoadedCount = in.readInt(); 925 mCount.set(mLoadedCount); 926 mLastCount = 0; 927 mUnpluggedCount = mPluggedCount = mLoadedCount; 928 } 929 } 930 931 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 932 final TimeBase mTimeBase; 933 long mCount; 934 long mLoadedCount; 935 long mUnpluggedCount; 936 long mPluggedCount; 937 LongSamplingCounter(TimeBase timeBase, Parcel in)938 LongSamplingCounter(TimeBase timeBase, Parcel in) { 939 mTimeBase = timeBase; 940 mPluggedCount = in.readLong(); 941 mCount = mPluggedCount; 942 mLoadedCount = in.readLong(); 943 mUnpluggedCount = in.readLong(); 944 timeBase.add(this); 945 } 946 LongSamplingCounter(TimeBase timeBase)947 LongSamplingCounter(TimeBase timeBase) { 948 mTimeBase = timeBase; 949 timeBase.add(this); 950 } 951 writeToParcel(Parcel out)952 public void writeToParcel(Parcel out) { 953 out.writeLong(mCount); 954 out.writeLong(mLoadedCount); 955 out.writeLong(mUnpluggedCount); 956 } 957 958 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)959 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 960 mUnpluggedCount = mPluggedCount; 961 mCount = mPluggedCount; 962 } 963 964 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)965 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 966 mPluggedCount = mCount; 967 } 968 getCountLocked(int which)969 public long getCountLocked(int which) { 970 long val = mTimeBase.isRunning() ? mCount : mPluggedCount; 971 if (which == STATS_SINCE_UNPLUGGED) { 972 val -= mUnpluggedCount; 973 } else if (which != STATS_SINCE_CHARGED) { 974 val -= mLoadedCount; 975 } 976 return val; 977 } 978 979 @Override logState(Printer pw, String prefix)980 public void logState(Printer pw, String prefix) { 981 pw.println(prefix + "mCount=" + mCount 982 + " mLoadedCount=" + mLoadedCount 983 + " mUnpluggedCount=" + mUnpluggedCount 984 + " mPluggedCount=" + mPluggedCount); 985 } 986 addCountLocked(long count)987 void addCountLocked(long count) { 988 mCount += count; 989 } 990 991 /** 992 * Clear state of this counter. 993 */ reset(boolean detachIfReset)994 void reset(boolean detachIfReset) { 995 mCount = 0; 996 mLoadedCount = mPluggedCount = mUnpluggedCount = 0; 997 if (detachIfReset) { 998 detach(); 999 } 1000 } 1001 detach()1002 void detach() { 1003 mTimeBase.remove(this); 1004 } 1005 writeSummaryFromParcelLocked(Parcel out)1006 void writeSummaryFromParcelLocked(Parcel out) { 1007 out.writeLong(mCount); 1008 } 1009 readSummaryFromParcelLocked(Parcel in)1010 void readSummaryFromParcelLocked(Parcel in) { 1011 mLoadedCount = in.readLong(); 1012 mCount = mLoadedCount; 1013 mUnpluggedCount = mPluggedCount = mLoadedCount; 1014 } 1015 } 1016 1017 /** 1018 * State for keeping track of timing information. 1019 */ 1020 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 1021 protected final Clocks mClocks; 1022 protected final int mType; 1023 protected final TimeBase mTimeBase; 1024 1025 protected int mCount; 1026 protected int mLoadedCount; 1027 protected int mLastCount; 1028 protected int mUnpluggedCount; 1029 1030 // Times are in microseconds for better accuracy when dividing by the 1031 // lock count, and are in "battery realtime" units. 1032 1033 /** 1034 * The total time we have accumulated since the start of the original 1035 * boot, to the last time something interesting happened in the 1036 * current run. 1037 */ 1038 protected long mTotalTime; 1039 1040 /** 1041 * The total time we loaded for the previous runs. Subtract this from 1042 * mTotalTime to find the time for the current run of the system. 1043 */ 1044 protected long mLoadedTime; 1045 1046 /** 1047 * The run time of the last run of the system, as loaded from the 1048 * saved data. 1049 */ 1050 protected long mLastTime; 1051 1052 /** 1053 * The value of mTotalTime when unplug() was last called. Subtract 1054 * this from mTotalTime to find the time since the last unplug from 1055 * power. 1056 */ 1057 protected long mUnpluggedTime; 1058 1059 /** 1060 * The total time this timer has been running until the latest mark has been set. 1061 * Subtract this from mTotalTime to get the time spent running since the mark was set. 1062 */ 1063 protected long mTimeBeforeMark; 1064 1065 /** 1066 * Constructs from a parcel. 1067 * @param type 1068 * @param timeBase 1069 * @param in 1070 */ Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in)1071 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) { 1072 mClocks = clocks; 1073 mType = type; 1074 mTimeBase = timeBase; 1075 1076 mCount = in.readInt(); 1077 mLoadedCount = in.readInt(); 1078 mLastCount = 0; 1079 mUnpluggedCount = in.readInt(); 1080 mTotalTime = in.readLong(); 1081 mLoadedTime = in.readLong(); 1082 mLastTime = 0; 1083 mUnpluggedTime = in.readLong(); 1084 mTimeBeforeMark = in.readLong(); 1085 timeBase.add(this); 1086 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime); 1087 } 1088 Timer(Clocks clocks, int type, TimeBase timeBase)1089 public Timer(Clocks clocks, int type, TimeBase timeBase) { 1090 mClocks = clocks; 1091 mType = type; 1092 mTimeBase = timeBase; 1093 timeBase.add(this); 1094 } 1095 computeRunTimeLocked(long curBatteryRealtime)1096 protected abstract long computeRunTimeLocked(long curBatteryRealtime); 1097 computeCurrentCountLocked()1098 protected abstract int computeCurrentCountLocked(); 1099 1100 /** 1101 * Clear state of this timer. Returns true if the timer is inactive 1102 * so can be completely dropped. 1103 */ reset(boolean detachIfReset)1104 public boolean reset(boolean detachIfReset) { 1105 mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0; 1106 mCount = mLoadedCount = mLastCount = 0; 1107 if (detachIfReset) { 1108 detach(); 1109 } 1110 return true; 1111 } 1112 detach()1113 public void detach() { 1114 mTimeBase.remove(this); 1115 } 1116 writeToParcel(Parcel out, long elapsedRealtimeUs)1117 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1118 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 1119 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1120 out.writeInt(computeCurrentCountLocked()); 1121 out.writeInt(mLoadedCount); 1122 out.writeInt(mUnpluggedCount); 1123 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1124 out.writeLong(mLoadedTime); 1125 out.writeLong(mUnpluggedTime); 1126 out.writeLong(mTimeBeforeMark); 1127 } 1128 1129 @Override onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime)1130 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) { 1131 if (DEBUG && mType < 0) { 1132 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime 1133 + " old mUnpluggedTime=" + mUnpluggedTime 1134 + " old mUnpluggedCount=" + mUnpluggedCount); 1135 } 1136 mUnpluggedTime = computeRunTimeLocked(baseRealtime); 1137 mUnpluggedCount = computeCurrentCountLocked(); 1138 if (DEBUG && mType < 0) { 1139 Log.v(TAG, "unplug #" + mType 1140 + ": new mUnpluggedTime=" + mUnpluggedTime 1141 + " new mUnpluggedCount=" + mUnpluggedCount); 1142 } 1143 } 1144 1145 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1146 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1147 if (DEBUG && mType < 0) { 1148 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime 1149 + " old mTotalTime=" + mTotalTime); 1150 } 1151 mTotalTime = computeRunTimeLocked(baseRealtime); 1152 mCount = computeCurrentCountLocked(); 1153 if (DEBUG && mType < 0) { 1154 Log.v(TAG, "plug #" + mType 1155 + ": new mTotalTime=" + mTotalTime); 1156 } 1157 } 1158 1159 /** 1160 * Writes a possibly null Timer to a Parcel. 1161 * 1162 * @param out the Parcel to be written to. 1163 * @param timer a Timer, or null. 1164 */ writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)1165 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 1166 if (timer == null) { 1167 out.writeInt(0); // indicates null 1168 return; 1169 } 1170 out.writeInt(1); // indicates non-null 1171 1172 timer.writeToParcel(out, elapsedRealtimeUs); 1173 } 1174 1175 @Override getTotalTimeLocked(long elapsedRealtimeUs, int which)1176 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 1177 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1178 if (which == STATS_SINCE_UNPLUGGED) { 1179 val -= mUnpluggedTime; 1180 } else if (which != STATS_SINCE_CHARGED) { 1181 val -= mLoadedTime; 1182 } 1183 1184 return val; 1185 } 1186 1187 @Override getCountLocked(int which)1188 public int getCountLocked(int which) { 1189 int val = computeCurrentCountLocked(); 1190 if (which == STATS_SINCE_UNPLUGGED) { 1191 val -= mUnpluggedCount; 1192 } else if (which != STATS_SINCE_CHARGED) { 1193 val -= mLoadedCount; 1194 } 1195 1196 return val; 1197 } 1198 1199 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)1200 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 1201 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1202 return val - mTimeBeforeMark; 1203 } 1204 1205 @Override logState(Printer pw, String prefix)1206 public void logState(Printer pw, String prefix) { 1207 pw.println(prefix + "mCount=" + mCount 1208 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 1209 + " mUnpluggedCount=" + mUnpluggedCount); 1210 pw.println(prefix + "mTotalTime=" + mTotalTime 1211 + " mLoadedTime=" + mLoadedTime); 1212 pw.println(prefix + "mLastTime=" + mLastTime 1213 + " mUnpluggedTime=" + mUnpluggedTime); 1214 } 1215 1216 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)1217 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 1218 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1219 out.writeLong(runTime); 1220 out.writeInt(computeCurrentCountLocked()); 1221 } 1222 readSummaryFromParcelLocked(Parcel in)1223 public void readSummaryFromParcelLocked(Parcel in) { 1224 // Multiply by 1000 for backwards compatibility 1225 mTotalTime = mLoadedTime = in.readLong(); 1226 mLastTime = 0; 1227 mUnpluggedTime = mTotalTime; 1228 mCount = mLoadedCount = in.readInt(); 1229 mLastCount = 0; 1230 mUnpluggedCount = mCount; 1231 1232 // When reading the summary, we set the mark to be the latest information. 1233 mTimeBeforeMark = mTotalTime; 1234 } 1235 } 1236 1237 /** 1238 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 1239 * method. The state of the timer according to its {@link TimeBase} will determine how much 1240 * of the value is recorded. 1241 * 1242 * If the value being recorded resets, {@link #endSample()} can be called in order to 1243 * account for the change. If the value passed in to {@link #update(long, int)} decreased 1244 * between calls, the {@link #endSample()} is automatically called and the new value is 1245 * expected to increase monotonically from that point on. 1246 */ 1247 public static class SamplingTimer extends Timer { 1248 1249 /** 1250 * The most recent reported count from /proc/wakelocks. 1251 */ 1252 int mCurrentReportedCount; 1253 1254 /** 1255 * The reported count from /proc/wakelocks when unplug() was last 1256 * called. 1257 */ 1258 int mUnpluggedReportedCount; 1259 1260 /** 1261 * The most recent reported total_time from /proc/wakelocks. 1262 */ 1263 long mCurrentReportedTotalTime; 1264 1265 1266 /** 1267 * The reported total_time from /proc/wakelocks when unplug() was last 1268 * called. 1269 */ 1270 long mUnpluggedReportedTotalTime; 1271 1272 /** 1273 * Whether we are currently in a discharge cycle. 1274 */ 1275 boolean mTimeBaseRunning; 1276 1277 /** 1278 * Whether we are currently recording reported values. 1279 */ 1280 boolean mTrackingReportedValues; 1281 1282 /* 1283 * A sequence counter, incremented once for each update of the stats. 1284 */ 1285 int mUpdateVersion; 1286 1287 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in)1288 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) { 1289 super(clocks, 0, timeBase, in); 1290 mCurrentReportedCount = in.readInt(); 1291 mUnpluggedReportedCount = in.readInt(); 1292 mCurrentReportedTotalTime = in.readLong(); 1293 mUnpluggedReportedTotalTime = in.readLong(); 1294 mTrackingReportedValues = in.readInt() == 1; 1295 mTimeBaseRunning = timeBase.isRunning(); 1296 } 1297 1298 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase)1299 public SamplingTimer(Clocks clocks, TimeBase timeBase) { 1300 super(clocks, 0, timeBase); 1301 mTrackingReportedValues = false; 1302 mTimeBaseRunning = timeBase.isRunning(); 1303 } 1304 1305 /** 1306 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 1307 * be less than the values used for a previous invocation. 1308 */ endSample()1309 public void endSample() { 1310 mTotalTime = computeRunTimeLocked(0 /* unused by us */); 1311 mCount = computeCurrentCountLocked(); 1312 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0; 1313 mUnpluggedReportedCount = mCurrentReportedCount = 0; 1314 } 1315 setUpdateVersion(int version)1316 public void setUpdateVersion(int version) { 1317 mUpdateVersion = version; 1318 } 1319 getUpdateVersion()1320 public int getUpdateVersion() { 1321 return mUpdateVersion; 1322 } 1323 1324 /** 1325 * Updates the current recorded values. These are meant to be monotonically increasing 1326 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 1327 * 1328 * If the values being recorded have been reset, the monotonically increasing requirement 1329 * will be broken. In this case, {@link #endSample()} is automatically called and 1330 * the total value of totalTime and count are recorded, starting a new monotonically 1331 * increasing sample. 1332 * 1333 * @param totalTime total time of sample in microseconds. 1334 * @param count total number of times the event being sampled occurred. 1335 */ update(long totalTime, int count)1336 public void update(long totalTime, int count) { 1337 if (mTimeBaseRunning && !mTrackingReportedValues) { 1338 // Updating the reported value for the first time. 1339 mUnpluggedReportedTotalTime = totalTime; 1340 mUnpluggedReportedCount = count; 1341 } 1342 1343 mTrackingReportedValues = true; 1344 1345 if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) { 1346 endSample(); 1347 } 1348 1349 mCurrentReportedTotalTime = totalTime; 1350 mCurrentReportedCount = count; 1351 } 1352 1353 /** 1354 * Adds deltaTime and deltaCount to the current sample. 1355 * 1356 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 1357 * @param deltaCount additional number of times the event being sampled occurred. 1358 */ add(long deltaTime, int deltaCount)1359 public void add(long deltaTime, int deltaCount) { 1360 update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount); 1361 } 1362 1363 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1364 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1365 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 1366 if (mTrackingReportedValues) { 1367 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; 1368 mUnpluggedReportedCount = mCurrentReportedCount; 1369 } 1370 mTimeBaseRunning = true; 1371 } 1372 1373 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1374 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1375 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 1376 mTimeBaseRunning = false; 1377 } 1378 1379 @Override logState(Printer pw, String prefix)1380 public void logState(Printer pw, String prefix) { 1381 super.logState(pw, prefix); 1382 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 1383 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 1384 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime 1385 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); 1386 } 1387 1388 @Override computeRunTimeLocked(long curBatteryRealtime)1389 protected long computeRunTimeLocked(long curBatteryRealtime) { 1390 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues 1391 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); 1392 } 1393 1394 @Override computeCurrentCountLocked()1395 protected int computeCurrentCountLocked() { 1396 return mCount + (mTimeBaseRunning && mTrackingReportedValues 1397 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 1398 } 1399 1400 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)1401 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1402 super.writeToParcel(out, elapsedRealtimeUs); 1403 out.writeInt(mCurrentReportedCount); 1404 out.writeInt(mUnpluggedReportedCount); 1405 out.writeLong(mCurrentReportedTotalTime); 1406 out.writeLong(mUnpluggedReportedTotalTime); 1407 out.writeInt(mTrackingReportedValues ? 1 : 0); 1408 } 1409 1410 @Override reset(boolean detachIfReset)1411 public boolean reset(boolean detachIfReset) { 1412 super.reset(detachIfReset); 1413 mTrackingReportedValues = false; 1414 mUnpluggedReportedTotalTime = 0; 1415 mUnpluggedReportedCount = 0; 1416 return true; 1417 } 1418 1419 @Override writeSummaryFromParcelLocked(Parcel out, long batteryRealtime)1420 public void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) { 1421 super.writeSummaryFromParcelLocked(out, batteryRealtime); 1422 out.writeLong(mCurrentReportedTotalTime); 1423 out.writeInt(mCurrentReportedCount); 1424 out.writeInt(mTrackingReportedValues ? 1 : 0); 1425 } 1426 1427 @Override readSummaryFromParcelLocked(Parcel in)1428 public void readSummaryFromParcelLocked(Parcel in) { 1429 super.readSummaryFromParcelLocked(in); 1430 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong(); 1431 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt(); 1432 mTrackingReportedValues = in.readInt() == 1; 1433 } 1434 } 1435 1436 /** 1437 * A timer that increments in batches. It does not run for durations, but just jumps 1438 * for a pre-determined amount. 1439 */ 1440 public static class BatchTimer extends Timer { 1441 final Uid mUid; 1442 1443 /** 1444 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 1445 */ 1446 long mLastAddedTime; 1447 1448 /** 1449 * The last duration that we added to the timer. This is in microseconds. 1450 */ 1451 long mLastAddedDuration; 1452 1453 /** 1454 * Whether we are currently in a discharge cycle. 1455 */ 1456 boolean mInDischarge; 1457 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in)1458 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) { 1459 super(clocks, type, timeBase, in); 1460 mUid = uid; 1461 mLastAddedTime = in.readLong(); 1462 mLastAddedDuration = in.readLong(); 1463 mInDischarge = timeBase.isRunning(); 1464 } 1465 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase)1466 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) { 1467 super(clocks, type, timeBase); 1468 mUid = uid; 1469 mInDischarge = timeBase.isRunning(); 1470 } 1471 1472 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)1473 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1474 super.writeToParcel(out, elapsedRealtimeUs); 1475 out.writeLong(mLastAddedTime); 1476 out.writeLong(mLastAddedDuration); 1477 } 1478 1479 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1480 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1481 recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false); 1482 mInDischarge = false; 1483 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 1484 } 1485 1486 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1487 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1488 recomputeLastDuration(elapsedRealtime, false); 1489 mInDischarge = true; 1490 // If we are still within the last added duration, then re-added whatever remains. 1491 if (mLastAddedTime == elapsedRealtime) { 1492 mTotalTime += mLastAddedDuration; 1493 } 1494 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 1495 } 1496 1497 @Override logState(Printer pw, String prefix)1498 public void logState(Printer pw, String prefix) { 1499 super.logState(pw, prefix); 1500 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime 1501 + " mLastAddedDuration=" + mLastAddedDuration); 1502 } 1503 computeOverage(long curTime)1504 private long computeOverage(long curTime) { 1505 if (mLastAddedTime > 0) { 1506 return mLastTime + mLastAddedDuration - curTime; 1507 } 1508 return 0; 1509 } 1510 recomputeLastDuration(long curTime, boolean abort)1511 private void recomputeLastDuration(long curTime, boolean abort) { 1512 final long overage = computeOverage(curTime); 1513 if (overage > 0) { 1514 // Aborting before the duration ran out -- roll back the remaining 1515 // duration. Only do this if currently discharging; otherwise we didn't 1516 // actually add the time. 1517 if (mInDischarge) { 1518 mTotalTime -= overage; 1519 } 1520 if (abort) { 1521 mLastAddedTime = 0; 1522 } else { 1523 mLastAddedTime = curTime; 1524 mLastAddedDuration -= overage; 1525 } 1526 } 1527 } 1528 addDuration(BatteryStatsImpl stats, long durationMillis)1529 public void addDuration(BatteryStatsImpl stats, long durationMillis) { 1530 final long now = mClocks.elapsedRealtime() * 1000; 1531 recomputeLastDuration(now, true); 1532 mLastAddedTime = now; 1533 mLastAddedDuration = durationMillis * 1000; 1534 if (mInDischarge) { 1535 mTotalTime += mLastAddedDuration; 1536 mCount++; 1537 } 1538 } 1539 abortLastDuration(BatteryStatsImpl stats)1540 public void abortLastDuration(BatteryStatsImpl stats) { 1541 final long now = mClocks.elapsedRealtime() * 1000; 1542 recomputeLastDuration(now, true); 1543 } 1544 1545 @Override computeCurrentCountLocked()1546 protected int computeCurrentCountLocked() { 1547 return mCount; 1548 } 1549 1550 @Override computeRunTimeLocked(long curBatteryRealtime)1551 protected long computeRunTimeLocked(long curBatteryRealtime) { 1552 final long overage = computeOverage(mClocks.elapsedRealtime() * 1000); 1553 if (overage > 0) { 1554 return mTotalTime = overage; 1555 } 1556 return mTotalTime; 1557 } 1558 1559 @Override reset(boolean detachIfReset)1560 public boolean reset(boolean detachIfReset) { 1561 final long now = mClocks.elapsedRealtime() * 1000; 1562 recomputeLastDuration(now, true); 1563 boolean stillActive = mLastAddedTime == now; 1564 super.reset(!stillActive && detachIfReset); 1565 return !stillActive; 1566 } 1567 } 1568 1569 /** 1570 * State for keeping track of timing information. 1571 */ 1572 public static class StopwatchTimer extends Timer { 1573 final Uid mUid; 1574 final ArrayList<StopwatchTimer> mTimerPool; 1575 1576 int mNesting; 1577 1578 /** 1579 * The last time at which we updated the timer. If mNesting is > 0, 1580 * subtract this from the current battery time to find the amount of 1581 * time we have been running since we last computed an update. 1582 */ 1583 long mUpdateTime; 1584 1585 /** 1586 * The total time at which the timer was acquired, to determine if it 1587 * was actually held for an interesting duration. 1588 */ 1589 long mAcquireTime; 1590 1591 long mTimeout; 1592 1593 /** 1594 * For partial wake locks, keep track of whether we are in the list 1595 * to consume CPU cycles. 1596 */ 1597 boolean mInList; 1598 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)1599 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 1600 TimeBase timeBase, Parcel in) { 1601 super(clocks, type, timeBase, in); 1602 mUid = uid; 1603 mTimerPool = timerPool; 1604 mUpdateTime = in.readLong(); 1605 } 1606 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)1607 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 1608 TimeBase timeBase) { 1609 super(clocks, type, timeBase); 1610 mUid = uid; 1611 mTimerPool = timerPool; 1612 } 1613 setTimeout(long timeout)1614 public void setTimeout(long timeout) { 1615 mTimeout = timeout; 1616 } 1617 writeToParcel(Parcel out, long elapsedRealtimeUs)1618 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1619 super.writeToParcel(out, elapsedRealtimeUs); 1620 out.writeLong(mUpdateTime); 1621 } 1622 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1623 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1624 if (mNesting > 0) { 1625 if (DEBUG && mType < 0) { 1626 Log.v(TAG, "old mUpdateTime=" + mUpdateTime); 1627 } 1628 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 1629 mUpdateTime = baseRealtime; 1630 if (DEBUG && mType < 0) { 1631 Log.v(TAG, "new mUpdateTime=" + mUpdateTime); 1632 } 1633 } 1634 } 1635 logState(Printer pw, String prefix)1636 public void logState(Printer pw, String prefix) { 1637 super.logState(pw, prefix); 1638 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime 1639 + " mAcquireTime=" + mAcquireTime); 1640 } 1641 startRunningLocked(long elapsedRealtimeMs)1642 public void startRunningLocked(long elapsedRealtimeMs) { 1643 if (mNesting++ == 0) { 1644 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 1645 mUpdateTime = batteryRealtime; 1646 if (mTimerPool != null) { 1647 // Accumulate time to all currently active timers before adding 1648 // this new one to the pool. 1649 refreshTimersLocked(batteryRealtime, mTimerPool, null); 1650 // Add this timer to the active pool 1651 mTimerPool.add(this); 1652 } 1653 // Increment the count 1654 mCount++; 1655 mAcquireTime = mTotalTime; 1656 if (DEBUG && mType < 0) { 1657 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime 1658 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 1659 + " mAcquireTime=" + mAcquireTime); 1660 } 1661 } 1662 } 1663 isRunningLocked()1664 public boolean isRunningLocked() { 1665 return mNesting > 0; 1666 } 1667 stopRunningLocked(long elapsedRealtimeMs)1668 public void stopRunningLocked(long elapsedRealtimeMs) { 1669 // Ignore attempt to stop a timer that isn't running 1670 if (mNesting == 0) { 1671 return; 1672 } 1673 if (--mNesting == 0) { 1674 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 1675 if (mTimerPool != null) { 1676 // Accumulate time to all active counters, scaled by the total 1677 // active in the pool, before taking this one out of the pool. 1678 refreshTimersLocked(batteryRealtime, mTimerPool, null); 1679 // Remove this timer from the active pool 1680 mTimerPool.remove(this); 1681 } else { 1682 mNesting = 1; 1683 mTotalTime = computeRunTimeLocked(batteryRealtime); 1684 mNesting = 0; 1685 } 1686 1687 if (DEBUG && mType < 0) { 1688 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime 1689 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 1690 + " mAcquireTime=" + mAcquireTime); 1691 } 1692 1693 if (mTotalTime == mAcquireTime) { 1694 // If there was no change in the time, then discard this 1695 // count. A somewhat cheezy strategy, but hey. 1696 mCount--; 1697 } 1698 } 1699 } 1700 stopAllRunningLocked(long elapsedRealtimeMs)1701 public void stopAllRunningLocked(long elapsedRealtimeMs) { 1702 if (mNesting > 0) { 1703 mNesting = 1; 1704 stopRunningLocked(elapsedRealtimeMs); 1705 } 1706 } 1707 1708 // Update the total time for all other running Timers with the same type as this Timer 1709 // due to a change in timer count refreshTimersLocked(long batteryRealtime, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)1710 private static long refreshTimersLocked(long batteryRealtime, 1711 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 1712 long selfTime = 0; 1713 final int N = pool.size(); 1714 for (int i=N-1; i>= 0; i--) { 1715 final StopwatchTimer t = pool.get(i); 1716 long heldTime = batteryRealtime - t.mUpdateTime; 1717 if (heldTime > 0) { 1718 final long myTime = heldTime / N; 1719 if (t == self) { 1720 selfTime = myTime; 1721 } 1722 t.mTotalTime += myTime; 1723 } 1724 t.mUpdateTime = batteryRealtime; 1725 } 1726 return selfTime; 1727 } 1728 1729 @Override computeRunTimeLocked(long curBatteryRealtime)1730 protected long computeRunTimeLocked(long curBatteryRealtime) { 1731 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { 1732 curBatteryRealtime = mUpdateTime + mTimeout; 1733 } 1734 return mTotalTime + (mNesting > 0 1735 ? (curBatteryRealtime - mUpdateTime) 1736 / (mTimerPool != null ? mTimerPool.size() : 1) 1737 : 0); 1738 } 1739 1740 @Override computeCurrentCountLocked()1741 protected int computeCurrentCountLocked() { 1742 return mCount; 1743 } 1744 1745 @Override reset(boolean detachIfReset)1746 public boolean reset(boolean detachIfReset) { 1747 boolean canDetach = mNesting <= 0; 1748 super.reset(canDetach && detachIfReset); 1749 if (mNesting > 0) { 1750 mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000); 1751 } 1752 mAcquireTime = mTotalTime; 1753 return canDetach; 1754 } 1755 1756 @Override detach()1757 public void detach() { 1758 super.detach(); 1759 if (mTimerPool != null) { 1760 mTimerPool.remove(this); 1761 } 1762 } 1763 1764 @Override readSummaryFromParcelLocked(Parcel in)1765 public void readSummaryFromParcelLocked(Parcel in) { 1766 super.readSummaryFromParcelLocked(in); 1767 mNesting = 0; 1768 } 1769 1770 /** 1771 * Set the mark so that we can query later for the total time the timer has 1772 * accumulated since this point. The timer can be running or not. 1773 * 1774 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 1775 */ setMark(long elapsedRealtimeMs)1776 public void setMark(long elapsedRealtimeMs) { 1777 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 1778 if (mNesting > 0) { 1779 // We are running. 1780 if (mTimerPool != null) { 1781 refreshTimersLocked(batteryRealtime, mTimerPool, this); 1782 } else { 1783 mTotalTime += batteryRealtime - mUpdateTime; 1784 mUpdateTime = batteryRealtime; 1785 } 1786 } 1787 mTimeBeforeMark = mTotalTime; 1788 } 1789 } 1790 1791 public abstract class OverflowArrayMap<T> { 1792 private static final String OVERFLOW_NAME = "*overflow*"; 1793 1794 final ArrayMap<String, T> mMap = new ArrayMap<>(); 1795 T mCurOverflow; 1796 ArrayMap<String, MutableInt> mActiveOverflow; 1797 OverflowArrayMap()1798 public OverflowArrayMap() { 1799 } 1800 getMap()1801 public ArrayMap<String, T> getMap() { 1802 return mMap; 1803 } 1804 clear()1805 public void clear() { 1806 mMap.clear(); 1807 mCurOverflow = null; 1808 mActiveOverflow = null; 1809 } 1810 add(String name, T obj)1811 public void add(String name, T obj) { 1812 if (name == null) { 1813 name = ""; 1814 } 1815 mMap.put(name, obj); 1816 if (OVERFLOW_NAME.equals(name)) { 1817 mCurOverflow = obj; 1818 } 1819 } 1820 cleanup()1821 public void cleanup() { 1822 if (mActiveOverflow != null) { 1823 if (mActiveOverflow.size() == 0) { 1824 mActiveOverflow = null; 1825 } 1826 } 1827 if (mActiveOverflow == null) { 1828 // There is no currently active overflow, so we should no longer have 1829 // an overflow entry. 1830 if (mMap.containsKey(OVERFLOW_NAME)) { 1831 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 1832 + mMap.get(OVERFLOW_NAME)); 1833 mMap.remove(OVERFLOW_NAME); 1834 } 1835 mCurOverflow = null; 1836 } else { 1837 // There is currently active overflow, so we should still have an overflow entry. 1838 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 1839 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 1840 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 1841 } 1842 } 1843 } 1844 startObject(String name)1845 public T startObject(String name) { 1846 if (name == null) { 1847 name = ""; 1848 } 1849 T obj = mMap.get(name); 1850 if (obj != null) { 1851 return obj; 1852 } 1853 1854 // No object exists for the given name, but do we currently have it 1855 // running as part of the overflow? 1856 if (mActiveOverflow != null) { 1857 MutableInt over = mActiveOverflow.get(name); 1858 if (over != null) { 1859 // We are already actively counting this name in the overflow object. 1860 obj = mCurOverflow; 1861 if (obj == null) { 1862 // Shouldn't be here, but we'll try to recover. 1863 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 1864 obj = mCurOverflow = instantiateObject(); 1865 mMap.put(OVERFLOW_NAME, obj); 1866 } 1867 over.value++; 1868 return obj; 1869 } 1870 } 1871 1872 // No object exists for given name nor in the overflow; we need to make 1873 // a new one. 1874 final int N = mMap.size(); 1875 if (N >= MAX_WAKELOCKS_PER_UID) { 1876 // Went over the limit on number of objects to track; this one goes 1877 // in to the overflow. 1878 obj = mCurOverflow; 1879 if (obj == null) { 1880 // Need to start overflow now... 1881 obj = mCurOverflow = instantiateObject(); 1882 mMap.put(OVERFLOW_NAME, obj); 1883 } 1884 if (mActiveOverflow == null) { 1885 mActiveOverflow = new ArrayMap<>(); 1886 } 1887 mActiveOverflow.put(name, new MutableInt(1)); 1888 return obj; 1889 } 1890 1891 // Normal case where we just need to make a new object. 1892 obj = instantiateObject(); 1893 mMap.put(name, obj); 1894 return obj; 1895 } 1896 stopObject(String name)1897 public T stopObject(String name) { 1898 if (name == null) { 1899 name = ""; 1900 } 1901 T obj = mMap.get(name); 1902 if (obj != null) { 1903 return obj; 1904 } 1905 1906 // No object exists for the given name, but do we currently have it 1907 // running as part of the overflow? 1908 if (mActiveOverflow != null) { 1909 MutableInt over = mActiveOverflow.get(name); 1910 if (over != null) { 1911 // We are already actively counting this name in the overflow object. 1912 obj = mCurOverflow; 1913 if (obj != null) { 1914 over.value--; 1915 if (over.value <= 0) { 1916 mActiveOverflow.remove(name); 1917 } 1918 return obj; 1919 } 1920 } 1921 } 1922 1923 // Huh, they are stopping an active operation but we can't find one! 1924 // That's not good. 1925 Slog.wtf(TAG, "Unable to find object for " + name + " mapsize=" 1926 + mMap.size() + " activeoverflow=" + mActiveOverflow 1927 + " curoverflow=" + mCurOverflow); 1928 return null; 1929 } 1930 instantiateObject()1931 public abstract T instantiateObject(); 1932 } 1933 1934 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 1935 implements Parcelable { 1936 private final LongSamplingCounter mIdleTimeMillis; 1937 private final LongSamplingCounter mRxTimeMillis; 1938 private final LongSamplingCounter[] mTxTimeMillis; 1939 private final LongSamplingCounter mPowerDrainMaMs; 1940 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates)1941 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) { 1942 mIdleTimeMillis = new LongSamplingCounter(timeBase); 1943 mRxTimeMillis = new LongSamplingCounter(timeBase); 1944 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 1945 for (int i = 0; i < numTxStates; i++) { 1946 mTxTimeMillis[i] = new LongSamplingCounter(timeBase); 1947 } 1948 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 1949 } 1950 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in)1951 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) { 1952 mIdleTimeMillis = new LongSamplingCounter(timeBase, in); 1953 mRxTimeMillis = new LongSamplingCounter(timeBase, in); 1954 final int recordedTxStates = in.readInt(); 1955 if (recordedTxStates != numTxStates) { 1956 throw new ParcelFormatException("inconsistent tx state lengths"); 1957 } 1958 1959 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 1960 for (int i = 0; i < numTxStates; i++) { 1961 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in); 1962 } 1963 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in); 1964 } 1965 readSummaryFromParcel(Parcel in)1966 public void readSummaryFromParcel(Parcel in) { 1967 mIdleTimeMillis.readSummaryFromParcelLocked(in); 1968 mRxTimeMillis.readSummaryFromParcelLocked(in); 1969 final int recordedTxStates = in.readInt(); 1970 if (recordedTxStates != mTxTimeMillis.length) { 1971 throw new ParcelFormatException("inconsistent tx state lengths"); 1972 } 1973 for (LongSamplingCounter counter : mTxTimeMillis) { 1974 counter.readSummaryFromParcelLocked(in); 1975 } 1976 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 1977 } 1978 1979 @Override describeContents()1980 public int describeContents() { 1981 return 0; 1982 } 1983 writeSummaryToParcel(Parcel dest)1984 public void writeSummaryToParcel(Parcel dest) { 1985 mIdleTimeMillis.writeSummaryFromParcelLocked(dest); 1986 mRxTimeMillis.writeSummaryFromParcelLocked(dest); 1987 dest.writeInt(mTxTimeMillis.length); 1988 for (LongSamplingCounter counter : mTxTimeMillis) { 1989 counter.writeSummaryFromParcelLocked(dest); 1990 } 1991 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 1992 } 1993 1994 @Override writeToParcel(Parcel dest, int flags)1995 public void writeToParcel(Parcel dest, int flags) { 1996 mIdleTimeMillis.writeToParcel(dest); 1997 mRxTimeMillis.writeToParcel(dest); 1998 dest.writeInt(mTxTimeMillis.length); 1999 for (LongSamplingCounter counter : mTxTimeMillis) { 2000 counter.writeToParcel(dest); 2001 } 2002 mPowerDrainMaMs.writeToParcel(dest); 2003 } 2004 reset(boolean detachIfReset)2005 public void reset(boolean detachIfReset) { 2006 mIdleTimeMillis.reset(detachIfReset); 2007 mRxTimeMillis.reset(detachIfReset); 2008 for (LongSamplingCounter counter : mTxTimeMillis) { 2009 counter.reset(detachIfReset); 2010 } 2011 mPowerDrainMaMs.reset(detachIfReset); 2012 } 2013 detach()2014 public void detach() { 2015 mIdleTimeMillis.detach(); 2016 mRxTimeMillis.detach(); 2017 for (LongSamplingCounter counter : mTxTimeMillis) { 2018 counter.detach(); 2019 } 2020 mPowerDrainMaMs.detach(); 2021 } 2022 2023 /** 2024 * @return a LongSamplingCounter, measuring time spent in the idle state in 2025 * milliseconds. 2026 */ 2027 @Override getIdleTimeCounter()2028 public LongSamplingCounter getIdleTimeCounter() { 2029 return mIdleTimeMillis; 2030 } 2031 2032 /** 2033 * @return a LongSamplingCounter, measuring time spent in the receive state in 2034 * milliseconds. 2035 */ 2036 @Override getRxTimeCounter()2037 public LongSamplingCounter getRxTimeCounter() { 2038 return mRxTimeMillis; 2039 } 2040 2041 /** 2042 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 2043 * milliseconds. 2044 */ 2045 @Override getTxTimeCounters()2046 public LongSamplingCounter[] getTxTimeCounters() { 2047 return mTxTimeMillis; 2048 } 2049 2050 /** 2051 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 2052 */ 2053 @Override getPowerCounter()2054 public LongSamplingCounter getPowerCounter() { 2055 return mPowerDrainMaMs; 2056 } 2057 } 2058 2059 /* 2060 * Get the wakeup reason counter, and create a new one if one 2061 * doesn't already exist. 2062 */ getWakeupReasonTimerLocked(String name)2063 public SamplingTimer getWakeupReasonTimerLocked(String name) { 2064 SamplingTimer timer = mWakeupReasonStats.get(name); 2065 if (timer == null) { 2066 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 2067 mWakeupReasonStats.put(name, timer); 2068 } 2069 return timer; 2070 } 2071 2072 /* 2073 * Get the KernelWakelockTimer associated with name, and create a new one if one 2074 * doesn't already exist. 2075 */ getKernelWakelockTimerLocked(String name)2076 public SamplingTimer getKernelWakelockTimerLocked(String name) { 2077 SamplingTimer kwlt = mKernelWakelockStats.get(name); 2078 if (kwlt == null) { 2079 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 2080 mKernelWakelockStats.put(name, kwlt); 2081 } 2082 return kwlt; 2083 } 2084 writeHistoryTag(HistoryTag tag)2085 private int writeHistoryTag(HistoryTag tag) { 2086 Integer idxObj = mHistoryTagPool.get(tag); 2087 int idx; 2088 if (idxObj != null) { 2089 idx = idxObj; 2090 } else { 2091 idx = mNextHistoryTagIdx; 2092 HistoryTag key = new HistoryTag(); 2093 key.setTo(tag); 2094 tag.poolIdx = idx; 2095 mHistoryTagPool.put(key, idx); 2096 mNextHistoryTagIdx++; 2097 mNumHistoryTagChars += key.string.length() + 1; 2098 } 2099 return idx; 2100 } 2101 readHistoryTag(int index, HistoryTag tag)2102 private void readHistoryTag(int index, HistoryTag tag) { 2103 tag.string = mReadHistoryStrings[index]; 2104 tag.uid = mReadHistoryUids[index]; 2105 tag.poolIdx = index; 2106 } 2107 2108 /* 2109 The history delta format uses flags to denote further data in subsequent ints in the parcel. 2110 2111 There is always the first token, which may contain the delta time, or an indicator of 2112 the length of the time (int or long) following this token. 2113 2114 First token: always present, 2115 31 23 15 7 0 2116 █M|L|K|J|I|H|G|F█E|D|C|B|A|T|T|T█T|T|T|T|T|T|T|T█T|T|T|T|T|T|T|T█ 2117 2118 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately 2119 follows containing the time, and 0x7ffff indicates a long immediately follows with the 2120 delta time. 2121 A: battery level changed and an int follows with battery data. 2122 B: state changed and an int follows with state change data. 2123 C: state2 has changed and an int follows with state2 change data. 2124 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows. 2125 E: event data has changed and an event struct follows. 2126 F: battery charge in coulombs has changed and an int with the charge follows. 2127 G: state flag denoting that the mobile radio was active. 2128 H: state flag denoting that the wifi radio was active. 2129 I: state flag denoting that a wifi scan occurred. 2130 J: state flag denoting that a wifi full lock was held. 2131 K: state flag denoting that the gps was on. 2132 L: state flag denoting that a wakelock was held. 2133 M: state flag denoting that the cpu was running. 2134 2135 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows 2136 with the time delta. 2137 2138 Battery level int: if A in the first token is set, 2139 31 23 15 7 0 2140 █L|L|L|L|L|L|L|T█T|T|T|T|T|T|T|T█T|V|V|V|V|V|V|V█V|V|V|V|V|V|V|D█ 2141 2142 D: indicates that extra history details follow. 2143 V: the battery voltage. 2144 T: the battery temperature. 2145 L: the battery level (out of 100). 2146 2147 State change int: if B in the first token is set, 2148 31 23 15 7 0 2149 █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █ 2150 2151 A: wifi multicast was on. 2152 B: battery was plugged in. 2153 C: screen was on. 2154 D: phone was scanning for signal. 2155 E: audio was on. 2156 F: a sensor was active. 2157 2158 State2 change int: if C in the first token is set, 2159 31 23 15 7 0 2160 █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█ 2161 2162 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}. 2163 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4. 2164 C: a bluetooth scan was active. 2165 D: the camera was active. 2166 E: bluetooth was on. 2167 F: a phone call was active. 2168 G: the device was charging. 2169 H: 2 bits indicating the device-idle (doze) state: off, light, full 2170 I: the flashlight was on. 2171 J: wifi was on. 2172 K: wifi was running. 2173 L: video was playing. 2174 M: power save mode was on. 2175 2176 Wakelock/wakereason struct: if D in the first token is set, 2177 TODO(adamlesinski): describe wakelock/wakereason struct. 2178 2179 Event struct: if E in the first token is set, 2180 TODO(adamlesinski): describe the event struct. 2181 2182 History step details struct: if D in the battery level int is set, 2183 TODO(adamlesinski): describe the history step details struct. 2184 2185 Battery charge int: if F in the first token is set, an int representing the battery charge 2186 in coulombs follows. 2187 */ 2188 2189 // Part of initial delta int that specifies the time delta. 2190 static final int DELTA_TIME_MASK = 0x7ffff; 2191 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long 2192 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int 2193 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. 2194 // Flag in delta int: a new battery level int follows. 2195 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; 2196 // Flag in delta int: a new full state and battery status int follows. 2197 static final int DELTA_STATE_FLAG = 0x00100000; 2198 // Flag in delta int: a new full state2 int follows. 2199 static final int DELTA_STATE2_FLAG = 0x00200000; 2200 // Flag in delta int: contains a wakelock or wakeReason tag. 2201 static final int DELTA_WAKELOCK_FLAG = 0x00400000; 2202 // Flag in delta int: contains an event description. 2203 static final int DELTA_EVENT_FLAG = 0x00800000; 2204 // Flag in delta int: contains the battery charge count in uAh. 2205 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000; 2206 // These upper bits are the frequently changing state bits. 2207 static final int DELTA_STATE_MASK = 0xfe000000; 2208 2209 // These are the pieces of battery state that are packed in to the upper bits of 2210 // the state int that have been packed in to the first delta int. They must fit 2211 // in STATE_BATTERY_MASK. 2212 static final int STATE_BATTERY_MASK = 0xff000000; 2213 static final int STATE_BATTERY_STATUS_MASK = 0x00000007; 2214 static final int STATE_BATTERY_STATUS_SHIFT = 29; 2215 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007; 2216 static final int STATE_BATTERY_HEALTH_SHIFT = 26; 2217 static final int STATE_BATTERY_PLUG_MASK = 0x00000003; 2218 static final int STATE_BATTERY_PLUG_SHIFT = 24; 2219 2220 // We use the low bit of the battery state int to indicate that we have full details 2221 // from a battery level change. 2222 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; 2223 writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last)2224 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { 2225 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { 2226 dest.writeInt(DELTA_TIME_ABS); 2227 cur.writeToParcel(dest, 0); 2228 return; 2229 } 2230 2231 final long deltaTime = cur.time - last.time; 2232 final int lastBatteryLevelInt = buildBatteryLevelInt(last); 2233 final int lastStateInt = buildStateInt(last); 2234 2235 int deltaTimeToken; 2236 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 2237 deltaTimeToken = DELTA_TIME_LONG; 2238 } else if (deltaTime >= DELTA_TIME_ABS) { 2239 deltaTimeToken = DELTA_TIME_INT; 2240 } else { 2241 deltaTimeToken = (int)deltaTime; 2242 } 2243 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); 2244 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel 2245 ? BATTERY_DELTA_LEVEL_FLAG : 0; 2246 final boolean computeStepDetails = includeStepDetails != 0 2247 || mLastHistoryStepDetails == null; 2248 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; 2249 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 2250 if (batteryLevelIntChanged) { 2251 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 2252 } 2253 final int stateInt = buildStateInt(cur); 2254 final boolean stateIntChanged = stateInt != lastStateInt; 2255 if (stateIntChanged) { 2256 firstToken |= DELTA_STATE_FLAG; 2257 } 2258 final boolean state2IntChanged = cur.states2 != last.states2; 2259 if (state2IntChanged) { 2260 firstToken |= DELTA_STATE2_FLAG; 2261 } 2262 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 2263 firstToken |= DELTA_WAKELOCK_FLAG; 2264 } 2265 if (cur.eventCode != HistoryItem.EVENT_NONE) { 2266 firstToken |= DELTA_EVENT_FLAG; 2267 } 2268 2269 final boolean batteryChargeChanged = cur.batteryChargeUAh != last.batteryChargeUAh; 2270 if (batteryChargeChanged) { 2271 firstToken |= DELTA_BATTERY_CHARGE_FLAG; 2272 } 2273 dest.writeInt(firstToken); 2274 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 2275 + " deltaTime=" + deltaTime); 2276 2277 if (deltaTimeToken >= DELTA_TIME_INT) { 2278 if (deltaTimeToken == DELTA_TIME_INT) { 2279 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 2280 dest.writeInt((int)deltaTime); 2281 } else { 2282 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 2283 dest.writeLong(deltaTime); 2284 } 2285 } 2286 if (batteryLevelIntChanged) { 2287 dest.writeInt(batteryLevelInt); 2288 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 2289 + Integer.toHexString(batteryLevelInt) 2290 + " batteryLevel=" + cur.batteryLevel 2291 + " batteryTemp=" + cur.batteryTemperature 2292 + " batteryVolt=" + (int)cur.batteryVoltage); 2293 } 2294 if (stateIntChanged) { 2295 dest.writeInt(stateInt); 2296 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 2297 + Integer.toHexString(stateInt) 2298 + " batteryStatus=" + cur.batteryStatus 2299 + " batteryHealth=" + cur.batteryHealth 2300 + " batteryPlugType=" + cur.batteryPlugType 2301 + " states=0x" + Integer.toHexString(cur.states)); 2302 } 2303 if (state2IntChanged) { 2304 dest.writeInt(cur.states2); 2305 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x" 2306 + Integer.toHexString(cur.states2)); 2307 } 2308 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 2309 int wakeLockIndex; 2310 int wakeReasonIndex; 2311 if (cur.wakelockTag != null) { 2312 wakeLockIndex = writeHistoryTag(cur.wakelockTag); 2313 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 2314 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 2315 } else { 2316 wakeLockIndex = 0xffff; 2317 } 2318 if (cur.wakeReasonTag != null) { 2319 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag); 2320 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 2321 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 2322 } else { 2323 wakeReasonIndex = 0xffff; 2324 } 2325 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex); 2326 } 2327 if (cur.eventCode != HistoryItem.EVENT_NONE) { 2328 int index = writeHistoryTag(cur.eventTag); 2329 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16); 2330 dest.writeInt(codeAndIndex); 2331 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#" 2332 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 2333 + cur.eventTag.string); 2334 } 2335 if (computeStepDetails) { 2336 if (mPlatformIdleStateCallback != null) { 2337 mCurHistoryStepDetails.statPlatformIdleState = 2338 mPlatformIdleStateCallback.getPlatformLowPowerStats(); 2339 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" + 2340 mCurHistoryStepDetails.statPlatformIdleState); 2341 } 2342 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); 2343 if (includeStepDetails != 0) { 2344 mCurHistoryStepDetails.writeToParcel(dest); 2345 } 2346 cur.stepDetails = mCurHistoryStepDetails; 2347 mLastHistoryStepDetails = mCurHistoryStepDetails; 2348 } else { 2349 cur.stepDetails = null; 2350 } 2351 if (mLastHistoryStepLevel < cur.batteryLevel) { 2352 mLastHistoryStepDetails = null; 2353 } 2354 mLastHistoryStepLevel = cur.batteryLevel; 2355 2356 if (batteryChargeChanged) { 2357 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh); 2358 dest.writeInt(cur.batteryChargeUAh); 2359 } 2360 } 2361 buildBatteryLevelInt(HistoryItem h)2362 private int buildBatteryLevelInt(HistoryItem h) { 2363 return ((((int)h.batteryLevel)<<25)&0xfe000000) 2364 | ((((int)h.batteryTemperature)<<15)&0x01ff8000) 2365 | ((((int)h.batteryVoltage)<<1)&0x00007ffe); 2366 } 2367 readBatteryLevelInt(int batteryLevelInt, HistoryItem out)2368 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) { 2369 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25); 2370 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15); 2371 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1); 2372 } 2373 buildStateInt(HistoryItem h)2374 private int buildStateInt(HistoryItem h) { 2375 int plugType = 0; 2376 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) { 2377 plugType = 1; 2378 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) { 2379 plugType = 2; 2380 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) { 2381 plugType = 3; 2382 } 2383 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT) 2384 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT) 2385 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT) 2386 | (h.states&(~STATE_BATTERY_MASK)); 2387 } 2388 computeHistoryStepDetails(final HistoryStepDetails out, final HistoryStepDetails last)2389 private void computeHistoryStepDetails(final HistoryStepDetails out, 2390 final HistoryStepDetails last) { 2391 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; 2392 2393 // Perform a CPU update right after we do this collection, so we have started 2394 // collecting good data for the next step. 2395 requestImmediateCpuUpdate(); 2396 2397 if (last == null) { 2398 // We are not generating a delta, so all we need to do is reset the stats 2399 // we will later be doing a delta from. 2400 final int NU = mUidStats.size(); 2401 for (int i=0; i<NU; i++) { 2402 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 2403 uid.mLastStepUserTime = uid.mCurStepUserTime; 2404 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 2405 } 2406 mLastStepCpuUserTime = mCurStepCpuUserTime; 2407 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 2408 mLastStepStatUserTime = mCurStepStatUserTime; 2409 mLastStepStatSystemTime = mCurStepStatSystemTime; 2410 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 2411 mLastStepStatIrqTime = mCurStepStatIrqTime; 2412 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 2413 mLastStepStatIdleTime = mCurStepStatIdleTime; 2414 tmp.clear(); 2415 return; 2416 } 2417 if (DEBUG) { 2418 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys=" 2419 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime 2420 + " irq=" + mLastStepStatIrqTime + " sirq=" 2421 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime); 2422 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys=" 2423 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime 2424 + " irq=" + mCurStepStatIrqTime + " sirq=" 2425 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime); 2426 } 2427 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime); 2428 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime); 2429 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime); 2430 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime); 2431 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime); 2432 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime); 2433 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime); 2434 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime); 2435 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; 2436 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; 2437 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; 2438 final int NU = mUidStats.size(); 2439 for (int i=0; i<NU; i++) { 2440 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 2441 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime); 2442 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime); 2443 final int totalTime = totalUTime + totalSTime; 2444 uid.mLastStepUserTime = uid.mCurStepUserTime; 2445 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 2446 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) { 2447 continue; 2448 } 2449 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) { 2450 out.appCpuUid3 = uid.mUid; 2451 out.appCpuUTime3 = totalUTime; 2452 out.appCpuSTime3 = totalSTime; 2453 } else { 2454 out.appCpuUid3 = out.appCpuUid2; 2455 out.appCpuUTime3 = out.appCpuUTime2; 2456 out.appCpuSTime3 = out.appCpuSTime2; 2457 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) { 2458 out.appCpuUid2 = uid.mUid; 2459 out.appCpuUTime2 = totalUTime; 2460 out.appCpuSTime2 = totalSTime; 2461 } else { 2462 out.appCpuUid2 = out.appCpuUid1; 2463 out.appCpuUTime2 = out.appCpuUTime1; 2464 out.appCpuSTime2 = out.appCpuSTime1; 2465 out.appCpuUid1 = uid.mUid; 2466 out.appCpuUTime1 = totalUTime; 2467 out.appCpuSTime1 = totalSTime; 2468 } 2469 } 2470 } 2471 mLastStepCpuUserTime = mCurStepCpuUserTime; 2472 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 2473 mLastStepStatUserTime = mCurStepStatUserTime; 2474 mLastStepStatSystemTime = mCurStepStatSystemTime; 2475 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 2476 mLastStepStatIrqTime = mCurStepStatIrqTime; 2477 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 2478 mLastStepStatIdleTime = mCurStepStatIdleTime; 2479 } 2480 readHistoryDelta(Parcel src, HistoryItem cur)2481 public void readHistoryDelta(Parcel src, HistoryItem cur) { 2482 int firstToken = src.readInt(); 2483 int deltaTimeToken = firstToken&DELTA_TIME_MASK; 2484 cur.cmd = HistoryItem.CMD_UPDATE; 2485 cur.numReadInts = 1; 2486 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) 2487 + " deltaTimeToken=" + deltaTimeToken); 2488 2489 if (deltaTimeToken < DELTA_TIME_ABS) { 2490 cur.time += deltaTimeToken; 2491 } else if (deltaTimeToken == DELTA_TIME_ABS) { 2492 cur.time = src.readLong(); 2493 cur.numReadInts += 2; 2494 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time); 2495 cur.readFromParcel(src); 2496 return; 2497 } else if (deltaTimeToken == DELTA_TIME_INT) { 2498 int delta = src.readInt(); 2499 cur.time += delta; 2500 cur.numReadInts += 1; 2501 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 2502 } else { 2503 long delta = src.readLong(); 2504 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 2505 cur.time += delta; 2506 cur.numReadInts += 2; 2507 } 2508 2509 final int batteryLevelInt; 2510 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) { 2511 batteryLevelInt = src.readInt(); 2512 readBatteryLevelInt(batteryLevelInt, cur); 2513 cur.numReadInts += 1; 2514 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x" 2515 + Integer.toHexString(batteryLevelInt) 2516 + " batteryLevel=" + cur.batteryLevel 2517 + " batteryTemp=" + cur.batteryTemperature 2518 + " batteryVolt=" + (int)cur.batteryVoltage); 2519 } else { 2520 batteryLevelInt = 0; 2521 } 2522 2523 if ((firstToken&DELTA_STATE_FLAG) != 0) { 2524 int stateInt = src.readInt(); 2525 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK)); 2526 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT) 2527 & STATE_BATTERY_STATUS_MASK); 2528 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT) 2529 & STATE_BATTERY_HEALTH_MASK); 2530 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT) 2531 & STATE_BATTERY_PLUG_MASK); 2532 switch (cur.batteryPlugType) { 2533 case 1: 2534 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC; 2535 break; 2536 case 2: 2537 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB; 2538 break; 2539 case 3: 2540 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS; 2541 break; 2542 } 2543 cur.numReadInts += 1; 2544 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x" 2545 + Integer.toHexString(stateInt) 2546 + " batteryStatus=" + cur.batteryStatus 2547 + " batteryHealth=" + cur.batteryHealth 2548 + " batteryPlugType=" + cur.batteryPlugType 2549 + " states=0x" + Integer.toHexString(cur.states)); 2550 } else { 2551 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK)); 2552 } 2553 2554 if ((firstToken&DELTA_STATE2_FLAG) != 0) { 2555 cur.states2 = src.readInt(); 2556 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x" 2557 + Integer.toHexString(cur.states2)); 2558 } 2559 2560 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) { 2561 int indexes = src.readInt(); 2562 int wakeLockIndex = indexes&0xffff; 2563 int wakeReasonIndex = (indexes>>16)&0xffff; 2564 if (wakeLockIndex != 0xffff) { 2565 cur.wakelockTag = cur.localWakelockTag; 2566 readHistoryTag(wakeLockIndex, cur.wakelockTag); 2567 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 2568 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 2569 } else { 2570 cur.wakelockTag = null; 2571 } 2572 if (wakeReasonIndex != 0xffff) { 2573 cur.wakeReasonTag = cur.localWakeReasonTag; 2574 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag); 2575 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 2576 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 2577 } else { 2578 cur.wakeReasonTag = null; 2579 } 2580 cur.numReadInts += 1; 2581 } else { 2582 cur.wakelockTag = null; 2583 cur.wakeReasonTag = null; 2584 } 2585 2586 if ((firstToken&DELTA_EVENT_FLAG) != 0) { 2587 cur.eventTag = cur.localEventTag; 2588 final int codeAndIndex = src.readInt(); 2589 cur.eventCode = (codeAndIndex&0xffff); 2590 final int index = ((codeAndIndex>>16)&0xffff); 2591 readHistoryTag(index, cur.eventTag); 2592 cur.numReadInts += 1; 2593 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#" 2594 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 2595 + cur.eventTag.string); 2596 } else { 2597 cur.eventCode = HistoryItem.EVENT_NONE; 2598 } 2599 2600 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) { 2601 cur.stepDetails = mReadHistoryStepDetails; 2602 cur.stepDetails.readFromParcel(src); 2603 } else { 2604 cur.stepDetails = null; 2605 } 2606 2607 if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) { 2608 cur.batteryChargeUAh = src.readInt(); 2609 } 2610 } 2611 2612 @Override commitCurrentHistoryBatchLocked()2613 public void commitCurrentHistoryBatchLocked() { 2614 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; 2615 } 2616 addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur)2617 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 2618 if (!mHaveBatteryLevel || !mRecordingHistory) { 2619 return; 2620 } 2621 2622 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time; 2623 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates); 2624 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2); 2625 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; 2626 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; 2627 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff=" 2628 + Integer.toHexString(diffStates) + " lastDiff=" 2629 + Integer.toHexString(lastDiffStates) + " diff2=" 2630 + Integer.toHexString(diffStates2) + " lastDiff2=" 2631 + Integer.toHexString(lastDiffStates2)); 2632 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 2633 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 2634 && (diffStates2&lastDiffStates2) == 0 2635 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) 2636 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) 2637 && mHistoryLastWritten.stepDetails == null 2638 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE 2639 || cur.eventCode == HistoryItem.EVENT_NONE) 2640 && mHistoryLastWritten.batteryLevel == cur.batteryLevel 2641 && mHistoryLastWritten.batteryStatus == cur.batteryStatus 2642 && mHistoryLastWritten.batteryHealth == cur.batteryHealth 2643 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType 2644 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature 2645 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) { 2646 // We can merge this new change in with the last one. Merging is 2647 // allowed as long as only the states have changed, and within those states 2648 // as long as no bit has changed both between now and the last entry, as 2649 // well as the last entry and the one before it (so we capture any toggles). 2650 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos); 2651 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 2652 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 2653 mHistoryBufferLastPos = -1; 2654 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime; 2655 // If the last written history had a wakelock tag, we need to retain it. 2656 // Note that the condition above made sure that we aren't in a case where 2657 // both it and the current history item have a wakelock tag. 2658 if (mHistoryLastWritten.wakelockTag != null) { 2659 cur.wakelockTag = cur.localWakelockTag; 2660 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); 2661 } 2662 // If the last written history had a wake reason tag, we need to retain it. 2663 // Note that the condition above made sure that we aren't in a case where 2664 // both it and the current history item have a wakelock tag. 2665 if (mHistoryLastWritten.wakeReasonTag != null) { 2666 cur.wakeReasonTag = cur.localWakeReasonTag; 2667 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); 2668 } 2669 // If the last written history had an event, we need to retain it. 2670 // Note that the condition above made sure that we aren't in a case where 2671 // both it and the current history item have an event. 2672 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { 2673 cur.eventCode = mHistoryLastWritten.eventCode; 2674 cur.eventTag = cur.localEventTag; 2675 cur.eventTag.setTo(mHistoryLastWritten.eventTag); 2676 } 2677 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 2678 } 2679 2680 final int dataSize = mHistoryBuffer.dataSize(); 2681 if (dataSize >= MAX_HISTORY_BUFFER) { 2682 if (!mHistoryOverflow) { 2683 mHistoryOverflow = true; 2684 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur); 2685 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur); 2686 return; 2687 } 2688 2689 // After overflow, we allow various bit-wise states to settle to 0. 2690 boolean writeAnyway = false; 2691 final int curStates = cur.states & HistoryItem.SETTLE_TO_ZERO_STATES 2692 & mActiveHistoryStates; 2693 if (mHistoryLastWritten.states != curStates) { 2694 // mActiveHistoryStates keeps track of which bits in .states are now being 2695 // forced to 0. 2696 int old = mActiveHistoryStates; 2697 mActiveHistoryStates &= curStates | ~HistoryItem.SETTLE_TO_ZERO_STATES; 2698 writeAnyway |= old != mActiveHistoryStates; 2699 } 2700 final int curStates2 = cur.states2 & HistoryItem.SETTLE_TO_ZERO_STATES2 2701 & mActiveHistoryStates2; 2702 if (mHistoryLastWritten.states2 != curStates2) { 2703 // mActiveHistoryStates2 keeps track of which bits in .states2 are now being 2704 // forced to 0. 2705 int old = mActiveHistoryStates2; 2706 mActiveHistoryStates2 &= curStates2 | ~HistoryItem.SETTLE_TO_ZERO_STATES2; 2707 writeAnyway |= old != mActiveHistoryStates2; 2708 } 2709 2710 // Once we've reached the maximum number of items, we only 2711 // record changes to the battery level and the most interesting states. 2712 // Once we've reached the maximum maximum number of items, we only 2713 // record changes to the battery level. 2714 if (!writeAnyway && mHistoryLastWritten.batteryLevel == cur.batteryLevel && 2715 (dataSize >= MAX_MAX_HISTORY_BUFFER 2716 || ((mHistoryLastWritten.states^cur.states) 2717 & HistoryItem.MOST_INTERESTING_STATES) == 0 2718 || ((mHistoryLastWritten.states2^cur.states2) 2719 & HistoryItem.MOST_INTERESTING_STATES2) == 0)) { 2720 return; 2721 } 2722 2723 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur); 2724 return; 2725 } 2726 2727 if (dataSize == 0) { 2728 // The history is currently empty; we need it to start with a time stamp. 2729 cur.currentTime = System.currentTimeMillis(); 2730 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_RESET, cur); 2731 } 2732 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur); 2733 } 2734 addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur)2735 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, 2736 HistoryItem cur) { 2737 if (mIteratingHistory) { 2738 throw new IllegalStateException("Can't do this while iterating history!"); 2739 } 2740 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 2741 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 2742 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 2743 mHistoryLastWritten.states &= mActiveHistoryStates; 2744 mHistoryLastWritten.states2 &= mActiveHistoryStates2; 2745 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 2746 mLastHistoryElapsedRealtime = elapsedRealtimeMs; 2747 cur.wakelockTag = null; 2748 cur.wakeReasonTag = null; 2749 cur.eventCode = HistoryItem.EVENT_NONE; 2750 cur.eventTag = null; 2751 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 2752 + " now " + mHistoryBuffer.dataPosition() 2753 + " size is now " + mHistoryBuffer.dataSize()); 2754 } 2755 2756 int mChangedStates = 0; 2757 int mChangedStates2 = 0; 2758 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs)2759 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { 2760 if (mTrackRunningHistoryElapsedRealtime != 0) { 2761 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime; 2762 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime; 2763 if (diffUptime < (diffElapsed-20)) { 2764 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime); 2765 mHistoryAddTmp.setTo(mHistoryLastWritten); 2766 mHistoryAddTmp.wakelockTag = null; 2767 mHistoryAddTmp.wakeReasonTag = null; 2768 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; 2769 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; 2770 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp); 2771 } 2772 } 2773 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; 2774 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs; 2775 mTrackRunningHistoryUptime = uptimeMs; 2776 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur); 2777 } 2778 addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur)2779 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 2780 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur); 2781 2782 if (!USE_OLD_HISTORY) { 2783 return; 2784 } 2785 2786 if (!mHaveBatteryLevel || !mRecordingHistory) { 2787 return; 2788 } 2789 2790 // If the current time is basically the same as the last time, 2791 // and no states have since the last recorded entry changed and 2792 // are now resetting back to their original value, then just collapse 2793 // into one record. 2794 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE 2795 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000) 2796 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0 2797 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) { 2798 // If the current is the same as the one before, then we no 2799 // longer need the entry. 2800 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE 2801 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500) 2802 && mHistoryLastEnd.sameNonEvent(cur)) { 2803 mHistoryLastEnd.next = null; 2804 mHistoryEnd.next = mHistoryCache; 2805 mHistoryCache = mHistoryEnd; 2806 mHistoryEnd = mHistoryLastEnd; 2807 mHistoryLastEnd = null; 2808 } else { 2809 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates); 2810 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2); 2811 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur); 2812 } 2813 return; 2814 } 2815 2816 mChangedStates = 0; 2817 mChangedStates2 = 0; 2818 2819 if (mNumHistoryItems == MAX_HISTORY_ITEMS 2820 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) { 2821 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW); 2822 } 2823 2824 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) { 2825 // Once we've reached the maximum number of items, we only 2826 // record changes to the battery level and the most interesting states. 2827 // Once we've reached the maximum maximum number of items, we only 2828 // record changes to the battery level. 2829 if (mHistoryEnd != null && mHistoryEnd.batteryLevel 2830 == cur.batteryLevel && 2831 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS 2832 || ((mHistoryEnd.states^(cur.states&mActiveHistoryStates)) 2833 & HistoryItem.MOST_INTERESTING_STATES) == 0)) { 2834 return; 2835 } 2836 } 2837 2838 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE); 2839 } 2840 addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)2841 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 2842 String name, int uid) { 2843 mHistoryCur.eventCode = code; 2844 mHistoryCur.eventTag = mHistoryCur.localEventTag; 2845 mHistoryCur.eventTag.string = name; 2846 mHistoryCur.eventTag.uid = uid; 2847 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 2848 } 2849 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur)2850 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { 2851 HistoryItem rec = mHistoryCache; 2852 if (rec != null) { 2853 mHistoryCache = rec.next; 2854 } else { 2855 rec = new HistoryItem(); 2856 } 2857 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 2858 2859 addHistoryRecordLocked(rec); 2860 } 2861 addHistoryRecordLocked(HistoryItem rec)2862 void addHistoryRecordLocked(HistoryItem rec) { 2863 mNumHistoryItems++; 2864 rec.next = null; 2865 mHistoryLastEnd = mHistoryEnd; 2866 if (mHistoryEnd != null) { 2867 mHistoryEnd.next = rec; 2868 mHistoryEnd = rec; 2869 } else { 2870 mHistory = mHistoryEnd = rec; 2871 } 2872 } 2873 clearHistoryLocked()2874 void clearHistoryLocked() { 2875 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 2876 if (USE_OLD_HISTORY) { 2877 if (mHistory != null) { 2878 mHistoryEnd.next = mHistoryCache; 2879 mHistoryCache = mHistory; 2880 mHistory = mHistoryLastEnd = mHistoryEnd = null; 2881 } 2882 mNumHistoryItems = 0; 2883 } 2884 2885 mHistoryBaseTime = 0; 2886 mLastHistoryElapsedRealtime = 0; 2887 mTrackRunningHistoryElapsedRealtime = 0; 2888 mTrackRunningHistoryUptime = 0; 2889 2890 mHistoryBuffer.setDataSize(0); 2891 mHistoryBuffer.setDataPosition(0); 2892 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2); 2893 mHistoryLastLastWritten.clear(); 2894 mHistoryLastWritten.clear(); 2895 mHistoryTagPool.clear(); 2896 mNextHistoryTagIdx = 0; 2897 mNumHistoryTagChars = 0; 2898 mHistoryBufferLastPos = -1; 2899 mHistoryOverflow = false; 2900 mActiveHistoryStates = 0xffffffff; 2901 mActiveHistoryStates2 = 0xffffffff; 2902 } 2903 updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime, long realtime)2904 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime, 2905 long realtime) { 2906 mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime); 2907 2908 boolean unpluggedScreenOff = unplugged && screenOff; 2909 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) { 2910 updateKernelWakelocksLocked(); 2911 if (DEBUG_ENERGY_CPU) { 2912 Slog.d(TAG, "Updating cpu time because screen is now " + 2913 (unpluggedScreenOff ? "off" : "on")); 2914 } 2915 updateCpuTimeLocked(); 2916 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime); 2917 } 2918 } 2919 addIsolatedUidLocked(int isolatedUid, int appUid)2920 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 2921 mIsolatedUids.put(isolatedUid, appUid); 2922 } 2923 2924 /** 2925 * Schedules a read of the latest cpu times before removing the isolated UID. 2926 * @see #removeIsolatedUidLocked(int) 2927 */ scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid)2928 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { 2929 int curUid = mIsolatedUids.get(isolatedUid, -1); 2930 if (curUid == appUid) { 2931 if (mExternalSync != null) { 2932 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 2933 } 2934 } 2935 } 2936 2937 /** 2938 * This should only be called after the cpu times have been read. 2939 * @see #scheduleRemoveIsolatedUidLocked(int, int) 2940 */ removeIsolatedUidLocked(int isolatedUid)2941 public void removeIsolatedUidLocked(int isolatedUid) { 2942 mIsolatedUids.delete(isolatedUid); 2943 mKernelUidCpuTimeReader.removeUid(isolatedUid); 2944 } 2945 mapUid(int uid)2946 public int mapUid(int uid) { 2947 int isolated = mIsolatedUids.get(uid, -1); 2948 return isolated > 0 ? isolated : uid; 2949 } 2950 noteEventLocked(int code, String name, int uid)2951 public void noteEventLocked(int code, String name, int uid) { 2952 uid = mapUid(uid); 2953 if (!mActiveEvents.updateState(code, name, uid, 0)) { 2954 return; 2955 } 2956 final long elapsedRealtime = mClocks.elapsedRealtime(); 2957 final long uptime = mClocks.uptimeMillis(); 2958 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); 2959 } 2960 ensureStartClockTime(final long currentTime)2961 boolean ensureStartClockTime(final long currentTime) { 2962 final long ABOUT_ONE_YEAR = 365*24*60*60*1000L; 2963 if (currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) { 2964 // If the start clock time has changed by more than a year, then presumably 2965 // the previous time was completely bogus. So we are going to figure out a 2966 // new time based on how much time has elapsed since we started counting. 2967 mStartClockTime = currentTime - (mClocks.elapsedRealtime()-(mRealtimeStart/1000)); 2968 return true; 2969 } 2970 return false; 2971 } 2972 noteCurrentTimeChangedLocked()2973 public void noteCurrentTimeChangedLocked() { 2974 final long currentTime = System.currentTimeMillis(); 2975 final long elapsedRealtime = mClocks.elapsedRealtime(); 2976 final long uptime = mClocks.uptimeMillis(); 2977 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime); 2978 ensureStartClockTime(currentTime); 2979 } 2980 noteProcessStartLocked(String name, int uid)2981 public void noteProcessStartLocked(String name, int uid) { 2982 uid = mapUid(uid); 2983 if (isOnBattery()) { 2984 Uid u = getUidStatsLocked(uid); 2985 u.getProcessStatsLocked(name).incStartsLocked(); 2986 } 2987 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 2988 return; 2989 } 2990 if (!mRecordAllHistory) { 2991 return; 2992 } 2993 final long elapsedRealtime = mClocks.elapsedRealtime(); 2994 final long uptime = mClocks.uptimeMillis(); 2995 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid); 2996 } 2997 noteProcessCrashLocked(String name, int uid)2998 public void noteProcessCrashLocked(String name, int uid) { 2999 uid = mapUid(uid); 3000 if (isOnBattery()) { 3001 Uid u = getUidStatsLocked(uid); 3002 u.getProcessStatsLocked(name).incNumCrashesLocked(); 3003 } 3004 } 3005 noteProcessAnrLocked(String name, int uid)3006 public void noteProcessAnrLocked(String name, int uid) { 3007 uid = mapUid(uid); 3008 if (isOnBattery()) { 3009 Uid u = getUidStatsLocked(uid); 3010 u.getProcessStatsLocked(name).incNumAnrsLocked(); 3011 } 3012 } 3013 noteUidProcessStateLocked(int uid, int state)3014 public void noteUidProcessStateLocked(int uid, int state) { 3015 uid = mapUid(uid); 3016 getUidStatsLocked(uid).updateUidProcessStateLocked(state); 3017 } 3018 noteProcessFinishLocked(String name, int uid)3019 public void noteProcessFinishLocked(String name, int uid) { 3020 uid = mapUid(uid); 3021 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 3022 return; 3023 } 3024 if (!mRecordAllHistory) { 3025 return; 3026 } 3027 final long elapsedRealtime = mClocks.elapsedRealtime(); 3028 final long uptime = mClocks.uptimeMillis(); 3029 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid); 3030 } 3031 noteSyncStartLocked(String name, int uid)3032 public void noteSyncStartLocked(String name, int uid) { 3033 uid = mapUid(uid); 3034 final long elapsedRealtime = mClocks.elapsedRealtime(); 3035 final long uptime = mClocks.uptimeMillis(); 3036 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime); 3037 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 3038 return; 3039 } 3040 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid); 3041 } 3042 noteSyncFinishLocked(String name, int uid)3043 public void noteSyncFinishLocked(String name, int uid) { 3044 uid = mapUid(uid); 3045 final long elapsedRealtime = mClocks.elapsedRealtime(); 3046 final long uptime = mClocks.uptimeMillis(); 3047 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime); 3048 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 3049 return; 3050 } 3051 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid); 3052 } 3053 noteJobStartLocked(String name, int uid)3054 public void noteJobStartLocked(String name, int uid) { 3055 uid = mapUid(uid); 3056 final long elapsedRealtime = mClocks.elapsedRealtime(); 3057 final long uptime = mClocks.uptimeMillis(); 3058 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime); 3059 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 3060 return; 3061 } 3062 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid); 3063 } 3064 noteJobFinishLocked(String name, int uid)3065 public void noteJobFinishLocked(String name, int uid) { 3066 uid = mapUid(uid); 3067 final long elapsedRealtime = mClocks.elapsedRealtime(); 3068 final long uptime = mClocks.uptimeMillis(); 3069 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime); 3070 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 3071 return; 3072 } 3073 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid); 3074 } 3075 noteAlarmStartLocked(String name, int uid)3076 public void noteAlarmStartLocked(String name, int uid) { 3077 if (!mRecordAllHistory) { 3078 return; 3079 } 3080 uid = mapUid(uid); 3081 final long elapsedRealtime = mClocks.elapsedRealtime(); 3082 final long uptime = mClocks.uptimeMillis(); 3083 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_START, name, uid, 0)) { 3084 return; 3085 } 3086 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_START, name, uid); 3087 } 3088 noteAlarmFinishLocked(String name, int uid)3089 public void noteAlarmFinishLocked(String name, int uid) { 3090 if (!mRecordAllHistory) { 3091 return; 3092 } 3093 uid = mapUid(uid); 3094 final long elapsedRealtime = mClocks.elapsedRealtime(); 3095 final long uptime = mClocks.uptimeMillis(); 3096 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_FINISH, name, uid, 0)) { 3097 return; 3098 } 3099 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_FINISH, name, uid); 3100 } 3101 requestWakelockCpuUpdate()3102 private void requestWakelockCpuUpdate() { 3103 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { 3104 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); 3105 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); 3106 } 3107 } 3108 requestImmediateCpuUpdate()3109 private void requestImmediateCpuUpdate() { 3110 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); 3111 mHandler.sendEmptyMessage(MSG_UPDATE_WAKELOCKS); 3112 } 3113 setRecordAllHistoryLocked(boolean enabled)3114 public void setRecordAllHistoryLocked(boolean enabled) { 3115 mRecordAllHistory = enabled; 3116 if (!enabled) { 3117 // Clear out any existing state. 3118 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 3119 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 3120 // Record the currently running processes as stopping, now that we are no 3121 // longer tracking them. 3122 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 3123 HistoryItem.EVENT_PROC); 3124 if (active != null) { 3125 long mSecRealtime = mClocks.elapsedRealtime(); 3126 final long mSecUptime = mClocks.uptimeMillis(); 3127 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 3128 SparseIntArray uids = ent.getValue(); 3129 for (int j=0; j<uids.size(); j++) { 3130 addHistoryEventLocked(mSecRealtime, mSecUptime, 3131 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 3132 } 3133 } 3134 } 3135 } else { 3136 // Record the currently running processes as starting, now that we are tracking them. 3137 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 3138 HistoryItem.EVENT_PROC); 3139 if (active != null) { 3140 long mSecRealtime = mClocks.elapsedRealtime(); 3141 final long mSecUptime = mClocks.uptimeMillis(); 3142 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 3143 SparseIntArray uids = ent.getValue(); 3144 for (int j=0; j<uids.size(); j++) { 3145 addHistoryEventLocked(mSecRealtime, mSecUptime, 3146 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j)); 3147 } 3148 } 3149 } 3150 } 3151 } 3152 setNoAutoReset(boolean enabled)3153 public void setNoAutoReset(boolean enabled) { 3154 mNoAutoReset = enabled; 3155 } 3156 3157 private String mInitialAcquireWakeName; 3158 private int mInitialAcquireWakeUid = -1; 3159 noteStartWakeLocked(int uid, int pid, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtime, long uptime)3160 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type, 3161 boolean unimportantForLogging, long elapsedRealtime, long uptime) { 3162 uid = mapUid(uid); 3163 if (type == WAKE_TYPE_PARTIAL) { 3164 // Only care about partial wake locks, since full wake locks 3165 // will be canceled when the user puts the screen to sleep. 3166 aggregateLastWakeupUptimeLocked(uptime); 3167 if (historyName == null) { 3168 historyName = name; 3169 } 3170 if (mRecordAllHistory) { 3171 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 3172 uid, 0)) { 3173 addHistoryEventLocked(elapsedRealtime, uptime, 3174 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid); 3175 } 3176 } 3177 if (mWakeLockNesting == 0) { 3178 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 3179 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 3180 + Integer.toHexString(mHistoryCur.states)); 3181 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 3182 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 3183 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 3184 mWakeLockImportant = !unimportantForLogging; 3185 addHistoryRecordLocked(elapsedRealtime, uptime); 3186 } else if (!mWakeLockImportant && !unimportantForLogging 3187 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { 3188 if (mHistoryLastWritten.wakelockTag != null) { 3189 // We'll try to update the last tag. 3190 mHistoryLastWritten.wakelockTag = null; 3191 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 3192 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 3193 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 3194 addHistoryRecordLocked(elapsedRealtime, uptime); 3195 } 3196 mWakeLockImportant = true; 3197 } 3198 mWakeLockNesting++; 3199 } 3200 if (uid >= 0) { 3201 if (mOnBatteryScreenOffTimeBase.isRunning()) { 3202 // We only update the cpu time when a wake lock is acquired if the screen is off. 3203 // If the screen is on, we don't distribute the power amongst partial wakelocks. 3204 if (DEBUG_ENERGY_CPU) { 3205 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 3206 } 3207 requestWakelockCpuUpdate(); 3208 } 3209 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime); 3210 } 3211 } 3212 noteStopWakeLocked(int uid, int pid, String name, String historyName, int type, long elapsedRealtime, long uptime)3213 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type, 3214 long elapsedRealtime, long uptime) { 3215 uid = mapUid(uid); 3216 if (type == WAKE_TYPE_PARTIAL) { 3217 mWakeLockNesting--; 3218 if (mRecordAllHistory) { 3219 if (historyName == null) { 3220 historyName = name; 3221 } 3222 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 3223 uid, 0)) { 3224 addHistoryEventLocked(elapsedRealtime, uptime, 3225 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid); 3226 } 3227 } 3228 if (mWakeLockNesting == 0) { 3229 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 3230 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 3231 + Integer.toHexString(mHistoryCur.states)); 3232 mInitialAcquireWakeName = null; 3233 mInitialAcquireWakeUid = -1; 3234 addHistoryRecordLocked(elapsedRealtime, uptime); 3235 } 3236 } 3237 if (uid >= 0) { 3238 if (mOnBatteryScreenOffTimeBase.isRunning()) { 3239 if (DEBUG_ENERGY_CPU) { 3240 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 3241 } 3242 requestWakelockCpuUpdate(); 3243 } 3244 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime); 3245 } 3246 } 3247 noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging)3248 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 3249 String historyName, int type, boolean unimportantForLogging) { 3250 final long elapsedRealtime = mClocks.elapsedRealtime(); 3251 final long uptime = mClocks.uptimeMillis(); 3252 final int N = ws.size(); 3253 for (int i=0; i<N; i++) { 3254 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging, 3255 elapsedRealtime, uptime); 3256 } 3257 } 3258 noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, WorkSource newWs, int newPid, String newName, String newHistoryName, int newType, boolean newUnimportantForLogging)3259 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 3260 String historyName, int type, WorkSource newWs, int newPid, String newName, 3261 String newHistoryName, int newType, boolean newUnimportantForLogging) { 3262 final long elapsedRealtime = mClocks.elapsedRealtime(); 3263 final long uptime = mClocks.uptimeMillis(); 3264 // For correct semantics, we start the need worksources first, so that we won't 3265 // make inappropriate history items as if all wake locks went away and new ones 3266 // appeared. This is okay because tracking of wake locks allows nesting. 3267 final int NN = newWs.size(); 3268 for (int i=0; i<NN; i++) { 3269 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType, 3270 newUnimportantForLogging, elapsedRealtime, uptime); 3271 } 3272 final int NO = ws.size(); 3273 for (int i=0; i<NO; i++) { 3274 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime); 3275 } 3276 } 3277 noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type)3278 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 3279 String historyName, int type) { 3280 final long elapsedRealtime = mClocks.elapsedRealtime(); 3281 final long uptime = mClocks.uptimeMillis(); 3282 final int N = ws.size(); 3283 for (int i=0; i<N; i++) { 3284 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime); 3285 } 3286 } 3287 aggregateLastWakeupUptimeLocked(long uptimeMs)3288 void aggregateLastWakeupUptimeLocked(long uptimeMs) { 3289 if (mLastWakeupReason != null) { 3290 long deltaUptime = uptimeMs - mLastWakeupUptimeMs; 3291 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 3292 timer.add(deltaUptime * 1000, 1); // time in in microseconds 3293 mLastWakeupReason = null; 3294 } 3295 } 3296 noteWakeupReasonLocked(String reason)3297 public void noteWakeupReasonLocked(String reason) { 3298 final long elapsedRealtime = mClocks.elapsedRealtime(); 3299 final long uptime = mClocks.uptimeMillis(); 3300 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": " 3301 + Integer.toHexString(mHistoryCur.states)); 3302 aggregateLastWakeupUptimeLocked(uptime); 3303 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; 3304 mHistoryCur.wakeReasonTag.string = reason; 3305 mHistoryCur.wakeReasonTag.uid = 0; 3306 mLastWakeupReason = reason; 3307 mLastWakeupUptimeMs = uptime; 3308 addHistoryRecordLocked(elapsedRealtime, uptime); 3309 } 3310 startAddingCpuLocked()3311 public boolean startAddingCpuLocked() { 3312 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); 3313 return mOnBatteryInternal; 3314 } 3315 finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, int statSystemTime, int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime)3316 public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, 3317 int statSystemTime, int statIOWaitTime, int statIrqTime, 3318 int statSoftIrqTime, int statIdleTime) { 3319 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime 3320 + " user=" + statUserTime + " sys=" + statSystemTime 3321 + " io=" + statIOWaitTime + " irq=" + statIrqTime 3322 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime); 3323 mCurStepCpuUserTime += totalUTime; 3324 mCurStepCpuSystemTime += totalSTime; 3325 mCurStepStatUserTime += statUserTime; 3326 mCurStepStatSystemTime += statSystemTime; 3327 mCurStepStatIOWaitTime += statIOWaitTime; 3328 mCurStepStatIrqTime += statIrqTime; 3329 mCurStepStatSoftIrqTime += statSoftIrqTime; 3330 mCurStepStatIdleTime += statIdleTime; 3331 } 3332 noteProcessDiedLocked(int uid, int pid)3333 public void noteProcessDiedLocked(int uid, int pid) { 3334 uid = mapUid(uid); 3335 Uid u = mUidStats.get(uid); 3336 if (u != null) { 3337 u.mPids.remove(pid); 3338 } 3339 } 3340 getProcessWakeTime(int uid, int pid, long realtime)3341 public long getProcessWakeTime(int uid, int pid, long realtime) { 3342 uid = mapUid(uid); 3343 Uid u = mUidStats.get(uid); 3344 if (u != null) { 3345 Uid.Pid p = u.mPids.get(pid); 3346 if (p != null) { 3347 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0); 3348 } 3349 } 3350 return 0; 3351 } 3352 reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime)3353 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) { 3354 uid = mapUid(uid); 3355 Uid u = mUidStats.get(uid); 3356 if (u != null) { 3357 u.reportExcessiveWakeLocked(proc, overTime, usedTime); 3358 } 3359 } 3360 reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime)3361 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) { 3362 uid = mapUid(uid); 3363 Uid u = mUidStats.get(uid); 3364 if (u != null) { 3365 u.reportExcessiveCpuLocked(proc, overTime, usedTime); 3366 } 3367 } 3368 3369 int mSensorNesting; 3370 noteStartSensorLocked(int uid, int sensor)3371 public void noteStartSensorLocked(int uid, int sensor) { 3372 uid = mapUid(uid); 3373 final long elapsedRealtime = mClocks.elapsedRealtime(); 3374 final long uptime = mClocks.uptimeMillis(); 3375 if (mSensorNesting == 0) { 3376 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 3377 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 3378 + Integer.toHexString(mHistoryCur.states)); 3379 addHistoryRecordLocked(elapsedRealtime, uptime); 3380 } 3381 mSensorNesting++; 3382 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime); 3383 } 3384 noteStopSensorLocked(int uid, int sensor)3385 public void noteStopSensorLocked(int uid, int sensor) { 3386 uid = mapUid(uid); 3387 final long elapsedRealtime = mClocks.elapsedRealtime(); 3388 final long uptime = mClocks.uptimeMillis(); 3389 mSensorNesting--; 3390 if (mSensorNesting == 0) { 3391 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 3392 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 3393 + Integer.toHexString(mHistoryCur.states)); 3394 addHistoryRecordLocked(elapsedRealtime, uptime); 3395 } 3396 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime); 3397 } 3398 3399 int mGpsNesting; 3400 noteStartGpsLocked(int uid)3401 public void noteStartGpsLocked(int uid) { 3402 uid = mapUid(uid); 3403 final long elapsedRealtime = mClocks.elapsedRealtime(); 3404 final long uptime = mClocks.uptimeMillis(); 3405 if (mGpsNesting == 0) { 3406 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 3407 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 3408 + Integer.toHexString(mHistoryCur.states)); 3409 addHistoryRecordLocked(elapsedRealtime, uptime); 3410 } 3411 mGpsNesting++; 3412 getUidStatsLocked(uid).noteStartGps(elapsedRealtime); 3413 } 3414 noteStopGpsLocked(int uid)3415 public void noteStopGpsLocked(int uid) { 3416 uid = mapUid(uid); 3417 final long elapsedRealtime = mClocks.elapsedRealtime(); 3418 final long uptime = mClocks.uptimeMillis(); 3419 mGpsNesting--; 3420 if (mGpsNesting == 0) { 3421 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 3422 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 3423 + Integer.toHexString(mHistoryCur.states)); 3424 addHistoryRecordLocked(elapsedRealtime, uptime); 3425 } 3426 getUidStatsLocked(uid).noteStopGps(elapsedRealtime); 3427 } 3428 noteScreenStateLocked(int state)3429 public void noteScreenStateLocked(int state) { 3430 if (mScreenState != state) { 3431 recordDailyStatsIfNeededLocked(true); 3432 final int oldState = mScreenState; 3433 mScreenState = state; 3434 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 3435 + ", newState=" + Display.stateToString(state)); 3436 3437 if (state != Display.STATE_UNKNOWN) { 3438 int stepState = state-1; 3439 if (stepState < 4) { 3440 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 3441 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 3442 } else { 3443 Slog.wtf(TAG, "Unexpected screen state: " + state); 3444 } 3445 } 3446 3447 if (state == Display.STATE_ON) { 3448 // Screen turning on. 3449 final long elapsedRealtime = mClocks.elapsedRealtime(); 3450 final long uptime = mClocks.uptimeMillis(); 3451 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 3452 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 3453 + Integer.toHexString(mHistoryCur.states)); 3454 addHistoryRecordLocked(elapsedRealtime, uptime); 3455 mScreenOnTimer.startRunningLocked(elapsedRealtime); 3456 if (mScreenBrightnessBin >= 0) { 3457 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime); 3458 } 3459 3460 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false, 3461 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 3462 3463 // Fake a wake lock, so we consider the device waked as long 3464 // as the screen is on. 3465 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false, 3466 elapsedRealtime, uptime); 3467 3468 // Update discharge amounts. 3469 if (mOnBatteryInternal) { 3470 updateDischargeScreenLevelsLocked(false, true); 3471 } 3472 } else if (oldState == Display.STATE_ON) { 3473 // Screen turning off or dozing. 3474 final long elapsedRealtime = mClocks.elapsedRealtime(); 3475 final long uptime = mClocks.uptimeMillis(); 3476 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 3477 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 3478 + Integer.toHexString(mHistoryCur.states)); 3479 addHistoryRecordLocked(elapsedRealtime, uptime); 3480 mScreenOnTimer.stopRunningLocked(elapsedRealtime); 3481 if (mScreenBrightnessBin >= 0) { 3482 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 3483 } 3484 3485 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL, 3486 elapsedRealtime, uptime); 3487 3488 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true, 3489 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 3490 3491 // Update discharge amounts. 3492 if (mOnBatteryInternal) { 3493 updateDischargeScreenLevelsLocked(true, false); 3494 } 3495 } 3496 } 3497 } 3498 noteScreenBrightnessLocked(int brightness)3499 public void noteScreenBrightnessLocked(int brightness) { 3500 // Bin the brightness. 3501 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 3502 if (bin < 0) bin = 0; 3503 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 3504 if (mScreenBrightnessBin != bin) { 3505 final long elapsedRealtime = mClocks.elapsedRealtime(); 3506 final long uptime = mClocks.uptimeMillis(); 3507 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 3508 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 3509 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 3510 + Integer.toHexString(mHistoryCur.states)); 3511 addHistoryRecordLocked(elapsedRealtime, uptime); 3512 if (mScreenState == Display.STATE_ON) { 3513 if (mScreenBrightnessBin >= 0) { 3514 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 3515 } 3516 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime); 3517 } 3518 mScreenBrightnessBin = bin; 3519 } 3520 } 3521 noteUserActivityLocked(int uid, int event)3522 public void noteUserActivityLocked(int uid, int event) { 3523 if (mOnBatteryInternal) { 3524 uid = mapUid(uid); 3525 getUidStatsLocked(uid).noteUserActivityLocked(event); 3526 } 3527 } 3528 noteWakeUpLocked(String reason, int reasonUid)3529 public void noteWakeUpLocked(String reason, int reasonUid) { 3530 final long elapsedRealtime = mClocks.elapsedRealtime(); 3531 final long uptime = mClocks.uptimeMillis(); 3532 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP, 3533 reason, reasonUid); 3534 } 3535 noteInteractiveLocked(boolean interactive)3536 public void noteInteractiveLocked(boolean interactive) { 3537 if (mInteractive != interactive) { 3538 final long elapsedRealtime = mClocks.elapsedRealtime(); 3539 mInteractive = interactive; 3540 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 3541 if (interactive) { 3542 mInteractiveTimer.startRunningLocked(elapsedRealtime); 3543 } else { 3544 mInteractiveTimer.stopRunningLocked(elapsedRealtime); 3545 } 3546 } 3547 } 3548 noteConnectivityChangedLocked(int type, String extra)3549 public void noteConnectivityChangedLocked(int type, String extra) { 3550 final long elapsedRealtime = mClocks.elapsedRealtime(); 3551 final long uptime = mClocks.uptimeMillis(); 3552 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 3553 extra, type); 3554 mNumConnectivityChange++; 3555 } 3556 noteMobileRadioPowerState(int powerState, long timestampNs, int uid)3557 public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) { 3558 final long elapsedRealtime = mClocks.elapsedRealtime(); 3559 final long uptime = mClocks.uptimeMillis(); 3560 if (mMobileRadioPowerState != powerState) { 3561 long realElapsedRealtimeMs; 3562 final boolean active = 3563 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 3564 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 3565 if (active) { 3566 mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 3567 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 3568 } else { 3569 realElapsedRealtimeMs = timestampNs / (1000*1000); 3570 long lastUpdateTimeMs = mMobileRadioActiveStartTime; 3571 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 3572 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 3573 + " is before start time " + lastUpdateTimeMs); 3574 realElapsedRealtimeMs = elapsedRealtime; 3575 } else if (realElapsedRealtimeMs < elapsedRealtime) { 3576 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime 3577 - realElapsedRealtimeMs); 3578 } 3579 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 3580 } 3581 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " 3582 + Integer.toHexString(mHistoryCur.states)); 3583 addHistoryRecordLocked(elapsedRealtime, uptime); 3584 mMobileRadioPowerState = powerState; 3585 if (active) { 3586 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime); 3587 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime); 3588 } else { 3589 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 3590 updateMobileRadioStateLocked(realElapsedRealtimeMs, null); 3591 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 3592 } 3593 } 3594 } 3595 notePowerSaveMode(boolean enabled)3596 public void notePowerSaveMode(boolean enabled) { 3597 if (mPowerSaveModeEnabled != enabled) { 3598 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 3599 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 3600 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 3601 final long elapsedRealtime = mClocks.elapsedRealtime(); 3602 final long uptime = mClocks.uptimeMillis(); 3603 mPowerSaveModeEnabled = enabled; 3604 if (enabled) { 3605 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG; 3606 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: " 3607 + Integer.toHexString(mHistoryCur.states2)); 3608 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime); 3609 } else { 3610 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG; 3611 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: " 3612 + Integer.toHexString(mHistoryCur.states2)); 3613 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime); 3614 } 3615 addHistoryRecordLocked(elapsedRealtime, uptime); 3616 } 3617 } 3618 noteDeviceIdleModeLocked(int mode, String activeReason, int activeUid)3619 public void noteDeviceIdleModeLocked(int mode, String activeReason, int activeUid) { 3620 final long elapsedRealtime = mClocks.elapsedRealtime(); 3621 final long uptime = mClocks.uptimeMillis(); 3622 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 3623 if (mDeviceIdling && !nowIdling && activeReason == null) { 3624 // We don't go out of general idling mode until explicitly taken out of 3625 // device idle through going active or significant motion. 3626 nowIdling = true; 3627 } 3628 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 3629 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 3630 // We don't go out of general light idling mode until explicitly taken out of 3631 // device idle through going active or significant motion. 3632 nowLightIdling = true; 3633 } 3634 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 3635 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE, 3636 activeReason, activeUid); 3637 } 3638 if (mDeviceIdling != nowIdling) { 3639 mDeviceIdling = nowIdling; 3640 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 3641 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 3642 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 3643 if (nowIdling) { 3644 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime); 3645 } else { 3646 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime); 3647 } 3648 } 3649 if (mDeviceLightIdling != nowLightIdling) { 3650 mDeviceLightIdling = nowLightIdling; 3651 if (nowLightIdling) { 3652 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime); 3653 } else { 3654 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime); 3655 } 3656 } 3657 if (mDeviceIdleMode != mode) { 3658 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK) 3659 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT); 3660 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: " 3661 + Integer.toHexString(mHistoryCur.states2)); 3662 addHistoryRecordLocked(elapsedRealtime, uptime); 3663 long lastDuration = elapsedRealtime - mLastIdleTimeStart; 3664 mLastIdleTimeStart = elapsedRealtime; 3665 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 3666 if (lastDuration > mLongestLightIdleTime) { 3667 mLongestLightIdleTime = lastDuration; 3668 } 3669 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime); 3670 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 3671 if (lastDuration > mLongestFullIdleTime) { 3672 mLongestFullIdleTime = lastDuration; 3673 } 3674 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime); 3675 } 3676 if (mode == DEVICE_IDLE_MODE_LIGHT) { 3677 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime); 3678 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 3679 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime); 3680 } 3681 mDeviceIdleMode = mode; 3682 } 3683 } 3684 notePackageInstalledLocked(String pkgName, int versionCode)3685 public void notePackageInstalledLocked(String pkgName, int versionCode) { 3686 final long elapsedRealtime = mClocks.elapsedRealtime(); 3687 final long uptime = mClocks.uptimeMillis(); 3688 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED, 3689 pkgName, versionCode); 3690 PackageChange pc = new PackageChange(); 3691 pc.mPackageName = pkgName; 3692 pc.mUpdate = true; 3693 pc.mVersionCode = versionCode; 3694 addPackageChange(pc); 3695 } 3696 notePackageUninstalledLocked(String pkgName)3697 public void notePackageUninstalledLocked(String pkgName) { 3698 final long elapsedRealtime = mClocks.elapsedRealtime(); 3699 final long uptime = mClocks.uptimeMillis(); 3700 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED, 3701 pkgName, 0); 3702 PackageChange pc = new PackageChange(); 3703 pc.mPackageName = pkgName; 3704 pc.mUpdate = true; 3705 addPackageChange(pc); 3706 } 3707 addPackageChange(PackageChange pc)3708 private void addPackageChange(PackageChange pc) { 3709 if (mDailyPackageChanges == null) { 3710 mDailyPackageChanges = new ArrayList<>(); 3711 } 3712 mDailyPackageChanges.add(pc); 3713 } 3714 notePhoneOnLocked()3715 public void notePhoneOnLocked() { 3716 if (!mPhoneOn) { 3717 final long elapsedRealtime = mClocks.elapsedRealtime(); 3718 final long uptime = mClocks.uptimeMillis(); 3719 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 3720 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 3721 + Integer.toHexString(mHistoryCur.states)); 3722 addHistoryRecordLocked(elapsedRealtime, uptime); 3723 mPhoneOn = true; 3724 mPhoneOnTimer.startRunningLocked(elapsedRealtime); 3725 } 3726 } 3727 notePhoneOffLocked()3728 public void notePhoneOffLocked() { 3729 if (mPhoneOn) { 3730 final long elapsedRealtime = mClocks.elapsedRealtime(); 3731 final long uptime = mClocks.uptimeMillis(); 3732 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 3733 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 3734 + Integer.toHexString(mHistoryCur.states)); 3735 addHistoryRecordLocked(elapsedRealtime, uptime); 3736 mPhoneOn = false; 3737 mPhoneOnTimer.stopRunningLocked(elapsedRealtime); 3738 } 3739 } 3740 stopAllPhoneSignalStrengthTimersLocked(int except)3741 void stopAllPhoneSignalStrengthTimersLocked(int except) { 3742 final long elapsedRealtime = mClocks.elapsedRealtime(); 3743 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 3744 if (i == except) { 3745 continue; 3746 } 3747 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 3748 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 3749 } 3750 } 3751 } 3752 fixPhoneServiceState(int state, int signalBin)3753 private int fixPhoneServiceState(int state, int signalBin) { 3754 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 3755 // In this case we will always be STATE_OUT_OF_SERVICE, so need 3756 // to infer that we are scanning from other data. 3757 if (state == ServiceState.STATE_OUT_OF_SERVICE 3758 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 3759 state = ServiceState.STATE_IN_SERVICE; 3760 } 3761 } 3762 3763 return state; 3764 } 3765 updateAllPhoneStateLocked(int state, int simState, int strengthBin)3766 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) { 3767 boolean scanning = false; 3768 boolean newHistory = false; 3769 3770 mPhoneServiceStateRaw = state; 3771 mPhoneSimStateRaw = simState; 3772 mPhoneSignalStrengthBinRaw = strengthBin; 3773 3774 final long elapsedRealtime = mClocks.elapsedRealtime(); 3775 final long uptime = mClocks.uptimeMillis(); 3776 3777 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 3778 // In this case we will always be STATE_OUT_OF_SERVICE, so need 3779 // to infer that we are scanning from other data. 3780 if (state == ServiceState.STATE_OUT_OF_SERVICE 3781 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 3782 state = ServiceState.STATE_IN_SERVICE; 3783 } 3784 } 3785 3786 // If the phone is powered off, stop all timers. 3787 if (state == ServiceState.STATE_POWER_OFF) { 3788 strengthBin = -1; 3789 3790 // If we are in service, make sure the correct signal string timer is running. 3791 } else if (state == ServiceState.STATE_IN_SERVICE) { 3792 // Bin will be changed below. 3793 3794 // If we're out of service, we are in the lowest signal strength 3795 // bin and have the scanning bit set. 3796 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 3797 scanning = true; 3798 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 3799 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 3800 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 3801 newHistory = true; 3802 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 3803 + Integer.toHexString(mHistoryCur.states)); 3804 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime); 3805 } 3806 } 3807 3808 if (!scanning) { 3809 // If we are no longer scanning, then stop the scanning timer. 3810 if (mPhoneSignalScanningTimer.isRunningLocked()) { 3811 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 3812 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 3813 + Integer.toHexString(mHistoryCur.states)); 3814 newHistory = true; 3815 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime); 3816 } 3817 } 3818 3819 if (mPhoneServiceState != state) { 3820 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 3821 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 3822 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 3823 + Integer.toHexString(mHistoryCur.states)); 3824 newHistory = true; 3825 mPhoneServiceState = state; 3826 } 3827 3828 if (mPhoneSignalStrengthBin != strengthBin) { 3829 if (mPhoneSignalStrengthBin >= 0) { 3830 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 3831 elapsedRealtime); 3832 } 3833 if (strengthBin >= 0) { 3834 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 3835 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 3836 } 3837 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 3838 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); 3839 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " 3840 + Integer.toHexString(mHistoryCur.states)); 3841 newHistory = true; 3842 } else { 3843 stopAllPhoneSignalStrengthTimersLocked(-1); 3844 } 3845 mPhoneSignalStrengthBin = strengthBin; 3846 } 3847 3848 if (newHistory) { 3849 addHistoryRecordLocked(elapsedRealtime, uptime); 3850 } 3851 } 3852 3853 /** 3854 * Telephony stack updates the phone state. 3855 * @param state phone state from ServiceState.getState() 3856 */ notePhoneStateLocked(int state, int simState)3857 public void notePhoneStateLocked(int state, int simState) { 3858 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw); 3859 } 3860 notePhoneSignalStrengthLocked(SignalStrength signalStrength)3861 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 3862 // Bin the strength. 3863 int bin = signalStrength.getLevel(); 3864 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin); 3865 } 3866 notePhoneDataConnectionStateLocked(int dataType, boolean hasData)3867 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) { 3868 int bin = DATA_CONNECTION_NONE; 3869 if (hasData) { 3870 switch (dataType) { 3871 case TelephonyManager.NETWORK_TYPE_EDGE: 3872 bin = DATA_CONNECTION_EDGE; 3873 break; 3874 case TelephonyManager.NETWORK_TYPE_GPRS: 3875 bin = DATA_CONNECTION_GPRS; 3876 break; 3877 case TelephonyManager.NETWORK_TYPE_UMTS: 3878 bin = DATA_CONNECTION_UMTS; 3879 break; 3880 case TelephonyManager.NETWORK_TYPE_CDMA: 3881 bin = DATA_CONNECTION_CDMA; 3882 break; 3883 case TelephonyManager.NETWORK_TYPE_EVDO_0: 3884 bin = DATA_CONNECTION_EVDO_0; 3885 break; 3886 case TelephonyManager.NETWORK_TYPE_EVDO_A: 3887 bin = DATA_CONNECTION_EVDO_A; 3888 break; 3889 case TelephonyManager.NETWORK_TYPE_1xRTT: 3890 bin = DATA_CONNECTION_1xRTT; 3891 break; 3892 case TelephonyManager.NETWORK_TYPE_HSDPA: 3893 bin = DATA_CONNECTION_HSDPA; 3894 break; 3895 case TelephonyManager.NETWORK_TYPE_HSUPA: 3896 bin = DATA_CONNECTION_HSUPA; 3897 break; 3898 case TelephonyManager.NETWORK_TYPE_HSPA: 3899 bin = DATA_CONNECTION_HSPA; 3900 break; 3901 case TelephonyManager.NETWORK_TYPE_IDEN: 3902 bin = DATA_CONNECTION_IDEN; 3903 break; 3904 case TelephonyManager.NETWORK_TYPE_EVDO_B: 3905 bin = DATA_CONNECTION_EVDO_B; 3906 break; 3907 case TelephonyManager.NETWORK_TYPE_LTE: 3908 bin = DATA_CONNECTION_LTE; 3909 break; 3910 case TelephonyManager.NETWORK_TYPE_EHRPD: 3911 bin = DATA_CONNECTION_EHRPD; 3912 break; 3913 case TelephonyManager.NETWORK_TYPE_HSPAP: 3914 bin = DATA_CONNECTION_HSPAP; 3915 break; 3916 default: 3917 bin = DATA_CONNECTION_OTHER; 3918 break; 3919 } 3920 } 3921 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 3922 if (mPhoneDataConnectionType != bin) { 3923 final long elapsedRealtime = mClocks.elapsedRealtime(); 3924 final long uptime = mClocks.uptimeMillis(); 3925 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 3926 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 3927 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 3928 + Integer.toHexString(mHistoryCur.states)); 3929 addHistoryRecordLocked(elapsedRealtime, uptime); 3930 if (mPhoneDataConnectionType >= 0) { 3931 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 3932 elapsedRealtime); 3933 } 3934 mPhoneDataConnectionType = bin; 3935 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime); 3936 } 3937 } 3938 noteWifiOnLocked()3939 public void noteWifiOnLocked() { 3940 if (!mWifiOn) { 3941 final long elapsedRealtime = mClocks.elapsedRealtime(); 3942 final long uptime = mClocks.uptimeMillis(); 3943 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; 3944 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 3945 + Integer.toHexString(mHistoryCur.states)); 3946 addHistoryRecordLocked(elapsedRealtime, uptime); 3947 mWifiOn = true; 3948 mWifiOnTimer.startRunningLocked(elapsedRealtime); 3949 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 3950 } 3951 } 3952 noteWifiOffLocked()3953 public void noteWifiOffLocked() { 3954 final long elapsedRealtime = mClocks.elapsedRealtime(); 3955 final long uptime = mClocks.uptimeMillis(); 3956 if (mWifiOn) { 3957 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; 3958 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 3959 + Integer.toHexString(mHistoryCur.states)); 3960 addHistoryRecordLocked(elapsedRealtime, uptime); 3961 mWifiOn = false; 3962 mWifiOnTimer.stopRunningLocked(elapsedRealtime); 3963 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 3964 } 3965 } 3966 noteAudioOnLocked(int uid)3967 public void noteAudioOnLocked(int uid) { 3968 uid = mapUid(uid); 3969 final long elapsedRealtime = mClocks.elapsedRealtime(); 3970 final long uptime = mClocks.uptimeMillis(); 3971 if (mAudioOnNesting == 0) { 3972 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 3973 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 3974 + Integer.toHexString(mHistoryCur.states)); 3975 addHistoryRecordLocked(elapsedRealtime, uptime); 3976 mAudioOnTimer.startRunningLocked(elapsedRealtime); 3977 } 3978 mAudioOnNesting++; 3979 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime); 3980 } 3981 noteAudioOffLocked(int uid)3982 public void noteAudioOffLocked(int uid) { 3983 if (mAudioOnNesting == 0) { 3984 return; 3985 } 3986 uid = mapUid(uid); 3987 final long elapsedRealtime = mClocks.elapsedRealtime(); 3988 final long uptime = mClocks.uptimeMillis(); 3989 if (--mAudioOnNesting == 0) { 3990 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 3991 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 3992 + Integer.toHexString(mHistoryCur.states)); 3993 addHistoryRecordLocked(elapsedRealtime, uptime); 3994 mAudioOnTimer.stopRunningLocked(elapsedRealtime); 3995 } 3996 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime); 3997 } 3998 noteVideoOnLocked(int uid)3999 public void noteVideoOnLocked(int uid) { 4000 uid = mapUid(uid); 4001 final long elapsedRealtime = mClocks.elapsedRealtime(); 4002 final long uptime = mClocks.uptimeMillis(); 4003 if (mVideoOnNesting == 0) { 4004 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; 4005 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 4006 + Integer.toHexString(mHistoryCur.states)); 4007 addHistoryRecordLocked(elapsedRealtime, uptime); 4008 mVideoOnTimer.startRunningLocked(elapsedRealtime); 4009 } 4010 mVideoOnNesting++; 4011 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime); 4012 } 4013 noteVideoOffLocked(int uid)4014 public void noteVideoOffLocked(int uid) { 4015 if (mVideoOnNesting == 0) { 4016 return; 4017 } 4018 uid = mapUid(uid); 4019 final long elapsedRealtime = mClocks.elapsedRealtime(); 4020 final long uptime = mClocks.uptimeMillis(); 4021 if (--mVideoOnNesting == 0) { 4022 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 4023 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 4024 + Integer.toHexString(mHistoryCur.states)); 4025 addHistoryRecordLocked(elapsedRealtime, uptime); 4026 mVideoOnTimer.stopRunningLocked(elapsedRealtime); 4027 } 4028 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime); 4029 } 4030 noteResetAudioLocked()4031 public void noteResetAudioLocked() { 4032 if (mAudioOnNesting > 0) { 4033 final long elapsedRealtime = mClocks.elapsedRealtime(); 4034 final long uptime = mClocks.uptimeMillis(); 4035 mAudioOnNesting = 0; 4036 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 4037 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 4038 + Integer.toHexString(mHistoryCur.states)); 4039 addHistoryRecordLocked(elapsedRealtime, uptime); 4040 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime); 4041 for (int i=0; i<mUidStats.size(); i++) { 4042 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4043 uid.noteResetAudioLocked(elapsedRealtime); 4044 } 4045 } 4046 } 4047 noteResetVideoLocked()4048 public void noteResetVideoLocked() { 4049 if (mVideoOnNesting > 0) { 4050 final long elapsedRealtime = mClocks.elapsedRealtime(); 4051 final long uptime = mClocks.uptimeMillis(); 4052 mAudioOnNesting = 0; 4053 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 4054 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 4055 + Integer.toHexString(mHistoryCur.states)); 4056 addHistoryRecordLocked(elapsedRealtime, uptime); 4057 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime); 4058 for (int i=0; i<mUidStats.size(); i++) { 4059 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4060 uid.noteResetVideoLocked(elapsedRealtime); 4061 } 4062 } 4063 } 4064 noteActivityResumedLocked(int uid)4065 public void noteActivityResumedLocked(int uid) { 4066 uid = mapUid(uid); 4067 getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime()); 4068 } 4069 noteActivityPausedLocked(int uid)4070 public void noteActivityPausedLocked(int uid) { 4071 uid = mapUid(uid); 4072 getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime()); 4073 } 4074 noteVibratorOnLocked(int uid, long durationMillis)4075 public void noteVibratorOnLocked(int uid, long durationMillis) { 4076 uid = mapUid(uid); 4077 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis); 4078 } 4079 noteVibratorOffLocked(int uid)4080 public void noteVibratorOffLocked(int uid) { 4081 uid = mapUid(uid); 4082 getUidStatsLocked(uid).noteVibratorOffLocked(); 4083 } 4084 noteFlashlightOnLocked(int uid)4085 public void noteFlashlightOnLocked(int uid) { 4086 uid = mapUid(uid); 4087 final long elapsedRealtime = mClocks.elapsedRealtime(); 4088 final long uptime = mClocks.uptimeMillis(); 4089 if (mFlashlightOnNesting++ == 0) { 4090 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; 4091 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " 4092 + Integer.toHexString(mHistoryCur.states2)); 4093 addHistoryRecordLocked(elapsedRealtime, uptime); 4094 mFlashlightOnTimer.startRunningLocked(elapsedRealtime); 4095 } 4096 getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime); 4097 } 4098 noteFlashlightOffLocked(int uid)4099 public void noteFlashlightOffLocked(int uid) { 4100 if (mFlashlightOnNesting == 0) { 4101 return; 4102 } 4103 uid = mapUid(uid); 4104 final long elapsedRealtime = mClocks.elapsedRealtime(); 4105 final long uptime = mClocks.uptimeMillis(); 4106 if (--mFlashlightOnNesting == 0) { 4107 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 4108 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 4109 + Integer.toHexString(mHistoryCur.states2)); 4110 addHistoryRecordLocked(elapsedRealtime, uptime); 4111 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime); 4112 } 4113 getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime); 4114 } 4115 noteCameraOnLocked(int uid)4116 public void noteCameraOnLocked(int uid) { 4117 uid = mapUid(uid); 4118 final long elapsedRealtime = mClocks.elapsedRealtime(); 4119 final long uptime = mClocks.uptimeMillis(); 4120 if (mCameraOnNesting++ == 0) { 4121 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG; 4122 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: " 4123 + Integer.toHexString(mHistoryCur.states2)); 4124 addHistoryRecordLocked(elapsedRealtime, uptime); 4125 mCameraOnTimer.startRunningLocked(elapsedRealtime); 4126 } 4127 getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime); 4128 } 4129 noteCameraOffLocked(int uid)4130 public void noteCameraOffLocked(int uid) { 4131 if (mCameraOnNesting == 0) { 4132 return; 4133 } 4134 uid = mapUid(uid); 4135 final long elapsedRealtime = mClocks.elapsedRealtime(); 4136 final long uptime = mClocks.uptimeMillis(); 4137 if (--mCameraOnNesting == 0) { 4138 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 4139 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 4140 + Integer.toHexString(mHistoryCur.states2)); 4141 addHistoryRecordLocked(elapsedRealtime, uptime); 4142 mCameraOnTimer.stopRunningLocked(elapsedRealtime); 4143 } 4144 getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime); 4145 } 4146 noteResetCameraLocked()4147 public void noteResetCameraLocked() { 4148 if (mCameraOnNesting > 0) { 4149 final long elapsedRealtime = mClocks.elapsedRealtime(); 4150 final long uptime = mClocks.uptimeMillis(); 4151 mCameraOnNesting = 0; 4152 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 4153 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 4154 + Integer.toHexString(mHistoryCur.states2)); 4155 addHistoryRecordLocked(elapsedRealtime, uptime); 4156 mCameraOnTimer.stopAllRunningLocked(elapsedRealtime); 4157 for (int i=0; i<mUidStats.size(); i++) { 4158 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4159 uid.noteResetCameraLocked(elapsedRealtime); 4160 } 4161 } 4162 } 4163 noteResetFlashlightLocked()4164 public void noteResetFlashlightLocked() { 4165 if (mFlashlightOnNesting > 0) { 4166 final long elapsedRealtime = mClocks.elapsedRealtime(); 4167 final long uptime = mClocks.uptimeMillis(); 4168 mFlashlightOnNesting = 0; 4169 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 4170 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 4171 + Integer.toHexString(mHistoryCur.states2)); 4172 addHistoryRecordLocked(elapsedRealtime, uptime); 4173 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime); 4174 for (int i=0; i<mUidStats.size(); i++) { 4175 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4176 uid.noteResetFlashlightLocked(elapsedRealtime); 4177 } 4178 } 4179 } 4180 noteBluetoothScanStartedLocked(int uid)4181 private void noteBluetoothScanStartedLocked(int uid) { 4182 uid = mapUid(uid); 4183 final long elapsedRealtime = SystemClock.elapsedRealtime(); 4184 final long uptime = SystemClock.uptimeMillis(); 4185 if (mBluetoothScanNesting == 0) { 4186 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 4187 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: " 4188 + Integer.toHexString(mHistoryCur.states2)); 4189 addHistoryRecordLocked(elapsedRealtime, uptime); 4190 mBluetoothScanTimer.startRunningLocked(elapsedRealtime); 4191 } 4192 mBluetoothScanNesting++; 4193 getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime); 4194 } 4195 noteBluetoothScanStartedFromSourceLocked(WorkSource ws)4196 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws) { 4197 final int N = ws.size(); 4198 for (int i = 0; i < N; i++) { 4199 noteBluetoothScanStartedLocked(ws.get(i)); 4200 } 4201 } 4202 noteBluetoothScanStoppedLocked(int uid)4203 private void noteBluetoothScanStoppedLocked(int uid) { 4204 uid = mapUid(uid); 4205 final long elapsedRealtime = SystemClock.elapsedRealtime(); 4206 final long uptime = SystemClock.uptimeMillis(); 4207 mBluetoothScanNesting--; 4208 if (mBluetoothScanNesting == 0) { 4209 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 4210 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: " 4211 + Integer.toHexString(mHistoryCur.states2)); 4212 addHistoryRecordLocked(elapsedRealtime, uptime); 4213 mBluetoothScanTimer.stopRunningLocked(elapsedRealtime); 4214 } 4215 getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime); 4216 } 4217 noteBluetoothScanStoppedFromSourceLocked(WorkSource ws)4218 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws) { 4219 final int N = ws.size(); 4220 for (int i = 0; i < N; i++) { 4221 noteBluetoothScanStoppedLocked(ws.get(i)); 4222 } 4223 } 4224 noteResetBluetoothScanLocked()4225 public void noteResetBluetoothScanLocked() { 4226 if (mBluetoothScanNesting > 0) { 4227 final long elapsedRealtime = SystemClock.elapsedRealtime(); 4228 final long uptime = SystemClock.uptimeMillis(); 4229 mBluetoothScanNesting = 0; 4230 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 4231 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: " 4232 + Integer.toHexString(mHistoryCur.states2)); 4233 addHistoryRecordLocked(elapsedRealtime, uptime); 4234 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime); 4235 for (int i=0; i<mUidStats.size(); i++) { 4236 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4237 uid.noteResetBluetoothScanLocked(elapsedRealtime); 4238 } 4239 } 4240 } 4241 noteWifiRadioPowerState(int powerState, long timestampNs)4242 public void noteWifiRadioPowerState(int powerState, long timestampNs) { 4243 final long elapsedRealtime = mClocks.elapsedRealtime(); 4244 final long uptime = mClocks.uptimeMillis(); 4245 if (mWifiRadioPowerState != powerState) { 4246 final boolean active = 4247 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 4248 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 4249 if (active) { 4250 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 4251 } else { 4252 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 4253 } 4254 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " 4255 + Integer.toHexString(mHistoryCur.states)); 4256 addHistoryRecordLocked(elapsedRealtime, uptime); 4257 mWifiRadioPowerState = powerState; 4258 } 4259 } 4260 noteWifiRunningLocked(WorkSource ws)4261 public void noteWifiRunningLocked(WorkSource ws) { 4262 if (!mGlobalWifiRunning) { 4263 final long elapsedRealtime = mClocks.elapsedRealtime(); 4264 final long uptime = mClocks.uptimeMillis(); 4265 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; 4266 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 4267 + Integer.toHexString(mHistoryCur.states)); 4268 addHistoryRecordLocked(elapsedRealtime, uptime); 4269 mGlobalWifiRunning = true; 4270 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime); 4271 int N = ws.size(); 4272 for (int i=0; i<N; i++) { 4273 int uid = mapUid(ws.get(i)); 4274 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 4275 } 4276 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 4277 } else { 4278 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 4279 } 4280 } 4281 noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs)4282 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 4283 if (mGlobalWifiRunning) { 4284 final long elapsedRealtime = mClocks.elapsedRealtime(); 4285 int N = oldWs.size(); 4286 for (int i=0; i<N; i++) { 4287 int uid = mapUid(oldWs.get(i)); 4288 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 4289 } 4290 N = newWs.size(); 4291 for (int i=0; i<N; i++) { 4292 int uid = mapUid(newWs.get(i)); 4293 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 4294 } 4295 } else { 4296 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 4297 } 4298 } 4299 noteWifiStoppedLocked(WorkSource ws)4300 public void noteWifiStoppedLocked(WorkSource ws) { 4301 if (mGlobalWifiRunning) { 4302 final long elapsedRealtime = mClocks.elapsedRealtime(); 4303 final long uptime = mClocks.uptimeMillis(); 4304 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; 4305 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 4306 + Integer.toHexString(mHistoryCur.states)); 4307 addHistoryRecordLocked(elapsedRealtime, uptime); 4308 mGlobalWifiRunning = false; 4309 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime); 4310 int N = ws.size(); 4311 for (int i=0; i<N; i++) { 4312 int uid = mapUid(ws.get(i)); 4313 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 4314 } 4315 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 4316 } else { 4317 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 4318 } 4319 } 4320 noteWifiStateLocked(int wifiState, String accessPoint)4321 public void noteWifiStateLocked(int wifiState, String accessPoint) { 4322 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 4323 if (mWifiState != wifiState) { 4324 final long elapsedRealtime = mClocks.elapsedRealtime(); 4325 if (mWifiState >= 0) { 4326 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime); 4327 } 4328 mWifiState = wifiState; 4329 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime); 4330 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 4331 } 4332 } 4333 noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth)4334 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { 4335 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 4336 if (mWifiSupplState != supplState) { 4337 final long elapsedRealtime = mClocks.elapsedRealtime(); 4338 final long uptime = mClocks.uptimeMillis(); 4339 if (mWifiSupplState >= 0) { 4340 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime); 4341 } 4342 mWifiSupplState = supplState; 4343 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime); 4344 mHistoryCur.states2 = 4345 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 4346 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 4347 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " 4348 + Integer.toHexString(mHistoryCur.states2)); 4349 addHistoryRecordLocked(elapsedRealtime, uptime); 4350 } 4351 } 4352 stopAllWifiSignalStrengthTimersLocked(int except)4353 void stopAllWifiSignalStrengthTimersLocked(int except) { 4354 final long elapsedRealtime = mClocks.elapsedRealtime(); 4355 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 4356 if (i == except) { 4357 continue; 4358 } 4359 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 4360 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 4361 } 4362 } 4363 } 4364 noteWifiRssiChangedLocked(int newRssi)4365 public void noteWifiRssiChangedLocked(int newRssi) { 4366 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 4367 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 4368 if (mWifiSignalStrengthBin != strengthBin) { 4369 final long elapsedRealtime = mClocks.elapsedRealtime(); 4370 final long uptime = mClocks.uptimeMillis(); 4371 if (mWifiSignalStrengthBin >= 0) { 4372 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 4373 elapsedRealtime); 4374 } 4375 if (strengthBin >= 0) { 4376 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 4377 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 4378 } 4379 mHistoryCur.states2 = 4380 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) 4381 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); 4382 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " 4383 + Integer.toHexString(mHistoryCur.states2)); 4384 addHistoryRecordLocked(elapsedRealtime, uptime); 4385 } else { 4386 stopAllWifiSignalStrengthTimersLocked(-1); 4387 } 4388 mWifiSignalStrengthBin = strengthBin; 4389 } 4390 } 4391 4392 int mWifiFullLockNesting = 0; 4393 noteFullWifiLockAcquiredLocked(int uid)4394 public void noteFullWifiLockAcquiredLocked(int uid) { 4395 uid = mapUid(uid); 4396 final long elapsedRealtime = mClocks.elapsedRealtime(); 4397 final long uptime = mClocks.uptimeMillis(); 4398 if (mWifiFullLockNesting == 0) { 4399 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 4400 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 4401 + Integer.toHexString(mHistoryCur.states)); 4402 addHistoryRecordLocked(elapsedRealtime, uptime); 4403 } 4404 mWifiFullLockNesting++; 4405 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime); 4406 } 4407 noteFullWifiLockReleasedLocked(int uid)4408 public void noteFullWifiLockReleasedLocked(int uid) { 4409 uid = mapUid(uid); 4410 final long elapsedRealtime = mClocks.elapsedRealtime(); 4411 final long uptime = mClocks.uptimeMillis(); 4412 mWifiFullLockNesting--; 4413 if (mWifiFullLockNesting == 0) { 4414 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 4415 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 4416 + Integer.toHexString(mHistoryCur.states)); 4417 addHistoryRecordLocked(elapsedRealtime, uptime); 4418 } 4419 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime); 4420 } 4421 4422 int mWifiScanNesting = 0; 4423 noteWifiScanStartedLocked(int uid)4424 public void noteWifiScanStartedLocked(int uid) { 4425 uid = mapUid(uid); 4426 final long elapsedRealtime = mClocks.elapsedRealtime(); 4427 final long uptime = mClocks.uptimeMillis(); 4428 if (mWifiScanNesting == 0) { 4429 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 4430 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 4431 + Integer.toHexString(mHistoryCur.states)); 4432 addHistoryRecordLocked(elapsedRealtime, uptime); 4433 } 4434 mWifiScanNesting++; 4435 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime); 4436 } 4437 noteWifiScanStoppedLocked(int uid)4438 public void noteWifiScanStoppedLocked(int uid) { 4439 uid = mapUid(uid); 4440 final long elapsedRealtime = mClocks.elapsedRealtime(); 4441 final long uptime = mClocks.uptimeMillis(); 4442 mWifiScanNesting--; 4443 if (mWifiScanNesting == 0) { 4444 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 4445 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 4446 + Integer.toHexString(mHistoryCur.states)); 4447 addHistoryRecordLocked(elapsedRealtime, uptime); 4448 } 4449 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime); 4450 } 4451 noteWifiBatchedScanStartedLocked(int uid, int csph)4452 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 4453 uid = mapUid(uid); 4454 final long elapsedRealtime = mClocks.elapsedRealtime(); 4455 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime); 4456 } 4457 noteWifiBatchedScanStoppedLocked(int uid)4458 public void noteWifiBatchedScanStoppedLocked(int uid) { 4459 uid = mapUid(uid); 4460 final long elapsedRealtime = mClocks.elapsedRealtime(); 4461 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime); 4462 } 4463 4464 int mWifiMulticastNesting = 0; 4465 noteWifiMulticastEnabledLocked(int uid)4466 public void noteWifiMulticastEnabledLocked(int uid) { 4467 uid = mapUid(uid); 4468 final long elapsedRealtime = mClocks.elapsedRealtime(); 4469 final long uptime = mClocks.uptimeMillis(); 4470 if (mWifiMulticastNesting == 0) { 4471 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 4472 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 4473 + Integer.toHexString(mHistoryCur.states)); 4474 addHistoryRecordLocked(elapsedRealtime, uptime); 4475 } 4476 mWifiMulticastNesting++; 4477 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime); 4478 } 4479 noteWifiMulticastDisabledLocked(int uid)4480 public void noteWifiMulticastDisabledLocked(int uid) { 4481 uid = mapUid(uid); 4482 final long elapsedRealtime = mClocks.elapsedRealtime(); 4483 final long uptime = mClocks.uptimeMillis(); 4484 mWifiMulticastNesting--; 4485 if (mWifiMulticastNesting == 0) { 4486 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 4487 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 4488 + Integer.toHexString(mHistoryCur.states)); 4489 addHistoryRecordLocked(elapsedRealtime, uptime); 4490 } 4491 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime); 4492 } 4493 noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws)4494 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 4495 int N = ws.size(); 4496 for (int i=0; i<N; i++) { 4497 noteFullWifiLockAcquiredLocked(ws.get(i)); 4498 } 4499 } 4500 noteFullWifiLockReleasedFromSourceLocked(WorkSource ws)4501 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 4502 int N = ws.size(); 4503 for (int i=0; i<N; i++) { 4504 noteFullWifiLockReleasedLocked(ws.get(i)); 4505 } 4506 } 4507 noteWifiScanStartedFromSourceLocked(WorkSource ws)4508 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 4509 int N = ws.size(); 4510 for (int i=0; i<N; i++) { 4511 noteWifiScanStartedLocked(ws.get(i)); 4512 } 4513 } 4514 noteWifiScanStoppedFromSourceLocked(WorkSource ws)4515 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 4516 int N = ws.size(); 4517 for (int i=0; i<N; i++) { 4518 noteWifiScanStoppedLocked(ws.get(i)); 4519 } 4520 } 4521 noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph)4522 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 4523 int N = ws.size(); 4524 for (int i=0; i<N; i++) { 4525 noteWifiBatchedScanStartedLocked(ws.get(i), csph); 4526 } 4527 } 4528 noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws)4529 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 4530 int N = ws.size(); 4531 for (int i=0; i<N; i++) { 4532 noteWifiBatchedScanStoppedLocked(ws.get(i)); 4533 } 4534 } 4535 noteWifiMulticastEnabledFromSourceLocked(WorkSource ws)4536 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) { 4537 int N = ws.size(); 4538 for (int i=0; i<N; i++) { 4539 noteWifiMulticastEnabledLocked(ws.get(i)); 4540 } 4541 } 4542 noteWifiMulticastDisabledFromSourceLocked(WorkSource ws)4543 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) { 4544 int N = ws.size(); 4545 for (int i=0; i<N; i++) { 4546 noteWifiMulticastDisabledLocked(ws.get(i)); 4547 } 4548 } 4549 includeInStringArray(String[] array, String str)4550 private static String[] includeInStringArray(String[] array, String str) { 4551 if (ArrayUtils.indexOf(array, str) >= 0) { 4552 return array; 4553 } 4554 String[] newArray = new String[array.length+1]; 4555 System.arraycopy(array, 0, newArray, 0, array.length); 4556 newArray[array.length] = str; 4557 return newArray; 4558 } 4559 excludeFromStringArray(String[] array, String str)4560 private static String[] excludeFromStringArray(String[] array, String str) { 4561 int index = ArrayUtils.indexOf(array, str); 4562 if (index >= 0) { 4563 String[] newArray = new String[array.length-1]; 4564 if (index > 0) { 4565 System.arraycopy(array, 0, newArray, 0, index); 4566 } 4567 if (index < array.length-1) { 4568 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 4569 } 4570 return newArray; 4571 } 4572 return array; 4573 } 4574 noteNetworkInterfaceTypeLocked(String iface, int networkType)4575 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) { 4576 if (TextUtils.isEmpty(iface)) return; 4577 if (ConnectivityManager.isNetworkTypeMobile(networkType)) { 4578 mMobileIfaces = includeInStringArray(mMobileIfaces, iface); 4579 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces); 4580 } else { 4581 mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface); 4582 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces); 4583 } 4584 if (ConnectivityManager.isNetworkTypeWifi(networkType)) { 4585 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 4586 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); 4587 } else { 4588 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 4589 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); 4590 } 4591 } 4592 noteNetworkStatsEnabledLocked()4593 public void noteNetworkStatsEnabledLocked() { 4594 // During device boot, qtaguid isn't enabled until after the inital 4595 // loading of battery stats. Now that they're enabled, take our initial 4596 // snapshot for future delta calculation. 4597 updateMobileRadioStateLocked(mClocks.elapsedRealtime(), null); 4598 updateWifiStateLocked(null); 4599 } 4600 getScreenOnTime(long elapsedRealtimeUs, int which)4601 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 4602 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4603 } 4604 getScreenOnCount(int which)4605 @Override public int getScreenOnCount(int which) { 4606 return mScreenOnTimer.getCountLocked(which); 4607 } 4608 getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)4609 @Override public long getScreenBrightnessTime(int brightnessBin, 4610 long elapsedRealtimeUs, int which) { 4611 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 4612 elapsedRealtimeUs, which); 4613 } 4614 getInteractiveTime(long elapsedRealtimeUs, int which)4615 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 4616 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4617 } 4618 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)4619 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 4620 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4621 } 4622 getPowerSaveModeEnabledCount(int which)4623 @Override public int getPowerSaveModeEnabledCount(int which) { 4624 return mPowerSaveModeEnabledTimer.getCountLocked(which); 4625 } 4626 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)4627 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 4628 int which) { 4629 switch (mode) { 4630 case DEVICE_IDLE_MODE_LIGHT: 4631 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4632 case DEVICE_IDLE_MODE_DEEP: 4633 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4634 } 4635 return 0; 4636 } 4637 getDeviceIdleModeCount(int mode, int which)4638 @Override public int getDeviceIdleModeCount(int mode, int which) { 4639 switch (mode) { 4640 case DEVICE_IDLE_MODE_LIGHT: 4641 return mDeviceIdleModeLightTimer.getCountLocked(which); 4642 case DEVICE_IDLE_MODE_DEEP: 4643 return mDeviceIdleModeFullTimer.getCountLocked(which); 4644 } 4645 return 0; 4646 } 4647 getLongestDeviceIdleModeTime(int mode)4648 @Override public long getLongestDeviceIdleModeTime(int mode) { 4649 switch (mode) { 4650 case DEVICE_IDLE_MODE_LIGHT: 4651 return mLongestLightIdleTime; 4652 case DEVICE_IDLE_MODE_DEEP: 4653 return mLongestFullIdleTime; 4654 } 4655 return 0; 4656 } 4657 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)4658 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 4659 switch (mode) { 4660 case DEVICE_IDLE_MODE_LIGHT: 4661 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4662 case DEVICE_IDLE_MODE_DEEP: 4663 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4664 } 4665 return 0; 4666 } 4667 getDeviceIdlingCount(int mode, int which)4668 @Override public int getDeviceIdlingCount(int mode, int which) { 4669 switch (mode) { 4670 case DEVICE_IDLE_MODE_LIGHT: 4671 return mDeviceLightIdlingTimer.getCountLocked(which); 4672 case DEVICE_IDLE_MODE_DEEP: 4673 return mDeviceIdlingTimer.getCountLocked(which); 4674 } 4675 return 0; 4676 } 4677 getNumConnectivityChange(int which)4678 @Override public int getNumConnectivityChange(int which) { 4679 int val = mNumConnectivityChange; 4680 if (which == STATS_CURRENT) { 4681 val -= mLoadedNumConnectivityChange; 4682 } else if (which == STATS_SINCE_UNPLUGGED) { 4683 val -= mUnpluggedNumConnectivityChange; 4684 } 4685 return val; 4686 } 4687 getPhoneOnTime(long elapsedRealtimeUs, int which)4688 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 4689 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4690 } 4691 getPhoneOnCount(int which)4692 @Override public int getPhoneOnCount(int which) { 4693 return mPhoneOnTimer.getCountLocked(which); 4694 } 4695 getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)4696 @Override public long getPhoneSignalStrengthTime(int strengthBin, 4697 long elapsedRealtimeUs, int which) { 4698 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 4699 elapsedRealtimeUs, which); 4700 } 4701 getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)4702 @Override public long getPhoneSignalScanningTime( 4703 long elapsedRealtimeUs, int which) { 4704 return mPhoneSignalScanningTimer.getTotalTimeLocked( 4705 elapsedRealtimeUs, which); 4706 } 4707 getPhoneSignalStrengthCount(int strengthBin, int which)4708 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 4709 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 4710 } 4711 getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)4712 @Override public long getPhoneDataConnectionTime(int dataType, 4713 long elapsedRealtimeUs, int which) { 4714 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 4715 elapsedRealtimeUs, which); 4716 } 4717 getPhoneDataConnectionCount(int dataType, int which)4718 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 4719 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 4720 } 4721 getMobileRadioActiveTime(long elapsedRealtimeUs, int which)4722 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 4723 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4724 } 4725 getMobileRadioActiveCount(int which)4726 @Override public int getMobileRadioActiveCount(int which) { 4727 return mMobileRadioActiveTimer.getCountLocked(which); 4728 } 4729 getMobileRadioActiveAdjustedTime(int which)4730 @Override public long getMobileRadioActiveAdjustedTime(int which) { 4731 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 4732 } 4733 getMobileRadioActiveUnknownTime(int which)4734 @Override public long getMobileRadioActiveUnknownTime(int which) { 4735 return mMobileRadioActiveUnknownTime.getCountLocked(which); 4736 } 4737 getMobileRadioActiveUnknownCount(int which)4738 @Override public int getMobileRadioActiveUnknownCount(int which) { 4739 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 4740 } 4741 getWifiOnTime(long elapsedRealtimeUs, int which)4742 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 4743 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4744 } 4745 getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)4746 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 4747 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4748 } 4749 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)4750 @Override public long getWifiStateTime(int wifiState, 4751 long elapsedRealtimeUs, int which) { 4752 return mWifiStateTimer[wifiState].getTotalTimeLocked( 4753 elapsedRealtimeUs, which); 4754 } 4755 getWifiStateCount(int wifiState, int which)4756 @Override public int getWifiStateCount(int wifiState, int which) { 4757 return mWifiStateTimer[wifiState].getCountLocked(which); 4758 } 4759 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)4760 @Override public long getWifiSupplStateTime(int state, 4761 long elapsedRealtimeUs, int which) { 4762 return mWifiSupplStateTimer[state].getTotalTimeLocked( 4763 elapsedRealtimeUs, which); 4764 } 4765 getWifiSupplStateCount(int state, int which)4766 @Override public int getWifiSupplStateCount(int state, int which) { 4767 return mWifiSupplStateTimer[state].getCountLocked(which); 4768 } 4769 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)4770 @Override public long getWifiSignalStrengthTime(int strengthBin, 4771 long elapsedRealtimeUs, int which) { 4772 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 4773 elapsedRealtimeUs, which); 4774 } 4775 getWifiSignalStrengthCount(int strengthBin, int which)4776 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 4777 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 4778 } 4779 4780 @Override getBluetoothControllerActivity()4781 public ControllerActivityCounter getBluetoothControllerActivity() { 4782 return mBluetoothActivity; 4783 } 4784 4785 @Override getWifiControllerActivity()4786 public ControllerActivityCounter getWifiControllerActivity() { 4787 return mWifiActivity; 4788 } 4789 4790 @Override getModemControllerActivity()4791 public ControllerActivityCounter getModemControllerActivity() { 4792 return mModemActivity; 4793 } 4794 4795 @Override hasBluetoothActivityReporting()4796 public boolean hasBluetoothActivityReporting() { 4797 return mHasBluetoothReporting; 4798 } 4799 4800 @Override hasWifiActivityReporting()4801 public boolean hasWifiActivityReporting() { 4802 return mHasWifiReporting; 4803 } 4804 4805 @Override hasModemActivityReporting()4806 public boolean hasModemActivityReporting() { 4807 return mHasModemReporting; 4808 } 4809 4810 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)4811 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 4812 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4813 } 4814 4815 @Override getFlashlightOnCount(int which)4816 public long getFlashlightOnCount(int which) { 4817 return mFlashlightOnTimer.getCountLocked(which); 4818 } 4819 4820 @Override getCameraOnTime(long elapsedRealtimeUs, int which)4821 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 4822 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4823 } 4824 4825 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)4826 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 4827 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4828 } 4829 4830 @Override getNetworkActivityBytes(int type, int which)4831 public long getNetworkActivityBytes(int type, int which) { 4832 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 4833 return mNetworkByteActivityCounters[type].getCountLocked(which); 4834 } else { 4835 return 0; 4836 } 4837 } 4838 4839 @Override getNetworkActivityPackets(int type, int which)4840 public long getNetworkActivityPackets(int type, int which) { 4841 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 4842 return mNetworkPacketActivityCounters[type].getCountLocked(which); 4843 } else { 4844 return 0; 4845 } 4846 } 4847 getStartClockTime()4848 @Override public long getStartClockTime() { 4849 final long currentTime = System.currentTimeMillis(); 4850 if (ensureStartClockTime(currentTime)) { 4851 recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(), 4852 mClocks.uptimeMillis()); 4853 } 4854 return mStartClockTime; 4855 } 4856 getStartPlatformVersion()4857 @Override public String getStartPlatformVersion() { 4858 return mStartPlatformVersion; 4859 } 4860 getEndPlatformVersion()4861 @Override public String getEndPlatformVersion() { 4862 return mEndPlatformVersion; 4863 } 4864 getParcelVersion()4865 @Override public int getParcelVersion() { 4866 return VERSION; 4867 } 4868 getIsOnBattery()4869 @Override public boolean getIsOnBattery() { 4870 return mOnBattery; 4871 } 4872 getUidStats()4873 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 4874 return mUidStats; 4875 } 4876 4877 /** 4878 * The statistics associated with a particular uid. 4879 */ 4880 public static class Uid extends BatteryStats.Uid { 4881 /** 4882 * BatteryStatsImpl that we are associated with. 4883 */ 4884 protected BatteryStatsImpl mBsi; 4885 4886 final int mUid; 4887 4888 boolean mWifiRunning; 4889 StopwatchTimer mWifiRunningTimer; 4890 4891 boolean mFullWifiLockOut; 4892 StopwatchTimer mFullWifiLockTimer; 4893 4894 boolean mWifiScanStarted; 4895 StopwatchTimer mWifiScanTimer; 4896 4897 static final int NO_BATCHED_SCAN_STARTED = -1; 4898 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 4899 StopwatchTimer[] mWifiBatchedScanTimer; 4900 4901 boolean mWifiMulticastEnabled; 4902 StopwatchTimer mWifiMulticastTimer; 4903 4904 StopwatchTimer mAudioTurnedOnTimer; 4905 StopwatchTimer mVideoTurnedOnTimer; 4906 StopwatchTimer mFlashlightTurnedOnTimer; 4907 StopwatchTimer mCameraTurnedOnTimer; 4908 StopwatchTimer mForegroundActivityTimer; 4909 StopwatchTimer mBluetoothScanTimer; 4910 4911 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 4912 StopwatchTimer[] mProcessStateTimer; 4913 4914 BatchTimer mVibratorOnTimer; 4915 4916 Counter[] mUserActivityCounters; 4917 4918 LongSamplingCounter[] mNetworkByteActivityCounters; 4919 LongSamplingCounter[] mNetworkPacketActivityCounters; 4920 LongSamplingCounter mMobileRadioActiveTime; 4921 LongSamplingCounter mMobileRadioActiveCount; 4922 4923 /** 4924 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 4925 * Can be null if the UID has had no such activity. 4926 */ 4927 private ControllerActivityCounterImpl mWifiControllerActivity; 4928 4929 /** 4930 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 4931 * Can be null if the UID has had no such activity. 4932 */ 4933 private ControllerActivityCounterImpl mBluetoothControllerActivity; 4934 4935 /** 4936 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 4937 * Can be null if the UID has had no such activity. 4938 */ 4939 private ControllerActivityCounterImpl mModemControllerActivity; 4940 4941 /** 4942 * The CPU times we had at the last history details update. 4943 */ 4944 long mLastStepUserTime; 4945 long mLastStepSystemTime; 4946 long mCurStepUserTime; 4947 long mCurStepSystemTime; 4948 4949 LongSamplingCounter mUserCpuTime; 4950 LongSamplingCounter mSystemCpuTime; 4951 LongSamplingCounter mCpuPower; 4952 LongSamplingCounter[][] mCpuClusterSpeed; 4953 4954 /** 4955 * The statistics we have collected for this uid's wake locks. 4956 */ 4957 final OverflowArrayMap<Wakelock> mWakelockStats; 4958 4959 /** 4960 * The statistics we have collected for this uid's syncs. 4961 */ 4962 final OverflowArrayMap<StopwatchTimer> mSyncStats; 4963 4964 /** 4965 * The statistics we have collected for this uid's jobs. 4966 */ 4967 final OverflowArrayMap<StopwatchTimer> mJobStats; 4968 4969 /** 4970 * The statistics we have collected for this uid's sensor activations. 4971 */ 4972 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 4973 4974 /** 4975 * The statistics we have collected for this uid's processes. 4976 */ 4977 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 4978 4979 /** 4980 * The statistics we have collected for this uid's processes. 4981 */ 4982 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 4983 4984 /** 4985 * The transient wake stats we have collected for this uid's pids. 4986 */ 4987 final SparseArray<Pid> mPids = new SparseArray<>(); 4988 Uid(BatteryStatsImpl bsi, int uid)4989 public Uid(BatteryStatsImpl bsi, int uid) { 4990 mBsi = bsi; 4991 mUid = uid; 4992 4993 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 4994 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 4995 mCpuPower = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 4996 4997 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>() { 4998 @Override public Wakelock instantiateObject() { 4999 return new Wakelock(mBsi, Uid.this); 5000 } 5001 }; 5002 mSyncStats = mBsi.new OverflowArrayMap<StopwatchTimer>() { 5003 @Override public StopwatchTimer instantiateObject() { 5004 return new StopwatchTimer(mBsi.mClocks, Uid.this, SYNC, null, 5005 mBsi.mOnBatteryTimeBase); 5006 } 5007 }; 5008 mJobStats = mBsi.new OverflowArrayMap<StopwatchTimer>() { 5009 @Override public StopwatchTimer instantiateObject() { 5010 return new StopwatchTimer(mBsi.mClocks, Uid.this, JOB, null, 5011 mBsi.mOnBatteryTimeBase); 5012 } 5013 }; 5014 5015 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING, 5016 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 5017 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK, 5018 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 5019 mWifiScanTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_SCAN, 5020 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase); 5021 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 5022 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED, 5023 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 5024 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 5025 } 5026 5027 @Override getWakelockStats()5028 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 5029 return mWakelockStats.getMap(); 5030 } 5031 5032 @Override getSyncStats()5033 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 5034 return mSyncStats.getMap(); 5035 } 5036 5037 @Override getJobStats()5038 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 5039 return mJobStats.getMap(); 5040 } 5041 5042 @Override getSensorStats()5043 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 5044 return mSensorStats; 5045 } 5046 5047 @Override getProcessStats()5048 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 5049 return mProcessStats; 5050 } 5051 5052 @Override getPackageStats()5053 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 5054 return mPackageStats; 5055 } 5056 5057 @Override getUid()5058 public int getUid() { 5059 return mUid; 5060 } 5061 5062 @Override noteWifiRunningLocked(long elapsedRealtimeMs)5063 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 5064 if (!mWifiRunning) { 5065 mWifiRunning = true; 5066 if (mWifiRunningTimer == null) { 5067 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 5068 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 5069 } 5070 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 5071 } 5072 } 5073 5074 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)5075 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 5076 if (mWifiRunning) { 5077 mWifiRunning = false; 5078 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 5079 } 5080 } 5081 5082 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)5083 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 5084 if (!mFullWifiLockOut) { 5085 mFullWifiLockOut = true; 5086 if (mFullWifiLockTimer == null) { 5087 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 5088 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 5089 } 5090 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 5091 } 5092 } 5093 5094 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)5095 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 5096 if (mFullWifiLockOut) { 5097 mFullWifiLockOut = false; 5098 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 5099 } 5100 } 5101 5102 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)5103 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 5104 if (!mWifiScanStarted) { 5105 mWifiScanStarted = true; 5106 if (mWifiScanTimer == null) { 5107 mWifiScanTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 5108 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase); 5109 } 5110 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 5111 } 5112 } 5113 5114 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)5115 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 5116 if (mWifiScanStarted) { 5117 mWifiScanStarted = false; 5118 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 5119 } 5120 } 5121 5122 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)5123 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 5124 int bin = 0; 5125 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 5126 csph = csph >> 3; 5127 bin++; 5128 } 5129 5130 if (mWifiBatchedScanBinStarted == bin) return; 5131 5132 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 5133 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 5134 stopRunningLocked(elapsedRealtimeMs); 5135 } 5136 mWifiBatchedScanBinStarted = bin; 5137 if (mWifiBatchedScanTimer[bin] == null) { 5138 makeWifiBatchedScanBin(bin, null); 5139 } 5140 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 5141 } 5142 5143 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)5144 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 5145 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 5146 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 5147 stopRunningLocked(elapsedRealtimeMs); 5148 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 5149 } 5150 } 5151 5152 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)5153 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 5154 if (!mWifiMulticastEnabled) { 5155 mWifiMulticastEnabled = true; 5156 if (mWifiMulticastTimer == null) { 5157 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 5158 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 5159 } 5160 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 5161 } 5162 } 5163 5164 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)5165 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 5166 if (mWifiMulticastEnabled) { 5167 mWifiMulticastEnabled = false; 5168 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 5169 } 5170 } 5171 5172 @Override getWifiControllerActivity()5173 public ControllerActivityCounter getWifiControllerActivity() { 5174 return mWifiControllerActivity; 5175 } 5176 5177 @Override getBluetoothControllerActivity()5178 public ControllerActivityCounter getBluetoothControllerActivity() { 5179 return mBluetoothControllerActivity; 5180 } 5181 5182 @Override getModemControllerActivity()5183 public ControllerActivityCounter getModemControllerActivity() { 5184 return mModemControllerActivity; 5185 } 5186 getOrCreateWifiControllerActivityLocked()5187 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 5188 if (mWifiControllerActivity == null) { 5189 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 5190 NUM_BT_TX_LEVELS); 5191 } 5192 return mWifiControllerActivity; 5193 } 5194 getOrCreateBluetoothControllerActivityLocked()5195 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 5196 if (mBluetoothControllerActivity == null) { 5197 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 5198 NUM_BT_TX_LEVELS); 5199 } 5200 return mBluetoothControllerActivity; 5201 } 5202 getOrCreateModemControllerActivityLocked()5203 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 5204 if (mModemControllerActivity == null) { 5205 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 5206 ModemActivityInfo.TX_POWER_LEVELS); 5207 } 5208 return mModemControllerActivity; 5209 } 5210 createAudioTurnedOnTimerLocked()5211 public StopwatchTimer createAudioTurnedOnTimerLocked() { 5212 if (mAudioTurnedOnTimer == null) { 5213 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 5214 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5215 } 5216 return mAudioTurnedOnTimer; 5217 } 5218 noteAudioTurnedOnLocked(long elapsedRealtimeMs)5219 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 5220 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5221 } 5222 noteAudioTurnedOffLocked(long elapsedRealtimeMs)5223 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 5224 if (mAudioTurnedOnTimer != null) { 5225 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5226 } 5227 } 5228 noteResetAudioLocked(long elapsedRealtimeMs)5229 public void noteResetAudioLocked(long elapsedRealtimeMs) { 5230 if (mAudioTurnedOnTimer != null) { 5231 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5232 } 5233 } 5234 createVideoTurnedOnTimerLocked()5235 public StopwatchTimer createVideoTurnedOnTimerLocked() { 5236 if (mVideoTurnedOnTimer == null) { 5237 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 5238 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5239 } 5240 return mVideoTurnedOnTimer; 5241 } 5242 noteVideoTurnedOnLocked(long elapsedRealtimeMs)5243 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 5244 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5245 } 5246 noteVideoTurnedOffLocked(long elapsedRealtimeMs)5247 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 5248 if (mVideoTurnedOnTimer != null) { 5249 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5250 } 5251 } 5252 noteResetVideoLocked(long elapsedRealtimeMs)5253 public void noteResetVideoLocked(long elapsedRealtimeMs) { 5254 if (mVideoTurnedOnTimer != null) { 5255 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5256 } 5257 } 5258 createFlashlightTurnedOnTimerLocked()5259 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 5260 if (mFlashlightTurnedOnTimer == null) { 5261 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 5262 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5263 } 5264 return mFlashlightTurnedOnTimer; 5265 } 5266 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)5267 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 5268 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5269 } 5270 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)5271 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 5272 if (mFlashlightTurnedOnTimer != null) { 5273 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5274 } 5275 } 5276 noteResetFlashlightLocked(long elapsedRealtimeMs)5277 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 5278 if (mFlashlightTurnedOnTimer != null) { 5279 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5280 } 5281 } 5282 createCameraTurnedOnTimerLocked()5283 public StopwatchTimer createCameraTurnedOnTimerLocked() { 5284 if (mCameraTurnedOnTimer == null) { 5285 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 5286 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5287 } 5288 return mCameraTurnedOnTimer; 5289 } 5290 noteCameraTurnedOnLocked(long elapsedRealtimeMs)5291 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 5292 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5293 } 5294 noteCameraTurnedOffLocked(long elapsedRealtimeMs)5295 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 5296 if (mCameraTurnedOnTimer != null) { 5297 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5298 } 5299 } 5300 noteResetCameraLocked(long elapsedRealtimeMs)5301 public void noteResetCameraLocked(long elapsedRealtimeMs) { 5302 if (mCameraTurnedOnTimer != null) { 5303 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5304 } 5305 } 5306 createForegroundActivityTimerLocked()5307 public StopwatchTimer createForegroundActivityTimerLocked() { 5308 if (mForegroundActivityTimer == null) { 5309 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 5310 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 5311 } 5312 return mForegroundActivityTimer; 5313 } 5314 createBluetoothScanTimerLocked()5315 public StopwatchTimer createBluetoothScanTimerLocked() { 5316 if (mBluetoothScanTimer == null) { 5317 mBluetoothScanTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 5318 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase); 5319 } 5320 return mBluetoothScanTimer; 5321 } 5322 noteBluetoothScanStartedLocked(long elapsedRealtimeMs)5323 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs) { 5324 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 5325 } 5326 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs)5327 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs) { 5328 if (mBluetoothScanTimer != null) { 5329 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 5330 } 5331 } 5332 noteResetBluetoothScanLocked(long elapsedRealtimeMs)5333 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 5334 if (mBluetoothScanTimer != null) { 5335 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 5336 } 5337 } 5338 5339 @Override noteActivityResumedLocked(long elapsedRealtimeMs)5340 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 5341 // We always start, since we want multiple foreground PIDs to nest 5342 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 5343 } 5344 5345 @Override noteActivityPausedLocked(long elapsedRealtimeMs)5346 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 5347 if (mForegroundActivityTimer != null) { 5348 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 5349 } 5350 } 5351 createVibratorOnTimerLocked()5352 public BatchTimer createVibratorOnTimerLocked() { 5353 if (mVibratorOnTimer == null) { 5354 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 5355 mBsi.mOnBatteryTimeBase); 5356 } 5357 return mVibratorOnTimer; 5358 } 5359 noteVibratorOnLocked(long durationMillis)5360 public void noteVibratorOnLocked(long durationMillis) { 5361 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis); 5362 } 5363 noteVibratorOffLocked()5364 public void noteVibratorOffLocked() { 5365 if (mVibratorOnTimer != null) { 5366 mVibratorOnTimer.abortLastDuration(mBsi); 5367 } 5368 } 5369 5370 @Override getWifiRunningTime(long elapsedRealtimeUs, int which)5371 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 5372 if (mWifiRunningTimer == null) { 5373 return 0; 5374 } 5375 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5376 } 5377 5378 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)5379 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 5380 if (mFullWifiLockTimer == null) { 5381 return 0; 5382 } 5383 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5384 } 5385 5386 @Override getWifiScanTime(long elapsedRealtimeUs, int which)5387 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 5388 if (mWifiScanTimer == null) { 5389 return 0; 5390 } 5391 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5392 } 5393 5394 @Override getWifiScanCount(int which)5395 public int getWifiScanCount(int which) { 5396 if (mWifiScanTimer == null) { 5397 return 0; 5398 } 5399 return mWifiScanTimer.getCountLocked(which); 5400 } 5401 5402 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)5403 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 5404 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 5405 if (mWifiBatchedScanTimer[csphBin] == null) { 5406 return 0; 5407 } 5408 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 5409 } 5410 5411 @Override getWifiBatchedScanCount(int csphBin, int which)5412 public int getWifiBatchedScanCount(int csphBin, int which) { 5413 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 5414 if (mWifiBatchedScanTimer[csphBin] == null) { 5415 return 0; 5416 } 5417 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 5418 } 5419 5420 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)5421 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 5422 if (mWifiMulticastTimer == null) { 5423 return 0; 5424 } 5425 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5426 } 5427 5428 @Override getAudioTurnedOnTimer()5429 public Timer getAudioTurnedOnTimer() { 5430 return mAudioTurnedOnTimer; 5431 } 5432 5433 @Override getVideoTurnedOnTimer()5434 public Timer getVideoTurnedOnTimer() { 5435 return mVideoTurnedOnTimer; 5436 } 5437 5438 @Override getFlashlightTurnedOnTimer()5439 public Timer getFlashlightTurnedOnTimer() { 5440 return mFlashlightTurnedOnTimer; 5441 } 5442 5443 @Override getCameraTurnedOnTimer()5444 public Timer getCameraTurnedOnTimer() { 5445 return mCameraTurnedOnTimer; 5446 } 5447 5448 @Override getForegroundActivityTimer()5449 public Timer getForegroundActivityTimer() { 5450 return mForegroundActivityTimer; 5451 } 5452 5453 @Override getBluetoothScanTimer()5454 public Timer getBluetoothScanTimer() { 5455 return mBluetoothScanTimer; 5456 } 5457 makeProcessState(int i, Parcel in)5458 void makeProcessState(int i, Parcel in) { 5459 if (i < 0 || i >= NUM_PROCESS_STATE) return; 5460 5461 if (in == null) { 5462 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 5463 mBsi.mOnBatteryTimeBase); 5464 } else { 5465 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 5466 mBsi.mOnBatteryTimeBase, in); 5467 } 5468 } 5469 5470 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)5471 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 5472 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 5473 if (mProcessStateTimer[state] == null) { 5474 return 0; 5475 } 5476 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 5477 } 5478 5479 @Override getProcessStateTimer(int state)5480 public Timer getProcessStateTimer(int state) { 5481 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 5482 return mProcessStateTimer[state]; 5483 } 5484 5485 @Override getVibratorOnTimer()5486 public Timer getVibratorOnTimer() { 5487 return mVibratorOnTimer; 5488 } 5489 5490 @Override noteUserActivityLocked(int type)5491 public void noteUserActivityLocked(int type) { 5492 if (mUserActivityCounters == null) { 5493 initUserActivityLocked(); 5494 } 5495 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 5496 mUserActivityCounters[type].stepAtomic(); 5497 } else { 5498 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 5499 new Throwable()); 5500 } 5501 } 5502 5503 @Override hasUserActivity()5504 public boolean hasUserActivity() { 5505 return mUserActivityCounters != null; 5506 } 5507 5508 @Override getUserActivityCount(int type, int which)5509 public int getUserActivityCount(int type, int which) { 5510 if (mUserActivityCounters == null) { 5511 return 0; 5512 } 5513 return mUserActivityCounters[type].getCountLocked(which); 5514 } 5515 makeWifiBatchedScanBin(int i, Parcel in)5516 void makeWifiBatchedScanBin(int i, Parcel in) { 5517 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 5518 5519 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 5520 if (collected == null) { 5521 collected = new ArrayList<StopwatchTimer>(); 5522 mBsi.mWifiBatchedScanTimers.put(i, collected); 5523 } 5524 if (in == null) { 5525 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 5526 collected, mBsi.mOnBatteryTimeBase); 5527 } else { 5528 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 5529 collected, mBsi.mOnBatteryTimeBase, in); 5530 } 5531 } 5532 5533 initUserActivityLocked()5534 void initUserActivityLocked() { 5535 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 5536 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 5537 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 5538 } 5539 } 5540 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)5541 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 5542 if (mNetworkByteActivityCounters == null) { 5543 initNetworkActivityLocked(); 5544 } 5545 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 5546 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 5547 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 5548 } else { 5549 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 5550 new Throwable()); 5551 } 5552 } 5553 noteMobileRadioActiveTimeLocked(long batteryUptime)5554 void noteMobileRadioActiveTimeLocked(long batteryUptime) { 5555 if (mNetworkByteActivityCounters == null) { 5556 initNetworkActivityLocked(); 5557 } 5558 mMobileRadioActiveTime.addCountLocked(batteryUptime); 5559 mMobileRadioActiveCount.addCountLocked(1); 5560 } 5561 5562 @Override hasNetworkActivity()5563 public boolean hasNetworkActivity() { 5564 return mNetworkByteActivityCounters != null; 5565 } 5566 5567 @Override getNetworkActivityBytes(int type, int which)5568 public long getNetworkActivityBytes(int type, int which) { 5569 if (mNetworkByteActivityCounters != null && type >= 0 5570 && type < mNetworkByteActivityCounters.length) { 5571 return mNetworkByteActivityCounters[type].getCountLocked(which); 5572 } else { 5573 return 0; 5574 } 5575 } 5576 5577 @Override getNetworkActivityPackets(int type, int which)5578 public long getNetworkActivityPackets(int type, int which) { 5579 if (mNetworkPacketActivityCounters != null && type >= 0 5580 && type < mNetworkPacketActivityCounters.length) { 5581 return mNetworkPacketActivityCounters[type].getCountLocked(which); 5582 } else { 5583 return 0; 5584 } 5585 } 5586 5587 @Override getMobileRadioActiveTime(int which)5588 public long getMobileRadioActiveTime(int which) { 5589 return mMobileRadioActiveTime != null 5590 ? mMobileRadioActiveTime.getCountLocked(which) : 0; 5591 } 5592 5593 @Override getMobileRadioActiveCount(int which)5594 public int getMobileRadioActiveCount(int which) { 5595 return mMobileRadioActiveCount != null 5596 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 5597 } 5598 5599 @Override getUserCpuTimeUs(int which)5600 public long getUserCpuTimeUs(int which) { 5601 return mUserCpuTime.getCountLocked(which); 5602 } 5603 5604 @Override getSystemCpuTimeUs(int which)5605 public long getSystemCpuTimeUs(int which) { 5606 return mSystemCpuTime.getCountLocked(which); 5607 } 5608 5609 @Override getCpuPowerMaUs(int which)5610 public long getCpuPowerMaUs(int which) { 5611 return mCpuPower.getCountLocked(which); 5612 } 5613 5614 @Override getTimeAtCpuSpeed(int cluster, int step, int which)5615 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 5616 if (mCpuClusterSpeed != null) { 5617 if (cluster >= 0 && cluster < mCpuClusterSpeed.length) { 5618 final LongSamplingCounter[] cpuSpeeds = mCpuClusterSpeed[cluster]; 5619 if (cpuSpeeds != null) { 5620 if (step >= 0 && step < cpuSpeeds.length) { 5621 final LongSamplingCounter c = cpuSpeeds[step]; 5622 if (c != null) { 5623 return c.getCountLocked(which); 5624 } 5625 } 5626 } 5627 } 5628 } 5629 return 0; 5630 } 5631 initNetworkActivityLocked()5632 void initNetworkActivityLocked() { 5633 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 5634 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 5635 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 5636 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 5637 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 5638 } 5639 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 5640 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 5641 } 5642 5643 /** 5644 * Clear all stats for this uid. Returns true if the uid is completely 5645 * inactive so can be dropped. 5646 */ reset()5647 boolean reset() { 5648 boolean active = false; 5649 5650 if (mWifiRunningTimer != null) { 5651 active |= !mWifiRunningTimer.reset(false); 5652 active |= mWifiRunning; 5653 } 5654 if (mFullWifiLockTimer != null) { 5655 active |= !mFullWifiLockTimer.reset(false); 5656 active |= mFullWifiLockOut; 5657 } 5658 if (mWifiScanTimer != null) { 5659 active |= !mWifiScanTimer.reset(false); 5660 active |= mWifiScanStarted; 5661 } 5662 if (mWifiBatchedScanTimer != null) { 5663 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 5664 if (mWifiBatchedScanTimer[i] != null) { 5665 active |= !mWifiBatchedScanTimer[i].reset(false); 5666 } 5667 } 5668 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 5669 } 5670 if (mWifiMulticastTimer != null) { 5671 active |= !mWifiMulticastTimer.reset(false); 5672 active |= mWifiMulticastEnabled; 5673 } 5674 if (mAudioTurnedOnTimer != null) { 5675 active |= !mAudioTurnedOnTimer.reset(false); 5676 } 5677 if (mVideoTurnedOnTimer != null) { 5678 active |= !mVideoTurnedOnTimer.reset(false); 5679 } 5680 if (mFlashlightTurnedOnTimer != null) { 5681 active |= !mFlashlightTurnedOnTimer.reset(false); 5682 } 5683 if (mCameraTurnedOnTimer != null) { 5684 active |= !mCameraTurnedOnTimer.reset(false); 5685 } 5686 if (mForegroundActivityTimer != null) { 5687 active |= !mForegroundActivityTimer.reset(false); 5688 } 5689 if (mBluetoothScanTimer != null) { 5690 active |= !mBluetoothScanTimer.reset(false); 5691 } 5692 if (mProcessStateTimer != null) { 5693 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 5694 if (mProcessStateTimer[i] != null) { 5695 active |= !mProcessStateTimer[i].reset(false); 5696 } 5697 } 5698 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); 5699 } 5700 if (mVibratorOnTimer != null) { 5701 if (mVibratorOnTimer.reset(false)) { 5702 mVibratorOnTimer.detach(); 5703 mVibratorOnTimer = null; 5704 } else { 5705 active = true; 5706 } 5707 } 5708 5709 if (mUserActivityCounters != null) { 5710 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 5711 mUserActivityCounters[i].reset(false); 5712 } 5713 } 5714 5715 if (mNetworkByteActivityCounters != null) { 5716 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 5717 mNetworkByteActivityCounters[i].reset(false); 5718 mNetworkPacketActivityCounters[i].reset(false); 5719 } 5720 mMobileRadioActiveTime.reset(false); 5721 mMobileRadioActiveCount.reset(false); 5722 } 5723 5724 if (mWifiControllerActivity != null) { 5725 mWifiControllerActivity.reset(false); 5726 } 5727 5728 if (mBluetoothControllerActivity != null) { 5729 mBluetoothControllerActivity.reset(false); 5730 } 5731 5732 if (mModemControllerActivity != null) { 5733 mModemControllerActivity.reset(false); 5734 } 5735 5736 mUserCpuTime.reset(false); 5737 mSystemCpuTime.reset(false); 5738 mCpuPower.reset(false); 5739 5740 if (mCpuClusterSpeed != null) { 5741 for (LongSamplingCounter[] speeds : mCpuClusterSpeed) { 5742 if (speeds != null) { 5743 for (LongSamplingCounter speed : speeds) { 5744 if (speed != null) { 5745 speed.reset(false); 5746 } 5747 } 5748 } 5749 } 5750 } 5751 5752 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 5753 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 5754 Wakelock wl = wakeStats.valueAt(iw); 5755 if (wl.reset()) { 5756 wakeStats.removeAt(iw); 5757 } else { 5758 active = true; 5759 } 5760 } 5761 mWakelockStats.cleanup(); 5762 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap(); 5763 for (int is=syncStats.size()-1; is>=0; is--) { 5764 StopwatchTimer timer = syncStats.valueAt(is); 5765 if (timer.reset(false)) { 5766 syncStats.removeAt(is); 5767 timer.detach(); 5768 } else { 5769 active = true; 5770 } 5771 } 5772 mSyncStats.cleanup(); 5773 final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap(); 5774 for (int ij=jobStats.size()-1; ij>=0; ij--) { 5775 StopwatchTimer timer = jobStats.valueAt(ij); 5776 if (timer.reset(false)) { 5777 jobStats.removeAt(ij); 5778 timer.detach(); 5779 } else { 5780 active = true; 5781 } 5782 } 5783 mJobStats.cleanup(); 5784 for (int ise=mSensorStats.size()-1; ise>=0; ise--) { 5785 Sensor s = mSensorStats.valueAt(ise); 5786 if (s.reset()) { 5787 mSensorStats.removeAt(ise); 5788 } else { 5789 active = true; 5790 } 5791 } 5792 for (int ip=mProcessStats.size()-1; ip>=0; ip--) { 5793 Proc proc = mProcessStats.valueAt(ip); 5794 proc.detach(); 5795 } 5796 mProcessStats.clear(); 5797 if (mPids.size() > 0) { 5798 for (int i=mPids.size()-1; i>=0; i--) { 5799 Pid pid = mPids.valueAt(i); 5800 if (pid.mWakeNesting > 0) { 5801 active = true; 5802 } else { 5803 mPids.removeAt(i); 5804 } 5805 } 5806 } 5807 if (mPackageStats.size() > 0) { 5808 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator(); 5809 while (it.hasNext()) { 5810 Map.Entry<String, Pkg> pkgEntry = it.next(); 5811 Pkg p = pkgEntry.getValue(); 5812 p.detach(); 5813 if (p.mServiceStats.size() > 0) { 5814 Iterator<Map.Entry<String, Pkg.Serv>> it2 5815 = p.mServiceStats.entrySet().iterator(); 5816 while (it2.hasNext()) { 5817 Map.Entry<String, Pkg.Serv> servEntry = it2.next(); 5818 servEntry.getValue().detach(); 5819 } 5820 } 5821 } 5822 mPackageStats.clear(); 5823 } 5824 5825 mLastStepUserTime = mLastStepSystemTime = 0; 5826 mCurStepUserTime = mCurStepSystemTime = 0; 5827 5828 if (!active) { 5829 if (mWifiRunningTimer != null) { 5830 mWifiRunningTimer.detach(); 5831 } 5832 if (mFullWifiLockTimer != null) { 5833 mFullWifiLockTimer.detach(); 5834 } 5835 if (mWifiScanTimer != null) { 5836 mWifiScanTimer.detach(); 5837 } 5838 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 5839 if (mWifiBatchedScanTimer[i] != null) { 5840 mWifiBatchedScanTimer[i].detach(); 5841 } 5842 } 5843 if (mWifiMulticastTimer != null) { 5844 mWifiMulticastTimer.detach(); 5845 } 5846 if (mAudioTurnedOnTimer != null) { 5847 mAudioTurnedOnTimer.detach(); 5848 mAudioTurnedOnTimer = null; 5849 } 5850 if (mVideoTurnedOnTimer != null) { 5851 mVideoTurnedOnTimer.detach(); 5852 mVideoTurnedOnTimer = null; 5853 } 5854 if (mFlashlightTurnedOnTimer != null) { 5855 mFlashlightTurnedOnTimer.detach(); 5856 mFlashlightTurnedOnTimer = null; 5857 } 5858 if (mCameraTurnedOnTimer != null) { 5859 mCameraTurnedOnTimer.detach(); 5860 mCameraTurnedOnTimer = null; 5861 } 5862 if (mForegroundActivityTimer != null) { 5863 mForegroundActivityTimer.detach(); 5864 mForegroundActivityTimer = null; 5865 } 5866 if (mBluetoothScanTimer != null) { 5867 mBluetoothScanTimer.detach(); 5868 mBluetoothScanTimer = null; 5869 } 5870 if (mUserActivityCounters != null) { 5871 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 5872 mUserActivityCounters[i].detach(); 5873 } 5874 } 5875 if (mNetworkByteActivityCounters != null) { 5876 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 5877 mNetworkByteActivityCounters[i].detach(); 5878 mNetworkPacketActivityCounters[i].detach(); 5879 } 5880 } 5881 5882 if (mWifiControllerActivity != null) { 5883 mWifiControllerActivity.detach(); 5884 } 5885 5886 if (mBluetoothControllerActivity != null) { 5887 mBluetoothControllerActivity.detach(); 5888 } 5889 5890 if (mModemControllerActivity != null) { 5891 mModemControllerActivity.detach(); 5892 } 5893 5894 mPids.clear(); 5895 5896 mUserCpuTime.detach(); 5897 mSystemCpuTime.detach(); 5898 mCpuPower.detach(); 5899 5900 if (mCpuClusterSpeed != null) { 5901 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) { 5902 if (cpuSpeeds != null) { 5903 for (LongSamplingCounter c : cpuSpeeds) { 5904 if (c != null) { 5905 c.detach(); 5906 } 5907 } 5908 } 5909 } 5910 } 5911 } 5912 5913 return !active; 5914 } 5915 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)5916 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 5917 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 5918 int NW = wakeStats.size(); 5919 out.writeInt(NW); 5920 for (int iw=0; iw<NW; iw++) { 5921 out.writeString(wakeStats.keyAt(iw)); 5922 Uid.Wakelock wakelock = wakeStats.valueAt(iw); 5923 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 5924 } 5925 5926 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap(); 5927 int NS = syncStats.size(); 5928 out.writeInt(NS); 5929 for (int is=0; is<NS; is++) { 5930 out.writeString(syncStats.keyAt(is)); 5931 StopwatchTimer timer = syncStats.valueAt(is); 5932 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 5933 } 5934 5935 final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap(); 5936 int NJ = jobStats.size(); 5937 out.writeInt(NJ); 5938 for (int ij=0; ij<NJ; ij++) { 5939 out.writeString(jobStats.keyAt(ij)); 5940 StopwatchTimer timer = jobStats.valueAt(ij); 5941 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 5942 } 5943 5944 int NSE = mSensorStats.size(); 5945 out.writeInt(NSE); 5946 for (int ise=0; ise<NSE; ise++) { 5947 out.writeInt(mSensorStats.keyAt(ise)); 5948 Uid.Sensor sensor = mSensorStats.valueAt(ise); 5949 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 5950 } 5951 5952 int NP = mProcessStats.size(); 5953 out.writeInt(NP); 5954 for (int ip=0; ip<NP; ip++) { 5955 out.writeString(mProcessStats.keyAt(ip)); 5956 Uid.Proc proc = mProcessStats.valueAt(ip); 5957 proc.writeToParcelLocked(out); 5958 } 5959 5960 out.writeInt(mPackageStats.size()); 5961 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 5962 out.writeString(pkgEntry.getKey()); 5963 Uid.Pkg pkg = pkgEntry.getValue(); 5964 pkg.writeToParcelLocked(out); 5965 } 5966 5967 if (mWifiRunningTimer != null) { 5968 out.writeInt(1); 5969 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 5970 } else { 5971 out.writeInt(0); 5972 } 5973 if (mFullWifiLockTimer != null) { 5974 out.writeInt(1); 5975 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 5976 } else { 5977 out.writeInt(0); 5978 } 5979 if (mWifiScanTimer != null) { 5980 out.writeInt(1); 5981 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 5982 } else { 5983 out.writeInt(0); 5984 } 5985 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 5986 if (mWifiBatchedScanTimer[i] != null) { 5987 out.writeInt(1); 5988 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 5989 } else { 5990 out.writeInt(0); 5991 } 5992 } 5993 if (mWifiMulticastTimer != null) { 5994 out.writeInt(1); 5995 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 5996 } else { 5997 out.writeInt(0); 5998 } 5999 6000 if (mAudioTurnedOnTimer != null) { 6001 out.writeInt(1); 6002 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6003 } else { 6004 out.writeInt(0); 6005 } 6006 if (mVideoTurnedOnTimer != null) { 6007 out.writeInt(1); 6008 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6009 } else { 6010 out.writeInt(0); 6011 } 6012 if (mFlashlightTurnedOnTimer != null) { 6013 out.writeInt(1); 6014 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6015 } else { 6016 out.writeInt(0); 6017 } 6018 if (mCameraTurnedOnTimer != null) { 6019 out.writeInt(1); 6020 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6021 } else { 6022 out.writeInt(0); 6023 } 6024 if (mForegroundActivityTimer != null) { 6025 out.writeInt(1); 6026 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 6027 } else { 6028 out.writeInt(0); 6029 } 6030 if (mBluetoothScanTimer != null) { 6031 out.writeInt(1); 6032 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs); 6033 } else { 6034 out.writeInt(0); 6035 } 6036 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 6037 if (mProcessStateTimer[i] != null) { 6038 out.writeInt(1); 6039 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 6040 } else { 6041 out.writeInt(0); 6042 } 6043 } 6044 if (mVibratorOnTimer != null) { 6045 out.writeInt(1); 6046 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 6047 } else { 6048 out.writeInt(0); 6049 } 6050 if (mUserActivityCounters != null) { 6051 out.writeInt(1); 6052 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6053 mUserActivityCounters[i].writeToParcel(out); 6054 } 6055 } else { 6056 out.writeInt(0); 6057 } 6058 if (mNetworkByteActivityCounters != null) { 6059 out.writeInt(1); 6060 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6061 mNetworkByteActivityCounters[i].writeToParcel(out); 6062 mNetworkPacketActivityCounters[i].writeToParcel(out); 6063 } 6064 mMobileRadioActiveTime.writeToParcel(out); 6065 mMobileRadioActiveCount.writeToParcel(out); 6066 } else { 6067 out.writeInt(0); 6068 } 6069 6070 if (mWifiControllerActivity != null) { 6071 out.writeInt(1); 6072 mWifiControllerActivity.writeToParcel(out, 0); 6073 } else { 6074 out.writeInt(0); 6075 } 6076 6077 if (mBluetoothControllerActivity != null) { 6078 out.writeInt(1); 6079 mBluetoothControllerActivity.writeToParcel(out, 0); 6080 } else { 6081 out.writeInt(0); 6082 } 6083 6084 if (mModemControllerActivity != null) { 6085 out.writeInt(1); 6086 mModemControllerActivity.writeToParcel(out, 0); 6087 } else { 6088 out.writeInt(0); 6089 } 6090 6091 mUserCpuTime.writeToParcel(out); 6092 mSystemCpuTime.writeToParcel(out); 6093 mCpuPower.writeToParcel(out); 6094 6095 if (mCpuClusterSpeed != null) { 6096 out.writeInt(1); 6097 out.writeInt(mCpuClusterSpeed.length); 6098 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) { 6099 if (cpuSpeeds != null) { 6100 out.writeInt(1); 6101 out.writeInt(cpuSpeeds.length); 6102 for (LongSamplingCounter c : cpuSpeeds) { 6103 if (c != null) { 6104 out.writeInt(1); 6105 c.writeToParcel(out); 6106 } else { 6107 out.writeInt(0); 6108 } 6109 } 6110 } else { 6111 out.writeInt(0); 6112 } 6113 } 6114 } else { 6115 out.writeInt(0); 6116 } 6117 } 6118 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in)6119 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 6120 int numWakelocks = in.readInt(); 6121 mWakelockStats.clear(); 6122 for (int j = 0; j < numWakelocks; j++) { 6123 String wakelockName = in.readString(); 6124 Uid.Wakelock wakelock = new Wakelock(mBsi, this); 6125 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in); 6126 mWakelockStats.add(wakelockName, wakelock); 6127 } 6128 6129 int numSyncs = in.readInt(); 6130 mSyncStats.clear(); 6131 for (int j = 0; j < numSyncs; j++) { 6132 String syncName = in.readString(); 6133 if (in.readInt() != 0) { 6134 mSyncStats.add(syncName, 6135 new StopwatchTimer(mBsi.mClocks, Uid.this, SYNC, null, timeBase, in)); 6136 } 6137 } 6138 6139 int numJobs = in.readInt(); 6140 mJobStats.clear(); 6141 for (int j = 0; j < numJobs; j++) { 6142 String jobName = in.readString(); 6143 if (in.readInt() != 0) { 6144 mJobStats.add(jobName, new StopwatchTimer(mBsi.mClocks, Uid.this, JOB, null, 6145 timeBase, in)); 6146 } 6147 } 6148 6149 int numSensors = in.readInt(); 6150 mSensorStats.clear(); 6151 for (int k = 0; k < numSensors; k++) { 6152 int sensorNumber = in.readInt(); 6153 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber); 6154 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, in); 6155 mSensorStats.put(sensorNumber, sensor); 6156 } 6157 6158 int numProcs = in.readInt(); 6159 mProcessStats.clear(); 6160 for (int k = 0; k < numProcs; k++) { 6161 String processName = in.readString(); 6162 Uid.Proc proc = new Proc(mBsi, processName); 6163 proc.readFromParcelLocked(in); 6164 mProcessStats.put(processName, proc); 6165 } 6166 6167 int numPkgs = in.readInt(); 6168 mPackageStats.clear(); 6169 for (int l = 0; l < numPkgs; l++) { 6170 String packageName = in.readString(); 6171 Uid.Pkg pkg = new Pkg(mBsi); 6172 pkg.readFromParcelLocked(in); 6173 mPackageStats.put(packageName, pkg); 6174 } 6175 6176 mWifiRunning = false; 6177 if (in.readInt() != 0) { 6178 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 6179 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in); 6180 } else { 6181 mWifiRunningTimer = null; 6182 } 6183 mFullWifiLockOut = false; 6184 if (in.readInt() != 0) { 6185 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 6186 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in); 6187 } else { 6188 mFullWifiLockTimer = null; 6189 } 6190 mWifiScanStarted = false; 6191 if (in.readInt() != 0) { 6192 mWifiScanTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 6193 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, in); 6194 } else { 6195 mWifiScanTimer = null; 6196 } 6197 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 6198 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6199 if (in.readInt() != 0) { 6200 makeWifiBatchedScanBin(i, in); 6201 } else { 6202 mWifiBatchedScanTimer[i] = null; 6203 } 6204 } 6205 mWifiMulticastEnabled = false; 6206 if (in.readInt() != 0) { 6207 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED, 6208 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in); 6209 } else { 6210 mWifiMulticastTimer = null; 6211 } 6212 if (in.readInt() != 0) { 6213 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 6214 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6215 } else { 6216 mAudioTurnedOnTimer = null; 6217 } 6218 if (in.readInt() != 0) { 6219 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 6220 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6221 } else { 6222 mVideoTurnedOnTimer = null; 6223 } 6224 if (in.readInt() != 0) { 6225 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 6226 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6227 } else { 6228 mFlashlightTurnedOnTimer = null; 6229 } 6230 if (in.readInt() != 0) { 6231 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 6232 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6233 } else { 6234 mCameraTurnedOnTimer = null; 6235 } 6236 if (in.readInt() != 0) { 6237 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 6238 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in); 6239 } else { 6240 mForegroundActivityTimer = null; 6241 } 6242 if (in.readInt() != 0) { 6243 mBluetoothScanTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 6244 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, in); 6245 } else { 6246 mBluetoothScanTimer = null; 6247 } 6248 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 6249 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 6250 if (in.readInt() != 0) { 6251 makeProcessState(i, in); 6252 } else { 6253 mProcessStateTimer[i] = null; 6254 } 6255 } 6256 if (in.readInt() != 0) { 6257 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 6258 mBsi.mOnBatteryTimeBase, in); 6259 } else { 6260 mVibratorOnTimer = null; 6261 } 6262 if (in.readInt() != 0) { 6263 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 6264 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6265 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in); 6266 } 6267 } else { 6268 mUserActivityCounters = null; 6269 } 6270 if (in.readInt() != 0) { 6271 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 6272 mNetworkPacketActivityCounters 6273 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 6274 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6275 mNetworkByteActivityCounters[i] 6276 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6277 mNetworkPacketActivityCounters[i] 6278 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6279 } 6280 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6281 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6282 } else { 6283 mNetworkByteActivityCounters = null; 6284 mNetworkPacketActivityCounters = null; 6285 } 6286 6287 if (in.readInt() != 0) { 6288 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 6289 NUM_WIFI_TX_LEVELS, in); 6290 } else { 6291 mWifiControllerActivity = null; 6292 } 6293 6294 if (in.readInt() != 0) { 6295 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 6296 NUM_BT_TX_LEVELS, in); 6297 } else { 6298 mBluetoothControllerActivity = null; 6299 } 6300 6301 if (in.readInt() != 0) { 6302 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 6303 ModemActivityInfo.TX_POWER_LEVELS, in); 6304 } else { 6305 mModemControllerActivity = null; 6306 } 6307 6308 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6309 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6310 mCpuPower = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6311 6312 if (in.readInt() != 0) { 6313 int numCpuClusters = in.readInt(); 6314 if (mBsi.mPowerProfile != null && mBsi.mPowerProfile.getNumCpuClusters() != numCpuClusters) { 6315 throw new ParcelFormatException("Incompatible number of cpu clusters"); 6316 } 6317 6318 mCpuClusterSpeed = new LongSamplingCounter[numCpuClusters][]; 6319 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 6320 if (in.readInt() != 0) { 6321 int numSpeeds = in.readInt(); 6322 if (mBsi.mPowerProfile != null && 6323 mBsi.mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) { 6324 throw new ParcelFormatException("Incompatible number of cpu speeds"); 6325 } 6326 6327 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds]; 6328 mCpuClusterSpeed[cluster] = cpuSpeeds; 6329 for (int speed = 0; speed < numSpeeds; speed++) { 6330 if (in.readInt() != 0) { 6331 cpuSpeeds[speed] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6332 } 6333 } 6334 } else { 6335 mCpuClusterSpeed[cluster] = null; 6336 } 6337 } 6338 } else { 6339 mCpuClusterSpeed = null; 6340 } 6341 } 6342 6343 /** 6344 * The statistics associated with a particular wake lock. 6345 */ 6346 public static class Wakelock extends BatteryStats.Uid.Wakelock { 6347 /** 6348 * BatteryStatsImpl that we are associated with. 6349 */ 6350 protected BatteryStatsImpl mBsi; 6351 6352 /** 6353 * BatteryStatsImpl that we are associated with. 6354 */ 6355 protected Uid mUid; 6356 6357 /** 6358 * How long (in ms) this uid has been keeping the device partially awake. 6359 */ 6360 StopwatchTimer mTimerPartial; 6361 6362 /** 6363 * How long (in ms) this uid has been keeping the device fully awake. 6364 */ 6365 StopwatchTimer mTimerFull; 6366 6367 /** 6368 * How long (in ms) this uid has had a window keeping the device awake. 6369 */ 6370 StopwatchTimer mTimerWindow; 6371 6372 /** 6373 * How long (in ms) this uid has had a draw wake lock. 6374 */ 6375 StopwatchTimer mTimerDraw; 6376 Wakelock(BatteryStatsImpl bsi, Uid uid)6377 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 6378 mBsi = bsi; 6379 mUid = uid; 6380 } 6381 6382 /** 6383 * Reads a possibly null Timer from a Parcel. The timer is associated with the 6384 * proper timer pool from the given BatteryStatsImpl object. 6385 * 6386 * @param in the Parcel to be read from. 6387 * return a new Timer, or null. 6388 */ readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)6389 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 6390 TimeBase timeBase, Parcel in) { 6391 if (in.readInt() == 0) { 6392 return null; 6393 } 6394 6395 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 6396 } 6397 reset()6398 boolean reset() { 6399 boolean wlactive = false; 6400 if (mTimerFull != null) { 6401 wlactive |= !mTimerFull.reset(false); 6402 } 6403 if (mTimerPartial != null) { 6404 wlactive |= !mTimerPartial.reset(false); 6405 } 6406 if (mTimerWindow != null) { 6407 wlactive |= !mTimerWindow.reset(false); 6408 } 6409 if (mTimerDraw != null) { 6410 wlactive |= !mTimerDraw.reset(false); 6411 } 6412 if (!wlactive) { 6413 if (mTimerFull != null) { 6414 mTimerFull.detach(); 6415 mTimerFull = null; 6416 } 6417 if (mTimerPartial != null) { 6418 mTimerPartial.detach(); 6419 mTimerPartial = null; 6420 } 6421 if (mTimerWindow != null) { 6422 mTimerWindow.detach(); 6423 mTimerWindow = null; 6424 } 6425 if (mTimerDraw != null) { 6426 mTimerDraw.detach(); 6427 mTimerDraw = null; 6428 } 6429 } 6430 return !wlactive; 6431 } 6432 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in)6433 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 6434 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL, 6435 mBsi.mPartialTimers, screenOffTimeBase, in); 6436 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL, mBsi.mFullTimers, timeBase, in); 6437 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW, mBsi.mWindowTimers, timeBase, in); 6438 mTimerDraw = readTimerFromParcel(WAKE_TYPE_DRAW, mBsi.mDrawTimers, timeBase, in); 6439 } 6440 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)6441 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 6442 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 6443 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 6444 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 6445 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 6446 } 6447 6448 @Override getWakeTime(int type)6449 public Timer getWakeTime(int type) { 6450 switch (type) { 6451 case WAKE_TYPE_FULL: return mTimerFull; 6452 case WAKE_TYPE_PARTIAL: return mTimerPartial; 6453 case WAKE_TYPE_WINDOW: return mTimerWindow; 6454 case WAKE_TYPE_DRAW: return mTimerDraw; 6455 default: throw new IllegalArgumentException("type = " + type); 6456 } 6457 } 6458 getStopwatchTimer(int type)6459 public StopwatchTimer getStopwatchTimer(int type) { 6460 StopwatchTimer t; 6461 switch (type) { 6462 case WAKE_TYPE_PARTIAL: 6463 t = mTimerPartial; 6464 if (t == null) { 6465 t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_PARTIAL, 6466 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase); 6467 mTimerPartial = t; 6468 } 6469 return t; 6470 case WAKE_TYPE_FULL: 6471 t = mTimerFull; 6472 if (t == null) { 6473 t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_FULL, 6474 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 6475 mTimerFull = t; 6476 } 6477 return t; 6478 case WAKE_TYPE_WINDOW: 6479 t = mTimerWindow; 6480 if (t == null) { 6481 t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_WINDOW, 6482 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 6483 mTimerWindow = t; 6484 } 6485 return t; 6486 case WAKE_TYPE_DRAW: 6487 t = mTimerDraw; 6488 if (t == null) { 6489 t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_DRAW, 6490 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 6491 mTimerDraw = t; 6492 } 6493 return t; 6494 default: 6495 throw new IllegalArgumentException("type=" + type); 6496 } 6497 } 6498 } 6499 6500 public static class Sensor extends BatteryStats.Uid.Sensor { 6501 /** 6502 * BatteryStatsImpl that we are associated with. 6503 */ 6504 protected BatteryStatsImpl mBsi; 6505 6506 /** 6507 * BatteryStatsImpl that we are associated with. 6508 */ 6509 protected Uid mUid; 6510 6511 final int mHandle; 6512 StopwatchTimer mTimer; 6513 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)6514 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 6515 mBsi = bsi; 6516 mUid = uid; 6517 mHandle = handle; 6518 } 6519 readTimerFromParcel(TimeBase timeBase, Parcel in)6520 private StopwatchTimer readTimerFromParcel(TimeBase timeBase, Parcel in) { 6521 if (in.readInt() == 0) { 6522 return null; 6523 } 6524 6525 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 6526 if (pool == null) { 6527 pool = new ArrayList<StopwatchTimer>(); 6528 mBsi.mSensorTimers.put(mHandle, pool); 6529 } 6530 return new StopwatchTimer(mBsi.mClocks, mUid, 0, pool, timeBase, in); 6531 } 6532 reset()6533 boolean reset() { 6534 if (mTimer.reset(true)) { 6535 mTimer = null; 6536 return true; 6537 } 6538 return false; 6539 } 6540 readFromParcelLocked(TimeBase timeBase, Parcel in)6541 void readFromParcelLocked(TimeBase timeBase, Parcel in) { 6542 mTimer = readTimerFromParcel(timeBase, in); 6543 } 6544 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)6545 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 6546 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 6547 } 6548 6549 @Override getSensorTime()6550 public Timer getSensorTime() { 6551 return mTimer; 6552 } 6553 6554 @Override getHandle()6555 public int getHandle() { 6556 return mHandle; 6557 } 6558 } 6559 6560 /** 6561 * The statistics associated with a particular process. 6562 */ 6563 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 6564 /** 6565 * BatteryStatsImpl that we are associated with. 6566 */ 6567 protected BatteryStatsImpl mBsi; 6568 6569 /** 6570 * The name of this process. 6571 */ 6572 final String mName; 6573 6574 /** 6575 * Remains true until removed from the stats. 6576 */ 6577 boolean mActive = true; 6578 6579 /** 6580 * Total time (in ms) spent executing in user code. 6581 */ 6582 long mUserTime; 6583 6584 /** 6585 * Total time (in ms) spent executing in kernel code. 6586 */ 6587 long mSystemTime; 6588 6589 /** 6590 * Amount of time (in ms) the process was running in the foreground. 6591 */ 6592 long mForegroundTime; 6593 6594 /** 6595 * Number of times the process has been started. 6596 */ 6597 int mStarts; 6598 6599 /** 6600 * Number of times the process has crashed. 6601 */ 6602 int mNumCrashes; 6603 6604 /** 6605 * Number of times the process has had an ANR. 6606 */ 6607 int mNumAnrs; 6608 6609 /** 6610 * The amount of user time loaded from a previous save. 6611 */ 6612 long mLoadedUserTime; 6613 6614 /** 6615 * The amount of system time loaded from a previous save. 6616 */ 6617 long mLoadedSystemTime; 6618 6619 /** 6620 * The amount of foreground time loaded from a previous save. 6621 */ 6622 long mLoadedForegroundTime; 6623 6624 /** 6625 * The number of times the process has started from a previous save. 6626 */ 6627 int mLoadedStarts; 6628 6629 /** 6630 * Number of times the process has crashed from a previous save. 6631 */ 6632 int mLoadedNumCrashes; 6633 6634 /** 6635 * Number of times the process has had an ANR from a previous save. 6636 */ 6637 int mLoadedNumAnrs; 6638 6639 /** 6640 * The amount of user time when last unplugged. 6641 */ 6642 long mUnpluggedUserTime; 6643 6644 /** 6645 * The amount of system time when last unplugged. 6646 */ 6647 long mUnpluggedSystemTime; 6648 6649 /** 6650 * The amount of foreground time since unplugged. 6651 */ 6652 long mUnpluggedForegroundTime; 6653 6654 /** 6655 * The number of times the process has started before unplugged. 6656 */ 6657 int mUnpluggedStarts; 6658 6659 /** 6660 * Number of times the process has crashed before unplugged. 6661 */ 6662 int mUnpluggedNumCrashes; 6663 6664 /** 6665 * Number of times the process has had an ANR before unplugged. 6666 */ 6667 int mUnpluggedNumAnrs; 6668 6669 ArrayList<ExcessivePower> mExcessivePower; 6670 Proc(BatteryStatsImpl bsi, String name)6671 public Proc(BatteryStatsImpl bsi, String name) { 6672 mBsi = bsi; 6673 mName = name; 6674 mBsi.mOnBatteryTimeBase.add(this); 6675 } 6676 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)6677 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 6678 mUnpluggedUserTime = mUserTime; 6679 mUnpluggedSystemTime = mSystemTime; 6680 mUnpluggedForegroundTime = mForegroundTime; 6681 mUnpluggedStarts = mStarts; 6682 mUnpluggedNumCrashes = mNumCrashes; 6683 mUnpluggedNumAnrs = mNumAnrs; 6684 } 6685 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)6686 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 6687 } 6688 detach()6689 void detach() { 6690 mActive = false; 6691 mBsi.mOnBatteryTimeBase.remove(this); 6692 } 6693 countExcessivePowers()6694 public int countExcessivePowers() { 6695 return mExcessivePower != null ? mExcessivePower.size() : 0; 6696 } 6697 getExcessivePower(int i)6698 public ExcessivePower getExcessivePower(int i) { 6699 if (mExcessivePower != null) { 6700 return mExcessivePower.get(i); 6701 } 6702 return null; 6703 } 6704 addExcessiveWake(long overTime, long usedTime)6705 public void addExcessiveWake(long overTime, long usedTime) { 6706 if (mExcessivePower == null) { 6707 mExcessivePower = new ArrayList<ExcessivePower>(); 6708 } 6709 ExcessivePower ew = new ExcessivePower(); 6710 ew.type = ExcessivePower.TYPE_WAKE; 6711 ew.overTime = overTime; 6712 ew.usedTime = usedTime; 6713 mExcessivePower.add(ew); 6714 } 6715 addExcessiveCpu(long overTime, long usedTime)6716 public void addExcessiveCpu(long overTime, long usedTime) { 6717 if (mExcessivePower == null) { 6718 mExcessivePower = new ArrayList<ExcessivePower>(); 6719 } 6720 ExcessivePower ew = new ExcessivePower(); 6721 ew.type = ExcessivePower.TYPE_CPU; 6722 ew.overTime = overTime; 6723 ew.usedTime = usedTime; 6724 mExcessivePower.add(ew); 6725 } 6726 writeExcessivePowerToParcelLocked(Parcel out)6727 void writeExcessivePowerToParcelLocked(Parcel out) { 6728 if (mExcessivePower == null) { 6729 out.writeInt(0); 6730 return; 6731 } 6732 6733 final int N = mExcessivePower.size(); 6734 out.writeInt(N); 6735 for (int i=0; i<N; i++) { 6736 ExcessivePower ew = mExcessivePower.get(i); 6737 out.writeInt(ew.type); 6738 out.writeLong(ew.overTime); 6739 out.writeLong(ew.usedTime); 6740 } 6741 } 6742 readExcessivePowerFromParcelLocked(Parcel in)6743 void readExcessivePowerFromParcelLocked(Parcel in) { 6744 final int N = in.readInt(); 6745 if (N == 0) { 6746 mExcessivePower = null; 6747 return; 6748 } 6749 6750 if (N > 10000) { 6751 throw new ParcelFormatException( 6752 "File corrupt: too many excessive power entries " + N); 6753 } 6754 6755 mExcessivePower = new ArrayList<>(); 6756 for (int i=0; i<N; i++) { 6757 ExcessivePower ew = new ExcessivePower(); 6758 ew.type = in.readInt(); 6759 ew.overTime = in.readLong(); 6760 ew.usedTime = in.readLong(); 6761 mExcessivePower.add(ew); 6762 } 6763 } 6764 writeToParcelLocked(Parcel out)6765 void writeToParcelLocked(Parcel out) { 6766 out.writeLong(mUserTime); 6767 out.writeLong(mSystemTime); 6768 out.writeLong(mForegroundTime); 6769 out.writeInt(mStarts); 6770 out.writeInt(mNumCrashes); 6771 out.writeInt(mNumAnrs); 6772 out.writeLong(mLoadedUserTime); 6773 out.writeLong(mLoadedSystemTime); 6774 out.writeLong(mLoadedForegroundTime); 6775 out.writeInt(mLoadedStarts); 6776 out.writeInt(mLoadedNumCrashes); 6777 out.writeInt(mLoadedNumAnrs); 6778 out.writeLong(mUnpluggedUserTime); 6779 out.writeLong(mUnpluggedSystemTime); 6780 out.writeLong(mUnpluggedForegroundTime); 6781 out.writeInt(mUnpluggedStarts); 6782 out.writeInt(mUnpluggedNumCrashes); 6783 out.writeInt(mUnpluggedNumAnrs); 6784 writeExcessivePowerToParcelLocked(out); 6785 } 6786 readFromParcelLocked(Parcel in)6787 void readFromParcelLocked(Parcel in) { 6788 mUserTime = in.readLong(); 6789 mSystemTime = in.readLong(); 6790 mForegroundTime = in.readLong(); 6791 mStarts = in.readInt(); 6792 mNumCrashes = in.readInt(); 6793 mNumAnrs = in.readInt(); 6794 mLoadedUserTime = in.readLong(); 6795 mLoadedSystemTime = in.readLong(); 6796 mLoadedForegroundTime = in.readLong(); 6797 mLoadedStarts = in.readInt(); 6798 mLoadedNumCrashes = in.readInt(); 6799 mLoadedNumAnrs = in.readInt(); 6800 mUnpluggedUserTime = in.readLong(); 6801 mUnpluggedSystemTime = in.readLong(); 6802 mUnpluggedForegroundTime = in.readLong(); 6803 mUnpluggedStarts = in.readInt(); 6804 mUnpluggedNumCrashes = in.readInt(); 6805 mUnpluggedNumAnrs = in.readInt(); 6806 readExcessivePowerFromParcelLocked(in); 6807 } 6808 addCpuTimeLocked(int utime, int stime)6809 public void addCpuTimeLocked(int utime, int stime) { 6810 mUserTime += utime; 6811 mSystemTime += stime; 6812 } 6813 addForegroundTimeLocked(long ttime)6814 public void addForegroundTimeLocked(long ttime) { 6815 mForegroundTime += ttime; 6816 } 6817 incStartsLocked()6818 public void incStartsLocked() { 6819 mStarts++; 6820 } 6821 incNumCrashesLocked()6822 public void incNumCrashesLocked() { 6823 mNumCrashes++; 6824 } 6825 incNumAnrsLocked()6826 public void incNumAnrsLocked() { 6827 mNumAnrs++; 6828 } 6829 6830 @Override isActive()6831 public boolean isActive() { 6832 return mActive; 6833 } 6834 6835 @Override getUserTime(int which)6836 public long getUserTime(int which) { 6837 long val = mUserTime; 6838 if (which == STATS_CURRENT) { 6839 val -= mLoadedUserTime; 6840 } else if (which == STATS_SINCE_UNPLUGGED) { 6841 val -= mUnpluggedUserTime; 6842 } 6843 return val; 6844 } 6845 6846 @Override getSystemTime(int which)6847 public long getSystemTime(int which) { 6848 long val = mSystemTime; 6849 if (which == STATS_CURRENT) { 6850 val -= mLoadedSystemTime; 6851 } else if (which == STATS_SINCE_UNPLUGGED) { 6852 val -= mUnpluggedSystemTime; 6853 } 6854 return val; 6855 } 6856 6857 @Override getForegroundTime(int which)6858 public long getForegroundTime(int which) { 6859 long val = mForegroundTime; 6860 if (which == STATS_CURRENT) { 6861 val -= mLoadedForegroundTime; 6862 } else if (which == STATS_SINCE_UNPLUGGED) { 6863 val -= mUnpluggedForegroundTime; 6864 } 6865 return val; 6866 } 6867 6868 @Override getStarts(int which)6869 public int getStarts(int which) { 6870 int val = mStarts; 6871 if (which == STATS_CURRENT) { 6872 val -= mLoadedStarts; 6873 } else if (which == STATS_SINCE_UNPLUGGED) { 6874 val -= mUnpluggedStarts; 6875 } 6876 return val; 6877 } 6878 6879 @Override getNumCrashes(int which)6880 public int getNumCrashes(int which) { 6881 int val = mNumCrashes; 6882 if (which == STATS_CURRENT) { 6883 val -= mLoadedNumCrashes; 6884 } else if (which == STATS_SINCE_UNPLUGGED) { 6885 val -= mUnpluggedNumCrashes; 6886 } 6887 return val; 6888 } 6889 6890 @Override getNumAnrs(int which)6891 public int getNumAnrs(int which) { 6892 int val = mNumAnrs; 6893 if (which == STATS_CURRENT) { 6894 val -= mLoadedNumAnrs; 6895 } else if (which == STATS_SINCE_UNPLUGGED) { 6896 val -= mUnpluggedNumAnrs; 6897 } 6898 return val; 6899 } 6900 } 6901 6902 /** 6903 * The statistics associated with a particular package. 6904 */ 6905 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 6906 /** 6907 * BatteryStatsImpl that we are associated with. 6908 */ 6909 protected BatteryStatsImpl mBsi; 6910 6911 /** 6912 * Number of times wakeup alarms have occurred for this app. 6913 */ 6914 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 6915 6916 /** 6917 * The statics we have collected for this package's services. 6918 */ 6919 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 6920 Pkg(BatteryStatsImpl bsi)6921 public Pkg(BatteryStatsImpl bsi) { 6922 mBsi = bsi; 6923 mBsi.mOnBatteryScreenOffTimeBase.add(this); 6924 } 6925 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)6926 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 6927 } 6928 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)6929 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 6930 } 6931 detach()6932 void detach() { 6933 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 6934 } 6935 readFromParcelLocked(Parcel in)6936 void readFromParcelLocked(Parcel in) { 6937 int numWA = in.readInt(); 6938 mWakeupAlarms.clear(); 6939 for (int i=0; i<numWA; i++) { 6940 String tag = in.readString(); 6941 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryTimeBase, in)); 6942 } 6943 6944 int numServs = in.readInt(); 6945 mServiceStats.clear(); 6946 for (int m = 0; m < numServs; m++) { 6947 String serviceName = in.readString(); 6948 Uid.Pkg.Serv serv = new Serv(mBsi); 6949 mServiceStats.put(serviceName, serv); 6950 6951 serv.readFromParcelLocked(in); 6952 } 6953 } 6954 writeToParcelLocked(Parcel out)6955 void writeToParcelLocked(Parcel out) { 6956 int numWA = mWakeupAlarms.size(); 6957 out.writeInt(numWA); 6958 for (int i=0; i<numWA; i++) { 6959 out.writeString(mWakeupAlarms.keyAt(i)); 6960 mWakeupAlarms.valueAt(i).writeToParcel(out); 6961 } 6962 6963 final int NS = mServiceStats.size(); 6964 out.writeInt(NS); 6965 for (int i=0; i<NS; i++) { 6966 out.writeString(mServiceStats.keyAt(i)); 6967 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 6968 serv.writeToParcelLocked(out); 6969 } 6970 } 6971 6972 @Override getWakeupAlarmStats()6973 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 6974 return mWakeupAlarms; 6975 } 6976 noteWakeupAlarmLocked(String tag)6977 public void noteWakeupAlarmLocked(String tag) { 6978 Counter c = mWakeupAlarms.get(tag); 6979 if (c == null) { 6980 c = new Counter(mBsi.mOnBatteryTimeBase); 6981 mWakeupAlarms.put(tag, c); 6982 } 6983 c.stepAtomic(); 6984 } 6985 6986 @Override getServiceStats()6987 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 6988 return mServiceStats; 6989 } 6990 6991 /** 6992 * The statistics associated with a particular service. 6993 */ 6994 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 6995 /** 6996 * BatteryStatsImpl that we are associated with. 6997 */ 6998 protected BatteryStatsImpl mBsi; 6999 7000 /** 7001 * The android package in which this service resides. 7002 */ 7003 protected Pkg mPkg; 7004 7005 /** 7006 * Total time (ms in battery uptime) the service has been left started. 7007 */ 7008 protected long mStartTime; 7009 7010 /** 7011 * If service has been started and not yet stopped, this is 7012 * when it was started. 7013 */ 7014 protected long mRunningSince; 7015 7016 /** 7017 * True if we are currently running. 7018 */ 7019 protected boolean mRunning; 7020 7021 /** 7022 * Total number of times startService() has been called. 7023 */ 7024 protected int mStarts; 7025 7026 /** 7027 * Total time (ms in battery uptime) the service has been left launched. 7028 */ 7029 protected long mLaunchedTime; 7030 7031 /** 7032 * If service has been launched and not yet exited, this is 7033 * when it was launched (ms in battery uptime). 7034 */ 7035 protected long mLaunchedSince; 7036 7037 /** 7038 * True if we are currently launched. 7039 */ 7040 protected boolean mLaunched; 7041 7042 /** 7043 * Total number times the service has been launched. 7044 */ 7045 protected int mLaunches; 7046 7047 /** 7048 * The amount of time spent started loaded from a previous save 7049 * (ms in battery uptime). 7050 */ 7051 protected long mLoadedStartTime; 7052 7053 /** 7054 * The number of starts loaded from a previous save. 7055 */ 7056 protected int mLoadedStarts; 7057 7058 /** 7059 * The number of launches loaded from a previous save. 7060 */ 7061 protected int mLoadedLaunches; 7062 7063 /** 7064 * The amount of time spent started as of the last run (ms 7065 * in battery uptime). 7066 */ 7067 protected long mLastStartTime; 7068 7069 /** 7070 * The number of starts as of the last run. 7071 */ 7072 protected int mLastStarts; 7073 7074 /** 7075 * The number of launches as of the last run. 7076 */ 7077 protected int mLastLaunches; 7078 7079 /** 7080 * The amount of time spent started when last unplugged (ms 7081 * in battery uptime). 7082 */ 7083 protected long mUnpluggedStartTime; 7084 7085 /** 7086 * The number of starts when last unplugged. 7087 */ 7088 protected int mUnpluggedStarts; 7089 7090 /** 7091 * The number of launches when last unplugged. 7092 */ 7093 protected int mUnpluggedLaunches; 7094 7095 /** 7096 * Construct a Serv. Also adds it to the on-battery time base as a listener. 7097 */ Serv(BatteryStatsImpl bsi)7098 public Serv(BatteryStatsImpl bsi) { 7099 mBsi = bsi; 7100 mBsi.mOnBatteryTimeBase.add(this); 7101 } 7102 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)7103 public void onTimeStarted(long elapsedRealtime, long baseUptime, 7104 long baseRealtime) { 7105 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime); 7106 mUnpluggedStarts = mStarts; 7107 mUnpluggedLaunches = mLaunches; 7108 } 7109 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)7110 public void onTimeStopped(long elapsedRealtime, long baseUptime, 7111 long baseRealtime) { 7112 } 7113 7114 /** 7115 * Remove this Serv as a listener from the time base. 7116 */ detach()7117 public void detach() { 7118 mBsi.mOnBatteryTimeBase.remove(this); 7119 } 7120 readFromParcelLocked(Parcel in)7121 public void readFromParcelLocked(Parcel in) { 7122 mStartTime = in.readLong(); 7123 mRunningSince = in.readLong(); 7124 mRunning = in.readInt() != 0; 7125 mStarts = in.readInt(); 7126 mLaunchedTime = in.readLong(); 7127 mLaunchedSince = in.readLong(); 7128 mLaunched = in.readInt() != 0; 7129 mLaunches = in.readInt(); 7130 mLoadedStartTime = in.readLong(); 7131 mLoadedStarts = in.readInt(); 7132 mLoadedLaunches = in.readInt(); 7133 mLastStartTime = 0; 7134 mLastStarts = 0; 7135 mLastLaunches = 0; 7136 mUnpluggedStartTime = in.readLong(); 7137 mUnpluggedStarts = in.readInt(); 7138 mUnpluggedLaunches = in.readInt(); 7139 } 7140 writeToParcelLocked(Parcel out)7141 public void writeToParcelLocked(Parcel out) { 7142 out.writeLong(mStartTime); 7143 out.writeLong(mRunningSince); 7144 out.writeInt(mRunning ? 1 : 0); 7145 out.writeInt(mStarts); 7146 out.writeLong(mLaunchedTime); 7147 out.writeLong(mLaunchedSince); 7148 out.writeInt(mLaunched ? 1 : 0); 7149 out.writeInt(mLaunches); 7150 out.writeLong(mLoadedStartTime); 7151 out.writeInt(mLoadedStarts); 7152 out.writeInt(mLoadedLaunches); 7153 out.writeLong(mUnpluggedStartTime); 7154 out.writeInt(mUnpluggedStarts); 7155 out.writeInt(mUnpluggedLaunches); 7156 } 7157 getLaunchTimeToNowLocked(long batteryUptime)7158 public long getLaunchTimeToNowLocked(long batteryUptime) { 7159 if (!mLaunched) return mLaunchedTime; 7160 return mLaunchedTime + batteryUptime - mLaunchedSince; 7161 } 7162 getStartTimeToNowLocked(long batteryUptime)7163 public long getStartTimeToNowLocked(long batteryUptime) { 7164 if (!mRunning) return mStartTime; 7165 return mStartTime + batteryUptime - mRunningSince; 7166 } 7167 startLaunchedLocked()7168 public void startLaunchedLocked() { 7169 if (!mLaunched) { 7170 mLaunches++; 7171 mLaunchedSince = mBsi.getBatteryUptimeLocked(); 7172 mLaunched = true; 7173 } 7174 } 7175 stopLaunchedLocked()7176 public void stopLaunchedLocked() { 7177 if (mLaunched) { 7178 long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince; 7179 if (time > 0) { 7180 mLaunchedTime += time; 7181 } else { 7182 mLaunches--; 7183 } 7184 mLaunched = false; 7185 } 7186 } 7187 startRunningLocked()7188 public void startRunningLocked() { 7189 if (!mRunning) { 7190 mStarts++; 7191 mRunningSince = mBsi.getBatteryUptimeLocked(); 7192 mRunning = true; 7193 } 7194 } 7195 stopRunningLocked()7196 public void stopRunningLocked() { 7197 if (mRunning) { 7198 long time = mBsi.getBatteryUptimeLocked() - mRunningSince; 7199 if (time > 0) { 7200 mStartTime += time; 7201 } else { 7202 mStarts--; 7203 } 7204 mRunning = false; 7205 } 7206 } 7207 getBatteryStats()7208 public BatteryStatsImpl getBatteryStats() { 7209 return mBsi; 7210 } 7211 7212 @Override getLaunches(int which)7213 public int getLaunches(int which) { 7214 int val = mLaunches; 7215 if (which == STATS_CURRENT) { 7216 val -= mLoadedLaunches; 7217 } else if (which == STATS_SINCE_UNPLUGGED) { 7218 val -= mUnpluggedLaunches; 7219 } 7220 return val; 7221 } 7222 7223 @Override getStartTime(long now, int which)7224 public long getStartTime(long now, int which) { 7225 long val = getStartTimeToNowLocked(now); 7226 if (which == STATS_CURRENT) { 7227 val -= mLoadedStartTime; 7228 } else if (which == STATS_SINCE_UNPLUGGED) { 7229 val -= mUnpluggedStartTime; 7230 } 7231 return val; 7232 } 7233 7234 @Override getStarts(int which)7235 public int getStarts(int which) { 7236 int val = mStarts; 7237 if (which == STATS_CURRENT) { 7238 val -= mLoadedStarts; 7239 } else if (which == STATS_SINCE_UNPLUGGED) { 7240 val -= mUnpluggedStarts; 7241 } 7242 7243 return val; 7244 } 7245 } 7246 newServiceStatsLocked()7247 final Serv newServiceStatsLocked() { 7248 return new Serv(mBsi); 7249 } 7250 } 7251 7252 /** 7253 * Retrieve the statistics object for a particular process, creating 7254 * if needed. 7255 */ getProcessStatsLocked(String name)7256 public Proc getProcessStatsLocked(String name) { 7257 Proc ps = mProcessStats.get(name); 7258 if (ps == null) { 7259 ps = new Proc(mBsi, name); 7260 mProcessStats.put(name, ps); 7261 } 7262 7263 return ps; 7264 } 7265 updateUidProcessStateLocked(int procState)7266 public void updateUidProcessStateLocked(int procState) { 7267 int uidRunningState; 7268 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) { 7269 uidRunningState = ActivityManager.PROCESS_STATE_NONEXISTENT; 7270 } else if (procState == ActivityManager.PROCESS_STATE_TOP) { 7271 uidRunningState = PROCESS_STATE_TOP; 7272 } else if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 7273 // Persistent and other foreground states go here. 7274 uidRunningState = PROCESS_STATE_FOREGROUND_SERVICE; 7275 } else if (procState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) { 7276 uidRunningState = PROCESS_STATE_TOP_SLEEPING; 7277 } else if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 7278 // Persistent and other foreground states go here. 7279 uidRunningState = PROCESS_STATE_FOREGROUND; 7280 } else if (procState <= ActivityManager.PROCESS_STATE_RECEIVER) { 7281 uidRunningState = PROCESS_STATE_BACKGROUND; 7282 } else { 7283 uidRunningState = PROCESS_STATE_CACHED; 7284 } 7285 7286 if (mProcessState == uidRunningState) return; 7287 7288 final long elapsedRealtime = mBsi.mClocks.elapsedRealtime(); 7289 7290 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 7291 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtime); 7292 } 7293 mProcessState = uidRunningState; 7294 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 7295 if (mProcessStateTimer[uidRunningState] == null) { 7296 makeProcessState(uidRunningState, null); 7297 } 7298 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtime); 7299 } 7300 } 7301 getPidStats()7302 public SparseArray<? extends Pid> getPidStats() { 7303 return mPids; 7304 } 7305 getPidStatsLocked(int pid)7306 public Pid getPidStatsLocked(int pid) { 7307 Pid p = mPids.get(pid); 7308 if (p == null) { 7309 p = new Pid(); 7310 mPids.put(pid, p); 7311 } 7312 return p; 7313 } 7314 7315 /** 7316 * Retrieve the statistics object for a particular service, creating 7317 * if needed. 7318 */ getPackageStatsLocked(String name)7319 public Pkg getPackageStatsLocked(String name) { 7320 Pkg ps = mPackageStats.get(name); 7321 if (ps == null) { 7322 ps = new Pkg(mBsi); 7323 mPackageStats.put(name, ps); 7324 } 7325 7326 return ps; 7327 } 7328 7329 /** 7330 * Retrieve the statistics object for a particular service, creating 7331 * if needed. 7332 */ getServiceStatsLocked(String pkg, String serv)7333 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 7334 Pkg ps = getPackageStatsLocked(pkg); 7335 Pkg.Serv ss = ps.mServiceStats.get(serv); 7336 if (ss == null) { 7337 ss = ps.newServiceStatsLocked(); 7338 ps.mServiceStats.put(serv, ss); 7339 } 7340 7341 return ss; 7342 } 7343 readSyncSummaryFromParcelLocked(String name, Parcel in)7344 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 7345 StopwatchTimer timer = mSyncStats.instantiateObject(); 7346 timer.readSummaryFromParcelLocked(in); 7347 mSyncStats.add(name, timer); 7348 } 7349 readJobSummaryFromParcelLocked(String name, Parcel in)7350 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 7351 StopwatchTimer timer = mJobStats.instantiateObject(); 7352 timer.readSummaryFromParcelLocked(in); 7353 mJobStats.add(name, timer); 7354 } 7355 readWakeSummaryFromParcelLocked(String wlName, Parcel in)7356 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 7357 Wakelock wl = new Wakelock(mBsi, this); 7358 mWakelockStats.add(wlName, wl); 7359 if (in.readInt() != 0) { 7360 wl.getStopwatchTimer(WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 7361 } 7362 if (in.readInt() != 0) { 7363 wl.getStopwatchTimer(WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 7364 } 7365 if (in.readInt() != 0) { 7366 wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 7367 } 7368 if (in.readInt() != 0) { 7369 wl.getStopwatchTimer(WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 7370 } 7371 } 7372 getSensorTimerLocked(int sensor, boolean create)7373 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) { 7374 Sensor se = mSensorStats.get(sensor); 7375 if (se == null) { 7376 if (!create) { 7377 return null; 7378 } 7379 se = new Sensor(mBsi, this, sensor); 7380 mSensorStats.put(sensor, se); 7381 } 7382 StopwatchTimer t = se.mTimer; 7383 if (t != null) { 7384 return t; 7385 } 7386 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 7387 if (timers == null) { 7388 timers = new ArrayList<StopwatchTimer>(); 7389 mBsi.mSensorTimers.put(sensor, timers); 7390 } 7391 t = new StopwatchTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers, 7392 mBsi.mOnBatteryTimeBase); 7393 se.mTimer = t; 7394 return t; 7395 } 7396 noteStartSyncLocked(String name, long elapsedRealtimeMs)7397 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 7398 StopwatchTimer t = mSyncStats.startObject(name); 7399 if (t != null) { 7400 t.startRunningLocked(elapsedRealtimeMs); 7401 } 7402 } 7403 noteStopSyncLocked(String name, long elapsedRealtimeMs)7404 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 7405 StopwatchTimer t = mSyncStats.stopObject(name); 7406 if (t != null) { 7407 t.stopRunningLocked(elapsedRealtimeMs); 7408 } 7409 } 7410 noteStartJobLocked(String name, long elapsedRealtimeMs)7411 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 7412 StopwatchTimer t = mJobStats.startObject(name); 7413 if (t != null) { 7414 t.startRunningLocked(elapsedRealtimeMs); 7415 } 7416 } 7417 noteStopJobLocked(String name, long elapsedRealtimeMs)7418 public void noteStopJobLocked(String name, long elapsedRealtimeMs) { 7419 StopwatchTimer t = mJobStats.stopObject(name); 7420 if (t != null) { 7421 t.stopRunningLocked(elapsedRealtimeMs); 7422 } 7423 } 7424 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)7425 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 7426 Wakelock wl = mWakelockStats.startObject(name); 7427 if (wl != null) { 7428 wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs); 7429 } 7430 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 7431 Pid p = getPidStatsLocked(pid); 7432 if (p.mWakeNesting++ == 0) { 7433 p.mWakeStartMs = elapsedRealtimeMs; 7434 } 7435 } 7436 } 7437 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)7438 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 7439 Wakelock wl = mWakelockStats.stopObject(name); 7440 if (wl != null) { 7441 wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs); 7442 } 7443 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 7444 Pid p = mPids.get(pid); 7445 if (p != null && p.mWakeNesting > 0) { 7446 if (p.mWakeNesting-- == 1) { 7447 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 7448 p.mWakeStartMs = 0; 7449 } 7450 } 7451 } 7452 } 7453 reportExcessiveWakeLocked(String proc, long overTime, long usedTime)7454 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) { 7455 Proc p = getProcessStatsLocked(proc); 7456 if (p != null) { 7457 p.addExcessiveWake(overTime, usedTime); 7458 } 7459 } 7460 reportExcessiveCpuLocked(String proc, long overTime, long usedTime)7461 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { 7462 Proc p = getProcessStatsLocked(proc); 7463 if (p != null) { 7464 p.addExcessiveCpu(overTime, usedTime); 7465 } 7466 } 7467 noteStartSensor(int sensor, long elapsedRealtimeMs)7468 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 7469 StopwatchTimer t = getSensorTimerLocked(sensor, true); 7470 if (t != null) { 7471 t.startRunningLocked(elapsedRealtimeMs); 7472 } 7473 } 7474 noteStopSensor(int sensor, long elapsedRealtimeMs)7475 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 7476 // Don't create a timer if one doesn't already exist 7477 StopwatchTimer t = getSensorTimerLocked(sensor, false); 7478 if (t != null) { 7479 t.stopRunningLocked(elapsedRealtimeMs); 7480 } 7481 } 7482 noteStartGps(long elapsedRealtimeMs)7483 public void noteStartGps(long elapsedRealtimeMs) { 7484 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true); 7485 if (t != null) { 7486 t.startRunningLocked(elapsedRealtimeMs); 7487 } 7488 } 7489 noteStopGps(long elapsedRealtimeMs)7490 public void noteStopGps(long elapsedRealtimeMs) { 7491 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false); 7492 if (t != null) { 7493 t.stopRunningLocked(elapsedRealtimeMs); 7494 } 7495 } 7496 getBatteryStats()7497 public BatteryStatsImpl getBatteryStats() { 7498 return mBsi; 7499 } 7500 } 7501 BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync)7502 public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) { 7503 this(new SystemClocks(), systemDir, handler, externalSync, null); 7504 } 7505 BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync, PlatformIdleStateCallback cb)7506 public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync, 7507 PlatformIdleStateCallback cb) { 7508 this(new SystemClocks(), systemDir, handler, externalSync, cb); 7509 } 7510 BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, ExternalStatsSync externalSync, PlatformIdleStateCallback cb)7511 public BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, 7512 ExternalStatsSync externalSync, PlatformIdleStateCallback cb) { 7513 init(clocks); 7514 7515 if (systemDir != null) { 7516 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"), 7517 new File(systemDir, "batterystats.bin.tmp")); 7518 } else { 7519 mFile = null; 7520 } 7521 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 7522 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 7523 mExternalSync = externalSync; 7524 mHandler = new MyHandler(handler.getLooper()); 7525 mStartCount++; 7526 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 7527 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 7528 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 7529 mOnBatteryTimeBase); 7530 } 7531 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase); 7532 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 7533 mOnBatteryTimeBase); 7534 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null, 7535 mOnBatteryTimeBase); 7536 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 7537 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase); 7538 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase); 7539 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase); 7540 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 7541 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null, 7542 mOnBatteryTimeBase); 7543 } 7544 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 7545 mOnBatteryTimeBase); 7546 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 7547 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null, 7548 mOnBatteryTimeBase); 7549 } 7550 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7551 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 7552 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 7553 } 7554 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 7555 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 7556 NUM_BT_TX_LEVELS); 7557 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 7558 ModemActivityInfo.TX_POWER_LEVELS); 7559 7560 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase); 7561 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 7562 mOnBatteryTimeBase); 7563 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 7564 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 7565 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 7566 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase); 7567 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase); 7568 for (int i=0; i<NUM_WIFI_STATES; i++) { 7569 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null, 7570 mOnBatteryTimeBase); 7571 } 7572 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 7573 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null, 7574 mOnBatteryTimeBase); 7575 } 7576 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 7577 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, 7578 mOnBatteryTimeBase); 7579 } 7580 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 7581 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 7582 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); 7583 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase); 7584 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 7585 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 7586 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 7587 mOnBattery = mOnBatteryInternal = false; 7588 long uptime = mClocks.uptimeMillis() * 1000; 7589 long realtime = mClocks.elapsedRealtime() * 1000; 7590 initTimes(uptime, realtime); 7591 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 7592 mDischargeStartLevel = 0; 7593 mDischargeUnplugLevel = 0; 7594 mDischargePlugLevel = -1; 7595 mDischargeCurrentLevel = 0; 7596 mCurrentBatteryLevel = 0; 7597 initDischarge(); 7598 clearHistoryLocked(); 7599 updateDailyDeadlineLocked(); 7600 mPlatformIdleStateCallback = cb; 7601 } 7602 BatteryStatsImpl(Parcel p)7603 public BatteryStatsImpl(Parcel p) { 7604 this(new SystemClocks(), p); 7605 } 7606 BatteryStatsImpl(Clocks clocks, Parcel p)7607 public BatteryStatsImpl(Clocks clocks, Parcel p) { 7608 init(clocks); 7609 mFile = null; 7610 mCheckinFile = null; 7611 mDailyFile = null; 7612 mHandler = null; 7613 mExternalSync = null; 7614 clearHistoryLocked(); 7615 readFromParcel(p); 7616 mPlatformIdleStateCallback = null; 7617 } 7618 setPowerProfile(PowerProfile profile)7619 public void setPowerProfile(PowerProfile profile) { 7620 synchronized (this) { 7621 mPowerProfile = profile; 7622 7623 // We need to initialize the KernelCpuSpeedReaders to read from 7624 // the first cpu of each core. Once we have the PowerProfile, we have access to this 7625 // information. 7626 final int numClusters = mPowerProfile.getNumCpuClusters(); 7627 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 7628 int firstCpuOfCluster = 0; 7629 for (int i = 0; i < numClusters; i++) { 7630 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 7631 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 7632 numSpeedSteps); 7633 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 7634 } 7635 7636 if (mEstimatedBatteryCapacity == -1) { 7637 // Initialize the estimated battery capacity to a known preset one. 7638 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 7639 } 7640 } 7641 } 7642 setCallback(BatteryCallback cb)7643 public void setCallback(BatteryCallback cb) { 7644 mCallback = cb; 7645 } 7646 setRadioScanningTimeout(long timeout)7647 public void setRadioScanningTimeout(long timeout) { 7648 if (mPhoneSignalScanningTimer != null) { 7649 mPhoneSignalScanningTimer.setTimeout(timeout); 7650 } 7651 } 7652 updateDailyDeadlineLocked()7653 public void updateDailyDeadlineLocked() { 7654 // Get the current time. 7655 long currentTime = mDailyStartTime = System.currentTimeMillis(); 7656 Calendar calDeadline = Calendar.getInstance(); 7657 calDeadline.setTimeInMillis(currentTime); 7658 7659 // Move time up to the next day, ranging from 1am to 3pm. 7660 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 7661 calDeadline.set(Calendar.MILLISECOND, 0); 7662 calDeadline.set(Calendar.SECOND, 0); 7663 calDeadline.set(Calendar.MINUTE, 0); 7664 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 7665 mNextMinDailyDeadline = calDeadline.getTimeInMillis(); 7666 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 7667 mNextMaxDailyDeadline = calDeadline.getTimeInMillis(); 7668 } 7669 recordDailyStatsIfNeededLocked(boolean settled)7670 public void recordDailyStatsIfNeededLocked(boolean settled) { 7671 long currentTime = System.currentTimeMillis(); 7672 if (currentTime >= mNextMaxDailyDeadline) { 7673 recordDailyStatsLocked(); 7674 } else if (settled && currentTime >= mNextMinDailyDeadline) { 7675 recordDailyStatsLocked(); 7676 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) { 7677 recordDailyStatsLocked(); 7678 } 7679 } 7680 recordDailyStatsLocked()7681 public void recordDailyStatsLocked() { 7682 DailyItem item = new DailyItem(); 7683 item.mStartTime = mDailyStartTime; 7684 item.mEndTime = System.currentTimeMillis(); 7685 boolean hasData = false; 7686 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 7687 hasData = true; 7688 item.mDischargeSteps = new LevelStepTracker( 7689 mDailyDischargeStepTracker.mNumStepDurations, 7690 mDailyDischargeStepTracker.mStepDurations); 7691 } 7692 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 7693 hasData = true; 7694 item.mChargeSteps = new LevelStepTracker( 7695 mDailyChargeStepTracker.mNumStepDurations, 7696 mDailyChargeStepTracker.mStepDurations); 7697 } 7698 if (mDailyPackageChanges != null) { 7699 hasData = true; 7700 item.mPackageChanges = mDailyPackageChanges; 7701 mDailyPackageChanges = null; 7702 } 7703 mDailyDischargeStepTracker.init(); 7704 mDailyChargeStepTracker.init(); 7705 updateDailyDeadlineLocked(); 7706 7707 if (hasData) { 7708 mDailyItems.add(item); 7709 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 7710 mDailyItems.remove(0); 7711 } 7712 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 7713 try { 7714 XmlSerializer out = new FastXmlSerializer(); 7715 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 7716 writeDailyItemsLocked(out); 7717 BackgroundThread.getHandler().post(new Runnable() { 7718 @Override 7719 public void run() { 7720 synchronized (mCheckinFile) { 7721 FileOutputStream stream = null; 7722 try { 7723 stream = mDailyFile.startWrite(); 7724 memStream.writeTo(stream); 7725 stream.flush(); 7726 FileUtils.sync(stream); 7727 stream.close(); 7728 mDailyFile.finishWrite(stream); 7729 } catch (IOException e) { 7730 Slog.w("BatteryStats", 7731 "Error writing battery daily items", e); 7732 mDailyFile.failWrite(stream); 7733 } 7734 } 7735 } 7736 }); 7737 } catch (IOException e) { 7738 } 7739 } 7740 } 7741 writeDailyItemsLocked(XmlSerializer out)7742 private void writeDailyItemsLocked(XmlSerializer out) throws IOException { 7743 StringBuilder sb = new StringBuilder(64); 7744 out.startDocument(null, true); 7745 out.startTag(null, "daily-items"); 7746 for (int i=0; i<mDailyItems.size(); i++) { 7747 final DailyItem dit = mDailyItems.get(i); 7748 out.startTag(null, "item"); 7749 out.attribute(null, "start", Long.toString(dit.mStartTime)); 7750 out.attribute(null, "end", Long.toString(dit.mEndTime)); 7751 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 7752 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 7753 if (dit.mPackageChanges != null) { 7754 for (int j=0; j<dit.mPackageChanges.size(); j++) { 7755 PackageChange pc = dit.mPackageChanges.get(j); 7756 if (pc.mUpdate) { 7757 out.startTag(null, "upd"); 7758 out.attribute(null, "pkg", pc.mPackageName); 7759 out.attribute(null, "ver", Integer.toString(pc.mVersionCode)); 7760 out.endTag(null, "upd"); 7761 } else { 7762 out.startTag(null, "rem"); 7763 out.attribute(null, "pkg", pc.mPackageName); 7764 out.endTag(null, "rem"); 7765 } 7766 } 7767 } 7768 out.endTag(null, "item"); 7769 } 7770 out.endTag(null, "daily-items"); 7771 out.endDocument(); 7772 } 7773 writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)7774 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, 7775 StringBuilder tmpBuilder) throws IOException { 7776 if (steps != null) { 7777 out.startTag(null, tag); 7778 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations)); 7779 for (int i=0; i<steps.mNumStepDurations; i++) { 7780 out.startTag(null, "s"); 7781 tmpBuilder.setLength(0); 7782 steps.encodeEntryAt(i, tmpBuilder); 7783 out.attribute(null, "v", tmpBuilder.toString()); 7784 out.endTag(null, "s"); 7785 } 7786 out.endTag(null, tag); 7787 } 7788 } 7789 readDailyStatsLocked()7790 public void readDailyStatsLocked() { 7791 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 7792 mDailyItems.clear(); 7793 FileInputStream stream; 7794 try { 7795 stream = mDailyFile.openRead(); 7796 } catch (FileNotFoundException e) { 7797 return; 7798 } 7799 try { 7800 XmlPullParser parser = Xml.newPullParser(); 7801 parser.setInput(stream, StandardCharsets.UTF_8.name()); 7802 readDailyItemsLocked(parser); 7803 } catch (XmlPullParserException e) { 7804 } finally { 7805 try { 7806 stream.close(); 7807 } catch (IOException e) { 7808 } 7809 } 7810 } 7811 readDailyItemsLocked(XmlPullParser parser)7812 private void readDailyItemsLocked(XmlPullParser parser) { 7813 try { 7814 int type; 7815 while ((type = parser.next()) != XmlPullParser.START_TAG 7816 && type != XmlPullParser.END_DOCUMENT) { 7817 ; 7818 } 7819 7820 if (type != XmlPullParser.START_TAG) { 7821 throw new IllegalStateException("no start tag found"); 7822 } 7823 7824 int outerDepth = parser.getDepth(); 7825 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 7826 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 7827 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 7828 continue; 7829 } 7830 7831 String tagName = parser.getName(); 7832 if (tagName.equals("item")) { 7833 readDailyItemTagLocked(parser); 7834 } else { 7835 Slog.w(TAG, "Unknown element under <daily-items>: " 7836 + parser.getName()); 7837 XmlUtils.skipCurrentTag(parser); 7838 } 7839 } 7840 7841 } catch (IllegalStateException e) { 7842 Slog.w(TAG, "Failed parsing daily " + e); 7843 } catch (NullPointerException e) { 7844 Slog.w(TAG, "Failed parsing daily " + e); 7845 } catch (NumberFormatException e) { 7846 Slog.w(TAG, "Failed parsing daily " + e); 7847 } catch (XmlPullParserException e) { 7848 Slog.w(TAG, "Failed parsing daily " + e); 7849 } catch (IOException e) { 7850 Slog.w(TAG, "Failed parsing daily " + e); 7851 } catch (IndexOutOfBoundsException e) { 7852 Slog.w(TAG, "Failed parsing daily " + e); 7853 } 7854 } 7855 readDailyItemTagLocked(XmlPullParser parser)7856 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException, 7857 XmlPullParserException, IOException { 7858 DailyItem dit = new DailyItem(); 7859 String attr = parser.getAttributeValue(null, "start"); 7860 if (attr != null) { 7861 dit.mStartTime = Long.parseLong(attr); 7862 } 7863 attr = parser.getAttributeValue(null, "end"); 7864 if (attr != null) { 7865 dit.mEndTime = Long.parseLong(attr); 7866 } 7867 int outerDepth = parser.getDepth(); 7868 int type; 7869 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 7870 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 7871 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 7872 continue; 7873 } 7874 7875 String tagName = parser.getName(); 7876 if (tagName.equals("dis")) { 7877 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 7878 } else if (tagName.equals("chg")) { 7879 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 7880 } else if (tagName.equals("upd")) { 7881 if (dit.mPackageChanges == null) { 7882 dit.mPackageChanges = new ArrayList<>(); 7883 } 7884 PackageChange pc = new PackageChange(); 7885 pc.mUpdate = true; 7886 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 7887 String verStr = parser.getAttributeValue(null, "ver"); 7888 pc.mVersionCode = verStr != null ? Integer.parseInt(verStr) : 0; 7889 dit.mPackageChanges.add(pc); 7890 XmlUtils.skipCurrentTag(parser); 7891 } else if (tagName.equals("rem")) { 7892 if (dit.mPackageChanges == null) { 7893 dit.mPackageChanges = new ArrayList<>(); 7894 } 7895 PackageChange pc = new PackageChange(); 7896 pc.mUpdate = false; 7897 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 7898 dit.mPackageChanges.add(pc); 7899 XmlUtils.skipCurrentTag(parser); 7900 } else { 7901 Slog.w(TAG, "Unknown element under <item>: " 7902 + parser.getName()); 7903 XmlUtils.skipCurrentTag(parser); 7904 } 7905 } 7906 mDailyItems.add(dit); 7907 } 7908 readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, String tag)7909 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, 7910 String tag) 7911 throws NumberFormatException, XmlPullParserException, IOException { 7912 final String numAttr = parser.getAttributeValue(null, "n"); 7913 if (numAttr == null) { 7914 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 7915 XmlUtils.skipCurrentTag(parser); 7916 return; 7917 } 7918 final int num = Integer.parseInt(numAttr); 7919 LevelStepTracker steps = new LevelStepTracker(num); 7920 if (isCharge) { 7921 dit.mChargeSteps = steps; 7922 } else { 7923 dit.mDischargeSteps = steps; 7924 } 7925 int i = 0; 7926 int outerDepth = parser.getDepth(); 7927 int type; 7928 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 7929 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 7930 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 7931 continue; 7932 } 7933 7934 String tagName = parser.getName(); 7935 if ("s".equals(tagName)) { 7936 if (i < num) { 7937 String valueAttr = parser.getAttributeValue(null, "v"); 7938 if (valueAttr != null) { 7939 steps.decodeEntryAt(i, valueAttr); 7940 i++; 7941 } 7942 } 7943 } else { 7944 Slog.w(TAG, "Unknown element under <" + tag + ">: " 7945 + parser.getName()); 7946 XmlUtils.skipCurrentTag(parser); 7947 } 7948 } 7949 steps.mNumStepDurations = i; 7950 } 7951 7952 @Override getDailyItemLocked(int daysAgo)7953 public DailyItem getDailyItemLocked(int daysAgo) { 7954 int index = mDailyItems.size()-1-daysAgo; 7955 return index >= 0 ? mDailyItems.get(index) : null; 7956 } 7957 7958 @Override getCurrentDailyStartTime()7959 public long getCurrentDailyStartTime() { 7960 return mDailyStartTime; 7961 } 7962 7963 @Override getNextMinDailyDeadline()7964 public long getNextMinDailyDeadline() { 7965 return mNextMinDailyDeadline; 7966 } 7967 7968 @Override getNextMaxDailyDeadline()7969 public long getNextMaxDailyDeadline() { 7970 return mNextMaxDailyDeadline; 7971 } 7972 7973 @Override startIteratingOldHistoryLocked()7974 public boolean startIteratingOldHistoryLocked() { 7975 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 7976 + " pos=" + mHistoryBuffer.dataPosition()); 7977 if ((mHistoryIterator = mHistory) == null) { 7978 return false; 7979 } 7980 mHistoryBuffer.setDataPosition(0); 7981 mHistoryReadTmp.clear(); 7982 mReadOverflow = false; 7983 mIteratingHistory = true; 7984 return true; 7985 } 7986 7987 @Override getNextOldHistoryLocked(HistoryItem out)7988 public boolean getNextOldHistoryLocked(HistoryItem out) { 7989 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); 7990 if (!end) { 7991 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp); 7992 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; 7993 } 7994 HistoryItem cur = mHistoryIterator; 7995 if (cur == null) { 7996 if (!mReadOverflow && !end) { 7997 Slog.w(TAG, "Old history ends before new history!"); 7998 } 7999 return false; 8000 } 8001 out.setTo(cur); 8002 mHistoryIterator = cur.next; 8003 if (!mReadOverflow) { 8004 if (end) { 8005 Slog.w(TAG, "New history ends before old history!"); 8006 } else if (!out.same(mHistoryReadTmp)) { 8007 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); 8008 pw.println("Histories differ!"); 8009 pw.println("Old history:"); 8010 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true); 8011 pw.println("New history:"); 8012 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false, 8013 true); 8014 pw.flush(); 8015 } 8016 } 8017 return true; 8018 } 8019 8020 @Override finishIteratingOldHistoryLocked()8021 public void finishIteratingOldHistoryLocked() { 8022 mIteratingHistory = false; 8023 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 8024 mHistoryIterator = null; 8025 } 8026 getHistoryTotalSize()8027 public int getHistoryTotalSize() { 8028 return MAX_HISTORY_BUFFER; 8029 } 8030 getHistoryUsedSize()8031 public int getHistoryUsedSize() { 8032 return mHistoryBuffer.dataSize(); 8033 } 8034 8035 @Override startIteratingHistoryLocked()8036 public boolean startIteratingHistoryLocked() { 8037 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 8038 + " pos=" + mHistoryBuffer.dataPosition()); 8039 if (mHistoryBuffer.dataSize() <= 0) { 8040 return false; 8041 } 8042 mHistoryBuffer.setDataPosition(0); 8043 mReadOverflow = false; 8044 mIteratingHistory = true; 8045 mReadHistoryStrings = new String[mHistoryTagPool.size()]; 8046 mReadHistoryUids = new int[mHistoryTagPool.size()]; 8047 mReadHistoryChars = 0; 8048 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 8049 final HistoryTag tag = ent.getKey(); 8050 final int idx = ent.getValue(); 8051 mReadHistoryStrings[idx] = tag.string; 8052 mReadHistoryUids[idx] = tag.uid; 8053 mReadHistoryChars += tag.string.length() + 1; 8054 } 8055 return true; 8056 } 8057 8058 @Override getHistoryStringPoolSize()8059 public int getHistoryStringPoolSize() { 8060 return mReadHistoryStrings.length; 8061 } 8062 8063 @Override getHistoryStringPoolBytes()8064 public int getHistoryStringPoolBytes() { 8065 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size 8066 // Each string character is 2 bytes. 8067 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2); 8068 } 8069 8070 @Override getHistoryTagPoolString(int index)8071 public String getHistoryTagPoolString(int index) { 8072 return mReadHistoryStrings[index]; 8073 } 8074 8075 @Override getHistoryTagPoolUid(int index)8076 public int getHistoryTagPoolUid(int index) { 8077 return mReadHistoryUids[index]; 8078 } 8079 8080 @Override getNextHistoryLocked(HistoryItem out)8081 public boolean getNextHistoryLocked(HistoryItem out) { 8082 final int pos = mHistoryBuffer.dataPosition(); 8083 if (pos == 0) { 8084 out.clear(); 8085 } 8086 boolean end = pos >= mHistoryBuffer.dataSize(); 8087 if (end) { 8088 return false; 8089 } 8090 8091 final long lastRealtime = out.time; 8092 final long lastWalltime = out.currentTime; 8093 readHistoryDelta(mHistoryBuffer, out); 8094 if (out.cmd != HistoryItem.CMD_CURRENT_TIME 8095 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) { 8096 out.currentTime = lastWalltime + (out.time - lastRealtime); 8097 } 8098 return true; 8099 } 8100 8101 @Override finishIteratingHistoryLocked()8102 public void finishIteratingHistoryLocked() { 8103 mIteratingHistory = false; 8104 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 8105 mReadHistoryStrings = null; 8106 } 8107 8108 @Override getHistoryBaseTime()8109 public long getHistoryBaseTime() { 8110 return mHistoryBaseTime; 8111 } 8112 8113 @Override getStartCount()8114 public int getStartCount() { 8115 return mStartCount; 8116 } 8117 isOnBattery()8118 public boolean isOnBattery() { 8119 return mOnBattery; 8120 } 8121 isCharging()8122 public boolean isCharging() { 8123 return mCharging; 8124 } 8125 isScreenOn()8126 public boolean isScreenOn() { 8127 return mScreenState == Display.STATE_ON; 8128 } 8129 initTimes(long uptime, long realtime)8130 void initTimes(long uptime, long realtime) { 8131 mStartClockTime = System.currentTimeMillis(); 8132 mOnBatteryTimeBase.init(uptime, realtime); 8133 mOnBatteryScreenOffTimeBase.init(uptime, realtime); 8134 mRealtime = 0; 8135 mUptime = 0; 8136 mRealtimeStart = realtime; 8137 mUptimeStart = uptime; 8138 } 8139 initDischarge()8140 void initDischarge() { 8141 mLowDischargeAmountSinceCharge = 0; 8142 mHighDischargeAmountSinceCharge = 0; 8143 mDischargeAmountScreenOn = 0; 8144 mDischargeAmountScreenOnSinceCharge = 0; 8145 mDischargeAmountScreenOff = 0; 8146 mDischargeAmountScreenOffSinceCharge = 0; 8147 mDischargeStepTracker.init(); 8148 mChargeStepTracker.init(); 8149 mDischargeScreenOffCounter.reset(false); 8150 mDischargeCounter.reset(false); 8151 } 8152 resetAllStatsCmdLocked()8153 public void resetAllStatsCmdLocked() { 8154 resetAllStatsLocked(); 8155 final long mSecUptime = mClocks.uptimeMillis(); 8156 long uptime = mSecUptime * 1000; 8157 long mSecRealtime = mClocks.elapsedRealtime(); 8158 long realtime = mSecRealtime * 1000; 8159 mDischargeStartLevel = mHistoryCur.batteryLevel; 8160 pullPendingStateUpdatesLocked(); 8161 addHistoryRecordLocked(mSecRealtime, mSecUptime); 8162 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 8163 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 8164 mOnBatteryTimeBase.reset(uptime, realtime); 8165 mOnBatteryScreenOffTimeBase.reset(uptime, realtime); 8166 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 8167 if (mScreenState == Display.STATE_ON) { 8168 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 8169 mDischargeScreenOffUnplugLevel = 0; 8170 } else { 8171 mDischargeScreenOnUnplugLevel = 0; 8172 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 8173 } 8174 mDischargeAmountScreenOn = 0; 8175 mDischargeAmountScreenOff = 0; 8176 } 8177 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 8178 } 8179 resetAllStatsLocked()8180 private void resetAllStatsLocked() { 8181 final long uptimeMillis = mClocks.uptimeMillis(); 8182 final long elapsedRealtimeMillis = mClocks.elapsedRealtime(); 8183 mStartCount = 0; 8184 initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000); 8185 mScreenOnTimer.reset(false); 8186 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 8187 mScreenBrightnessTimer[i].reset(false); 8188 } 8189 8190 if (mPowerProfile != null) { 8191 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 8192 } else { 8193 mEstimatedBatteryCapacity = -1; 8194 } 8195 mInteractiveTimer.reset(false); 8196 mPowerSaveModeEnabledTimer.reset(false); 8197 mLastIdleTimeStart = elapsedRealtimeMillis; 8198 mLongestLightIdleTime = 0; 8199 mLongestFullIdleTime = 0; 8200 mDeviceIdleModeLightTimer.reset(false); 8201 mDeviceIdleModeFullTimer.reset(false); 8202 mDeviceLightIdlingTimer.reset(false); 8203 mDeviceIdlingTimer.reset(false); 8204 mPhoneOnTimer.reset(false); 8205 mAudioOnTimer.reset(false); 8206 mVideoOnTimer.reset(false); 8207 mFlashlightOnTimer.reset(false); 8208 mCameraOnTimer.reset(false); 8209 mBluetoothScanTimer.reset(false); 8210 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 8211 mPhoneSignalStrengthsTimer[i].reset(false); 8212 } 8213 mPhoneSignalScanningTimer.reset(false); 8214 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 8215 mPhoneDataConnectionsTimer[i].reset(false); 8216 } 8217 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8218 mNetworkByteActivityCounters[i].reset(false); 8219 mNetworkPacketActivityCounters[i].reset(false); 8220 } 8221 mMobileRadioActiveTimer.reset(false); 8222 mMobileRadioActivePerAppTimer.reset(false); 8223 mMobileRadioActiveAdjustedTime.reset(false); 8224 mMobileRadioActiveUnknownTime.reset(false); 8225 mMobileRadioActiveUnknownCount.reset(false); 8226 mWifiOnTimer.reset(false); 8227 mGlobalWifiRunningTimer.reset(false); 8228 for (int i=0; i<NUM_WIFI_STATES; i++) { 8229 mWifiStateTimer[i].reset(false); 8230 } 8231 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 8232 mWifiSupplStateTimer[i].reset(false); 8233 } 8234 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 8235 mWifiSignalStrengthsTimer[i].reset(false); 8236 } 8237 mWifiActivity.reset(false); 8238 mBluetoothActivity.reset(false); 8239 mModemActivity.reset(false); 8240 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0; 8241 8242 for (int i=0; i<mUidStats.size(); i++) { 8243 if (mUidStats.valueAt(i).reset()) { 8244 mUidStats.remove(mUidStats.keyAt(i)); 8245 i--; 8246 } 8247 } 8248 8249 if (mKernelWakelockStats.size() > 0) { 8250 for (SamplingTimer timer : mKernelWakelockStats.values()) { 8251 mOnBatteryScreenOffTimeBase.remove(timer); 8252 } 8253 mKernelWakelockStats.clear(); 8254 } 8255 8256 if (mWakeupReasonStats.size() > 0) { 8257 for (SamplingTimer timer : mWakeupReasonStats.values()) { 8258 mOnBatteryTimeBase.remove(timer); 8259 } 8260 mWakeupReasonStats.clear(); 8261 } 8262 8263 mLastHistoryStepDetails = null; 8264 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0; 8265 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0; 8266 mLastStepCpuUserTime = mCurStepCpuUserTime = 0; 8267 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0; 8268 mLastStepStatUserTime = mCurStepStatUserTime = 0; 8269 mLastStepStatSystemTime = mCurStepStatSystemTime = 0; 8270 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0; 8271 mLastStepStatIrqTime = mCurStepStatIrqTime = 0; 8272 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0; 8273 mLastStepStatIdleTime = mCurStepStatIdleTime = 0; 8274 8275 initDischarge(); 8276 8277 clearHistoryLocked(); 8278 } 8279 initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)8280 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 8281 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 8282 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 8283 // Not recording process starts/stops. 8284 continue; 8285 } 8286 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 8287 if (active == null) { 8288 continue; 8289 } 8290 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 8291 SparseIntArray uids = ent.getValue(); 8292 for (int j=0; j<uids.size(); j++) { 8293 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 8294 uids.keyAt(j)); 8295 } 8296 } 8297 } 8298 } 8299 updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn)8300 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) { 8301 if (oldScreenOn) { 8302 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 8303 if (diff > 0) { 8304 mDischargeAmountScreenOn += diff; 8305 mDischargeAmountScreenOnSinceCharge += diff; 8306 } 8307 } else { 8308 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 8309 if (diff > 0) { 8310 mDischargeAmountScreenOff += diff; 8311 mDischargeAmountScreenOffSinceCharge += diff; 8312 } 8313 } 8314 if (newScreenOn) { 8315 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 8316 mDischargeScreenOffUnplugLevel = 0; 8317 } else { 8318 mDischargeScreenOnUnplugLevel = 0; 8319 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 8320 } 8321 } 8322 pullPendingStateUpdatesLocked()8323 public void pullPendingStateUpdatesLocked() { 8324 if (mOnBatteryInternal) { 8325 final boolean screenOn = mScreenState == Display.STATE_ON; 8326 updateDischargeScreenLevelsLocked(screenOn, screenOn); 8327 } 8328 } 8329 8330 private String[] mMobileIfaces = EmptyArray.STRING; 8331 private String[] mWifiIfaces = EmptyArray.STRING; 8332 8333 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory(); 8334 8335 private static final int NETWORK_STATS_LAST = 0; 8336 private static final int NETWORK_STATS_NEXT = 1; 8337 private static final int NETWORK_STATS_DELTA = 2; 8338 8339 private NetworkStats[] mMobileNetworkStats; 8340 private NetworkStats[] mWifiNetworkStats; 8341 8342 /** 8343 * Retrieves the delta of network stats for the given network ifaces. Uses networkStatsBuffer 8344 * as a buffer of NetworkStats objects to cycle through when computing deltas. 8345 */ getNetworkStatsDeltaLocked(String[] ifaces, NetworkStats[] networkStatsBuffer)8346 private NetworkStats getNetworkStatsDeltaLocked(String[] ifaces, 8347 NetworkStats[] networkStatsBuffer) 8348 throws IOException { 8349 if (!SystemProperties.getBoolean(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED, 8350 false)) { 8351 return null; 8352 } 8353 8354 final NetworkStats stats = mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, 8355 ifaces, NetworkStats.TAG_NONE, networkStatsBuffer[NETWORK_STATS_NEXT]); 8356 networkStatsBuffer[NETWORK_STATS_DELTA] = NetworkStats.subtract(stats, 8357 networkStatsBuffer[NETWORK_STATS_LAST], null, null, 8358 networkStatsBuffer[NETWORK_STATS_DELTA]); 8359 networkStatsBuffer[NETWORK_STATS_NEXT] = networkStatsBuffer[NETWORK_STATS_LAST]; 8360 networkStatsBuffer[NETWORK_STATS_LAST] = stats; 8361 return networkStatsBuffer[NETWORK_STATS_DELTA]; 8362 } 8363 8364 /** 8365 * Distribute WiFi energy info and network traffic to apps. 8366 * @param info The energy information from the WiFi controller. 8367 */ updateWifiStateLocked(@ullable final WifiActivityEnergyInfo info)8368 public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) { 8369 if (DEBUG_ENERGY) { 8370 Slog.d(TAG, "Updating wifi stats"); 8371 } 8372 8373 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 8374 NetworkStats delta = null; 8375 try { 8376 if (!ArrayUtils.isEmpty(mWifiIfaces)) { 8377 delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats); 8378 } 8379 } catch (IOException e) { 8380 Slog.wtf(TAG, "Failed to get wifi network stats", e); 8381 return; 8382 } 8383 8384 if (!mOnBatteryInternal) { 8385 return; 8386 } 8387 8388 SparseLongArray rxPackets = new SparseLongArray(); 8389 SparseLongArray txPackets = new SparseLongArray(); 8390 long totalTxPackets = 0; 8391 long totalRxPackets = 0; 8392 if (delta != null) { 8393 final int size = delta.size(); 8394 for (int i = 0; i < size; i++) { 8395 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 8396 8397 if (DEBUG_ENERGY) { 8398 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes 8399 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 8400 + " txPackets=" + entry.txPackets); 8401 } 8402 8403 if (entry.rxBytes == 0 && entry.txBytes == 0) { 8404 // Skip the lookup below since there is no work to do. 8405 continue; 8406 } 8407 8408 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 8409 if (entry.rxBytes != 0) { 8410 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, 8411 entry.rxPackets); 8412 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 8413 entry.rxBytes); 8414 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 8415 entry.rxPackets); 8416 8417 rxPackets.put(u.getUid(), entry.rxPackets); 8418 8419 // Sum the total number of packets so that the Rx Power can 8420 // be evenly distributed amongst the apps. 8421 totalRxPackets += entry.rxPackets; 8422 } 8423 8424 if (entry.txBytes != 0) { 8425 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, 8426 entry.txPackets); 8427 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 8428 entry.txBytes); 8429 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 8430 entry.txPackets); 8431 8432 txPackets.put(u.getUid(), entry.txPackets); 8433 8434 // Sum the total number of packets so that the Tx Power can 8435 // be evenly distributed amongst the apps. 8436 totalTxPackets += entry.txPackets; 8437 } 8438 } 8439 } 8440 8441 if (info != null) { 8442 mHasWifiReporting = true; 8443 8444 // Measured in mAms 8445 final long txTimeMs = info.getControllerTxTimeMillis(); 8446 final long rxTimeMs = info.getControllerRxTimeMillis(); 8447 final long idleTimeMs = info.getControllerIdleTimeMillis(); 8448 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 8449 8450 long leftOverRxTimeMs = rxTimeMs; 8451 long leftOverTxTimeMs = txTimeMs; 8452 8453 if (DEBUG_ENERGY) { 8454 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 8455 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 8456 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 8457 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 8458 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 8459 } 8460 8461 long totalWifiLockTimeMs = 0; 8462 long totalScanTimeMs = 0; 8463 8464 // On the first pass, collect some totals so that we can normalize power 8465 // calculations if we need to. 8466 final int uidStatsSize = mUidStats.size(); 8467 for (int i = 0; i < uidStatsSize; i++) { 8468 final Uid uid = mUidStats.valueAt(i); 8469 8470 // Sum the total scan power for all apps. 8471 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 8472 elapsedRealtimeMs * 1000) / 1000; 8473 8474 // Sum the total time holding wifi lock for all apps. 8475 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 8476 elapsedRealtimeMs * 1000) / 1000; 8477 } 8478 8479 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 8480 Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 8481 + rxTimeMs + " ms). Normalizing scan time."); 8482 } 8483 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 8484 Slog.d(TAG, " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 8485 + txTimeMs + " ms). Normalizing scan time."); 8486 } 8487 8488 // Actually assign and distribute power usage to apps. 8489 for (int i = 0; i < uidStatsSize; i++) { 8490 final Uid uid = mUidStats.valueAt(i); 8491 8492 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 8493 elapsedRealtimeMs * 1000) / 1000; 8494 if (scanTimeSinceMarkMs > 0) { 8495 // Set the new mark so that next time we get new data since this point. 8496 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 8497 8498 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; 8499 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; 8500 8501 // Our total scan time is more than the reported Tx/Rx time. 8502 // This is possible because the cost of a scan is approximate. 8503 // Let's normalize the result so that we evenly blame each app 8504 // scanning. 8505 // 8506 // This means that we may have apps that transmitted/received packets not be 8507 // blamed for this, but this is fine as scans are relatively more expensive. 8508 if (totalScanTimeMs > rxTimeMs) { 8509 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 8510 totalScanTimeMs; 8511 } 8512 if (totalScanTimeMs > txTimeMs) { 8513 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 8514 totalScanTimeMs; 8515 } 8516 8517 if (DEBUG_ENERGY) { 8518 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 8519 + scanRxTimeSinceMarkMs + " ms Tx:" 8520 + scanTxTimeSinceMarkMs + " ms)"); 8521 } 8522 8523 ControllerActivityCounterImpl activityCounter = 8524 uid.getOrCreateWifiControllerActivityLocked(); 8525 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); 8526 activityCounter.getTxTimeCounters()[0].addCountLocked(scanTxTimeSinceMarkMs); 8527 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 8528 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 8529 } 8530 8531 // Distribute evenly the power consumed while Idle to each app holding a WiFi 8532 // lock. 8533 final long wifiLockTimeSinceMarkMs = uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 8534 elapsedRealtimeMs * 1000) / 1000; 8535 if (wifiLockTimeSinceMarkMs > 0) { 8536 // Set the new mark so that next time we get new data since this point. 8537 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 8538 8539 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) 8540 / totalWifiLockTimeMs; 8541 if (DEBUG_ENERGY) { 8542 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 8543 + myIdleTimeMs + " ms"); 8544 } 8545 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() 8546 .addCountLocked(myIdleTimeMs); 8547 } 8548 } 8549 8550 if (DEBUG_ENERGY) { 8551 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 8552 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 8553 } 8554 8555 // Distribute the remaining Tx power appropriately between all apps that transmitted 8556 // packets. 8557 for (int i = 0; i < txPackets.size(); i++) { 8558 final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); 8559 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) / totalTxPackets; 8560 if (DEBUG_ENERGY) { 8561 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); 8562 } 8563 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] 8564 .addCountLocked(myTxTimeMs); 8565 } 8566 8567 // Distribute the remaining Rx power appropriately between all apps that received 8568 // packets. 8569 for (int i = 0; i < rxPackets.size(); i++) { 8570 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i)); 8571 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets; 8572 if (DEBUG_ENERGY) { 8573 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); 8574 } 8575 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() 8576 .addCountLocked(myRxTimeMs); 8577 } 8578 8579 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 8580 8581 // Update WiFi controller stats. 8582 mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis()); 8583 mWifiActivity.getTxTimeCounters()[0].addCountLocked(info.getControllerTxTimeMillis()); 8584 mWifiActivity.getIdleTimeCounter().addCountLocked(info.getControllerIdleTimeMillis()); 8585 8586 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 8587 final double opVolt = mPowerProfile.getAveragePower( 8588 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 8589 if (opVolt != 0) { 8590 // We store the power drain as mAms. 8591 mWifiActivity.getPowerCounter().addCountLocked( 8592 (long)(info.getControllerEnergyUsed() / opVolt)); 8593 } 8594 } 8595 } 8596 8597 /** 8598 * Distribute Cell radio energy info and network traffic to apps. 8599 */ updateMobileRadioStateLocked(final long elapsedRealtimeMs, final ModemActivityInfo activityInfo)8600 public void updateMobileRadioStateLocked(final long elapsedRealtimeMs, 8601 final ModemActivityInfo activityInfo) { 8602 if (DEBUG_ENERGY) { 8603 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 8604 } 8605 8606 NetworkStats delta = null; 8607 try { 8608 if (!ArrayUtils.isEmpty(mMobileIfaces)) { 8609 delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats); 8610 } 8611 } catch (IOException e) { 8612 Slog.wtf(TAG, "Failed to get mobile network stats", e); 8613 return; 8614 } 8615 8616 if (!mOnBatteryInternal) { 8617 return; 8618 } 8619 8620 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 8621 elapsedRealtimeMs * 1000); 8622 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 8623 8624 long totalRxPackets = 0; 8625 long totalTxPackets = 0; 8626 if (delta != null) { 8627 final int size = delta.size(); 8628 for (int i = 0; i < size; i++) { 8629 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 8630 if (entry.rxPackets == 0 && entry.txPackets == 0) { 8631 continue; 8632 } 8633 8634 if (DEBUG_ENERGY) { 8635 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes 8636 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 8637 + " txPackets=" + entry.txPackets); 8638 } 8639 8640 totalRxPackets += entry.rxPackets; 8641 totalTxPackets += entry.txPackets; 8642 8643 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 8644 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, entry.rxPackets); 8645 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, entry.txPackets); 8646 8647 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 8648 entry.rxBytes); 8649 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 8650 entry.txBytes); 8651 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 8652 entry.rxPackets); 8653 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 8654 entry.txPackets); 8655 } 8656 8657 // Now distribute proportional blame to the apps that did networking. 8658 long totalPackets = totalRxPackets + totalTxPackets; 8659 if (totalPackets > 0) { 8660 for (int i = 0; i < size; i++) { 8661 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 8662 if (entry.rxPackets == 0 && entry.txPackets == 0) { 8663 continue; 8664 } 8665 8666 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 8667 8668 // Distribute total radio active time in to this app. 8669 final long appPackets = entry.rxPackets + entry.txPackets; 8670 final long appRadioTime = (radioTime * appPackets) / totalPackets; 8671 u.noteMobileRadioActiveTimeLocked(appRadioTime); 8672 8673 // Remove this app from the totals, so that we don't lose any time 8674 // due to rounding. 8675 radioTime -= appRadioTime; 8676 totalPackets -= appPackets; 8677 8678 if (activityInfo != null) { 8679 ControllerActivityCounterImpl activityCounter = 8680 u.getOrCreateModemControllerActivityLocked(); 8681 if (totalRxPackets > 0 && entry.rxPackets > 0) { 8682 final long rxMs = (entry.rxPackets * activityInfo.getRxTimeMillis()) 8683 / totalRxPackets; 8684 activityCounter.getRxTimeCounter().addCountLocked(rxMs); 8685 } 8686 8687 if (totalTxPackets > 0 && entry.txPackets > 0) { 8688 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 8689 long txMs = entry.txPackets * activityInfo.getTxTimeMillis()[lvl]; 8690 txMs /= totalTxPackets; 8691 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); 8692 } 8693 } 8694 } 8695 } 8696 } 8697 8698 if (radioTime > 0) { 8699 // Whoops, there is some radio time we can't blame on an app! 8700 mMobileRadioActiveUnknownTime.addCountLocked(radioTime); 8701 mMobileRadioActiveUnknownCount.addCountLocked(1); 8702 } 8703 } 8704 8705 if (activityInfo != null) { 8706 mHasModemReporting = true; 8707 mModemActivity.getIdleTimeCounter().addCountLocked(activityInfo.getIdleTimeMillis()); 8708 mModemActivity.getRxTimeCounter().addCountLocked(activityInfo.getRxTimeMillis()); 8709 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 8710 mModemActivity.getTxTimeCounters()[lvl] 8711 .addCountLocked(activityInfo.getTxTimeMillis()[lvl]); 8712 } 8713 8714 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 8715 final double opVolt = mPowerProfile.getAveragePower( 8716 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 8717 if (opVolt != 0) { 8718 // We store the power drain as mAms. 8719 mModemActivity.getPowerCounter().addCountLocked( 8720 (long) (activityInfo.getEnergyUsed() / opVolt)); 8721 } 8722 } 8723 } 8724 8725 /** 8726 * Distribute Bluetooth energy info and network traffic to apps. 8727 * @param info The energy information from the bluetooth controller. 8728 */ updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info)8729 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) { 8730 if (DEBUG_ENERGY) { 8731 Slog.d(TAG, "Updating bluetooth stats: " + info); 8732 } 8733 8734 if (info == null || !mOnBatteryInternal) { 8735 return; 8736 } 8737 8738 mHasBluetoothReporting = true; 8739 8740 final long elapsedRealtimeMs = SystemClock.elapsedRealtime(); 8741 final long rxTimeMs = info.getControllerRxTimeMillis(); 8742 final long txTimeMs = info.getControllerTxTimeMillis(); 8743 8744 if (DEBUG_ENERGY) { 8745 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 8746 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 8747 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 8748 Slog.d(TAG, " Idle Time: " + info.getControllerIdleTimeMillis() + " ms"); 8749 } 8750 8751 long totalScanTimeMs = 0; 8752 8753 final int uidCount = mUidStats.size(); 8754 for (int i = 0; i < uidCount; i++) { 8755 final Uid u = mUidStats.valueAt(i); 8756 if (u.mBluetoothScanTimer == null) { 8757 continue; 8758 } 8759 8760 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 8761 elapsedRealtimeMs * 1000) / 1000; 8762 } 8763 8764 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 8765 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 8766 8767 if (DEBUG_ENERGY) { 8768 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 8769 + " TX=" + normalizeScanTxTime); 8770 } 8771 8772 long leftOverRxTimeMs = rxTimeMs; 8773 long leftOverTxTimeMs = txTimeMs; 8774 8775 for (int i = 0; i < uidCount; i++) { 8776 final Uid u = mUidStats.valueAt(i); 8777 if (u.mBluetoothScanTimer == null) { 8778 continue; 8779 } 8780 8781 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 8782 elapsedRealtimeMs * 1000) / 1000; 8783 if (scanTimeSinceMarkMs > 0) { 8784 // Set the new mark so that next time we get new data since this point. 8785 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 8786 8787 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 8788 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 8789 8790 if (normalizeScanRxTime) { 8791 // Scan time is longer than the total rx time in the controller, 8792 // so distribute the scan time proportionately. This means regular traffic 8793 // will not blamed, but scans are more expensive anyways. 8794 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 8795 } 8796 8797 if (normalizeScanTxTime) { 8798 // Scan time is longer than the total tx time in the controller, 8799 // so distribute the scan time proportionately. This means regular traffic 8800 // will not blamed, but scans are more expensive anyways. 8801 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 8802 } 8803 8804 final ControllerActivityCounterImpl counter = 8805 u.getOrCreateBluetoothControllerActivityLocked(); 8806 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs); 8807 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs); 8808 8809 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 8810 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 8811 } 8812 } 8813 8814 if (DEBUG_ENERGY) { 8815 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs 8816 + " TX=" + leftOverTxTimeMs); 8817 } 8818 8819 // 8820 // Now distribute blame to apps that did bluetooth traffic. 8821 // 8822 8823 long totalTxBytes = 0; 8824 long totalRxBytes = 0; 8825 8826 final UidTraffic[] uidTraffic = info.getUidTraffic(); 8827 final int numUids = uidTraffic != null ? uidTraffic.length : 0; 8828 for (int i = 0; i < numUids; i++) { 8829 final UidTraffic traffic = uidTraffic[i]; 8830 8831 // Add to the global counters. 8832 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked( 8833 traffic.getRxBytes()); 8834 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked( 8835 traffic.getTxBytes()); 8836 8837 // Add to the UID counters. 8838 final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); 8839 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, traffic.getRxBytes(), 0); 8840 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, traffic.getTxBytes(), 0); 8841 8842 // Calculate the total traffic. 8843 totalTxBytes += traffic.getTxBytes(); 8844 totalRxBytes += traffic.getRxBytes(); 8845 } 8846 8847 if ((totalTxBytes != 0 || totalRxBytes != 0) && 8848 (leftOverRxTimeMs != 0 || leftOverTxTimeMs != 0)) { 8849 for (int i = 0; i < numUids; i++) { 8850 final UidTraffic traffic = uidTraffic[i]; 8851 8852 final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); 8853 final ControllerActivityCounterImpl counter = 8854 u.getOrCreateBluetoothControllerActivityLocked(); 8855 8856 if (totalRxBytes > 0 && traffic.getRxBytes() > 0) { 8857 final long timeRxMs = (leftOverRxTimeMs * traffic.getRxBytes()) / totalRxBytes; 8858 8859 if (DEBUG_ENERGY) { 8860 Slog.d(TAG, "UID=" + traffic.getUid() + " rx_bytes=" + traffic.getRxBytes() 8861 + " rx_time=" + timeRxMs); 8862 } 8863 counter.getRxTimeCounter().addCountLocked(timeRxMs); 8864 leftOverRxTimeMs -= timeRxMs; 8865 } 8866 8867 if (totalTxBytes > 0 && traffic.getTxBytes() > 0) { 8868 final long timeTxMs = (leftOverTxTimeMs * traffic.getTxBytes()) / totalTxBytes; 8869 8870 if (DEBUG_ENERGY) { 8871 Slog.d(TAG, "UID=" + traffic.getUid() + " tx_bytes=" + traffic.getTxBytes() 8872 + " tx_time=" + timeTxMs); 8873 } 8874 8875 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs); 8876 leftOverTxTimeMs -= timeTxMs; 8877 } 8878 } 8879 } 8880 8881 mBluetoothActivity.getRxTimeCounter().addCountLocked( 8882 info.getControllerRxTimeMillis()); 8883 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked( 8884 info.getControllerTxTimeMillis()); 8885 mBluetoothActivity.getIdleTimeCounter().addCountLocked( 8886 info.getControllerIdleTimeMillis()); 8887 8888 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 8889 final double opVolt = mPowerProfile.getAveragePower( 8890 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 8891 if (opVolt != 0) { 8892 // We store the power drain as mAms. 8893 mBluetoothActivity.getPowerCounter().addCountLocked( 8894 (long) (info.getControllerEnergyUsed() / opVolt)); 8895 } 8896 } 8897 8898 /** 8899 * Read and distribute kernel wake lock use across apps. 8900 */ updateKernelWakelocksLocked()8901 public void updateKernelWakelocksLocked() { 8902 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 8903 mTmpWakelockStats); 8904 if (wakelockStats == null) { 8905 // Not crashing might make board bringup easier. 8906 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 8907 return; 8908 } 8909 8910 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 8911 String name = ent.getKey(); 8912 KernelWakelockStats.Entry kws = ent.getValue(); 8913 8914 SamplingTimer kwlt = mKernelWakelockStats.get(name); 8915 if (kwlt == null) { 8916 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 8917 mKernelWakelockStats.put(name, kwlt); 8918 } 8919 8920 kwlt.update(kws.mTotalTime, kws.mCount); 8921 kwlt.setUpdateVersion(kws.mVersion); 8922 } 8923 8924 int numWakelocksSetStale = 0; 8925 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 8926 // this time. 8927 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 8928 SamplingTimer st = ent.getValue(); 8929 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 8930 st.endSample(); 8931 numWakelocksSetStale++; 8932 } 8933 } 8934 8935 // Record whether we've seen a non-zero time (for debugging b/22716723). 8936 if (wakelockStats.isEmpty()) { 8937 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 8938 } 8939 8940 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 8941 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 8942 wakelockStats.kernelWakelockVersion); 8943 } 8944 } 8945 8946 // We use an anonymous class to access these variables, 8947 // so they can't live on the stack or they'd have to be 8948 // final MutableLong objects (more allocations). 8949 // Used in updateCpuTimeLocked(). 8950 long mTempTotalCpuUserTimeUs; 8951 long mTempTotalCpuSystemTimeUs; 8952 8953 /** 8954 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 8955 * and we are on battery with screen off, we give more of the cpu time to those apps holding 8956 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 8957 */ updateCpuTimeLocked()8958 public void updateCpuTimeLocked() { 8959 if (mPowerProfile == null) { 8960 return; 8961 } 8962 8963 if (DEBUG_ENERGY_CPU) { 8964 Slog.d(TAG, "!Cpu updating!"); 8965 } 8966 8967 // Holding a wakelock costs more than just using the cpu. 8968 // Currently, we assign only half the cpu time to an app that is running but 8969 // not holding a wakelock. The apps holding wakelocks get the rest of the blame. 8970 // If no app is holding a wakelock, then the distribution is normal. 8971 final int wakelockWeight = 50; 8972 8973 // Read the time spent for each cluster at various cpu frequencies. 8974 final long[][] clusterSpeeds = new long[mKernelCpuSpeedReaders.length][]; 8975 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 8976 clusterSpeeds[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 8977 } 8978 8979 int numWakelocks = 0; 8980 8981 // Calculate how many wakelocks we have to distribute amongst. The system is excluded. 8982 // Only distribute cpu power to wakelocks if the screen is off and we're on battery. 8983 final int numPartialTimers = mPartialTimers.size(); 8984 if (mOnBatteryScreenOffTimeBase.isRunning()) { 8985 for (int i = 0; i < numPartialTimers; i++) { 8986 final StopwatchTimer timer = mPartialTimers.get(i); 8987 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 8988 // Since the collection and blaming of wakelocks can be scheduled to run after 8989 // some delay, the mPartialTimers list may have new entries. We can't blame 8990 // the newly added timer for past cpu time, so we only consider timers that 8991 // were present for one round of collection. Once a timer has gone through 8992 // a round of collection, its mInList field is set to true. 8993 numWakelocks++; 8994 } 8995 } 8996 } 8997 8998 final int numWakelocksF = numWakelocks; 8999 mTempTotalCpuUserTimeUs = 0; 9000 mTempTotalCpuSystemTimeUs = 0; 9001 9002 // Read the CPU data for each UID. This will internally generate a snapshot so next time 9003 // we read, we get a delta. If we are to distribute the cpu time, then do so. Otherwise 9004 // we just ignore the data. 9005 final long startTimeMs = mClocks.elapsedRealtime(); 9006 mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null : 9007 new KernelUidCpuTimeReader.Callback() { 9008 @Override 9009 public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs, 9010 long powerMaUs) { 9011 final Uid u = getUidStatsLocked(mapUid(uid)); 9012 9013 // Accumulate the total system and user time. 9014 mTempTotalCpuUserTimeUs += userTimeUs; 9015 mTempTotalCpuSystemTimeUs += systemTimeUs; 9016 9017 StringBuilder sb = null; 9018 if (DEBUG_ENERGY_CPU) { 9019 sb = new StringBuilder(); 9020 sb.append(" got time for uid=").append(u.mUid).append(": u="); 9021 TimeUtils.formatDuration(userTimeUs / 1000, sb); 9022 sb.append(" s="); 9023 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 9024 sb.append(" p=").append(powerMaUs / 1000).append("mAms\n"); 9025 } 9026 9027 if (numWakelocksF > 0) { 9028 // We have wakelocks being held, so only give a portion of the 9029 // time to the process. The rest will be distributed among wakelock 9030 // holders. 9031 userTimeUs = (userTimeUs * wakelockWeight) / 100; 9032 systemTimeUs = (systemTimeUs * wakelockWeight) / 100; 9033 } 9034 9035 if (sb != null) { 9036 sb.append(" adding to uid=").append(u.mUid).append(": u="); 9037 TimeUtils.formatDuration(userTimeUs / 1000, sb); 9038 sb.append(" s="); 9039 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 9040 sb.append(" p=").append(powerMaUs / 1000).append("mAms"); 9041 Slog.d(TAG, sb.toString()); 9042 } 9043 9044 u.mUserCpuTime.addCountLocked(userTimeUs); 9045 u.mSystemCpuTime.addCountLocked(systemTimeUs); 9046 u.mCpuPower.addCountLocked(powerMaUs); 9047 9048 // Add the cpu speeds to this UID. These are used as a ratio 9049 // for computing the power this UID used. 9050 final int numClusters = mPowerProfile.getNumCpuClusters(); 9051 if (u.mCpuClusterSpeed == null || u.mCpuClusterSpeed.length != 9052 numClusters) { 9053 u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][]; 9054 } 9055 9056 for (int cluster = 0; cluster < clusterSpeeds.length; cluster++) { 9057 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster( 9058 cluster); 9059 if (u.mCpuClusterSpeed[cluster] == null || speedsInCluster != 9060 u.mCpuClusterSpeed[cluster].length) { 9061 u.mCpuClusterSpeed[cluster] = 9062 new LongSamplingCounter[speedsInCluster]; 9063 } 9064 9065 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeed[cluster]; 9066 for (int speed = 0; speed < clusterSpeeds[cluster].length; speed++) { 9067 if (cpuSpeeds[speed] == null) { 9068 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 9069 } 9070 cpuSpeeds[speed].addCountLocked(clusterSpeeds[cluster][speed]); 9071 } 9072 } 9073 } 9074 }); 9075 9076 if (DEBUG_ENERGY_CPU) { 9077 Slog.d(TAG, "Reading cpu stats took " + (mClocks.elapsedRealtime() - startTimeMs) + 9078 " ms"); 9079 } 9080 9081 if (mOnBatteryInternal && numWakelocks > 0) { 9082 // Distribute a portion of the total cpu time to wakelock holders. 9083 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - wakelockWeight)) / 100; 9084 mTempTotalCpuSystemTimeUs = 9085 (mTempTotalCpuSystemTimeUs * (100 - wakelockWeight)) / 100; 9086 9087 for (int i = 0; i < numPartialTimers; i++) { 9088 final StopwatchTimer timer = mPartialTimers.get(i); 9089 9090 // The system does not share any blame, as it is usually holding the wakelock 9091 // on behalf of an app. 9092 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 9093 int userTimeUs = (int) (mTempTotalCpuUserTimeUs / numWakelocks); 9094 int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / numWakelocks); 9095 9096 if (DEBUG_ENERGY_CPU) { 9097 StringBuilder sb = new StringBuilder(); 9098 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 9099 .append(": u="); 9100 TimeUtils.formatDuration(userTimeUs / 1000, sb); 9101 sb.append(" s="); 9102 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 9103 Slog.d(TAG, sb.toString()); 9104 } 9105 9106 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs); 9107 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs); 9108 9109 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 9110 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000); 9111 9112 mTempTotalCpuUserTimeUs -= userTimeUs; 9113 mTempTotalCpuSystemTimeUs -= systemTimeUs; 9114 numWakelocks--; 9115 } 9116 } 9117 9118 if (mTempTotalCpuUserTimeUs > 0 || mTempTotalCpuSystemTimeUs > 0) { 9119 // Anything left over is given to the system. 9120 if (DEBUG_ENERGY_CPU) { 9121 StringBuilder sb = new StringBuilder(); 9122 sb.append(" Distributing lost time to system: u="); 9123 TimeUtils.formatDuration(mTempTotalCpuUserTimeUs / 1000, sb); 9124 sb.append(" s="); 9125 TimeUtils.formatDuration(mTempTotalCpuSystemTimeUs / 1000, sb); 9126 Slog.d(TAG, sb.toString()); 9127 } 9128 9129 final Uid u = getUidStatsLocked(Process.SYSTEM_UID); 9130 u.mUserCpuTime.addCountLocked(mTempTotalCpuUserTimeUs); 9131 u.mSystemCpuTime.addCountLocked(mTempTotalCpuSystemTimeUs); 9132 9133 final Uid.Proc proc = u.getProcessStatsLocked("*lost*"); 9134 proc.addCpuTimeLocked((int) mTempTotalCpuUserTimeUs / 1000, 9135 (int) mTempTotalCpuSystemTimeUs / 1000); 9136 } 9137 } 9138 9139 // See if there is a difference in wakelocks between this collection and the last 9140 // collection. 9141 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 9142 // No difference, so each timer is now considered for the next collection. 9143 for (int i = 0; i < numPartialTimers; i++) { 9144 mPartialTimers.get(i).mInList = true; 9145 } 9146 } else { 9147 // The lists are different, meaning we added (or removed a timer) since the last 9148 // collection. 9149 final int numLastPartialTimers = mLastPartialTimers.size(); 9150 for (int i = 0; i < numLastPartialTimers; i++) { 9151 mLastPartialTimers.get(i).mInList = false; 9152 } 9153 mLastPartialTimers.clear(); 9154 9155 // Mark the current timers as gone through a collection. 9156 for (int i = 0; i < numPartialTimers; i++) { 9157 final StopwatchTimer timer = mPartialTimers.get(i); 9158 timer.mInList = true; 9159 mLastPartialTimers.add(timer); 9160 } 9161 } 9162 } 9163 setChargingLocked(boolean charging)9164 boolean setChargingLocked(boolean charging) { 9165 if (mCharging != charging) { 9166 mCharging = charging; 9167 if (charging) { 9168 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 9169 } else { 9170 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG; 9171 } 9172 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 9173 return true; 9174 } 9175 return false; 9176 } 9177 setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, final int oldStatus, final int level, final int chargeUAh)9178 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, 9179 final int oldStatus, final int level, final int chargeUAh) { 9180 boolean doWrite = false; 9181 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 9182 m.arg1 = onBattery ? 1 : 0; 9183 mHandler.sendMessage(m); 9184 9185 final long uptime = mSecUptime * 1000; 9186 final long realtime = mSecRealtime * 1000; 9187 final boolean screenOn = mScreenState == Display.STATE_ON; 9188 if (onBattery) { 9189 // We will reset our status if we are unplugging after the 9190 // battery was last full, or the level is at 100, or 9191 // we have gone through a significant charge (from a very low 9192 // level to a now very high level). 9193 boolean reset = false; 9194 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 9195 || level >= 90 9196 || (mDischargeCurrentLevel < 20 && level >= 80) 9197 || (getHighDischargeAmountSinceCharge() >= 200 9198 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) { 9199 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 9200 + " dischargeLevel=" + mDischargeCurrentLevel 9201 + " lowAmount=" + getLowDischargeAmountSinceCharge() 9202 + " highAmount=" + getHighDischargeAmountSinceCharge()); 9203 // Before we write, collect a snapshot of the final aggregated 9204 // stats to be reported in the next checkin. Only do this if we have 9205 // a sufficient amount of data to make it interesting. 9206 if (getLowDischargeAmountSinceCharge() >= 20) { 9207 final Parcel parcel = Parcel.obtain(); 9208 writeSummaryToParcel(parcel, true); 9209 BackgroundThread.getHandler().post(new Runnable() { 9210 @Override public void run() { 9211 synchronized (mCheckinFile) { 9212 FileOutputStream stream = null; 9213 try { 9214 stream = mCheckinFile.startWrite(); 9215 stream.write(parcel.marshall()); 9216 stream.flush(); 9217 FileUtils.sync(stream); 9218 stream.close(); 9219 mCheckinFile.finishWrite(stream); 9220 } catch (IOException e) { 9221 Slog.w("BatteryStats", 9222 "Error writing checkin battery statistics", e); 9223 mCheckinFile.failWrite(stream); 9224 } finally { 9225 parcel.recycle(); 9226 } 9227 } 9228 } 9229 }); 9230 } 9231 doWrite = true; 9232 resetAllStatsLocked(); 9233 if (chargeUAh > 0) { 9234 // Only use the reported coulomb charge value if it is supported and reported. 9235 mEstimatedBatteryCapacity = (int) ((level / 100.0) * (chargeUAh / 1000)); 9236 } 9237 mDischargeStartLevel = level; 9238 reset = true; 9239 mDischargeStepTracker.init(); 9240 } 9241 if (mCharging) { 9242 setChargingLocked(false); 9243 } 9244 mLastChargingStateLevel = level; 9245 mOnBattery = mOnBatteryInternal = true; 9246 mLastDischargeStepLevel = level; 9247 mMinDischargeStepLevel = level; 9248 mDischargeStepTracker.clearTime(); 9249 mDailyDischargeStepTracker.clearTime(); 9250 mInitStepMode = mCurStepMode; 9251 mModStepMode = 0; 9252 pullPendingStateUpdatesLocked(); 9253 mHistoryCur.batteryLevel = (byte)level; 9254 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 9255 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 9256 + Integer.toHexString(mHistoryCur.states)); 9257 if (reset) { 9258 mRecordingHistory = true; 9259 startRecordingHistory(mSecRealtime, mSecUptime, reset); 9260 } 9261 addHistoryRecordLocked(mSecRealtime, mSecUptime); 9262 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 9263 if (screenOn) { 9264 mDischargeScreenOnUnplugLevel = level; 9265 mDischargeScreenOffUnplugLevel = 0; 9266 } else { 9267 mDischargeScreenOnUnplugLevel = 0; 9268 mDischargeScreenOffUnplugLevel = level; 9269 } 9270 mDischargeAmountScreenOn = 0; 9271 mDischargeAmountScreenOff = 0; 9272 updateTimeBasesLocked(true, !screenOn, uptime, realtime); 9273 } else { 9274 mLastChargingStateLevel = level; 9275 mOnBattery = mOnBatteryInternal = false; 9276 pullPendingStateUpdatesLocked(); 9277 mHistoryCur.batteryLevel = (byte)level; 9278 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 9279 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 9280 + Integer.toHexString(mHistoryCur.states)); 9281 addHistoryRecordLocked(mSecRealtime, mSecUptime); 9282 mDischargeCurrentLevel = mDischargePlugLevel = level; 9283 if (level < mDischargeUnplugLevel) { 9284 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 9285 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 9286 } 9287 updateDischargeScreenLevelsLocked(screenOn, screenOn); 9288 updateTimeBasesLocked(false, !screenOn, uptime, realtime); 9289 mChargeStepTracker.init(); 9290 mLastChargeStepLevel = level; 9291 mMaxChargeStepLevel = level; 9292 mInitStepMode = mCurStepMode; 9293 mModStepMode = 0; 9294 } 9295 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 9296 if (mFile != null) { 9297 writeAsyncLocked(); 9298 } 9299 } 9300 } 9301 startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, boolean reset)9302 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 9303 boolean reset) { 9304 mRecordingHistory = true; 9305 mHistoryCur.currentTime = System.currentTimeMillis(); 9306 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, 9307 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 9308 mHistoryCur); 9309 mHistoryCur.currentTime = 0; 9310 if (reset) { 9311 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 9312 } 9313 } 9314 recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, final long uptimeMs)9315 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, 9316 final long uptimeMs) { 9317 if (mRecordingHistory) { 9318 mHistoryCur.currentTime = currentTime; 9319 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME, 9320 mHistoryCur); 9321 mHistoryCur.currentTime = 0; 9322 } 9323 } 9324 recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs)9325 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) { 9326 if (mRecordingHistory) { 9327 mHistoryCur.currentTime = System.currentTimeMillis(); 9328 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN, 9329 mHistoryCur); 9330 mHistoryCur.currentTime = 0; 9331 } 9332 } 9333 scheduleSyncExternalStatsLocked(String reason, int updateFlags)9334 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 9335 if (mExternalSync != null) { 9336 mExternalSync.scheduleSync(reason, updateFlags); 9337 } 9338 } 9339 9340 // This should probably be exposed in the API, though it's not critical 9341 public static final int BATTERY_PLUGGED_NONE = 0; 9342 setBatteryStateLocked(int status, int health, int plugType, int level, int temp, int volt, int chargeUAh)9343 public void setBatteryStateLocked(int status, int health, int plugType, int level, 9344 int temp, int volt, int chargeUAh) { 9345 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE; 9346 final long uptime = mClocks.uptimeMillis(); 9347 final long elapsedRealtime = mClocks.elapsedRealtime(); 9348 if (!mHaveBatteryLevel) { 9349 mHaveBatteryLevel = true; 9350 // We start out assuming that the device is plugged in (not 9351 // on battery). If our first report is now that we are indeed 9352 // plugged in, then twiddle our state to correctly reflect that 9353 // since we won't be going through the full setOnBattery(). 9354 if (onBattery == mOnBattery) { 9355 if (onBattery) { 9356 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 9357 } else { 9358 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 9359 } 9360 } 9361 // Always start out assuming charging, that will be updated later. 9362 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 9363 mHistoryCur.batteryStatus = (byte)status; 9364 mHistoryCur.batteryLevel = (byte)level; 9365 mHistoryCur.batteryChargeUAh = chargeUAh; 9366 mMaxChargeStepLevel = mMinDischargeStepLevel = 9367 mLastChargeStepLevel = mLastDischargeStepLevel = level; 9368 mLastChargingStateLevel = level; 9369 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { 9370 recordDailyStatsIfNeededLocked(level >= 100 && onBattery); 9371 } 9372 int oldStatus = mHistoryCur.batteryStatus; 9373 if (onBattery) { 9374 mDischargeCurrentLevel = level; 9375 if (!mRecordingHistory) { 9376 mRecordingHistory = true; 9377 startRecordingHistory(elapsedRealtime, uptime, true); 9378 } 9379 } else if (level < 96) { 9380 if (!mRecordingHistory) { 9381 mRecordingHistory = true; 9382 startRecordingHistory(elapsedRealtime, uptime, true); 9383 } 9384 } 9385 mCurrentBatteryLevel = level; 9386 if (mDischargePlugLevel < 0) { 9387 mDischargePlugLevel = level; 9388 } 9389 9390 if (onBattery != mOnBattery) { 9391 mHistoryCur.batteryLevel = (byte)level; 9392 mHistoryCur.batteryStatus = (byte)status; 9393 mHistoryCur.batteryHealth = (byte)health; 9394 mHistoryCur.batteryPlugType = (byte)plugType; 9395 mHistoryCur.batteryTemperature = (short)temp; 9396 mHistoryCur.batteryVoltage = (char)volt; 9397 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 9398 // Only record discharges 9399 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 9400 mDischargeCounter.addCountLocked(chargeDiff); 9401 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 9402 } 9403 mHistoryCur.batteryChargeUAh = chargeUAh; 9404 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh); 9405 } else { 9406 boolean changed = false; 9407 if (mHistoryCur.batteryLevel != level) { 9408 mHistoryCur.batteryLevel = (byte)level; 9409 changed = true; 9410 9411 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 9412 // which will pull external stats. 9413 scheduleSyncExternalStatsLocked("battery-level", ExternalStatsSync.UPDATE_ALL); 9414 } 9415 if (mHistoryCur.batteryStatus != status) { 9416 mHistoryCur.batteryStatus = (byte)status; 9417 changed = true; 9418 } 9419 if (mHistoryCur.batteryHealth != health) { 9420 mHistoryCur.batteryHealth = (byte)health; 9421 changed = true; 9422 } 9423 if (mHistoryCur.batteryPlugType != plugType) { 9424 mHistoryCur.batteryPlugType = (byte)plugType; 9425 changed = true; 9426 } 9427 if (temp >= (mHistoryCur.batteryTemperature+10) 9428 || temp <= (mHistoryCur.batteryTemperature-10)) { 9429 mHistoryCur.batteryTemperature = (short)temp; 9430 changed = true; 9431 } 9432 if (volt > (mHistoryCur.batteryVoltage+20) 9433 || volt < (mHistoryCur.batteryVoltage-20)) { 9434 mHistoryCur.batteryVoltage = (char)volt; 9435 changed = true; 9436 } 9437 if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10) 9438 || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) { 9439 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 9440 // Only record discharges 9441 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 9442 mDischargeCounter.addCountLocked(chargeDiff); 9443 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 9444 } 9445 mHistoryCur.batteryChargeUAh = chargeUAh; 9446 changed = true; 9447 } 9448 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 9449 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 9450 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 9451 if (onBattery) { 9452 changed |= setChargingLocked(false); 9453 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 9454 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 9455 modeBits, elapsedRealtime); 9456 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 9457 modeBits, elapsedRealtime); 9458 mLastDischargeStepLevel = level; 9459 mMinDischargeStepLevel = level; 9460 mInitStepMode = mCurStepMode; 9461 mModStepMode = 0; 9462 } 9463 } else { 9464 if (level >= 90) { 9465 // If the battery level is at least 90%, always consider the device to be 9466 // charging even if it happens to go down a level. 9467 changed |= setChargingLocked(true); 9468 mLastChargeStepLevel = level; 9469 } if (!mCharging) { 9470 if (mLastChargeStepLevel < level) { 9471 // We have not reporting that we are charging, but the level has now 9472 // gone up, so consider the state to be charging. 9473 changed |= setChargingLocked(true); 9474 mLastChargeStepLevel = level; 9475 } 9476 } else { 9477 if (mLastChargeStepLevel > level) { 9478 // We had reported that the device was charging, but here we are with 9479 // power connected and the level going down. Looks like the current 9480 // power supplied isn't enough, so consider the device to now be 9481 // discharging. 9482 changed |= setChargingLocked(false); 9483 mLastChargeStepLevel = level; 9484 } 9485 } 9486 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 9487 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 9488 modeBits, elapsedRealtime); 9489 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 9490 modeBits, elapsedRealtime); 9491 mLastChargeStepLevel = level; 9492 mMaxChargeStepLevel = level; 9493 mInitStepMode = mCurStepMode; 9494 mModStepMode = 0; 9495 } 9496 } 9497 if (changed) { 9498 addHistoryRecordLocked(elapsedRealtime, uptime); 9499 } 9500 } 9501 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) { 9502 // We don't record history while we are plugged in and fully charged. 9503 // The next time we are unplugged, history will be cleared. 9504 mRecordingHistory = DEBUG; 9505 } 9506 } 9507 getAwakeTimeBattery()9508 public long getAwakeTimeBattery() { 9509 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); 9510 } 9511 getAwakeTimePlugged()9512 public long getAwakeTimePlugged() { 9513 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery(); 9514 } 9515 9516 @Override computeUptime(long curTime, int which)9517 public long computeUptime(long curTime, int which) { 9518 switch (which) { 9519 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart); 9520 case STATS_CURRENT: return (curTime-mUptimeStart); 9521 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart()); 9522 } 9523 return 0; 9524 } 9525 9526 @Override computeRealtime(long curTime, int which)9527 public long computeRealtime(long curTime, int which) { 9528 switch (which) { 9529 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart); 9530 case STATS_CURRENT: return (curTime-mRealtimeStart); 9531 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart()); 9532 } 9533 return 0; 9534 } 9535 9536 @Override computeBatteryUptime(long curTime, int which)9537 public long computeBatteryUptime(long curTime, int which) { 9538 return mOnBatteryTimeBase.computeUptime(curTime, which); 9539 } 9540 9541 @Override computeBatteryRealtime(long curTime, int which)9542 public long computeBatteryRealtime(long curTime, int which) { 9543 return mOnBatteryTimeBase.computeRealtime(curTime, which); 9544 } 9545 9546 @Override computeBatteryScreenOffUptime(long curTime, int which)9547 public long computeBatteryScreenOffUptime(long curTime, int which) { 9548 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which); 9549 } 9550 9551 @Override computeBatteryScreenOffRealtime(long curTime, int which)9552 public long computeBatteryScreenOffRealtime(long curTime, int which) { 9553 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which); 9554 } 9555 computeTimePerLevel(long[] steps, int numSteps)9556 private long computeTimePerLevel(long[] steps, int numSteps) { 9557 // For now we'll do a simple average across all steps. 9558 if (numSteps <= 0) { 9559 return -1; 9560 } 9561 long total = 0; 9562 for (int i=0; i<numSteps; i++) { 9563 total += steps[i] & STEP_LEVEL_TIME_MASK; 9564 } 9565 return total / numSteps; 9566 /* 9567 long[] buckets = new long[numSteps]; 9568 int numBuckets = 0; 9569 int numToAverage = 4; 9570 int i = 0; 9571 while (i < numSteps) { 9572 long totalTime = 0; 9573 int num = 0; 9574 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 9575 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 9576 num++; 9577 } 9578 buckets[numBuckets] = totalTime / num; 9579 numBuckets++; 9580 numToAverage *= 2; 9581 i += num; 9582 } 9583 if (numBuckets < 1) { 9584 return -1; 9585 } 9586 long averageTime = buckets[numBuckets-1]; 9587 for (i=numBuckets-2; i>=0; i--) { 9588 averageTime = (averageTime + buckets[i]) / 2; 9589 } 9590 return averageTime; 9591 */ 9592 } 9593 9594 @Override computeBatteryTimeRemaining(long curTime)9595 public long computeBatteryTimeRemaining(long curTime) { 9596 if (!mOnBattery) { 9597 return -1; 9598 } 9599 /* Simple implementation just looks at the average discharge per level across the 9600 entire sample period. 9601 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 9602 if (discharge < 2) { 9603 return -1; 9604 } 9605 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 9606 if (duration < 1000*1000) { 9607 return -1; 9608 } 9609 long usPerLevel = duration/discharge; 9610 return usPerLevel * mCurrentBatteryLevel; 9611 */ 9612 if (mDischargeStepTracker.mNumStepDurations < 1) { 9613 return -1; 9614 } 9615 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 9616 if (msPerLevel <= 0) { 9617 return -1; 9618 } 9619 return (msPerLevel * mCurrentBatteryLevel) * 1000; 9620 } 9621 9622 @Override getDischargeLevelStepTracker()9623 public LevelStepTracker getDischargeLevelStepTracker() { 9624 return mDischargeStepTracker; 9625 } 9626 9627 @Override getDailyDischargeLevelStepTracker()9628 public LevelStepTracker getDailyDischargeLevelStepTracker() { 9629 return mDailyDischargeStepTracker; 9630 } 9631 9632 @Override computeChargeTimeRemaining(long curTime)9633 public long computeChargeTimeRemaining(long curTime) { 9634 if (mOnBattery) { 9635 // Not yet working. 9636 return -1; 9637 } 9638 /* Broken 9639 int curLevel = mCurrentBatteryLevel; 9640 int plugLevel = mDischargePlugLevel; 9641 if (plugLevel < 0 || curLevel < (plugLevel+1)) { 9642 return -1; 9643 } 9644 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED); 9645 if (duration < 1000*1000) { 9646 return -1; 9647 } 9648 long usPerLevel = duration/(curLevel-plugLevel); 9649 return usPerLevel * (100-curLevel); 9650 */ 9651 if (mChargeStepTracker.mNumStepDurations < 1) { 9652 return -1; 9653 } 9654 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 9655 if (msPerLevel <= 0) { 9656 return -1; 9657 } 9658 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000; 9659 } 9660 9661 @Override getChargeLevelStepTracker()9662 public LevelStepTracker getChargeLevelStepTracker() { 9663 return mChargeStepTracker; 9664 } 9665 9666 @Override getDailyChargeLevelStepTracker()9667 public LevelStepTracker getDailyChargeLevelStepTracker() { 9668 return mDailyChargeStepTracker; 9669 } 9670 9671 @Override getDailyPackageChanges()9672 public ArrayList<PackageChange> getDailyPackageChanges() { 9673 return mDailyPackageChanges; 9674 } 9675 getBatteryUptimeLocked()9676 protected long getBatteryUptimeLocked() { 9677 return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000); 9678 } 9679 9680 @Override getBatteryUptime(long curTime)9681 public long getBatteryUptime(long curTime) { 9682 return mOnBatteryTimeBase.getUptime(curTime); 9683 } 9684 9685 @Override getBatteryRealtime(long curTime)9686 public long getBatteryRealtime(long curTime) { 9687 return mOnBatteryTimeBase.getRealtime(curTime); 9688 } 9689 9690 @Override getDischargeStartLevel()9691 public int getDischargeStartLevel() { 9692 synchronized(this) { 9693 return getDischargeStartLevelLocked(); 9694 } 9695 } 9696 getDischargeStartLevelLocked()9697 public int getDischargeStartLevelLocked() { 9698 return mDischargeUnplugLevel; 9699 } 9700 9701 @Override getDischargeCurrentLevel()9702 public int getDischargeCurrentLevel() { 9703 synchronized(this) { 9704 return getDischargeCurrentLevelLocked(); 9705 } 9706 } 9707 getDischargeCurrentLevelLocked()9708 public int getDischargeCurrentLevelLocked() { 9709 return mDischargeCurrentLevel; 9710 } 9711 9712 @Override getLowDischargeAmountSinceCharge()9713 public int getLowDischargeAmountSinceCharge() { 9714 synchronized(this) { 9715 int val = mLowDischargeAmountSinceCharge; 9716 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 9717 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 9718 } 9719 return val; 9720 } 9721 } 9722 9723 @Override getHighDischargeAmountSinceCharge()9724 public int getHighDischargeAmountSinceCharge() { 9725 synchronized(this) { 9726 int val = mHighDischargeAmountSinceCharge; 9727 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 9728 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 9729 } 9730 return val; 9731 } 9732 } 9733 9734 @Override getDischargeAmount(int which)9735 public int getDischargeAmount(int which) { 9736 int dischargeAmount = which == STATS_SINCE_CHARGED 9737 ? getHighDischargeAmountSinceCharge() 9738 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 9739 if (dischargeAmount < 0) { 9740 dischargeAmount = 0; 9741 } 9742 return dischargeAmount; 9743 } 9744 getDischargeAmountScreenOn()9745 public int getDischargeAmountScreenOn() { 9746 synchronized(this) { 9747 int val = mDischargeAmountScreenOn; 9748 if (mOnBattery && mScreenState == Display.STATE_ON 9749 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 9750 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 9751 } 9752 return val; 9753 } 9754 } 9755 getDischargeAmountScreenOnSinceCharge()9756 public int getDischargeAmountScreenOnSinceCharge() { 9757 synchronized(this) { 9758 int val = mDischargeAmountScreenOnSinceCharge; 9759 if (mOnBattery && mScreenState == Display.STATE_ON 9760 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 9761 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 9762 } 9763 return val; 9764 } 9765 } 9766 getDischargeAmountScreenOff()9767 public int getDischargeAmountScreenOff() { 9768 synchronized(this) { 9769 int val = mDischargeAmountScreenOff; 9770 if (mOnBattery && mScreenState != Display.STATE_ON 9771 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 9772 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 9773 } 9774 return val; 9775 } 9776 } 9777 getDischargeAmountScreenOffSinceCharge()9778 public int getDischargeAmountScreenOffSinceCharge() { 9779 synchronized(this) { 9780 int val = mDischargeAmountScreenOffSinceCharge; 9781 if (mOnBattery && mScreenState != Display.STATE_ON 9782 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 9783 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 9784 } 9785 return val; 9786 } 9787 } 9788 9789 /** 9790 * Retrieve the statistics object for a particular uid, creating if needed. 9791 */ getUidStatsLocked(int uid)9792 public Uid getUidStatsLocked(int uid) { 9793 Uid u = mUidStats.get(uid); 9794 if (u == null) { 9795 u = new Uid(this, uid); 9796 mUidStats.put(uid, u); 9797 } 9798 return u; 9799 } 9800 9801 /** 9802 * Remove the statistics object for a particular uid. 9803 */ removeUidStatsLocked(int uid)9804 public void removeUidStatsLocked(int uid) { 9805 mKernelUidCpuTimeReader.removeUid(uid); 9806 mUidStats.remove(uid); 9807 } 9808 9809 /** 9810 * Retrieve the statistics object for a particular process, creating 9811 * if needed. 9812 */ getProcessStatsLocked(int uid, String name)9813 public Uid.Proc getProcessStatsLocked(int uid, String name) { 9814 uid = mapUid(uid); 9815 Uid u = getUidStatsLocked(uid); 9816 return u.getProcessStatsLocked(name); 9817 } 9818 9819 /** 9820 * Retrieve the statistics object for a particular process, creating 9821 * if needed. 9822 */ getPackageStatsLocked(int uid, String pkg)9823 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 9824 uid = mapUid(uid); 9825 Uid u = getUidStatsLocked(uid); 9826 return u.getPackageStatsLocked(pkg); 9827 } 9828 9829 /** 9830 * Retrieve the statistics object for a particular service, creating 9831 * if needed. 9832 */ getServiceStatsLocked(int uid, String pkg, String name)9833 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 9834 uid = mapUid(uid); 9835 Uid u = getUidStatsLocked(uid); 9836 return u.getServiceStatsLocked(pkg, name); 9837 } 9838 shutdownLocked()9839 public void shutdownLocked() { 9840 recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 9841 writeSyncLocked(); 9842 mShuttingDown = true; 9843 } 9844 9845 Parcel mPendingWrite = null; 9846 final ReentrantLock mWriteLock = new ReentrantLock(); 9847 writeAsyncLocked()9848 public void writeAsyncLocked() { 9849 writeLocked(false); 9850 } 9851 writeSyncLocked()9852 public void writeSyncLocked() { 9853 writeLocked(true); 9854 } 9855 writeLocked(boolean sync)9856 void writeLocked(boolean sync) { 9857 if (mFile == null) { 9858 Slog.w("BatteryStats", "writeLocked: no file associated with this instance"); 9859 return; 9860 } 9861 9862 if (mShuttingDown) { 9863 return; 9864 } 9865 9866 Parcel out = Parcel.obtain(); 9867 writeSummaryToParcel(out, true); 9868 mLastWriteTime = mClocks.elapsedRealtime(); 9869 9870 if (mPendingWrite != null) { 9871 mPendingWrite.recycle(); 9872 } 9873 mPendingWrite = out; 9874 9875 if (sync) { 9876 commitPendingDataToDisk(); 9877 } else { 9878 BackgroundThread.getHandler().post(new Runnable() { 9879 @Override public void run() { 9880 commitPendingDataToDisk(); 9881 } 9882 }); 9883 } 9884 } 9885 commitPendingDataToDisk()9886 public void commitPendingDataToDisk() { 9887 final Parcel next; 9888 synchronized (this) { 9889 next = mPendingWrite; 9890 mPendingWrite = null; 9891 if (next == null) { 9892 return; 9893 } 9894 9895 mWriteLock.lock(); 9896 } 9897 9898 try { 9899 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite()); 9900 stream.write(next.marshall()); 9901 stream.flush(); 9902 FileUtils.sync(stream); 9903 stream.close(); 9904 mFile.commit(); 9905 } catch (IOException e) { 9906 Slog.w("BatteryStats", "Error writing battery statistics", e); 9907 mFile.rollback(); 9908 } finally { 9909 next.recycle(); 9910 mWriteLock.unlock(); 9911 } 9912 } 9913 readLocked()9914 public void readLocked() { 9915 if (mDailyFile != null) { 9916 readDailyStatsLocked(); 9917 } 9918 9919 if (mFile == null) { 9920 Slog.w("BatteryStats", "readLocked: no file associated with this instance"); 9921 return; 9922 } 9923 9924 mUidStats.clear(); 9925 9926 try { 9927 File file = mFile.chooseForRead(); 9928 if (!file.exists()) { 9929 return; 9930 } 9931 FileInputStream stream = new FileInputStream(file); 9932 9933 byte[] raw = BatteryStatsHelper.readFully(stream); 9934 Parcel in = Parcel.obtain(); 9935 in.unmarshall(raw, 0, raw.length); 9936 in.setDataPosition(0); 9937 stream.close(); 9938 9939 readSummaryFromParcel(in); 9940 } catch(Exception e) { 9941 Slog.e("BatteryStats", "Error reading battery statistics", e); 9942 resetAllStatsLocked(); 9943 } 9944 9945 mEndPlatformVersion = Build.ID; 9946 9947 if (mHistoryBuffer.dataPosition() > 0) { 9948 mRecordingHistory = true; 9949 final long elapsedRealtime = mClocks.elapsedRealtime(); 9950 final long uptime = mClocks.uptimeMillis(); 9951 if (USE_OLD_HISTORY) { 9952 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 9953 } 9954 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 9955 startRecordingHistory(elapsedRealtime, uptime, false); 9956 } 9957 9958 recordDailyStatsIfNeededLocked(false); 9959 } 9960 describeContents()9961 public int describeContents() { 9962 return 0; 9963 } 9964 readHistory(Parcel in, boolean andOldHistory)9965 void readHistory(Parcel in, boolean andOldHistory) throws ParcelFormatException { 9966 final long historyBaseTime = in.readLong(); 9967 9968 mHistoryBuffer.setDataSize(0); 9969 mHistoryBuffer.setDataPosition(0); 9970 mHistoryTagPool.clear(); 9971 mNextHistoryTagIdx = 0; 9972 mNumHistoryTagChars = 0; 9973 9974 int numTags = in.readInt(); 9975 for (int i=0; i<numTags; i++) { 9976 int idx = in.readInt(); 9977 String str = in.readString(); 9978 if (str == null) { 9979 throw new ParcelFormatException("null history tag string"); 9980 } 9981 int uid = in.readInt(); 9982 HistoryTag tag = new HistoryTag(); 9983 tag.string = str; 9984 tag.uid = uid; 9985 tag.poolIdx = idx; 9986 mHistoryTagPool.put(tag, idx); 9987 if (idx >= mNextHistoryTagIdx) { 9988 mNextHistoryTagIdx = idx+1; 9989 } 9990 mNumHistoryTagChars += tag.string.length() + 1; 9991 } 9992 9993 int bufSize = in.readInt(); 9994 int curPos = in.dataPosition(); 9995 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) { 9996 throw new ParcelFormatException("File corrupt: history data buffer too large " + 9997 bufSize); 9998 } else if ((bufSize&~3) != bufSize) { 9999 throw new ParcelFormatException("File corrupt: history data buffer not aligned " + 10000 bufSize); 10001 } else { 10002 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 10003 + " bytes at " + curPos); 10004 mHistoryBuffer.appendFrom(in, curPos, bufSize); 10005 in.setDataPosition(curPos + bufSize); 10006 } 10007 10008 if (andOldHistory) { 10009 readOldHistory(in); 10010 } 10011 10012 if (DEBUG_HISTORY) { 10013 StringBuilder sb = new StringBuilder(128); 10014 sb.append("****************** OLD mHistoryBaseTime: "); 10015 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10016 Slog.i(TAG, sb.toString()); 10017 } 10018 mHistoryBaseTime = historyBaseTime; 10019 if (DEBUG_HISTORY) { 10020 StringBuilder sb = new StringBuilder(128); 10021 sb.append("****************** NEW mHistoryBaseTime: "); 10022 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10023 Slog.i(TAG, sb.toString()); 10024 } 10025 10026 // We are just arbitrarily going to insert 1 minute from the sample of 10027 // the last run until samples in this run. 10028 if (mHistoryBaseTime > 0) { 10029 long oldnow = mClocks.elapsedRealtime(); 10030 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1; 10031 if (DEBUG_HISTORY) { 10032 StringBuilder sb = new StringBuilder(128); 10033 sb.append("****************** ADJUSTED mHistoryBaseTime: "); 10034 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10035 Slog.i(TAG, sb.toString()); 10036 } 10037 } 10038 } 10039 readOldHistory(Parcel in)10040 void readOldHistory(Parcel in) { 10041 if (!USE_OLD_HISTORY) { 10042 return; 10043 } 10044 mHistory = mHistoryEnd = mHistoryCache = null; 10045 long time; 10046 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) { 10047 HistoryItem rec = new HistoryItem(time, in); 10048 addHistoryRecordLocked(rec); 10049 } 10050 } 10051 writeHistory(Parcel out, boolean inclData, boolean andOldHistory)10052 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) { 10053 if (DEBUG_HISTORY) { 10054 StringBuilder sb = new StringBuilder(128); 10055 sb.append("****************** WRITING mHistoryBaseTime: "); 10056 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10057 sb.append(" mLastHistoryElapsedRealtime: "); 10058 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb); 10059 Slog.i(TAG, sb.toString()); 10060 } 10061 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime); 10062 if (!inclData) { 10063 out.writeInt(0); 10064 out.writeInt(0); 10065 return; 10066 } 10067 out.writeInt(mHistoryTagPool.size()); 10068 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 10069 HistoryTag tag = ent.getKey(); 10070 out.writeInt(ent.getValue()); 10071 out.writeString(tag.string); 10072 out.writeInt(tag.uid); 10073 } 10074 out.writeInt(mHistoryBuffer.dataSize()); 10075 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 10076 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 10077 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 10078 10079 if (andOldHistory) { 10080 writeOldHistory(out); 10081 } 10082 } 10083 writeOldHistory(Parcel out)10084 void writeOldHistory(Parcel out) { 10085 if (!USE_OLD_HISTORY) { 10086 return; 10087 } 10088 HistoryItem rec = mHistory; 10089 while (rec != null) { 10090 if (rec.time >= 0) rec.writeToParcel(out, 0); 10091 rec = rec.next; 10092 } 10093 out.writeLong(-1); 10094 } 10095 readSummaryFromParcel(Parcel in)10096 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 10097 final int version = in.readInt(); 10098 if (version != VERSION) { 10099 Slog.w("BatteryStats", "readFromParcel: version got " + version 10100 + ", expected " + VERSION + "; erasing old stats"); 10101 return; 10102 } 10103 10104 readHistory(in, true); 10105 10106 mStartCount = in.readInt(); 10107 mUptime = in.readLong(); 10108 mRealtime = in.readLong(); 10109 mStartClockTime = in.readLong(); 10110 mStartPlatformVersion = in.readString(); 10111 mEndPlatformVersion = in.readString(); 10112 mOnBatteryTimeBase.readSummaryFromParcel(in); 10113 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 10114 mDischargeUnplugLevel = in.readInt(); 10115 mDischargePlugLevel = in.readInt(); 10116 mDischargeCurrentLevel = in.readInt(); 10117 mCurrentBatteryLevel = in.readInt(); 10118 mEstimatedBatteryCapacity = in.readInt(); 10119 mLowDischargeAmountSinceCharge = in.readInt(); 10120 mHighDischargeAmountSinceCharge = in.readInt(); 10121 mDischargeAmountScreenOnSinceCharge = in.readInt(); 10122 mDischargeAmountScreenOffSinceCharge = in.readInt(); 10123 mDischargeStepTracker.readFromParcel(in); 10124 mChargeStepTracker.readFromParcel(in); 10125 mDailyDischargeStepTracker.readFromParcel(in); 10126 mDailyChargeStepTracker.readFromParcel(in); 10127 mDischargeCounter.readSummaryFromParcelLocked(in); 10128 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 10129 int NPKG = in.readInt(); 10130 if (NPKG > 0) { 10131 mDailyPackageChanges = new ArrayList<>(NPKG); 10132 while (NPKG > 0) { 10133 NPKG--; 10134 PackageChange pc = new PackageChange(); 10135 pc.mPackageName = in.readString(); 10136 pc.mUpdate = in.readInt() != 0; 10137 pc.mVersionCode = in.readInt(); 10138 mDailyPackageChanges.add(pc); 10139 } 10140 } else { 10141 mDailyPackageChanges = null; 10142 } 10143 mDailyStartTime = in.readLong(); 10144 mNextMinDailyDeadline = in.readLong(); 10145 mNextMaxDailyDeadline = in.readLong(); 10146 10147 mStartCount++; 10148 10149 mScreenState = Display.STATE_UNKNOWN; 10150 mScreenOnTimer.readSummaryFromParcelLocked(in); 10151 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10152 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 10153 } 10154 mInteractive = false; 10155 mInteractiveTimer.readSummaryFromParcelLocked(in); 10156 mPhoneOn = false; 10157 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 10158 mLongestLightIdleTime = in.readLong(); 10159 mLongestFullIdleTime = in.readLong(); 10160 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 10161 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 10162 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 10163 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 10164 mPhoneOnTimer.readSummaryFromParcelLocked(in); 10165 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 10166 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 10167 } 10168 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 10169 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10170 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 10171 } 10172 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10173 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 10174 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 10175 } 10176 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 10177 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 10178 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 10179 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 10180 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 10181 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 10182 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 10183 mWifiOn = false; 10184 mWifiOnTimer.readSummaryFromParcelLocked(in); 10185 mGlobalWifiRunning = false; 10186 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 10187 for (int i=0; i<NUM_WIFI_STATES; i++) { 10188 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 10189 } 10190 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10191 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 10192 } 10193 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10194 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 10195 } 10196 mWifiActivity.readSummaryFromParcel(in); 10197 mBluetoothActivity.readSummaryFromParcel(in); 10198 mModemActivity.readSummaryFromParcel(in); 10199 mHasWifiReporting = in.readInt() != 0; 10200 mHasBluetoothReporting = in.readInt() != 0; 10201 mHasModemReporting = in.readInt() != 0; 10202 10203 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt(); 10204 mFlashlightOnNesting = 0; 10205 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 10206 mCameraOnNesting = 0; 10207 mCameraOnTimer.readSummaryFromParcelLocked(in); 10208 mBluetoothScanNesting = 0; 10209 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 10210 10211 int NKW = in.readInt(); 10212 if (NKW > 10000) { 10213 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 10214 } 10215 for (int ikw = 0; ikw < NKW; ikw++) { 10216 if (in.readInt() != 0) { 10217 String kwltName = in.readString(); 10218 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 10219 } 10220 } 10221 10222 int NWR = in.readInt(); 10223 if (NWR > 10000) { 10224 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 10225 } 10226 for (int iwr = 0; iwr < NWR; iwr++) { 10227 if (in.readInt() != 0) { 10228 String reasonName = in.readString(); 10229 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 10230 } 10231 } 10232 10233 final int NU = in.readInt(); 10234 if (NU > 10000) { 10235 throw new ParcelFormatException("File corrupt: too many uids " + NU); 10236 } 10237 for (int iu = 0; iu < NU; iu++) { 10238 int uid = in.readInt(); 10239 Uid u = new Uid(this, uid); 10240 mUidStats.put(uid, u); 10241 10242 u.mWifiRunning = false; 10243 if (in.readInt() != 0) { 10244 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 10245 } 10246 u.mFullWifiLockOut = false; 10247 if (in.readInt() != 0) { 10248 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 10249 } 10250 u.mWifiScanStarted = false; 10251 if (in.readInt() != 0) { 10252 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 10253 } 10254 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 10255 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 10256 if (in.readInt() != 0) { 10257 u.makeWifiBatchedScanBin(i, null); 10258 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 10259 } 10260 } 10261 u.mWifiMulticastEnabled = false; 10262 if (in.readInt() != 0) { 10263 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 10264 } 10265 if (in.readInt() != 0) { 10266 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10267 } 10268 if (in.readInt() != 0) { 10269 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10270 } 10271 if (in.readInt() != 0) { 10272 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10273 } 10274 if (in.readInt() != 0) { 10275 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10276 } 10277 if (in.readInt() != 0) { 10278 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 10279 } 10280 if (in.readInt() != 0) { 10281 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 10282 } 10283 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 10284 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 10285 if (in.readInt() != 0) { 10286 u.makeProcessState(i, null); 10287 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 10288 } 10289 } 10290 if (in.readInt() != 0) { 10291 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 10292 } 10293 10294 if (in.readInt() != 0) { 10295 if (u.mUserActivityCounters == null) { 10296 u.initUserActivityLocked(); 10297 } 10298 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 10299 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 10300 } 10301 } 10302 10303 if (in.readInt() != 0) { 10304 if (u.mNetworkByteActivityCounters == null) { 10305 u.initNetworkActivityLocked(); 10306 } 10307 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10308 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 10309 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 10310 } 10311 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in); 10312 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 10313 } 10314 10315 u.mUserCpuTime.readSummaryFromParcelLocked(in); 10316 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 10317 u.mCpuPower.readSummaryFromParcelLocked(in); 10318 10319 if (in.readInt() != 0) { 10320 final int numClusters = in.readInt(); 10321 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 10322 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 10323 } 10324 10325 u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][]; 10326 for (int cluster = 0; cluster < numClusters; cluster++) { 10327 if (in.readInt() != 0) { 10328 final int NSB = in.readInt(); 10329 if (mPowerProfile != null && 10330 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 10331 throw new ParcelFormatException("File corrupt: too many speed bins " + 10332 NSB); 10333 } 10334 10335 u.mCpuClusterSpeed[cluster] = new LongSamplingCounter[NSB]; 10336 for (int speed = 0; speed < NSB; speed++) { 10337 if (in.readInt() != 0) { 10338 u.mCpuClusterSpeed[cluster][speed] = new LongSamplingCounter( 10339 mOnBatteryTimeBase); 10340 u.mCpuClusterSpeed[cluster][speed].readSummaryFromParcelLocked(in); 10341 } 10342 } 10343 } else { 10344 u.mCpuClusterSpeed[cluster] = null; 10345 } 10346 } 10347 } else { 10348 u.mCpuClusterSpeed = null; 10349 } 10350 10351 int NW = in.readInt(); 10352 if (NW > 100) { 10353 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 10354 } 10355 for (int iw = 0; iw < NW; iw++) { 10356 String wlName = in.readString(); 10357 u.readWakeSummaryFromParcelLocked(wlName, in); 10358 } 10359 10360 int NS = in.readInt(); 10361 if (NS > 100) { 10362 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 10363 } 10364 for (int is = 0; is < NS; is++) { 10365 String name = in.readString(); 10366 u.readSyncSummaryFromParcelLocked(name, in); 10367 } 10368 10369 int NJ = in.readInt(); 10370 if (NJ > 100) { 10371 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 10372 } 10373 for (int ij = 0; ij < NJ; ij++) { 10374 String name = in.readString(); 10375 u.readJobSummaryFromParcelLocked(name, in); 10376 } 10377 10378 int NP = in.readInt(); 10379 if (NP > 1000) { 10380 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 10381 } 10382 for (int is = 0; is < NP; is++) { 10383 int seNumber = in.readInt(); 10384 if (in.readInt() != 0) { 10385 u.getSensorTimerLocked(seNumber, true) 10386 .readSummaryFromParcelLocked(in); 10387 } 10388 } 10389 10390 NP = in.readInt(); 10391 if (NP > 1000) { 10392 throw new ParcelFormatException("File corrupt: too many processes " + NP); 10393 } 10394 for (int ip = 0; ip < NP; ip++) { 10395 String procName = in.readString(); 10396 Uid.Proc p = u.getProcessStatsLocked(procName); 10397 p.mUserTime = p.mLoadedUserTime = in.readLong(); 10398 p.mSystemTime = p.mLoadedSystemTime = in.readLong(); 10399 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong(); 10400 p.mStarts = p.mLoadedStarts = in.readInt(); 10401 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt(); 10402 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt(); 10403 p.readExcessivePowerFromParcelLocked(in); 10404 } 10405 10406 NP = in.readInt(); 10407 if (NP > 10000) { 10408 throw new ParcelFormatException("File corrupt: too many packages " + NP); 10409 } 10410 for (int ip = 0; ip < NP; ip++) { 10411 String pkgName = in.readString(); 10412 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 10413 final int NWA = in.readInt(); 10414 if (NWA > 1000) { 10415 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 10416 } 10417 p.mWakeupAlarms.clear(); 10418 for (int iwa=0; iwa<NWA; iwa++) { 10419 String tag = in.readString(); 10420 Counter c = new Counter(mOnBatteryTimeBase); 10421 c.readSummaryFromParcelLocked(in); 10422 p.mWakeupAlarms.put(tag, c); 10423 } 10424 NS = in.readInt(); 10425 if (NS > 1000) { 10426 throw new ParcelFormatException("File corrupt: too many services " + NS); 10427 } 10428 for (int is = 0; is < NS; is++) { 10429 String servName = in.readString(); 10430 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 10431 s.mStartTime = s.mLoadedStartTime = in.readLong(); 10432 s.mStarts = s.mLoadedStarts = in.readInt(); 10433 s.mLaunches = s.mLoadedLaunches = in.readInt(); 10434 } 10435 } 10436 } 10437 } 10438 10439 /** 10440 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 10441 * disk. This format does not allow a lossless round-trip. 10442 * 10443 * @param out the Parcel to be written to. 10444 */ writeSummaryToParcel(Parcel out, boolean inclHistory)10445 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 10446 pullPendingStateUpdatesLocked(); 10447 10448 // Pull the clock time. This may update the time and make a new history entry 10449 // if we had originally pulled a time before the RTC was set. 10450 long startClockTime = getStartClockTime(); 10451 10452 final long NOW_SYS = mClocks.uptimeMillis() * 1000; 10453 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000; 10454 10455 out.writeInt(VERSION); 10456 10457 writeHistory(out, inclHistory, true); 10458 10459 out.writeInt(mStartCount); 10460 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 10461 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 10462 out.writeLong(startClockTime); 10463 out.writeString(mStartPlatformVersion); 10464 out.writeString(mEndPlatformVersion); 10465 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 10466 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 10467 out.writeInt(mDischargeUnplugLevel); 10468 out.writeInt(mDischargePlugLevel); 10469 out.writeInt(mDischargeCurrentLevel); 10470 out.writeInt(mCurrentBatteryLevel); 10471 out.writeInt(mEstimatedBatteryCapacity); 10472 out.writeInt(getLowDischargeAmountSinceCharge()); 10473 out.writeInt(getHighDischargeAmountSinceCharge()); 10474 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 10475 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 10476 mDischargeStepTracker.writeToParcel(out); 10477 mChargeStepTracker.writeToParcel(out); 10478 mDailyDischargeStepTracker.writeToParcel(out); 10479 mDailyChargeStepTracker.writeToParcel(out); 10480 mDischargeCounter.writeSummaryFromParcelLocked(out); 10481 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 10482 if (mDailyPackageChanges != null) { 10483 final int NPKG = mDailyPackageChanges.size(); 10484 out.writeInt(NPKG); 10485 for (int i=0; i<NPKG; i++) { 10486 PackageChange pc = mDailyPackageChanges.get(i); 10487 out.writeString(pc.mPackageName); 10488 out.writeInt(pc.mUpdate ? 1 : 0); 10489 out.writeInt(pc.mVersionCode); 10490 } 10491 } else { 10492 out.writeInt(0); 10493 } 10494 out.writeLong(mDailyStartTime); 10495 out.writeLong(mNextMinDailyDeadline); 10496 out.writeLong(mNextMaxDailyDeadline); 10497 10498 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10499 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10500 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10501 } 10502 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10503 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10504 out.writeLong(mLongestLightIdleTime); 10505 out.writeLong(mLongestFullIdleTime); 10506 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10507 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10508 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10509 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10510 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10511 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 10512 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10513 } 10514 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10515 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10516 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10517 } 10518 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10519 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 10520 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 10521 } 10522 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10523 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10524 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 10525 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 10526 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 10527 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10528 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10529 for (int i=0; i<NUM_WIFI_STATES; i++) { 10530 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10531 } 10532 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10533 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10534 } 10535 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10536 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10537 } 10538 mWifiActivity.writeSummaryToParcel(out); 10539 mBluetoothActivity.writeSummaryToParcel(out); 10540 mModemActivity.writeSummaryToParcel(out); 10541 out.writeInt(mHasWifiReporting ? 1 : 0); 10542 out.writeInt(mHasBluetoothReporting ? 1 : 0); 10543 out.writeInt(mHasModemReporting ? 1 : 0); 10544 10545 out.writeInt(mNumConnectivityChange); 10546 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10547 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10548 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10549 10550 out.writeInt(mKernelWakelockStats.size()); 10551 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 10552 Timer kwlt = ent.getValue(); 10553 if (kwlt != null) { 10554 out.writeInt(1); 10555 out.writeString(ent.getKey()); 10556 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10557 } else { 10558 out.writeInt(0); 10559 } 10560 } 10561 10562 out.writeInt(mWakeupReasonStats.size()); 10563 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 10564 SamplingTimer timer = ent.getValue(); 10565 if (timer != null) { 10566 out.writeInt(1); 10567 out.writeString(ent.getKey()); 10568 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10569 } else { 10570 out.writeInt(0); 10571 } 10572 } 10573 10574 final int NU = mUidStats.size(); 10575 out.writeInt(NU); 10576 for (int iu = 0; iu < NU; iu++) { 10577 out.writeInt(mUidStats.keyAt(iu)); 10578 Uid u = mUidStats.valueAt(iu); 10579 10580 if (u.mWifiRunningTimer != null) { 10581 out.writeInt(1); 10582 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10583 } else { 10584 out.writeInt(0); 10585 } 10586 if (u.mFullWifiLockTimer != null) { 10587 out.writeInt(1); 10588 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10589 } else { 10590 out.writeInt(0); 10591 } 10592 if (u.mWifiScanTimer != null) { 10593 out.writeInt(1); 10594 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10595 } else { 10596 out.writeInt(0); 10597 } 10598 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 10599 if (u.mWifiBatchedScanTimer[i] != null) { 10600 out.writeInt(1); 10601 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10602 } else { 10603 out.writeInt(0); 10604 } 10605 } 10606 if (u.mWifiMulticastTimer != null) { 10607 out.writeInt(1); 10608 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10609 } else { 10610 out.writeInt(0); 10611 } 10612 if (u.mAudioTurnedOnTimer != null) { 10613 out.writeInt(1); 10614 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10615 } else { 10616 out.writeInt(0); 10617 } 10618 if (u.mVideoTurnedOnTimer != null) { 10619 out.writeInt(1); 10620 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10621 } else { 10622 out.writeInt(0); 10623 } 10624 if (u.mFlashlightTurnedOnTimer != null) { 10625 out.writeInt(1); 10626 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10627 } else { 10628 out.writeInt(0); 10629 } 10630 if (u.mCameraTurnedOnTimer != null) { 10631 out.writeInt(1); 10632 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10633 } else { 10634 out.writeInt(0); 10635 } 10636 if (u.mForegroundActivityTimer != null) { 10637 out.writeInt(1); 10638 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10639 } else { 10640 out.writeInt(0); 10641 } 10642 if (u.mBluetoothScanTimer != null) { 10643 out.writeInt(1); 10644 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10645 } else { 10646 out.writeInt(0); 10647 } 10648 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 10649 if (u.mProcessStateTimer[i] != null) { 10650 out.writeInt(1); 10651 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10652 } else { 10653 out.writeInt(0); 10654 } 10655 } 10656 if (u.mVibratorOnTimer != null) { 10657 out.writeInt(1); 10658 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10659 } else { 10660 out.writeInt(0); 10661 } 10662 10663 if (u.mUserActivityCounters == null) { 10664 out.writeInt(0); 10665 } else { 10666 out.writeInt(1); 10667 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 10668 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 10669 } 10670 } 10671 10672 if (u.mNetworkByteActivityCounters == null) { 10673 out.writeInt(0); 10674 } else { 10675 out.writeInt(1); 10676 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10677 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 10678 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 10679 } 10680 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out); 10681 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 10682 } 10683 10684 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 10685 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 10686 u.mCpuPower.writeSummaryFromParcelLocked(out); 10687 10688 if (u.mCpuClusterSpeed != null) { 10689 out.writeInt(1); 10690 out.writeInt(u.mCpuClusterSpeed.length); 10691 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeed) { 10692 if (cpuSpeeds != null) { 10693 out.writeInt(1); 10694 out.writeInt(cpuSpeeds.length); 10695 for (LongSamplingCounter c : cpuSpeeds) { 10696 if (c != null) { 10697 out.writeInt(1); 10698 c.writeSummaryFromParcelLocked(out); 10699 } else { 10700 out.writeInt(0); 10701 } 10702 } 10703 } else { 10704 out.writeInt(0); 10705 } 10706 } 10707 } else { 10708 out.writeInt(0); 10709 } 10710 10711 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 10712 int NW = wakeStats.size(); 10713 out.writeInt(NW); 10714 for (int iw=0; iw<NW; iw++) { 10715 out.writeString(wakeStats.keyAt(iw)); 10716 Uid.Wakelock wl = wakeStats.valueAt(iw); 10717 if (wl.mTimerFull != null) { 10718 out.writeInt(1); 10719 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10720 } else { 10721 out.writeInt(0); 10722 } 10723 if (wl.mTimerPartial != null) { 10724 out.writeInt(1); 10725 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10726 } else { 10727 out.writeInt(0); 10728 } 10729 if (wl.mTimerWindow != null) { 10730 out.writeInt(1); 10731 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10732 } else { 10733 out.writeInt(0); 10734 } 10735 if (wl.mTimerDraw != null) { 10736 out.writeInt(1); 10737 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10738 } else { 10739 out.writeInt(0); 10740 } 10741 } 10742 10743 final ArrayMap<String, StopwatchTimer> syncStats = u.mSyncStats.getMap(); 10744 int NS = syncStats.size(); 10745 out.writeInt(NS); 10746 for (int is=0; is<NS; is++) { 10747 out.writeString(syncStats.keyAt(is)); 10748 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10749 } 10750 10751 final ArrayMap<String, StopwatchTimer> jobStats = u.mJobStats.getMap(); 10752 int NJ = jobStats.size(); 10753 out.writeInt(NJ); 10754 for (int ij=0; ij<NJ; ij++) { 10755 out.writeString(jobStats.keyAt(ij)); 10756 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10757 } 10758 10759 int NSE = u.mSensorStats.size(); 10760 out.writeInt(NSE); 10761 for (int ise=0; ise<NSE; ise++) { 10762 out.writeInt(u.mSensorStats.keyAt(ise)); 10763 Uid.Sensor se = u.mSensorStats.valueAt(ise); 10764 if (se.mTimer != null) { 10765 out.writeInt(1); 10766 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 10767 } else { 10768 out.writeInt(0); 10769 } 10770 } 10771 10772 int NP = u.mProcessStats.size(); 10773 out.writeInt(NP); 10774 for (int ip=0; ip<NP; ip++) { 10775 out.writeString(u.mProcessStats.keyAt(ip)); 10776 Uid.Proc ps = u.mProcessStats.valueAt(ip); 10777 out.writeLong(ps.mUserTime); 10778 out.writeLong(ps.mSystemTime); 10779 out.writeLong(ps.mForegroundTime); 10780 out.writeInt(ps.mStarts); 10781 out.writeInt(ps.mNumCrashes); 10782 out.writeInt(ps.mNumAnrs); 10783 ps.writeExcessivePowerToParcelLocked(out); 10784 } 10785 10786 NP = u.mPackageStats.size(); 10787 out.writeInt(NP); 10788 if (NP > 0) { 10789 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 10790 : u.mPackageStats.entrySet()) { 10791 out.writeString(ent.getKey()); 10792 Uid.Pkg ps = ent.getValue(); 10793 final int NWA = ps.mWakeupAlarms.size(); 10794 out.writeInt(NWA); 10795 for (int iwa=0; iwa<NWA; iwa++) { 10796 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 10797 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 10798 } 10799 NS = ps.mServiceStats.size(); 10800 out.writeInt(NS); 10801 for (int is=0; is<NS; is++) { 10802 out.writeString(ps.mServiceStats.keyAt(is)); 10803 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 10804 long time = ss.getStartTimeToNowLocked( 10805 mOnBatteryTimeBase.getUptime(NOW_SYS)); 10806 out.writeLong(time); 10807 out.writeInt(ss.mStarts); 10808 out.writeInt(ss.mLaunches); 10809 } 10810 } 10811 } 10812 } 10813 } 10814 readFromParcel(Parcel in)10815 public void readFromParcel(Parcel in) { 10816 readFromParcelLocked(in); 10817 } 10818 readFromParcelLocked(Parcel in)10819 void readFromParcelLocked(Parcel in) { 10820 int magic = in.readInt(); 10821 if (magic != MAGIC) { 10822 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); 10823 } 10824 10825 readHistory(in, false); 10826 10827 mStartCount = in.readInt(); 10828 mStartClockTime = in.readLong(); 10829 mStartPlatformVersion = in.readString(); 10830 mEndPlatformVersion = in.readString(); 10831 mUptime = in.readLong(); 10832 mUptimeStart = in.readLong(); 10833 mRealtime = in.readLong(); 10834 mRealtimeStart = in.readLong(); 10835 mOnBattery = in.readInt() != 0; 10836 mEstimatedBatteryCapacity = in.readInt(); 10837 mOnBatteryInternal = false; // we are no longer really running. 10838 mOnBatteryTimeBase.readFromParcel(in); 10839 mOnBatteryScreenOffTimeBase.readFromParcel(in); 10840 10841 mScreenState = Display.STATE_UNKNOWN; 10842 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 10843 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10844 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 10845 mOnBatteryTimeBase, in); 10846 } 10847 mInteractive = false; 10848 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in); 10849 mPhoneOn = false; 10850 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 10851 mOnBatteryTimeBase, in); 10852 mLongestLightIdleTime = in.readLong(); 10853 mLongestFullIdleTime = in.readLong(); 10854 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null, 10855 mOnBatteryTimeBase, in); 10856 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null, 10857 mOnBatteryTimeBase, in); 10858 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, 10859 mOnBatteryTimeBase, in); 10860 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in); 10861 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in); 10862 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 10863 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, 10864 null, mOnBatteryTimeBase, in); 10865 } 10866 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 10867 mOnBatteryTimeBase, in); 10868 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10869 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, 10870 null, mOnBatteryTimeBase, in); 10871 } 10872 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10873 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 10874 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 10875 } 10876 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 10877 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, 10878 mOnBatteryTimeBase, in); 10879 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 10880 mOnBatteryTimeBase, in); 10881 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 10882 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 10883 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 10884 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 10885 mWifiOn = false; 10886 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in); 10887 mGlobalWifiRunning = false; 10888 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, 10889 mOnBatteryTimeBase, in); 10890 for (int i=0; i<NUM_WIFI_STATES; i++) { 10891 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, 10892 null, mOnBatteryTimeBase, in); 10893 } 10894 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10895 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, 10896 null, mOnBatteryTimeBase, in); 10897 } 10898 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10899 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, 10900 null, mOnBatteryTimeBase, in); 10901 } 10902 10903 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 10904 NUM_WIFI_TX_LEVELS, in); 10905 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 10906 NUM_BT_TX_LEVELS, in); 10907 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 10908 ModemActivityInfo.TX_POWER_LEVELS, in); 10909 mHasWifiReporting = in.readInt() != 0; 10910 mHasBluetoothReporting = in.readInt() != 0; 10911 mHasModemReporting = in.readInt() != 0; 10912 10913 mNumConnectivityChange = in.readInt(); 10914 mLoadedNumConnectivityChange = in.readInt(); 10915 mUnpluggedNumConnectivityChange = in.readInt(); 10916 mAudioOnNesting = 0; 10917 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 10918 mVideoOnNesting = 0; 10919 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 10920 mFlashlightOnNesting = 0; 10921 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in); 10922 mCameraOnNesting = 0; 10923 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in); 10924 mBluetoothScanNesting = 0; 10925 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); 10926 mDischargeUnplugLevel = in.readInt(); 10927 mDischargePlugLevel = in.readInt(); 10928 mDischargeCurrentLevel = in.readInt(); 10929 mCurrentBatteryLevel = in.readInt(); 10930 mLowDischargeAmountSinceCharge = in.readInt(); 10931 mHighDischargeAmountSinceCharge = in.readInt(); 10932 mDischargeAmountScreenOn = in.readInt(); 10933 mDischargeAmountScreenOnSinceCharge = in.readInt(); 10934 mDischargeAmountScreenOff = in.readInt(); 10935 mDischargeAmountScreenOffSinceCharge = in.readInt(); 10936 mDischargeStepTracker.readFromParcel(in); 10937 mChargeStepTracker.readFromParcel(in); 10938 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 10939 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 10940 mLastWriteTime = in.readLong(); 10941 10942 mKernelWakelockStats.clear(); 10943 int NKW = in.readInt(); 10944 for (int ikw = 0; ikw < NKW; ikw++) { 10945 if (in.readInt() != 0) { 10946 String wakelockName = in.readString(); 10947 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 10948 mKernelWakelockStats.put(wakelockName, kwlt); 10949 } 10950 } 10951 10952 mWakeupReasonStats.clear(); 10953 int NWR = in.readInt(); 10954 for (int iwr = 0; iwr < NWR; iwr++) { 10955 if (in.readInt() != 0) { 10956 String reasonName = in.readString(); 10957 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 10958 mWakeupReasonStats.put(reasonName, timer); 10959 } 10960 } 10961 10962 mPartialTimers.clear(); 10963 mFullTimers.clear(); 10964 mWindowTimers.clear(); 10965 mWifiRunningTimers.clear(); 10966 mFullWifiLockTimers.clear(); 10967 mWifiScanTimers.clear(); 10968 mWifiBatchedScanTimers.clear(); 10969 mWifiMulticastTimers.clear(); 10970 mAudioTurnedOnTimers.clear(); 10971 mVideoTurnedOnTimers.clear(); 10972 mFlashlightTurnedOnTimers.clear(); 10973 mCameraTurnedOnTimers.clear(); 10974 10975 int numUids = in.readInt(); 10976 mUidStats.clear(); 10977 for (int i = 0; i < numUids; i++) { 10978 int uid = in.readInt(); 10979 Uid u = new Uid(this, uid); 10980 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); 10981 mUidStats.append(uid, u); 10982 } 10983 } 10984 writeToParcel(Parcel out, int flags)10985 public void writeToParcel(Parcel out, int flags) { 10986 writeToParcelLocked(out, true, flags); 10987 } 10988 writeToParcelWithoutUids(Parcel out, int flags)10989 public void writeToParcelWithoutUids(Parcel out, int flags) { 10990 writeToParcelLocked(out, false, flags); 10991 } 10992 10993 @SuppressWarnings("unused") writeToParcelLocked(Parcel out, boolean inclUids, int flags)10994 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 10995 // Need to update with current kernel wake lock counts. 10996 pullPendingStateUpdatesLocked(); 10997 10998 // Pull the clock time. This may update the time and make a new history entry 10999 // if we had originally pulled a time before the RTC was set. 11000 long startClockTime = getStartClockTime(); 11001 11002 final long uSecUptime = mClocks.uptimeMillis() * 1000; 11003 final long uSecRealtime = mClocks.elapsedRealtime() * 1000; 11004 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 11005 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 11006 11007 out.writeInt(MAGIC); 11008 11009 writeHistory(out, true, false); 11010 11011 out.writeInt(mStartCount); 11012 out.writeLong(startClockTime); 11013 out.writeString(mStartPlatformVersion); 11014 out.writeString(mEndPlatformVersion); 11015 out.writeLong(mUptime); 11016 out.writeLong(mUptimeStart); 11017 out.writeLong(mRealtime); 11018 out.writeLong(mRealtimeStart); 11019 out.writeInt(mOnBattery ? 1 : 0); 11020 out.writeInt(mEstimatedBatteryCapacity); 11021 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 11022 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 11023 11024 mScreenOnTimer.writeToParcel(out, uSecRealtime); 11025 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11026 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 11027 } 11028 mInteractiveTimer.writeToParcel(out, uSecRealtime); 11029 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); 11030 out.writeLong(mLongestLightIdleTime); 11031 out.writeLong(mLongestFullIdleTime); 11032 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); 11033 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); 11034 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); 11035 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); 11036 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 11037 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 11038 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 11039 } 11040 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 11041 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11042 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 11043 } 11044 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11045 mNetworkByteActivityCounters[i].writeToParcel(out); 11046 mNetworkPacketActivityCounters[i].writeToParcel(out); 11047 } 11048 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 11049 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 11050 mMobileRadioActiveAdjustedTime.writeToParcel(out); 11051 mMobileRadioActiveUnknownTime.writeToParcel(out); 11052 mMobileRadioActiveUnknownCount.writeToParcel(out); 11053 mWifiOnTimer.writeToParcel(out, uSecRealtime); 11054 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 11055 for (int i=0; i<NUM_WIFI_STATES; i++) { 11056 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 11057 } 11058 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11059 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 11060 } 11061 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11062 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 11063 } 11064 mWifiActivity.writeToParcel(out, 0); 11065 mBluetoothActivity.writeToParcel(out, 0); 11066 mModemActivity.writeToParcel(out, 0); 11067 out.writeInt(mHasWifiReporting ? 1 : 0); 11068 out.writeInt(mHasBluetoothReporting ? 1 : 0); 11069 out.writeInt(mHasModemReporting ? 1 : 0); 11070 11071 out.writeInt(mNumConnectivityChange); 11072 out.writeInt(mLoadedNumConnectivityChange); 11073 out.writeInt(mUnpluggedNumConnectivityChange); 11074 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 11075 mCameraOnTimer.writeToParcel(out, uSecRealtime); 11076 mBluetoothScanTimer.writeToParcel(out, uSecRealtime); 11077 out.writeInt(mDischargeUnplugLevel); 11078 out.writeInt(mDischargePlugLevel); 11079 out.writeInt(mDischargeCurrentLevel); 11080 out.writeInt(mCurrentBatteryLevel); 11081 out.writeInt(mLowDischargeAmountSinceCharge); 11082 out.writeInt(mHighDischargeAmountSinceCharge); 11083 out.writeInt(mDischargeAmountScreenOn); 11084 out.writeInt(mDischargeAmountScreenOnSinceCharge); 11085 out.writeInt(mDischargeAmountScreenOff); 11086 out.writeInt(mDischargeAmountScreenOffSinceCharge); 11087 mDischargeStepTracker.writeToParcel(out); 11088 mChargeStepTracker.writeToParcel(out); 11089 mDischargeCounter.writeToParcel(out); 11090 mDischargeScreenOffCounter.writeToParcel(out); 11091 out.writeLong(mLastWriteTime); 11092 11093 if (inclUids) { 11094 out.writeInt(mKernelWakelockStats.size()); 11095 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 11096 SamplingTimer kwlt = ent.getValue(); 11097 if (kwlt != null) { 11098 out.writeInt(1); 11099 out.writeString(ent.getKey()); 11100 kwlt.writeToParcel(out, uSecRealtime); 11101 } else { 11102 out.writeInt(0); 11103 } 11104 } 11105 out.writeInt(mWakeupReasonStats.size()); 11106 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 11107 SamplingTimer timer = ent.getValue(); 11108 if (timer != null) { 11109 out.writeInt(1); 11110 out.writeString(ent.getKey()); 11111 timer.writeToParcel(out, uSecRealtime); 11112 } else { 11113 out.writeInt(0); 11114 } 11115 } 11116 } else { 11117 out.writeInt(0); 11118 } 11119 11120 if (inclUids) { 11121 int size = mUidStats.size(); 11122 out.writeInt(size); 11123 for (int i = 0; i < size; i++) { 11124 out.writeInt(mUidStats.keyAt(i)); 11125 Uid uid = mUidStats.valueAt(i); 11126 11127 uid.writeToParcelLocked(out, uSecRealtime); 11128 } 11129 } else { 11130 out.writeInt(0); 11131 } 11132 } 11133 11134 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 11135 new Parcelable.Creator<BatteryStatsImpl>() { 11136 public BatteryStatsImpl createFromParcel(Parcel in) { 11137 return new BatteryStatsImpl(in); 11138 } 11139 11140 public BatteryStatsImpl[] newArray(int size) { 11141 return new BatteryStatsImpl[size]; 11142 } 11143 }; 11144 prepareForDumpLocked()11145 public void prepareForDumpLocked() { 11146 // Need to retrieve current kernel wake lock stats before printing. 11147 pullPendingStateUpdatesLocked(); 11148 11149 // Pull the clock time. This may update the time and make a new history entry 11150 // if we had originally pulled a time before the RTC was set. 11151 getStartClockTime(); 11152 } 11153 dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart)11154 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 11155 if (DEBUG) { 11156 pw.println("mOnBatteryTimeBase:"); 11157 mOnBatteryTimeBase.dump(pw, " "); 11158 pw.println("mOnBatteryScreenOffTimeBase:"); 11159 mOnBatteryScreenOffTimeBase.dump(pw, " "); 11160 Printer pr = new PrintWriterPrinter(pw); 11161 pr.println("*** Screen timer:"); 11162 mScreenOnTimer.logState(pr, " "); 11163 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11164 pr.println("*** Screen brightness #" + i + ":"); 11165 mScreenBrightnessTimer[i].logState(pr, " "); 11166 } 11167 pr.println("*** Interactive timer:"); 11168 mInteractiveTimer.logState(pr, " "); 11169 pr.println("*** Power save mode timer:"); 11170 mPowerSaveModeEnabledTimer.logState(pr, " "); 11171 pr.println("*** Device idle mode light timer:"); 11172 mDeviceIdleModeLightTimer.logState(pr, " "); 11173 pr.println("*** Device idle mode full timer:"); 11174 mDeviceIdleModeFullTimer.logState(pr, " "); 11175 pr.println("*** Device light idling timer:"); 11176 mDeviceLightIdlingTimer.logState(pr, " "); 11177 pr.println("*** Device idling timer:"); 11178 mDeviceIdlingTimer.logState(pr, " "); 11179 pr.println("*** Phone timer:"); 11180 mPhoneOnTimer.logState(pr, " "); 11181 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 11182 pr.println("*** Phone signal strength #" + i + ":"); 11183 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 11184 } 11185 pr.println("*** Signal scanning :"); 11186 mPhoneSignalScanningTimer.logState(pr, " "); 11187 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11188 pr.println("*** Data connection type #" + i + ":"); 11189 mPhoneDataConnectionsTimer[i].logState(pr, " "); 11190 } 11191 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 11192 pr.println("*** Mobile network active timer:"); 11193 mMobileRadioActiveTimer.logState(pr, " "); 11194 pr.println("*** Mobile network active adjusted timer:"); 11195 mMobileRadioActiveAdjustedTime.logState(pr, " "); 11196 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 11197 pr.println("*** Wifi timer:"); 11198 mWifiOnTimer.logState(pr, " "); 11199 pr.println("*** WifiRunning timer:"); 11200 mGlobalWifiRunningTimer.logState(pr, " "); 11201 for (int i=0; i<NUM_WIFI_STATES; i++) { 11202 pr.println("*** Wifi state #" + i + ":"); 11203 mWifiStateTimer[i].logState(pr, " "); 11204 } 11205 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11206 pr.println("*** Wifi suppl state #" + i + ":"); 11207 mWifiSupplStateTimer[i].logState(pr, " "); 11208 } 11209 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11210 pr.println("*** Wifi signal strength #" + i + ":"); 11211 mWifiSignalStrengthsTimer[i].logState(pr, " "); 11212 } 11213 pr.println("*** Flashlight timer:"); 11214 mFlashlightOnTimer.logState(pr, " "); 11215 pr.println("*** Camera timer:"); 11216 mCameraOnTimer.logState(pr, " "); 11217 } 11218 super.dumpLocked(context, pw, flags, reqUid, histStart); 11219 } 11220 } 11221