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