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