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