1 /* 2 * Copyright (C) 2006-2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.power.stats; 18 19 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 20 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 21 import static android.os.BatteryStats.Uid.NUM_PROCESS_STATE; 22 import static android.os.BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; 23 import static android.os.BatteryStatsManager.NUM_WIFI_STATES; 24 import static android.os.BatteryStatsManager.NUM_WIFI_SUPPL_STATES; 25 26 import static com.android.server.power.stats.MobileRadioPowerStatsCollector.mapRadioAccessNetworkTypeToRadioAccessTechnology; 27 28 import android.annotation.IntDef; 29 import android.annotation.NonNull; 30 import android.annotation.Nullable; 31 import android.app.ActivityManager; 32 import android.app.AlarmManager; 33 import android.app.usage.NetworkStatsManager; 34 import android.bluetooth.BluetoothActivityEnergyInfo; 35 import android.bluetooth.BluetoothAdapter; 36 import android.bluetooth.BluetoothManager; 37 import android.bluetooth.UidTraffic; 38 import android.content.BroadcastReceiver; 39 import android.content.ContentResolver; 40 import android.content.Context; 41 import android.content.Intent; 42 import android.content.IntentFilter; 43 import android.content.pm.PackageManager; 44 import android.database.ContentObserver; 45 import android.hardware.usb.UsbManager; 46 import android.location.GnssSignalQuality; 47 import android.net.NetworkStats; 48 import android.net.Uri; 49 import android.net.wifi.WifiManager; 50 import android.os.BatteryConsumer; 51 import android.os.BatteryManager; 52 import android.os.BatteryStats; 53 import android.os.BatteryUsageStats; 54 import android.os.BatteryUsageStatsQuery; 55 import android.os.Binder; 56 import android.os.BluetoothBatteryStats; 57 import android.os.Build; 58 import android.os.ConditionVariable; 59 import android.os.Handler; 60 import android.os.IBatteryPropertiesRegistrar; 61 import android.os.Looper; 62 import android.os.Message; 63 import android.os.OsProtoEnums; 64 import android.os.Parcel; 65 import android.os.ParcelFormatException; 66 import android.os.Parcelable; 67 import android.os.PowerManager; 68 import android.os.Process; 69 import android.os.RemoteException; 70 import android.os.ServiceManager; 71 import android.os.SystemClock; 72 import android.os.UserHandle; 73 import android.os.WakeLockStats; 74 import android.os.WorkSource; 75 import android.os.WorkSource.WorkChain; 76 import android.os.connectivity.CellularBatteryStats; 77 import android.os.connectivity.GpsBatteryStats; 78 import android.os.connectivity.WifiActivityEnergyInfo; 79 import android.os.connectivity.WifiBatteryStats; 80 import android.power.PowerStatsInternal; 81 import android.provider.Settings; 82 import android.telephony.AccessNetworkConstants; 83 import android.telephony.Annotation.NetworkType; 84 import android.telephony.CellSignalStrength; 85 import android.telephony.CellSignalStrengthLte; 86 import android.telephony.CellSignalStrengthNr; 87 import android.telephony.DataConnectionRealTimeInfo; 88 import android.telephony.ModemActivityInfo; 89 import android.telephony.NetworkRegistrationInfo; 90 import android.telephony.ServiceState; 91 import android.telephony.ServiceState.RegState; 92 import android.telephony.SignalStrength; 93 import android.telephony.TelephonyManager; 94 import android.text.TextUtils; 95 import android.text.format.DateUtils; 96 import android.util.ArrayMap; 97 import android.util.ArraySet; 98 import android.util.AtomicFile; 99 import android.util.IndentingPrintWriter; 100 import android.util.KeyValueListParser; 101 import android.util.Log; 102 import android.util.LongSparseArray; 103 import android.util.LongSparseLongArray; 104 import android.util.MutableInt; 105 import android.util.PrintWriterPrinter; 106 import android.util.Printer; 107 import android.util.Slog; 108 import android.util.SparseArray; 109 import android.util.SparseBooleanArray; 110 import android.util.SparseDoubleArray; 111 import android.util.SparseIntArray; 112 import android.util.SparseLongArray; 113 import android.util.TimeUtils; 114 import android.util.Xml; 115 import android.view.Display; 116 117 import com.android.internal.annotations.GuardedBy; 118 import com.android.internal.annotations.VisibleForTesting; 119 import com.android.internal.os.BackgroundThread; 120 import com.android.internal.os.BatteryStatsHistory; 121 import com.android.internal.os.BatteryStatsHistory.HistoryStepDetailsCalculator; 122 import com.android.internal.os.BatteryStatsHistoryIterator; 123 import com.android.internal.os.BinderCallsStats; 124 import com.android.internal.os.BinderTransactionNameResolver; 125 import com.android.internal.os.Clock; 126 import com.android.internal.os.CpuScalingPolicies; 127 import com.android.internal.os.KernelCpuSpeedReader; 128 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; 129 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; 130 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 131 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; 132 import com.android.internal.os.KernelMemoryBandwidthStats; 133 import com.android.internal.os.KernelSingleUidTimeReader; 134 import com.android.internal.os.LongArrayMultiStateCounter; 135 import com.android.internal.os.LongMultiStateCounter; 136 import com.android.internal.os.MonotonicClock; 137 import com.android.internal.os.PowerProfile; 138 import com.android.internal.os.PowerStats; 139 import com.android.internal.os.RailStats; 140 import com.android.internal.os.RpmStats; 141 import com.android.internal.power.EnergyConsumerStats; 142 import com.android.internal.power.EnergyConsumerStats.StandardPowerBucket; 143 import com.android.internal.util.ArrayUtils; 144 import com.android.internal.util.FrameworkStatsLog; 145 import com.android.internal.util.XmlUtils; 146 import com.android.modules.utils.TypedXmlPullParser; 147 import com.android.modules.utils.TypedXmlSerializer; 148 import com.android.server.LocalServices; 149 import com.android.server.power.optimization.Flags; 150 import com.android.server.power.stats.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes; 151 152 import libcore.util.EmptyArray; 153 154 import org.xmlpull.v1.XmlPullParser; 155 import org.xmlpull.v1.XmlPullParserException; 156 157 import java.io.ByteArrayOutputStream; 158 import java.io.File; 159 import java.io.FileInputStream; 160 import java.io.FileNotFoundException; 161 import java.io.FileOutputStream; 162 import java.io.IOException; 163 import java.io.PrintWriter; 164 import java.lang.annotation.Retention; 165 import java.lang.annotation.RetentionPolicy; 166 import java.util.ArrayList; 167 import java.util.Arrays; 168 import java.util.Calendar; 169 import java.util.Collection; 170 import java.util.HashMap; 171 import java.util.HashSet; 172 import java.util.Iterator; 173 import java.util.LinkedList; 174 import java.util.List; 175 import java.util.Map; 176 import java.util.Queue; 177 import java.util.concurrent.Executor; 178 import java.util.concurrent.Future; 179 import java.util.concurrent.TimeUnit; 180 import java.util.concurrent.atomic.AtomicInteger; 181 import java.util.concurrent.locks.ReentrantLock; 182 import java.util.function.IntSupplier; 183 import java.util.function.LongSupplier; 184 import java.util.function.Supplier; 185 186 /** 187 * All information we are collecting about things that can happen that impact 188 * battery life. All times are represented in microseconds except where indicated 189 * otherwise. 190 */ 191 public class BatteryStatsImpl extends BatteryStats { 192 private static final String TAG = "BatteryStatsImpl"; 193 private static final boolean DEBUG = false; 194 public static final boolean DEBUG_ENERGY = false; 195 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 196 private static final boolean DEBUG_BINDER_STATS = false; 197 private static final boolean DEBUG_MEMORY = false; 198 199 // TODO: remove "tcp" from network methods, since we measure total stats. 200 201 // Current on-disk Parcel version. Must be updated when the format of the parcelable changes 202 public static final int VERSION = 203 !Flags.disableSystemServicePowerAttr() ? 214 : 215; 204 205 // The maximum number of names wakelocks we will keep track of 206 // per uid; once the limit is reached, we batch the remaining wakelocks 207 // in to one common name. 208 private static final int MAX_WAKELOCKS_PER_UID = isLowRamDevice() ? 40 : 200; 209 210 private static final int CELL_SIGNAL_STRENGTH_LEVEL_COUNT = getCellSignalStrengthLevelCount(); 211 212 private static final int MODEM_TX_POWER_LEVEL_COUNT = getModemTxPowerLevelCount(); 213 214 // Number of transmit power states the Wifi controller can be in. 215 private static final int NUM_WIFI_TX_LEVELS = 1; 216 217 // Number of transmit power states the Bluetooth controller can be in. 218 private static final int NUM_BT_TX_LEVELS = 1; 219 220 /** 221 * Holding a wakelock costs more than just using the cpu. 222 * Currently, we assign only half the cpu time to an app that is running but 223 * not holding a wakelock. The apps holding wakelocks get the rest of the blame. 224 * If no app is holding a wakelock, then the distribution is normal. 225 */ 226 @VisibleForTesting 227 public static final int WAKE_LOCK_WEIGHT = 50; 228 229 public static final int RESET_REASON_CORRUPT_FILE = 1; 230 public static final int RESET_REASON_ADB_COMMAND = 2; 231 public static final int RESET_REASON_FULL_CHARGE = 3; 232 public static final int RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE = 4; 233 public static final int RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION = 5; 234 @NonNull 235 private final MonotonicClock mMonotonicClock; 236 237 protected Clock mClock; 238 239 private final AtomicFile mStatsFile; 240 public final AtomicFile mCheckinFile; 241 public final AtomicFile mDailyFile; 242 243 static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1; 244 static final int MSG_REPORT_POWER_CHANGE = 2; 245 static final int MSG_REPORT_CHARGING = 3; 246 static final int MSG_REPORT_RESET_STATS = 4; 247 static final long DELAY_UPDATE_WAKELOCKS = 60 * 1000; 248 249 private static final double MILLISECONDS_IN_HOUR = 3600 * 1000; 250 private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L; 251 252 private static final LongCounter ZERO_LONG_COUNTER = new LongCounter() { 253 @Override 254 public long getCountLocked(int which) { 255 return 0; 256 } 257 258 @Override 259 public long getCountForProcessState(int procState) { 260 return 0; 261 } 262 263 @Override 264 public void logState(Printer pw, String prefix) { 265 pw.println(prefix + "mCount=0"); 266 } 267 }; 268 269 private static final LongCounter[] ZERO_LONG_COUNTER_ARRAY = 270 new LongCounter[]{ZERO_LONG_COUNTER}; 271 272 @VisibleForTesting 273 protected CpuScalingPolicies mCpuScalingPolicies; 274 275 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 276 277 @VisibleForTesting 278 protected KernelWakelockReader mKernelWakelockReader; 279 @VisibleForTesting 280 protected KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader; 281 @VisibleForTesting 282 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 283 @VisibleForTesting 284 protected KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader; 285 @VisibleForTesting 286 protected KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader; 287 @VisibleForTesting 288 protected KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader; 289 @VisibleForTesting 290 protected KernelSingleUidTimeReader mKernelSingleUidTimeReader; 291 @VisibleForTesting 292 protected SystemServerCpuThreadReader mSystemServerCpuThreadReader; 293 294 private KernelMemoryBandwidthStats mKernelMemoryBandwidthStats; 295 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); 296 private int[] mCpuPowerBracketMap; 297 private final CpuPowerStatsCollector mCpuPowerStatsCollector; 298 private final MobileRadioPowerStatsCollector mMobileRadioPowerStatsCollector; 299 private final WifiPowerStatsCollector mWifiPowerStatsCollector; 300 private final BluetoothPowerStatsCollector mBluetoothPowerStatsCollector; 301 private final CameraPowerStatsCollector mCameraPowerStatsCollector; 302 private final GnssPowerStatsCollector mGnssPowerStatsCollector; 303 private final SparseBooleanArray mPowerStatsCollectorEnabled = new SparseBooleanArray(); 304 private final WifiPowerStatsCollector.WifiStatsRetriever mWifiStatsRetriever = 305 new WifiPowerStatsCollector.WifiStatsRetriever() { 306 @Override 307 public void retrieveWifiScanTimes(Callback callback) { 308 synchronized (BatteryStatsImpl.this) { 309 retrieveWifiScanTimesLocked(callback); 310 } 311 } 312 313 @Override 314 public long getWifiActiveDuration() { 315 synchronized (BatteryStatsImpl.this) { 316 return getGlobalWifiRunningTime(mClock.elapsedRealtime() * 1000, 317 STATS_SINCE_CHARGED) / 1000; 318 } 319 } 320 }; 321 322 private class BluetoothStatsRetrieverImpl implements 323 BluetoothPowerStatsCollector.BluetoothStatsRetriever { 324 private final BluetoothManager mBluetoothManager; 325 BluetoothStatsRetrieverImpl(BluetoothManager bluetoothManager)326 BluetoothStatsRetrieverImpl(BluetoothManager bluetoothManager) { 327 mBluetoothManager = bluetoothManager; 328 } 329 330 @Override retrieveBluetoothScanTimes(Callback callback)331 public void retrieveBluetoothScanTimes(Callback callback) { 332 synchronized (BatteryStatsImpl.this) { 333 retrieveBluetoothScanTimesLocked(callback); 334 } 335 } 336 337 @Override requestControllerActivityEnergyInfo(Executor executor, BluetoothAdapter.OnBluetoothActivityEnergyInfoCallback callback)338 public boolean requestControllerActivityEnergyInfo(Executor executor, 339 BluetoothAdapter.OnBluetoothActivityEnergyInfoCallback callback) { 340 if (mBluetoothManager == null) { 341 return false; 342 } 343 344 BluetoothAdapter adapter = mBluetoothManager.getAdapter(); 345 if (adapter == null) { 346 return false; 347 } 348 349 adapter.requestControllerActivityEnergyInfo(executor, callback); 350 return true; 351 } 352 } 353 getKernelMemoryStats()354 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 355 return mKernelMemoryStats; 356 } 357 358 private static final int[] SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS = { 359 EnergyConsumerStats.POWER_BUCKET_CPU, 360 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 361 EnergyConsumerStats.POWER_BUCKET_WIFI, 362 EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 363 }; 364 365 // TimeInState counters need NUM_PROCESS_STATE states in order to accommodate 366 // Uid.PROCESS_STATE_NONEXISTENT, which is outside the range of legitimate proc states. 367 private static final int PROC_STATE_TIME_COUNTER_STATE_COUNT = NUM_PROCESS_STATE + 1; 368 369 @GuardedBy("this") 370 public boolean mPerProcStateCpuTimesAvailable = true; 371 372 @GuardedBy("this") 373 private long mNumSingleUidCpuTimeReads; 374 @GuardedBy("this") 375 private long mCpuTimeReadsTrackingStartTimeMs = SystemClock.uptimeMillis(); 376 @GuardedBy("this") 377 private int mNumUidsRemoved; 378 @GuardedBy("this") 379 private int mNumAllUidCpuTimeReads; 380 381 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ 382 private RpmStats mTmpRpmStats = null; 383 /** The soonest the RPM stats can be updated after it was last updated. */ 384 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; 385 /** Last time that RPM stats were updated by updateRpmStatsLocked. */ 386 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS; 387 388 /** Container for Rail Energy Data stats. */ 389 private RailStats mTmpRailStats; 390 391 /** 392 * Estimate UID modem power usage based on their estimated mobile radio active time. 393 */ 394 public static final int PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME = 1; 395 /** 396 * Estimate UID modem power consumption by proportionally attributing estimated Rx and Tx 397 * power consumption individually. 398 * ModemActivityInfo must be available. 399 */ 400 public static final int PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX = 2; 401 402 @IntDef(flag = true, prefix = "PER_UID_MODEM_MODEL_", value = { 403 PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME, 404 PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX, 405 }) 406 @Retention(RetentionPolicy.SOURCE) 407 public @interface PerUidModemPowerModel { 408 } 409 410 /** 411 * Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader}, 412 * {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader}, 413 * {@link KernelCpuUidFreqTimeReader} and from the Kernel. 414 * 415 * Isolated and invalid UID info must be removed to conserve memory. However, STATSD and 416 * Batterystats both need to access UID cpu time. To resolve this race condition, only 417 * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is 418 * implemented so that STATSD can capture those UID times before they are deleted. 419 */ 420 @GuardedBy("this") 421 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 422 protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>(); 423 424 @NonNull getHistory()425 public BatteryStatsHistory getHistory() { 426 return mHistory; 427 } 428 429 @NonNull copyHistory()430 BatteryStatsHistory copyHistory() { 431 return mHistory.copy(); 432 } 433 434 @VisibleForTesting 435 public final class UidToRemove { 436 private final int mStartUid; 437 private final int mEndUid; 438 private final long mUidRemovalTimestamp; 439 440 /** Remove just one UID */ UidToRemove(int uid, long timestamp)441 public UidToRemove(int uid, long timestamp) { 442 this(uid, uid, timestamp); 443 } 444 445 /** Remove a range of UIDs, startUid must be smaller than endUid. */ UidToRemove(int startUid, int endUid, long timestamp)446 public UidToRemove(int startUid, int endUid, long timestamp) { 447 mStartUid = startUid; 448 mEndUid = endUid; 449 mUidRemovalTimestamp = timestamp; 450 } 451 getUidRemovalTimestamp()452 public long getUidRemovalTimestamp() { 453 return mUidRemovalTimestamp; 454 } 455 456 @GuardedBy("BatteryStatsImpl.this") removeLocked()457 void removeLocked() { 458 removeCpuStatsForUidRangeLocked(mStartUid, mEndUid); 459 } 460 } 461 462 private boolean mSaveBatteryUsageStatsOnReset; 463 private BatteryUsageStatsProvider mBatteryUsageStatsProvider; 464 private PowerStatsStore mPowerStatsStore; 465 466 public interface BatteryCallback { batteryNeedsCpuUpdate()467 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)468 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)469 public void batterySendBroadcast(Intent intent); batteryStatsReset()470 public void batteryStatsReset(); 471 } 472 473 public interface PlatformIdleStateCallback { fillLowPowerStats(RpmStats rpmStats)474 public void fillLowPowerStats(RpmStats rpmStats); getSubsystemLowPowerStats()475 public String getSubsystemLowPowerStats(); 476 } 477 478 /** interface to update rail information for power monitor */ 479 public interface EnergyStatsRetriever { 480 /** Function to fill the map for the rail data stats 481 * Used for power monitoring feature 482 * @param railStats 483 */ fillRailDataStats(RailStats railStats)484 void fillRailDataStats(RailStats railStats); 485 } 486 487 public static abstract class UserInfoProvider { 488 private int[] userIds; getUserIds()489 protected abstract @Nullable int[] getUserIds(); 490 @VisibleForTesting refreshUserIds()491 public final void refreshUserIds() { 492 userIds = getUserIds(); 493 } 494 @VisibleForTesting exists(int userId)495 public boolean exists(int userId) { 496 return userIds != null ? ArrayUtils.contains(userIds, userId) : true; 497 } 498 } 499 500 /** Provide BatteryStatsImpl configuration choices */ 501 public static class BatteryStatsConfig { 502 static final int RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG = 1 << 0; 503 static final int RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG = 1 << 1; 504 505 private final int mFlags; 506 private final Long mDefaultPowerStatsThrottlePeriod; 507 private final Map<String, Long> mPowerStatsThrottlePeriods; 508 509 @VisibleForTesting BatteryStatsConfig()510 public BatteryStatsConfig() { 511 mFlags = 0; 512 mDefaultPowerStatsThrottlePeriod = 0L; 513 mPowerStatsThrottlePeriods = Map.of(); 514 } 515 BatteryStatsConfig(Builder builder)516 private BatteryStatsConfig(Builder builder) { 517 int flags = 0; 518 if (builder.mResetOnUnplugHighBatteryLevel) { 519 flags |= RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG; 520 } 521 if (builder.mResetOnUnplugAfterSignificantCharge) { 522 flags |= RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG; 523 } 524 mFlags = flags; 525 mDefaultPowerStatsThrottlePeriod = builder.mDefaultPowerStatsThrottlePeriod; 526 mPowerStatsThrottlePeriods = builder.mPowerStatsThrottlePeriods; 527 } 528 529 /** 530 * Returns whether a BatteryStats reset should occur on unplug when the battery level is 531 * high. 532 */ shouldResetOnUnplugHighBatteryLevel()533 public boolean shouldResetOnUnplugHighBatteryLevel() { 534 return (mFlags & RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG) 535 == RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG; 536 } 537 538 /** 539 * Returns whether a BatteryStats reset should occur on unplug if the battery charge a 540 * significant amount since it has been plugged in. 541 */ shouldResetOnUnplugAfterSignificantCharge()542 public boolean shouldResetOnUnplugAfterSignificantCharge() { 543 return (mFlags & RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG) 544 == RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG; 545 } 546 547 /** 548 * Returns the minimum amount of time (in millis) to wait between passes 549 * of power stats collection for the specified power component. 550 */ getPowerStatsThrottlePeriod(String powerComponentName)551 public long getPowerStatsThrottlePeriod(String powerComponentName) { 552 return mPowerStatsThrottlePeriods.getOrDefault(powerComponentName, 553 mDefaultPowerStatsThrottlePeriod); 554 } 555 556 /** 557 * Builder for BatteryStatsConfig 558 */ 559 public static class Builder { 560 private boolean mResetOnUnplugHighBatteryLevel; 561 private boolean mResetOnUnplugAfterSignificantCharge; 562 public static final long DEFAULT_POWER_STATS_THROTTLE_PERIOD = 563 TimeUnit.HOURS.toMillis(1); 564 public static final long DEFAULT_POWER_STATS_THROTTLE_PERIOD_CPU = 565 TimeUnit.MINUTES.toMillis(1); 566 private long mDefaultPowerStatsThrottlePeriod = DEFAULT_POWER_STATS_THROTTLE_PERIOD; 567 private final Map<String, Long> mPowerStatsThrottlePeriods = new HashMap<>(); 568 Builder()569 public Builder() { 570 mResetOnUnplugHighBatteryLevel = true; 571 mResetOnUnplugAfterSignificantCharge = true; 572 setPowerStatsThrottlePeriodMillis(BatteryConsumer.powerComponentIdToString( 573 BatteryConsumer.POWER_COMPONENT_CPU), 574 DEFAULT_POWER_STATS_THROTTLE_PERIOD_CPU); 575 } 576 577 /** 578 * Build the BatteryStatsConfig. 579 */ build()580 public BatteryStatsConfig build() { 581 return new BatteryStatsConfig(this); 582 } 583 584 /** 585 * Set whether a BatteryStats reset should occur on unplug when the battery level is 586 * high. 587 */ setResetOnUnplugHighBatteryLevel(boolean reset)588 public Builder setResetOnUnplugHighBatteryLevel(boolean reset) { 589 mResetOnUnplugHighBatteryLevel = reset; 590 return this; 591 } 592 593 /** 594 * Set whether a BatteryStats reset should occur on unplug if the battery charge a 595 * significant amount since it has been plugged in. 596 */ setResetOnUnplugAfterSignificantCharge(boolean reset)597 public Builder setResetOnUnplugAfterSignificantCharge(boolean reset) { 598 mResetOnUnplugAfterSignificantCharge = reset; 599 return this; 600 } 601 602 /** 603 * Sets the minimum amount of time (in millis) to wait between passes 604 * of power stats collection for the specified power component. 605 */ setPowerStatsThrottlePeriodMillis(String powerComponentName, long periodMs)606 public Builder setPowerStatsThrottlePeriodMillis(String powerComponentName, 607 long periodMs) { 608 mPowerStatsThrottlePeriods.put(powerComponentName, periodMs); 609 return this; 610 } 611 612 /** 613 * Sets the minimum amount of time (in millis) to wait between passes 614 * of power stats collection for any components not configured explicitly. 615 */ setDefaultPowerStatsThrottlePeriodMillis(long periodMs)616 public Builder setDefaultPowerStatsThrottlePeriodMillis(long periodMs) { 617 mDefaultPowerStatsThrottlePeriod = periodMs; 618 return this; 619 } 620 } 621 } 622 623 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 624 625 private final Runnable mDeferSetCharging = new Runnable() { 626 @Override 627 public void run() { 628 synchronized (BatteryStatsImpl.this) { 629 if (mOnBattery) { 630 // if the device gets unplugged in the time between this runnable being 631 // executed and the lock being taken, we don't want to set charging state 632 return; 633 } 634 boolean changed = setChargingLocked(true); 635 if (changed) { 636 final long uptimeMs = mClock.uptimeMillis(); 637 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 638 mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs); 639 } 640 } 641 } 642 }; 643 644 public final EnergyStatsRetriever mEnergyConsumerRetriever; 645 646 /** 647 * This handler is running on {@link BackgroundThread}. 648 */ 649 final class MyHandler extends Handler { MyHandler(Looper looper)650 public MyHandler(Looper looper) { 651 super(looper, null, true); 652 } 653 654 @Override handleMessage(Message msg)655 public void handleMessage(Message msg) { 656 BatteryCallback cb = mCallback; 657 switch (msg.what) { 658 case MSG_REPORT_CPU_UPDATE_NEEDED: 659 if (cb != null) { 660 cb.batteryNeedsCpuUpdate(); 661 } 662 break; 663 case MSG_REPORT_POWER_CHANGE: 664 if (cb != null) { 665 cb.batteryPowerChanged(msg.arg1 != 0); 666 } 667 break; 668 case MSG_REPORT_CHARGING: 669 if (cb != null) { 670 final String action; 671 synchronized (BatteryStatsImpl.this) { 672 action = mCharging ? BatteryManager.ACTION_CHARGING 673 : BatteryManager.ACTION_DISCHARGING; 674 } 675 Intent intent = new Intent(action); 676 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 677 cb.batterySendBroadcast(intent); 678 } 679 break; 680 case MSG_REPORT_RESET_STATS: 681 if (cb != null) { 682 cb.batteryStatsReset(); 683 } 684 } 685 } 686 } 687 postBatteryNeedsCpuUpdateMsg()688 public void postBatteryNeedsCpuUpdateMsg() { 689 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); 690 } 691 692 /** 693 * Update per-freq cpu times for the supplied UID. 694 */ 695 @GuardedBy("this") 696 @SuppressWarnings("GuardedBy") // errorprone false positive on getProcStateTimeCounter 697 @VisibleForTesting updateProcStateCpuTimesLocked(int uid, long elapsedRealtimeMs, long uptimeMs)698 public void updateProcStateCpuTimesLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 699 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 700 return; 701 } 702 703 ensureKernelSingleUidTimeReaderLocked(); 704 705 final Uid u = getUidStatsLocked(uid); 706 707 mNumSingleUidCpuTimeReads++; 708 709 LongArrayMultiStateCounter onBatteryCounter = 710 u.getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 711 LongArrayMultiStateCounter onBatteryScreenOffCounter = 712 u.getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 713 714 715 mKernelSingleUidTimeReader.addDelta(uid, onBatteryCounter, elapsedRealtimeMs); 716 mKernelSingleUidTimeReader.addDelta(uid, onBatteryScreenOffCounter, elapsedRealtimeMs); 717 718 if (u.mChildUids != null) { 719 LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 720 getCpuTimeInFreqContainer(); 721 int childUidCount = u.mChildUids.size(); 722 for (int j = childUidCount - 1; j >= 0; --j) { 723 LongArrayMultiStateCounter cpuTimeInFreqCounter = 724 u.mChildUids.valueAt(j).cpuTimeInFreqCounter; 725 if (cpuTimeInFreqCounter != null) { 726 mKernelSingleUidTimeReader.addDelta(u.mChildUids.keyAt(j), 727 cpuTimeInFreqCounter, elapsedRealtimeMs, deltaContainer); 728 onBatteryCounter.addCounts(deltaContainer); 729 onBatteryScreenOffCounter.addCounts(deltaContainer); 730 } 731 } 732 } 733 } 734 735 /** 736 * Removes kernel CPU stats for removed UIDs, in the order they were added to the 737 * mPendingRemovedUids queue. 738 */ 739 @GuardedBy("this") 740 @SuppressWarnings("GuardedBy") // errorprone false positive on removeLocked clearPendingRemovedUidsLocked()741 public void clearPendingRemovedUidsLocked() { 742 long cutOffTimeMs = mClock.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; 743 while (!mPendingRemovedUids.isEmpty() 744 && mPendingRemovedUids.peek().getUidRemovalTimestamp() < cutOffTimeMs) { 745 mPendingRemovedUids.poll().removeLocked(); 746 } 747 } 748 749 /** 750 * When the battery/screen state changes, we don't attribute the cpu times to any process 751 * but we still need to take snapshots of all uids to get correct deltas later on. 752 */ 753 @SuppressWarnings("GuardedBy") // errorprone false positive on getProcStateTimeCounter updateCpuTimesForAllUids()754 public void updateCpuTimesForAllUids() { 755 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 756 mCpuPowerStatsCollector.schedule(); 757 return; 758 } 759 760 synchronized (BatteryStatsImpl.this) { 761 if (!trackPerProcStateCpuTimes()) { 762 return; 763 } 764 765 ensureKernelSingleUidTimeReaderLocked(); 766 767 // TODO(b/197162116): just get a list of UIDs 768 final SparseArray<long[]> allUidCpuFreqTimesMs = 769 mCpuUidFreqTimeReader.getAllUidCpuFreqTimeMs(); 770 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) { 771 final int uid = allUidCpuFreqTimesMs.keyAt(i); 772 final int parentUid = mapUid(uid); 773 final Uid u = getAvailableUidStatsLocked(parentUid); 774 if (u == null) { 775 continue; 776 } 777 778 final int procState = u.mProcessState; 779 if (procState == Uid.PROCESS_STATE_NONEXISTENT) { 780 continue; 781 } 782 783 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 784 final long uptimeMs = mClock.uptimeMillis(); 785 final LongArrayMultiStateCounter onBatteryCounter = 786 u.getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 787 final LongArrayMultiStateCounter onBatteryScreenOffCounter = 788 u.getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 789 790 if (uid == parentUid || Process.isSdkSandboxUid(uid)) { 791 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryCounter, 792 elapsedRealtimeMs); 793 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryScreenOffCounter, 794 elapsedRealtimeMs); 795 } else { 796 Uid.ChildUid childUid = u.getChildUid(uid); 797 if (childUid != null) { 798 final LongArrayMultiStateCounter counter = childUid.cpuTimeInFreqCounter; 799 if (counter != null) { 800 final LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 801 getCpuTimeInFreqContainer(); 802 mKernelSingleUidTimeReader.addDelta(uid, counter, elapsedRealtimeMs, 803 deltaContainer); 804 onBatteryCounter.addCounts(deltaContainer); 805 onBatteryScreenOffCounter.addCounts(deltaContainer); 806 } 807 } 808 } 809 } 810 } 811 } 812 813 @GuardedBy("this") ensureKernelSingleUidTimeReaderLocked()814 private void ensureKernelSingleUidTimeReaderLocked() { 815 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU) 816 || mKernelSingleUidTimeReader != null) { 817 return; 818 } 819 820 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader( 821 mCpuScalingPolicies.getScalingStepCount()); 822 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.perClusterTimesAvailable() 823 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable(); 824 } 825 826 public interface ExternalStatsSync { 827 int UPDATE_CPU = 0x01; 828 int UPDATE_WIFI = 0x02; 829 int UPDATE_RADIO = 0x04; 830 int UPDATE_BT = 0x08; 831 int UPDATE_RPM = 0x10; 832 int UPDATE_DISPLAY = 0x20; 833 int UPDATE_CAMERA = 0x40; 834 int RESET = 0x80; 835 836 int UPDATE_ALL = 837 UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM | UPDATE_DISPLAY 838 | UPDATE_CAMERA; 839 840 int UPDATE_ON_PROC_STATE_CHANGE = UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT; 841 842 int UPDATE_ON_RESET = UPDATE_ALL | RESET; 843 844 @IntDef(flag = true, prefix = "UPDATE_", value = { 845 UPDATE_CPU, 846 UPDATE_WIFI, 847 UPDATE_RADIO, 848 UPDATE_BT, 849 UPDATE_RPM, 850 UPDATE_DISPLAY, 851 UPDATE_CAMERA, 852 UPDATE_ALL, 853 }) 854 @Retention(RetentionPolicy.SOURCE) 855 public @interface ExternalUpdateFlag { 856 } 857 scheduleSync(String reason, int flags)858 Future<?> scheduleSync(String reason, int flags); scheduleCpuSyncDueToRemovedUid(int uid)859 Future<?> scheduleCpuSyncDueToRemovedUid(int uid); 860 861 /** 862 * Schedule a sync because of a screen state change. 863 */ scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates)864 Future<?> scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, 865 boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates); scheduleCpuSyncDueToWakelockChange(long delayMillis)866 Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); cancelCpuSyncDueToWakelockChange()867 void cancelCpuSyncDueToWakelockChange(); scheduleSyncDueToBatteryLevelChange(long delayMillis)868 Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); 869 /** Schedule removal of UIDs corresponding to a removed user */ scheduleCleanupDueToRemovedUser(int userId)870 Future<?> scheduleCleanupDueToRemovedUser(int userId); 871 /** Schedule a sync because of a process state change */ scheduleSyncDueToProcessStateChange(int flags, long delayMillis)872 void scheduleSyncDueToProcessStateChange(int flags, long delayMillis); 873 } 874 875 public Handler mHandler; 876 private ExternalStatsSync mExternalSync = null; 877 @VisibleForTesting 878 protected UserInfoProvider mUserInfoProvider = null; 879 880 private BatteryCallback mCallback; 881 882 /** 883 * Mapping child uids to their parent uid. 884 */ 885 @VisibleForTesting 886 protected final PowerStatsUidResolver mPowerStatsUidResolver; 887 888 /** 889 * The statistics we have collected organized by uids. 890 */ 891 private final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 892 893 // A set of pools of currently active timers. When a timer is queried, we will divide the 894 // elapsed time by the number of active timers to arrive at that timer's share of the time. 895 // In order to do this, we must refresh each timer whenever the number of active timers 896 // changes. 897 @VisibleForTesting 898 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 899 private final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 900 private final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 901 private final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 902 private final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 903 private final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 904 private final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 905 private final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 906 private final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 907 private final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = 908 new SparseArray<>(); 909 private final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 910 private final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 911 private final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 912 private final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 913 private final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 914 915 // Last partial timers we use for distributing CPU usage. 916 @VisibleForTesting 917 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 918 919 // These are the objects that will want to do something when the device 920 // is unplugged from power. 921 protected final TimeBase mOnBatteryTimeBase = new TimeBase(true); 922 923 // These are the objects that will want to do something when the device 924 // is unplugged from power *and* the screen is off or doze. 925 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true); 926 927 private boolean mSystemReady; 928 private boolean mShuttingDown; 929 930 private final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 931 private final HistoryStepDetailsCalculatorImpl mStepDetailsCalculator = 932 new HistoryStepDetailsCalculatorImpl(); 933 934 private boolean mHaveBatteryLevel = false; 935 private boolean mBatteryPluggedIn; 936 private long mBatteryPluggedInRealTimeMs = 0; 937 private int mBatteryStatus; 938 private int mBatteryLevel; 939 private int mBatteryPlugType; 940 private int mBatteryChargeUah; 941 private int mBatteryHealth; 942 private int mBatteryTemperature; 943 private int mBatteryVoltageMv; 944 945 @NonNull 946 private final BatteryStatsHistory mHistory; 947 948 int mStartCount; 949 950 /** 951 * Set to true when a reset occurs, informing us that the next time BatteryExternalStatsWorker 952 * gives us data, we mustn't process it since this data includes pre-reset-period data. 953 */ 954 @GuardedBy("this") 955 boolean mIgnoreNextExternalStats = false; 956 957 long mStartClockTimeMs; 958 String mStartPlatformVersion; 959 String mEndPlatformVersion; 960 961 long mUptimeUs; 962 long mUptimeStartUs; 963 long mRealtimeUs; 964 long mRealtimeStartUs; 965 long mMonotonicStartTime; 966 long mMonotonicEndTime = MonotonicClock.UNDEFINED; 967 968 int mWakeLockNesting; 969 boolean mWakeLockImportant; 970 public boolean mRecordAllHistory; 971 boolean mNoAutoReset; 972 973 /** 974 * Overall screen state. For multidisplay devices, this represents the current highest screen 975 * state of the displays. 976 */ 977 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 978 protected int mScreenState = Display.STATE_UNKNOWN; 979 /** 980 * Overall screen on timer. For multidisplay devices, this represents the time spent with at 981 * least one display in the screen on state. 982 */ 983 StopwatchTimer mScreenOnTimer; 984 /** 985 * Overall screen doze timer. For multidisplay devices, this represents the time spent with 986 * screen doze being the highest screen state. 987 */ 988 StopwatchTimer mScreenDozeTimer; 989 /** 990 * Overall screen brightness bin. For multidisplay devices, this represents the current 991 * brightest screen. 992 */ 993 int mScreenBrightnessBin = -1; 994 /** 995 * Overall screen brightness timers. For multidisplay devices, the {@link mScreenBrightnessBin} 996 * timer will be active at any given time 997 */ 998 final StopwatchTimer[] mScreenBrightnessTimer = 999 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 1000 1001 boolean mPretendScreenOff; 1002 1003 private static class DisplayBatteryStats { 1004 /** 1005 * Per display screen state. 1006 */ 1007 public int screenState = Display.STATE_UNKNOWN; 1008 /** 1009 * Per display screen on timers. 1010 */ 1011 public StopwatchTimer screenOnTimer; 1012 /** 1013 * Per display screen doze timers. 1014 */ 1015 public StopwatchTimer screenDozeTimer; 1016 /** 1017 * Per display screen brightness bins. 1018 */ 1019 public int screenBrightnessBin = -1; 1020 /** 1021 * Per display screen brightness timers. 1022 */ 1023 public StopwatchTimer[] screenBrightnessTimers = 1024 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 1025 /** 1026 * Per display screen state the last time {@link #updateDisplayEnergyConsumerStatsLocked} 1027 * was called. 1028 */ 1029 public int screenStateAtLastEnergyMeasurement = Display.STATE_UNKNOWN; 1030 DisplayBatteryStats(Clock clock, TimeBase timeBase)1031 DisplayBatteryStats(Clock clock, TimeBase timeBase) { 1032 screenOnTimer = new StopwatchTimer(clock, null, -1, null, 1033 timeBase); 1034 screenDozeTimer = new StopwatchTimer(clock, null, -1, null, 1035 timeBase); 1036 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1037 screenBrightnessTimers[i] = new StopwatchTimer(clock, null, -100 - i, null, 1038 timeBase); 1039 } 1040 } 1041 1042 /** 1043 * Reset display timers. 1044 */ reset(long elapsedRealtimeUs)1045 public void reset(long elapsedRealtimeUs) { 1046 screenOnTimer.reset(false, elapsedRealtimeUs); 1047 screenDozeTimer.reset(false, elapsedRealtimeUs); 1048 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1049 screenBrightnessTimers[i].reset(false, elapsedRealtimeUs); 1050 } 1051 } 1052 1053 /** 1054 * Write data to summary parcel 1055 */ writeSummaryToParcel(Parcel out, long elapsedRealtimeUs)1056 public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { 1057 screenOnTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1058 screenDozeTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1059 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1060 screenBrightnessTimers[i].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1061 } 1062 } 1063 1064 /** 1065 * Read data from summary parcel 1066 */ readSummaryFromParcel(Parcel in)1067 public void readSummaryFromParcel(Parcel in) { 1068 screenOnTimer.readSummaryFromParcelLocked(in); 1069 screenDozeTimer.readSummaryFromParcelLocked(in); 1070 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1071 screenBrightnessTimers[i].readSummaryFromParcelLocked(in); 1072 } 1073 } 1074 } 1075 1076 DisplayBatteryStats[] mPerDisplayBatteryStats; 1077 1078 private int mDisplayMismatchWtfCount = 0; 1079 1080 boolean mInteractive; 1081 StopwatchTimer mInteractiveTimer; 1082 1083 boolean mPowerSaveModeEnabled; 1084 StopwatchTimer mPowerSaveModeEnabledTimer; 1085 1086 boolean mDeviceIdling; 1087 StopwatchTimer mDeviceIdlingTimer; 1088 1089 boolean mDeviceLightIdling; 1090 StopwatchTimer mDeviceLightIdlingTimer; 1091 1092 int mDeviceIdleMode; 1093 long mLastIdleTimeStartMs; 1094 long mLongestLightIdleTimeMs; 1095 long mLongestFullIdleTimeMs; 1096 StopwatchTimer mDeviceIdleModeLightTimer; 1097 StopwatchTimer mDeviceIdleModeFullTimer; 1098 1099 boolean mPhoneOn; 1100 StopwatchTimer mPhoneOnTimer; 1101 1102 int mAudioOnNesting; 1103 StopwatchTimer mAudioOnTimer; 1104 1105 int mVideoOnNesting; 1106 StopwatchTimer mVideoOnTimer; 1107 1108 int mFlashlightOnNesting; 1109 StopwatchTimer mFlashlightOnTimer; 1110 1111 int mCameraOnNesting; 1112 StopwatchTimer mCameraOnTimer; 1113 1114 private static final int USB_DATA_UNKNOWN = 0; 1115 private static final int USB_DATA_DISCONNECTED = 1; 1116 private static final int USB_DATA_CONNECTED = 2; 1117 int mUsbDataState = USB_DATA_UNKNOWN; 1118 1119 private static final int GPS_SIGNAL_QUALITY_NONE = 2; 1120 int mGpsSignalQualityBin = -1; 1121 final StopwatchTimer[] mGpsSignalQualityTimer = 1122 new StopwatchTimer[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS]; 1123 1124 int mPhoneSignalStrengthBin = -1; 1125 int mPhoneSignalStrengthBinRaw = -1; 1126 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 1127 new StopwatchTimer[CELL_SIGNAL_STRENGTH_LEVEL_COUNT]; 1128 1129 StopwatchTimer mPhoneSignalScanningTimer; 1130 1131 int mPhoneDataConnectionType = -1; 1132 final StopwatchTimer[] mPhoneDataConnectionsTimer = 1133 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 1134 1135 int mNrState = -1; 1136 StopwatchTimer mNrNsaTimer; 1137 1138 @RadioAccessTechnology 1139 int mActiveRat = RADIO_ACCESS_TECHNOLOGY_OTHER; 1140 1141 private static class RadioAccessTechnologyBatteryStats { 1142 /** 1143 * This RAT is currently being used. 1144 */ 1145 private boolean mActive = false; 1146 /** 1147 * Current active frequency range for this RAT. 1148 */ 1149 @ServiceState.FrequencyRange 1150 private int mFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN; 1151 /** 1152 * Current signal strength for this RAT. 1153 */ 1154 private int mSignalStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1155 /** 1156 * Timers for each combination of frequency range and signal strength. 1157 */ 1158 public final StopwatchTimer[][] perStateTimers; 1159 /** 1160 * Counters tracking the time (in milliseconds) spent transmitting data in a given state. 1161 */ 1162 @Nullable 1163 private LongSamplingCounter[][] mPerStateTxDurationMs = null; 1164 /** 1165 * Counters tracking the time (in milliseconds) spent receiving data in at given frequency. 1166 */ 1167 @Nullable 1168 private LongSamplingCounter[] mPerFrequencyRxDurationMs = null; 1169 RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase)1170 RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase) { 1171 perStateTimers = 1172 new StopwatchTimer[freqCount][CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 1173 for (int i = 0; i < freqCount; i++) { 1174 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1175 perStateTimers[i][j] = new StopwatchTimer(clock, null, -1, null, timeBase); 1176 } 1177 } 1178 } 1179 1180 /** 1181 * Note this RAT is currently being used. 1182 */ noteActive(boolean active, long elapsedRealtimeMs)1183 public void noteActive(boolean active, long elapsedRealtimeMs) { 1184 if (mActive == active) return; 1185 mActive = active; 1186 if (mActive) { 1187 perStateTimers[mFrequencyRange][mSignalStrength].startRunningLocked( 1188 elapsedRealtimeMs); 1189 } else { 1190 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked( 1191 elapsedRealtimeMs); 1192 } 1193 } 1194 1195 /** 1196 * Note current frequency range has changed. 1197 */ noteFrequencyRange(@erviceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs)1198 public void noteFrequencyRange(@ServiceState.FrequencyRange int frequencyRange, 1199 long elapsedRealtimeMs) { 1200 if (mFrequencyRange == frequencyRange) return; 1201 1202 if (!mActive) { 1203 // RAT not in use, note the frequency change and move on. 1204 mFrequencyRange = frequencyRange; 1205 return; 1206 } 1207 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked(elapsedRealtimeMs); 1208 perStateTimers[frequencyRange][mSignalStrength].startRunningLocked(elapsedRealtimeMs); 1209 mFrequencyRange = frequencyRange; 1210 } 1211 1212 /** 1213 * Note current signal strength has changed. 1214 */ noteSignalStrength(int signalStrength, long elapsedRealtimeMs)1215 public void noteSignalStrength(int signalStrength, long elapsedRealtimeMs) { 1216 if (mSignalStrength == signalStrength) return; 1217 1218 if (!mActive) { 1219 // RAT not in use, note the signal strength change and move on. 1220 mSignalStrength = signalStrength; 1221 return; 1222 } 1223 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked(elapsedRealtimeMs); 1224 perStateTimers[mFrequencyRange][signalStrength].startRunningLocked(elapsedRealtimeMs); 1225 mSignalStrength = signalStrength; 1226 } 1227 1228 /** 1229 * Returns the duration in milliseconds spent in a given state since the last mark. 1230 */ getTimeSinceMark(@erviceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)1231 public long getTimeSinceMark(@ServiceState.FrequencyRange int frequencyRange, 1232 int signalStrength, long elapsedRealtimeMs) { 1233 return perStateTimers[frequencyRange][signalStrength].getTimeSinceMarkLocked( 1234 elapsedRealtimeMs * 1000) / 1000; 1235 } 1236 1237 /** 1238 * Set mark for all timers. 1239 */ setMark(long elapsedRealtimeMs)1240 public void setMark(long elapsedRealtimeMs) { 1241 final int size = perStateTimers.length; 1242 for (int i = 0; i < size; i++) { 1243 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1244 perStateTimers[i][j].setMark(elapsedRealtimeMs); 1245 } 1246 } 1247 } 1248 1249 /** 1250 * Returns numbers of frequencies tracked for this RAT. 1251 */ getFrequencyRangeCount()1252 public int getFrequencyRangeCount() { 1253 return perStateTimers.length; 1254 } 1255 1256 /** 1257 * Add TX time for a given state. 1258 */ incrementTxDuration(@erviceState.FrequencyRange int frequencyRange, int signalStrength, long durationMs)1259 public void incrementTxDuration(@ServiceState.FrequencyRange int frequencyRange, 1260 int signalStrength, long durationMs) { 1261 getTxDurationCounter(frequencyRange, signalStrength, true).addCountLocked(durationMs); 1262 } 1263 1264 /** 1265 * Add TX time for a given frequency. 1266 */ incrementRxDuration(@erviceState.FrequencyRange int frequencyRange, long durationMs)1267 public void incrementRxDuration(@ServiceState.FrequencyRange int frequencyRange, 1268 long durationMs) { 1269 getRxDurationCounter(frequencyRange, true).addCountLocked(durationMs); 1270 } 1271 1272 /** 1273 * Reset radio access technology timers and counts. 1274 */ reset(long elapsedRealtimeUs)1275 public void reset(long elapsedRealtimeUs) { 1276 final int size = perStateTimers.length; 1277 for (int i = 0; i < size; i++) { 1278 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1279 perStateTimers[i][j].reset(false, elapsedRealtimeUs); 1280 if (mPerStateTxDurationMs == null) continue; 1281 mPerStateTxDurationMs[i][j].reset(false, elapsedRealtimeUs); 1282 } 1283 if (mPerFrequencyRxDurationMs == null) continue; 1284 mPerFrequencyRxDurationMs[i].reset(false, elapsedRealtimeUs); 1285 } 1286 } 1287 1288 /** 1289 * Write data to summary parcel 1290 */ writeSummaryToParcel(Parcel out, long elapsedRealtimeUs)1291 public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { 1292 final int freqCount = perStateTimers.length; 1293 out.writeInt(freqCount); 1294 out.writeInt(CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS); 1295 for (int i = 0; i < freqCount; i++) { 1296 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1297 perStateTimers[i][j].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1298 } 1299 } 1300 1301 if (mPerStateTxDurationMs == null) { 1302 out.writeInt(0); 1303 } else { 1304 out.writeInt(1); 1305 for (int i = 0; i < freqCount; i++) { 1306 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1307 mPerStateTxDurationMs[i][j].writeSummaryFromParcelLocked(out); 1308 } 1309 } 1310 } 1311 1312 if (mPerFrequencyRxDurationMs == null) { 1313 out.writeInt(0); 1314 } else { 1315 out.writeInt(1); 1316 for (int i = 0; i < freqCount; i++) { 1317 mPerFrequencyRxDurationMs[i].writeSummaryFromParcelLocked(out); 1318 } 1319 } 1320 } 1321 1322 /** 1323 * Read data from summary parcel 1324 */ readSummaryFromParcel(Parcel in)1325 public void readSummaryFromParcel(Parcel in) { 1326 final int oldFreqCount = in.readInt(); 1327 final int oldSignalStrengthCount = in.readInt(); 1328 final int currFreqCount = perStateTimers.length; 1329 final int currSignalStrengthCount = CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; 1330 1331 for (int freq = 0; freq < oldFreqCount; freq++) { 1332 for (int strength = 0; strength < oldSignalStrengthCount; strength++) { 1333 if (freq >= currFreqCount || strength >= currSignalStrengthCount) { 1334 // Mismatch with the summary parcel. Consume the data but don't use it. 1335 final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, 1336 new TimeBase()); 1337 // Consume perStateTimers data. 1338 temp.readSummaryFromParcelLocked(in); 1339 } else { 1340 perStateTimers[freq][strength].readSummaryFromParcelLocked(in); 1341 } 1342 } 1343 } 1344 1345 if (in.readInt() == 1) { 1346 for (int freq = 0; freq < oldFreqCount; freq++) { 1347 for (int strength = 0; strength < oldSignalStrengthCount; strength++) { 1348 if (freq >= currFreqCount || strength >= currSignalStrengthCount) { 1349 // Mismatch with the summary parcel. Consume the data but don't use it. 1350 final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, 1351 new TimeBase()); 1352 // Consume mPerStateTxDurationMs data. 1353 temp.readSummaryFromParcelLocked(in); 1354 } 1355 getTxDurationCounter(freq, strength, true).readSummaryFromParcelLocked(in); 1356 } 1357 } 1358 } 1359 1360 if (in.readInt() == 1) { 1361 for (int freq = 0; freq < oldFreqCount; freq++) { 1362 if (freq >= currFreqCount) { 1363 // Mismatch with the summary parcel. Consume the data but don't use it. 1364 final StopwatchTimer 1365 temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); 1366 // Consume mPerFrequencyRxDurationMs data. 1367 temp.readSummaryFromParcelLocked(in); 1368 continue; 1369 } 1370 getRxDurationCounter(freq, true).readSummaryFromParcelLocked(in); 1371 } 1372 } 1373 } 1374 getTxDurationCounter( @erviceState.FrequencyRange int frequencyRange, int signalStrength, boolean make)1375 private LongSamplingCounter getTxDurationCounter( 1376 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, boolean make) { 1377 if (mPerStateTxDurationMs == null) { 1378 if (!make) return null; 1379 1380 final int freqCount = getFrequencyRangeCount(); 1381 final int signalStrengthCount = perStateTimers[0].length; 1382 final TimeBase timeBase = perStateTimers[0][0].mTimeBase; 1383 mPerStateTxDurationMs = new LongSamplingCounter[freqCount][signalStrengthCount]; 1384 for (int freq = 0; freq < freqCount; freq++) { 1385 for (int strength = 0; strength < signalStrengthCount; strength++) { 1386 mPerStateTxDurationMs[freq][strength] = new LongSamplingCounter(timeBase); 1387 } 1388 } 1389 } 1390 if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { 1391 Slog.w(TAG, "Unexpected frequency range (" + frequencyRange 1392 + ") requested in getTxDurationCounter"); 1393 return null; 1394 } 1395 if (signalStrength < 0 || signalStrength >= perStateTimers[0].length) { 1396 Slog.w(TAG, "Unexpected signal strength (" + signalStrength 1397 + ") requested in getTxDurationCounter"); 1398 return null; 1399 } 1400 return mPerStateTxDurationMs[frequencyRange][signalStrength]; 1401 } 1402 getRxDurationCounter( @erviceState.FrequencyRange int frequencyRange, boolean make)1403 private LongSamplingCounter getRxDurationCounter( 1404 @ServiceState.FrequencyRange int frequencyRange, boolean make) { 1405 if (mPerFrequencyRxDurationMs == null) { 1406 if (!make) return null; 1407 1408 final int freqCount = getFrequencyRangeCount(); 1409 final TimeBase timeBase = perStateTimers[0][0].mTimeBase; 1410 mPerFrequencyRxDurationMs = new LongSamplingCounter[freqCount]; 1411 for (int freq = 0; freq < freqCount; freq++) { 1412 mPerFrequencyRxDurationMs[freq] = new LongSamplingCounter(timeBase); 1413 } 1414 } 1415 if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { 1416 Slog.w(TAG, "Unexpected frequency range (" + frequencyRange 1417 + ") requested in getRxDurationCounter"); 1418 return null; 1419 } 1420 return mPerFrequencyRxDurationMs[frequencyRange]; 1421 } 1422 } 1423 1424 /** 1425 * Number of frequency ranges, keep in sync with {@link ServiceState.FrequencyRange} 1426 */ 1427 private static final int NR_FREQUENCY_COUNT = 5; 1428 1429 RadioAccessTechnologyBatteryStats[] mPerRatBatteryStats = 1430 new RadioAccessTechnologyBatteryStats[RADIO_ACCESS_TECHNOLOGY_COUNT]; 1431 1432 @GuardedBy("this") getRatBatteryStatsLocked( @adioAccessTechnology int rat)1433 private RadioAccessTechnologyBatteryStats getRatBatteryStatsLocked( 1434 @RadioAccessTechnology int rat) { 1435 RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 1436 if (stats == null) { 1437 final int freqCount = rat == RADIO_ACCESS_TECHNOLOGY_NR ? NR_FREQUENCY_COUNT : 1; 1438 stats = new RadioAccessTechnologyBatteryStats(freqCount, mClock, mOnBatteryTimeBase); 1439 mPerRatBatteryStats[rat] = stats; 1440 } 1441 return stats; 1442 } 1443 1444 final LongSamplingCounter[] mNetworkByteActivityCounters = 1445 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 1446 1447 final LongSamplingCounter[] mNetworkPacketActivityCounters = 1448 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 1449 1450 /** 1451 * The WiFi Overall wakelock timer 1452 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 1453 * since addition of per UID timers would not result in an accurate value due to overlapp of 1454 * per uid wakelock timers 1455 */ 1456 StopwatchTimer mWifiMulticastWakelockTimer; 1457 1458 /** 1459 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 1460 */ 1461 ControllerActivityCounterImpl mWifiActivity; 1462 1463 /** 1464 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 1465 */ 1466 ControllerActivityCounterImpl mBluetoothActivity; 1467 1468 /** 1469 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 1470 */ 1471 ControllerActivityCounterImpl mModemActivity; 1472 1473 /** 1474 * Whether the device supports WiFi controller energy reporting. This is set to true on 1475 * the first WiFi energy report. See {@link #mWifiActivity}. 1476 */ 1477 boolean mHasWifiReporting = false; 1478 1479 /** 1480 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 1481 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 1482 */ 1483 boolean mHasBluetoothReporting = false; 1484 1485 /** 1486 * Whether the device supports Modem controller energy reporting. This is set to true on 1487 * the first Modem energy report. See {@link #mModemActivity}. 1488 */ 1489 boolean mHasModemReporting = false; 1490 1491 boolean mWifiOn; 1492 StopwatchTimer mWifiOnTimer; 1493 1494 boolean mGlobalWifiRunning; 1495 StopwatchTimer mGlobalWifiRunningTimer; 1496 1497 int mWifiState = -1; 1498 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 1499 1500 int mWifiSupplState = -1; 1501 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 1502 1503 int mWifiSignalStrengthBin = -1; 1504 final StopwatchTimer[] mWifiSignalStrengthsTimer = 1505 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 1506 1507 StopwatchTimer mWifiActiveTimer; 1508 1509 int mBluetoothScanNesting; 1510 StopwatchTimer mBluetoothScanTimer; 1511 1512 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1513 long mMobileRadioActiveStartTimeMs; 1514 StopwatchTimer mMobileRadioActiveTimer; 1515 StopwatchTimer mMobileRadioActivePerAppTimer; 1516 LongSamplingCounter mMobileRadioActiveAdjustedTime; 1517 LongSamplingCounter mMobileRadioActiveUnknownTime; 1518 LongSamplingCounter mMobileRadioActiveUnknownCount; 1519 1520 /** 1521 * The soonest the Mobile Radio stats can be updated due to a mobile radio power state change 1522 * after it was last updated. 1523 */ 1524 @VisibleForTesting 1525 protected static final long MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS = 1000 * 60 * 10; 1526 1527 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1528 1529 @GuardedBy("this") 1530 @VisibleForTesting 1531 protected @Nullable EnergyConsumerStats.Config mEnergyConsumerStatsConfig; 1532 1533 /** 1534 * Accumulated global (generally, device-wide total) charge consumption of various consumers 1535 * while on battery. 1536 * Its '<b>custom</b> power buckets' correspond to the 1537 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 1538 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 1539 * 1540 * If energy consumer data is completely unavailable this will be null. 1541 */ 1542 @GuardedBy("this") 1543 @VisibleForTesting 1544 @Nullable 1545 protected EnergyConsumerStats mGlobalEnergyConsumerStats; 1546 /** Bluetooth Power calculator for attributing bluetooth EnergyConsumer to uids */ 1547 @Nullable BluetoothPowerCalculator mBluetoothPowerCalculator = null; 1548 /** Cpu Power calculator for attributing cpu EnergyConsumer to uids */ 1549 @Nullable CpuPowerCalculator mCpuPowerCalculator = null; 1550 /** Mobile Radio Power calculator for attributing radio EnergyConsumer to uids */ 1551 @Nullable MobileRadioPowerCalculator mMobileRadioPowerCalculator = null; 1552 /** Wifi Power calculator for attributing wifi EnergyConsumer to uids */ 1553 @Nullable WifiPowerCalculator mWifiPowerCalculator = null; 1554 1555 /** 1556 * These provide time bases that discount the time the device is plugged 1557 * in to power. 1558 */ 1559 boolean mOnBattery; 1560 @VisibleForTesting 1561 protected boolean mOnBatteryInternal; 1562 1563 /** 1564 * External reporting of whether the device is actually charging. 1565 */ 1566 boolean mCharging = true; 1567 1568 /* 1569 * These keep track of battery levels (1-100) at the last unplug event. 1570 */ 1571 int mDischargeUnplugLevel; 1572 int mDischargePlugLevel; 1573 int mDischargeCurrentLevel; 1574 int mLowDischargeAmountSinceCharge; 1575 int mHighDischargeAmountSinceCharge; 1576 int mDischargeScreenOnUnplugLevel; 1577 int mDischargeScreenOffUnplugLevel; 1578 int mDischargeScreenDozeUnplugLevel; 1579 int mDischargeAmountScreenOn; 1580 int mDischargeAmountScreenOnSinceCharge; 1581 int mDischargeAmountScreenOff; 1582 int mDischargeAmountScreenOffSinceCharge; 1583 int mDischargeAmountScreenDoze; 1584 int mDischargeAmountScreenDozeSinceCharge; 1585 1586 private LongSamplingCounter mDischargeScreenOffCounter; 1587 private LongSamplingCounter mDischargeScreenDozeCounter; 1588 private LongSamplingCounter mDischargeCounter; 1589 private LongSamplingCounter mDischargeLightDozeCounter; 1590 private LongSamplingCounter mDischargeDeepDozeCounter; 1591 1592 static final int MAX_LEVEL_STEPS = 200; 1593 1594 int mInitStepMode = 0; 1595 int mCurStepMode = 0; 1596 int mModStepMode = 0; 1597 1598 int mLastDischargeStepLevel; 1599 int mMinDischargeStepLevel; 1600 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1601 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1602 ArrayList<PackageChange> mDailyPackageChanges; 1603 1604 int mLastChargeStepLevel; 1605 int mMaxChargeStepLevel; 1606 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1607 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1608 1609 static final int MAX_DAILY_ITEMS = 10; 1610 1611 long mDailyStartTimeMs = 0; 1612 long mNextMinDailyDeadlineMs = 0; 1613 long mNextMaxDailyDeadlineMs = 0; 1614 1615 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 1616 1617 long mLastWriteTimeMs = 0; // Milliseconds 1618 1619 private int mPhoneServiceState = -1; 1620 private int mPhoneServiceStateRaw = -1; 1621 private int mPhoneSimStateRaw = -1; 1622 1623 private int mNumConnectivityChange; 1624 1625 private int mEstimatedBatteryCapacityMah = -1; 1626 1627 private int mLastLearnedBatteryCapacityUah = -1; 1628 private int mMinLearnedBatteryCapacityUah = -1; 1629 private int mMaxLearnedBatteryCapacityUah = -1; 1630 1631 private long mBatteryTimeToFullSeconds = -1; 1632 1633 private LongArrayMultiStateCounter.LongArrayContainer mTmpCpuTimeInFreq; 1634 1635 /** 1636 * Times spent by the system server threads handling incoming binder requests. 1637 */ 1638 private LongSamplingCounterArray mBinderThreadCpuTimesUs; 1639 1640 @VisibleForTesting 1641 protected PowerProfile mPowerProfile; 1642 1643 @VisibleForTesting 1644 @GuardedBy("this") 1645 protected final Constants mConstants; 1646 1647 @VisibleForTesting 1648 protected final BatteryStatsConfig mBatteryStatsConfig; 1649 1650 @GuardedBy("this") 1651 private AlarmManager mAlarmManager = null; 1652 1653 private final AlarmManager.OnAlarmListener mLongPlugInAlarmHandler = () -> 1654 mHandler.post(() -> { 1655 synchronized (BatteryStatsImpl.this) { 1656 maybeResetWhilePluggedInLocked(); 1657 } 1658 }); 1659 1660 /* 1661 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 1662 * recording their times when on-battery (regardless of screen state). 1663 */ 1664 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 1665 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 1666 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 1667 1668 @Override getRpmStats()1669 public Map<String, ? extends Timer> getRpmStats() { 1670 return mRpmStats; 1671 } 1672 1673 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 1674 @Override getScreenOffRpmStats()1675 public Map<String, ? extends Timer> getScreenOffRpmStats() { 1676 return mScreenOffRpmStats; 1677 } 1678 1679 /* 1680 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 1681 */ 1682 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 1683 getKernelWakelockStats()1684 public Map<String, ? extends Timer> getKernelWakelockStats() { 1685 return mKernelWakelockStats; 1686 } 1687 1688 @Override getWakeLockStats()1689 public WakeLockStats getWakeLockStats() { 1690 final long realtimeMs = mClock.elapsedRealtime(); 1691 List<WakeLockStats.WakeLock> uidWakeLockStats = new ArrayList<>(); 1692 List<WakeLockStats.WakeLock> uidAggregatedWakeLockStats = new ArrayList<>(); 1693 for (int i = mUidStats.size() - 1; i >= 0; i--) { 1694 final Uid uid = mUidStats.valueAt(i); 1695 1696 // Converts unaggregated wakelocks. 1697 final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = 1698 uid.mWakelockStats.getMap(); 1699 for (int j = wakelockStats.size() - 1; j >= 0; j--) { 1700 final String name = wakelockStats.keyAt(j); 1701 final Uid.Wakelock wakelock = (Uid.Wakelock) wakelockStats.valueAt(j); 1702 final WakeLockStats.WakeLock wakeLockItem = 1703 createWakeLock(uid, name, /* isAggregated= */ false, wakelock.mTimerPartial, 1704 realtimeMs); 1705 if (wakeLockItem != null) { 1706 uidWakeLockStats.add(wakeLockItem); 1707 } 1708 } 1709 1710 // Converts aggregated wakelocks. 1711 final WakeLockStats.WakeLock aggregatedWakeLockItem = 1712 createWakeLock( 1713 uid, 1714 WakeLockStats.WakeLock.NAME_AGGREGATED, 1715 /* isAggregated= */ true, 1716 uid.mAggregatedPartialWakelockTimer, 1717 realtimeMs); 1718 if (aggregatedWakeLockItem != null) { 1719 uidAggregatedWakeLockStats.add(aggregatedWakeLockItem); 1720 } 1721 } 1722 return new WakeLockStats(uidWakeLockStats, uidAggregatedWakeLockStats); 1723 } 1724 1725 // Returns a valid {@code WakeLockStats.WakeLock} or null. createWakeLock( Uid uid, String name, boolean isAggregated, DualTimer timer, final long realtimeMs)1726 private WakeLockStats.WakeLock createWakeLock( 1727 Uid uid, String name, boolean isAggregated, DualTimer timer, final long realtimeMs) { 1728 if (timer == null) { 1729 return null; 1730 } 1731 // Uses the primary timer for total wakelock data and used the sub timer for background 1732 // wakelock data. 1733 final WakeLockStats.WakeLockData totalWakeLockData = createWakeLockData(timer, realtimeMs); 1734 final WakeLockStats.WakeLockData backgroundWakeLockData = 1735 createWakeLockData(timer.getSubTimer(), realtimeMs); 1736 1737 return WakeLockStats.WakeLock.isDataValid(totalWakeLockData, backgroundWakeLockData) 1738 ? new WakeLockStats.WakeLock( 1739 uid.getUid(), 1740 name, 1741 isAggregated, 1742 totalWakeLockData, 1743 backgroundWakeLockData) : null; 1744 } 1745 1746 @NonNull createWakeLockData( DurationTimer timer, final long realtimeMs)1747 private WakeLockStats.WakeLockData createWakeLockData( 1748 DurationTimer timer, final long realtimeMs) { 1749 if (timer == null) { 1750 return WakeLockStats.WakeLockData.EMPTY; 1751 } 1752 final long totalTimeLockHeldMs = 1753 timer.getTotalTimeLocked(realtimeMs * 1000, STATS_SINCE_CHARGED) / 1000; 1754 if (totalTimeLockHeldMs == 0) { 1755 return WakeLockStats.WakeLockData.EMPTY; 1756 } 1757 return new WakeLockStats.WakeLockData( 1758 timer.getCountLocked(STATS_SINCE_CHARGED), 1759 totalTimeLockHeldMs, 1760 timer.isRunningLocked() ? timer.getCurrentDurationMsLocked(realtimeMs) : 0); 1761 } 1762 1763 @Override 1764 @GuardedBy("this") getBluetoothBatteryStats()1765 public BluetoothBatteryStats getBluetoothBatteryStats() { 1766 final long elapsedRealtimeUs = mClock.elapsedRealtime() * 1000; 1767 ArrayList<BluetoothBatteryStats.UidStats> uidStats = new ArrayList<>(); 1768 for (int i = mUidStats.size() - 1; i >= 0; i--) { 1769 final Uid uid = mUidStats.valueAt(i); 1770 final Timer scanTimer = uid.getBluetoothScanTimer(); 1771 final long scanTimeMs = 1772 scanTimer != null ? scanTimer.getTotalTimeLocked( 1773 elapsedRealtimeUs, STATS_SINCE_CHARGED) / 1000 : 0; 1774 1775 final Timer unoptimizedScanTimer = uid.getBluetoothUnoptimizedScanTimer(); 1776 final long unoptimizedScanTimeMs = 1777 unoptimizedScanTimer != null ? unoptimizedScanTimer.getTotalTimeLocked( 1778 elapsedRealtimeUs, STATS_SINCE_CHARGED) / 1000 : 0; 1779 1780 final Counter scanResultCounter = uid.getBluetoothScanResultCounter(); 1781 final int scanResultCount = 1782 scanResultCounter != null ? scanResultCounter.getCountLocked( 1783 STATS_SINCE_CHARGED) : 0; 1784 1785 final ControllerActivityCounter counter = uid.getBluetoothControllerActivity(); 1786 final long rxTimeMs = counter != null ? counter.getRxTimeCounter().getCountLocked( 1787 STATS_SINCE_CHARGED) : 0; 1788 final long txTimeMs = counter != null ? counter.getTxTimeCounters()[0].getCountLocked( 1789 STATS_SINCE_CHARGED) : 0; 1790 1791 if (scanTimeMs != 0 || unoptimizedScanTimeMs != 0 || scanResultCount != 0 1792 || rxTimeMs != 0 || txTimeMs != 0) { 1793 uidStats.add(new BluetoothBatteryStats.UidStats(uid.getUid(), 1794 scanTimeMs, 1795 unoptimizedScanTimeMs, 1796 scanResultCount, 1797 rxTimeMs, 1798 txTimeMs)); 1799 } 1800 } 1801 1802 return new BluetoothBatteryStats(uidStats); 1803 } 1804 1805 String mLastWakeupReason = null; 1806 long mLastWakeupUptimeMs = 0; 1807 long mLastWakeupElapsedTimeMs = 0; 1808 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 1809 getWakeupReasonStats()1810 public Map<String, ? extends Timer> getWakeupReasonStats() { 1811 return mWakeupReasonStats; 1812 } 1813 1814 @Override getUahDischarge(int which)1815 public long getUahDischarge(int which) { 1816 return mDischargeCounter.getCountLocked(which); 1817 } 1818 1819 @Override getUahDischargeScreenOff(int which)1820 public long getUahDischargeScreenOff(int which) { 1821 return mDischargeScreenOffCounter.getCountLocked(which); 1822 } 1823 1824 @Override getUahDischargeScreenDoze(int which)1825 public long getUahDischargeScreenDoze(int which) { 1826 return mDischargeScreenDozeCounter.getCountLocked(which); 1827 } 1828 1829 @Override getUahDischargeLightDoze(int which)1830 public long getUahDischargeLightDoze(int which) { 1831 return mDischargeLightDozeCounter.getCountLocked(which); 1832 } 1833 1834 @Override getUahDischargeDeepDoze(int which)1835 public long getUahDischargeDeepDoze(int which) { 1836 return mDischargeDeepDozeCounter.getCountLocked(which); 1837 } 1838 1839 @Override getEstimatedBatteryCapacity()1840 public int getEstimatedBatteryCapacity() { 1841 return mEstimatedBatteryCapacityMah; 1842 } 1843 1844 @Override getLearnedBatteryCapacity()1845 public int getLearnedBatteryCapacity() { 1846 return mLastLearnedBatteryCapacityUah; 1847 } 1848 1849 @Override getMinLearnedBatteryCapacity()1850 public int getMinLearnedBatteryCapacity() { 1851 return mMinLearnedBatteryCapacityUah; 1852 } 1853 1854 @Override getMaxLearnedBatteryCapacity()1855 public int getMaxLearnedBatteryCapacity() { 1856 return mMaxLearnedBatteryCapacityUah; 1857 } 1858 1859 public static class FrameworkStatsLogger { uidProcessStateChanged(int uid, int state)1860 public void uidProcessStateChanged(int uid, int state) { 1861 // TODO(b/155216561): It is possible for isolated uids to be in a higher 1862 // state than its parent uid. We should track the highest state within the union of host 1863 // and isolated uids rather than only the parent uid. 1864 FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, 1865 ActivityManager.processStateAmToProto(state)); 1866 } 1867 wakelockStateChanged(int uid, WorkChain wc, String name, int procState, boolean acquired, int powerManagerWakeLockLevel)1868 public void wakelockStateChanged(int uid, WorkChain wc, String name, 1869 int procState, boolean acquired, int powerManagerWakeLockLevel) { 1870 int event = acquired 1871 ? FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE 1872 : FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE; 1873 if (wc != null) { 1874 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 1875 wc.getTags(), powerManagerWakeLockLevel, name, event, procState); 1876 } else { 1877 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, uid, 1878 null, powerManagerWakeLockLevel, name, event, procState); 1879 } 1880 } 1881 kernelWakeupReported(long deltaUptimeUs, String lastWakeupReason, long lastWakeupElapsedTimeMs)1882 public void kernelWakeupReported(long deltaUptimeUs, String lastWakeupReason, 1883 long lastWakeupElapsedTimeMs) { 1884 FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, lastWakeupReason, 1885 /* duration_usec */ deltaUptimeUs, lastWakeupElapsedTimeMs); 1886 } 1887 gpsScanStateChanged(int uid, WorkChain workChain, boolean stateOn)1888 public void gpsScanStateChanged(int uid, WorkChain workChain, boolean stateOn) { 1889 int event = stateOn 1890 ? FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON 1891 : FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF; 1892 if (workChain != null) { 1893 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 1894 workChain.getUids(), workChain.getTags(), event); 1895 } else { 1896 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 1897 uid, null, event); 1898 } 1899 } 1900 batterySaverModeChanged(boolean enabled)1901 public void batterySaverModeChanged(boolean enabled) { 1902 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 1903 enabled 1904 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 1905 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 1906 } 1907 deviceIdlingModeStateChanged(int mode)1908 public void deviceIdlingModeStateChanged(int mode) { 1909 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, mode); 1910 } 1911 deviceIdleModeStateChanged(int mode)1912 public void deviceIdleModeStateChanged(int mode) { 1913 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 1914 } 1915 chargingStateChanged(int status)1916 public void chargingStateChanged(int status) { 1917 FrameworkStatsLog.write(FrameworkStatsLog.CHARGING_STATE_CHANGED, status); 1918 } 1919 pluggedStateChanged(int plugType)1920 public void pluggedStateChanged(int plugType) { 1921 FrameworkStatsLog.write(FrameworkStatsLog.PLUGGED_STATE_CHANGED, plugType); 1922 } 1923 batteryLevelChanged(int level)1924 public void batteryLevelChanged(int level) { 1925 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_LEVEL_CHANGED, level); 1926 } 1927 phoneServiceStateChanged(int state, int simState, int strengthBin)1928 public void phoneServiceStateChanged(int state, int simState, int strengthBin) { 1929 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 1930 simState, strengthBin); 1931 } 1932 phoneSignalStrengthChanged(int strengthBin)1933 public void phoneSignalStrengthChanged(int strengthBin) { 1934 FrameworkStatsLog.write( 1935 FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 1936 } 1937 1938 /** 1939 * Records a statsd event when the batterystats config file is written to disk. 1940 */ writeCommitSysConfigFile(String fileName, long durationMs)1941 public void writeCommitSysConfigFile(String fileName, long durationMs) { 1942 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(fileName, 1943 durationMs); 1944 } 1945 } 1946 1947 private final FrameworkStatsLogger mFrameworkStatsLogger; 1948 initKernelStatsReaders()1949 private void initKernelStatsReaders() { 1950 if (!isKernelStatsAvailable()) { 1951 return; 1952 } 1953 1954 mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(true, mClock); 1955 mCpuUidFreqTimeReader = new KernelCpuUidFreqTimeReader(true, mClock); 1956 mCpuUidActiveTimeReader = new KernelCpuUidActiveTimeReader(true, mClock); 1957 mCpuUidClusterTimeReader = new KernelCpuUidClusterTimeReader(true, mClock); 1958 mKernelWakelockReader = new KernelWakelockReader(); 1959 if (!Flags.disableSystemServicePowerAttr()) { 1960 mSystemServerCpuThreadReader = SystemServerCpuThreadReader.create(); 1961 } 1962 mKernelMemoryBandwidthStats = new KernelMemoryBandwidthStats(); 1963 mTmpRailStats = new RailStats(); 1964 } 1965 1966 private class PowerStatsCollectorInjector implements CpuPowerStatsCollector.Injector, 1967 MobileRadioPowerStatsCollector.Injector, WifiPowerStatsCollector.Injector, 1968 BluetoothPowerStatsCollector.Injector, EnergyConsumerPowerStatsCollector.Injector { 1969 private PackageManager mPackageManager; 1970 private PowerStatsCollector.ConsumedEnergyRetriever mConsumedEnergyRetriever; 1971 private NetworkStatsManager mNetworkStatsManager; 1972 private TelephonyManager mTelephonyManager; 1973 private WifiManager mWifiManager; 1974 private BluetoothPowerStatsCollector.BluetoothStatsRetriever mBluetoothStatsRetriever; 1975 setContext(Context context)1976 void setContext(Context context) { 1977 mPackageManager = context.getPackageManager(); 1978 mConsumedEnergyRetriever = new PowerStatsCollector.ConsumedEnergyRetrieverImpl( 1979 LocalServices.getService(PowerStatsInternal.class)); 1980 mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class); 1981 mTelephonyManager = context.getSystemService(TelephonyManager.class); 1982 mWifiManager = context.getSystemService(WifiManager.class); 1983 mBluetoothStatsRetriever = new BluetoothStatsRetrieverImpl( 1984 context.getSystemService(BluetoothManager.class)); 1985 } 1986 1987 @Override getHandler()1988 public Handler getHandler() { 1989 return mHandler; 1990 } 1991 1992 @Override getClock()1993 public Clock getClock() { 1994 return mClock; 1995 } 1996 1997 @Override getPowerStatsCollectionThrottlePeriod(String powerComponentName)1998 public long getPowerStatsCollectionThrottlePeriod(String powerComponentName) { 1999 return mBatteryStatsConfig.getPowerStatsThrottlePeriod(powerComponentName); 2000 } 2001 2002 @Override getUidResolver()2003 public PowerStatsUidResolver getUidResolver() { 2004 return mPowerStatsUidResolver; 2005 } 2006 2007 @Override getCpuScalingPolicies()2008 public CpuScalingPolicies getCpuScalingPolicies() { 2009 return mCpuScalingPolicies; 2010 } 2011 2012 @Override getPowerProfile()2013 public PowerProfile getPowerProfile() { 2014 return mPowerProfile; 2015 } 2016 2017 @Override getKernelCpuStatsReader()2018 public CpuPowerStatsCollector.KernelCpuStatsReader getKernelCpuStatsReader() { 2019 return new CpuPowerStatsCollector.KernelCpuStatsReader(); 2020 } 2021 2022 @Override getPackageManager()2023 public PackageManager getPackageManager() { 2024 return mPackageManager; 2025 } 2026 2027 @Override getConsumedEnergyRetriever()2028 public PowerStatsCollector.ConsumedEnergyRetriever getConsumedEnergyRetriever() { 2029 return mConsumedEnergyRetriever; 2030 } 2031 2032 @Override getVoltageSupplier()2033 public IntSupplier getVoltageSupplier() { 2034 return () -> mBatteryVoltageMv; 2035 } 2036 2037 @Override getMobileNetworkStatsSupplier()2038 public Supplier<NetworkStats> getMobileNetworkStatsSupplier() { 2039 return () -> readMobileNetworkStatsLocked(mNetworkStatsManager); 2040 } 2041 2042 @Override getWifiNetworkStatsSupplier()2043 public Supplier<NetworkStats> getWifiNetworkStatsSupplier() { 2044 return () -> readWifiNetworkStatsLocked(mNetworkStatsManager); 2045 } 2046 2047 @Override getWifiStatsRetriever()2048 public WifiPowerStatsCollector.WifiStatsRetriever getWifiStatsRetriever() { 2049 return mWifiStatsRetriever; 2050 } 2051 2052 @Override getTelephonyManager()2053 public TelephonyManager getTelephonyManager() { 2054 return mTelephonyManager; 2055 } 2056 2057 @Override getWifiManager()2058 public WifiManager getWifiManager() { 2059 return mWifiManager; 2060 } 2061 2062 @Override getBluetoothStatsRetriever()2063 public BluetoothPowerStatsCollector.BluetoothStatsRetriever getBluetoothStatsRetriever() { 2064 return mBluetoothStatsRetriever; 2065 } 2066 2067 @Override getCallDurationSupplier()2068 public LongSupplier getCallDurationSupplier() { 2069 return () -> mPhoneOnTimer.getTotalTimeLocked(mClock.elapsedRealtime() * 1000, 2070 STATS_SINCE_CHARGED); 2071 } 2072 2073 @Override getPhoneSignalScanDurationSupplier()2074 public LongSupplier getPhoneSignalScanDurationSupplier() { 2075 return () -> mPhoneSignalScanningTimer.getTotalTimeLocked( 2076 mClock.elapsedRealtime() * 1000, STATS_SINCE_CHARGED); 2077 } 2078 } 2079 2080 private final PowerStatsCollectorInjector mPowerStatsCollectorInjector = 2081 new PowerStatsCollectorInjector(); 2082 2083 /** 2084 * TimeBase observer. 2085 */ 2086 public interface TimeBaseObs { onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2087 void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2088 void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); 2089 2090 /** 2091 * Reset the observer's state, returns true if the timer/counter is inactive 2092 * so it can be destroyed. 2093 * @param detachIfReset detach if true, no-op if false. 2094 * @return Returns true if the timer/counter is inactive and can be destroyed. 2095 */ reset(boolean detachIfReset)2096 default boolean reset(boolean detachIfReset) { 2097 return reset(detachIfReset, SystemClock.elapsedRealtime() * 1000); 2098 } 2099 2100 /** 2101 * @see #reset(boolean) 2102 * @param detachIfReset detach if true, no-op if false. 2103 * @param elapsedRealtimeUs the timestamp when this reset is actually reequested 2104 * @return Returns true if the timer/counter is inactive and can be destroyed. 2105 */ reset(boolean detachIfReset, long elapsedRealtimeUs)2106 boolean reset(boolean detachIfReset, long elapsedRealtimeUs); 2107 2108 /** 2109 * Detach the observer from TimeBase. 2110 */ detach()2111 void detach(); 2112 } 2113 2114 // methods are protected not private to be VisibleForTesting 2115 public static class TimeBase { 2116 protected final Collection<TimeBaseObs> mObservers; 2117 2118 // All below time metrics are in microseconds. 2119 protected long mUptimeUs; 2120 protected long mRealtimeUs; 2121 2122 protected boolean mRunning; 2123 2124 protected long mPastUptimeUs; 2125 protected long mUptimeStartUs; 2126 protected long mPastRealtimeUs; 2127 protected long mRealtimeStartUs; 2128 protected long mUnpluggedUptimeUs; 2129 protected long mUnpluggedRealtimeUs; 2130 dump(PrintWriter pw, String prefix)2131 public void dump(PrintWriter pw, String prefix) { 2132 StringBuilder sb = new StringBuilder(128); 2133 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 2134 sb.setLength(0); 2135 sb.append(prefix); 2136 sb.append("mUptime="); 2137 formatTimeMs(sb, mUptimeUs / 1000); 2138 pw.println(sb.toString()); 2139 sb.setLength(0); 2140 sb.append(prefix); 2141 sb.append("mRealtime="); 2142 formatTimeMs(sb, mRealtimeUs / 1000); 2143 pw.println(sb.toString()); 2144 sb.setLength(0); 2145 sb.append(prefix); 2146 sb.append("mPastUptime="); 2147 formatTimeMs(sb, mPastUptimeUs / 1000); sb.append("mUptimeStart="); 2148 formatTimeMs(sb, mUptimeStartUs / 1000); 2149 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptimeUs / 1000); 2150 pw.println(sb.toString()); 2151 sb.setLength(0); 2152 sb.append(prefix); 2153 sb.append("mPastRealtime="); 2154 formatTimeMs(sb, mPastRealtimeUs / 1000); sb.append("mRealtimeStart="); 2155 formatTimeMs(sb, mRealtimeStartUs / 1000); 2156 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtimeUs / 1000); 2157 pw.println(sb.toString()); 2158 } 2159 /** 2160 * The mObservers of TimeBase in BatteryStatsImpl object can contain up to 20k entries. 2161 * The mObservers of TimeBase in BatteryStatsImpl.Uid object only contains a few or tens of 2162 * entries. 2163 * mObservers must have good performance on add(), remove(), also be memory efficient. 2164 * This is why we provide isLongList parameter for long and short list user cases. 2165 * @param isLongList If true, use HashSet for mObservers list. 2166 * If false, use ArrayList for mObservers list. 2167 */ TimeBase(boolean isLongList)2168 public TimeBase(boolean isLongList) { 2169 mObservers = isLongList ? new HashSet<>() : new ArrayList<>(); 2170 } 2171 TimeBase()2172 public TimeBase() { 2173 this(false); 2174 } 2175 add(TimeBaseObs observer)2176 public void add(TimeBaseObs observer) { 2177 mObservers.add(observer); 2178 } 2179 remove(TimeBaseObs observer)2180 public void remove(TimeBaseObs observer) { 2181 mObservers.remove(observer); 2182 } 2183 hasObserver(TimeBaseObs observer)2184 public boolean hasObserver(TimeBaseObs observer) { 2185 return mObservers.contains(observer); 2186 } 2187 init(long uptimeUs, long elapsedRealtimeUs)2188 public void init(long uptimeUs, long elapsedRealtimeUs) { 2189 mRealtimeUs = 0; 2190 mUptimeUs = 0; 2191 mPastUptimeUs = 0; 2192 mPastRealtimeUs = 0; 2193 mUptimeStartUs = uptimeUs; 2194 mRealtimeStartUs = elapsedRealtimeUs; 2195 mUnpluggedUptimeUs = getUptime(mUptimeStartUs); 2196 mUnpluggedRealtimeUs = getRealtime(mRealtimeStartUs); 2197 } 2198 reset(long uptimeUs, long elapsedRealtimeUs)2199 public void reset(long uptimeUs, long elapsedRealtimeUs) { 2200 if (!mRunning) { 2201 mPastUptimeUs = 0; 2202 mPastRealtimeUs = 0; 2203 } else { 2204 mUptimeStartUs = uptimeUs; 2205 mRealtimeStartUs = elapsedRealtimeUs; 2206 // TODO: Since mUptimeStartUs was just reset and we are running, getUptime will 2207 // just return mPastUptimeUs. Also, are we sure we don't want to reset that? 2208 mUnpluggedUptimeUs = getUptime(uptimeUs); 2209 // TODO: likewise. 2210 mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 2211 } 2212 } 2213 computeUptime(long curTimeUs, int which)2214 public long computeUptime(long curTimeUs, int which) { 2215 return mUptimeUs + getUptime(curTimeUs); 2216 } 2217 computeRealtime(long curTimeUs, int which)2218 public long computeRealtime(long curTimeUs, int which) { 2219 return mRealtimeUs + getRealtime(curTimeUs); 2220 } 2221 getUptime(long curTimeUs)2222 public long getUptime(long curTimeUs) { 2223 long time = mPastUptimeUs; 2224 if (mRunning) { 2225 time += curTimeUs - mUptimeStartUs; 2226 } 2227 return time; 2228 } 2229 getRealtime(long curTimeUs)2230 public long getRealtime(long curTimeUs) { 2231 long time = mPastRealtimeUs; 2232 if (mRunning) { 2233 time += curTimeUs - mRealtimeStartUs; 2234 } 2235 return time; 2236 } 2237 getUptimeStart()2238 public long getUptimeStart() { 2239 return mUptimeStartUs; 2240 } 2241 getRealtimeStart()2242 public long getRealtimeStart() { 2243 return mRealtimeStartUs; 2244 } 2245 isRunning()2246 public boolean isRunning() { 2247 return mRunning; 2248 } 2249 setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs)2250 public boolean setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs) { 2251 if (mRunning != running) { 2252 mRunning = running; 2253 if (running) { 2254 mUptimeStartUs = uptimeUs; 2255 mRealtimeStartUs = elapsedRealtimeUs; 2256 long batteryUptimeUs = mUnpluggedUptimeUs = getUptime(uptimeUs); 2257 long batteryRealtimeUs = mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 2258 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 2259 // Iterator object, here is an exception because mObservers' type is Collection 2260 // instead of list. 2261 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 2262 while (iter.hasNext()) { 2263 iter.next().onTimeStarted( 2264 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 2265 } 2266 } else { 2267 mPastUptimeUs += uptimeUs - mUptimeStartUs; 2268 mPastRealtimeUs += elapsedRealtimeUs - mRealtimeStartUs; 2269 long batteryUptimeUs = getUptime(uptimeUs); 2270 long batteryRealtimeUs = getRealtime(elapsedRealtimeUs); 2271 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 2272 // Iterator object, here is an exception because mObservers' type is Collection 2273 // instead of list. 2274 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 2275 while (iter.hasNext()) { 2276 iter.next().onTimeStopped( 2277 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 2278 } 2279 } 2280 return true; 2281 } 2282 return false; 2283 } 2284 readSummaryFromParcel(Parcel in)2285 public void readSummaryFromParcel(Parcel in) { 2286 mUptimeUs = in.readLong(); 2287 mRealtimeUs = in.readLong(); 2288 } 2289 writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)2290 public void writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 2291 out.writeLong(computeUptime(uptimeUs, STATS_SINCE_CHARGED)); 2292 out.writeLong(computeRealtime(elapsedRealtimeUs, STATS_SINCE_CHARGED)); 2293 } 2294 readFromParcel(Parcel in)2295 public void readFromParcel(Parcel in) { 2296 mRunning = false; 2297 mUptimeUs = in.readLong(); 2298 mPastUptimeUs = in.readLong(); 2299 mUptimeStartUs = in.readLong(); 2300 mRealtimeUs = in.readLong(); 2301 mPastRealtimeUs = in.readLong(); 2302 mRealtimeStartUs = in.readLong(); 2303 mUnpluggedUptimeUs = in.readLong(); 2304 mUnpluggedRealtimeUs = in.readLong(); 2305 } 2306 writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)2307 public void writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 2308 final long runningUptime = getUptime(uptimeUs); 2309 final long runningRealtime = getRealtime(elapsedRealtimeUs); 2310 out.writeLong(mUptimeUs); 2311 out.writeLong(runningUptime); 2312 out.writeLong(mUptimeStartUs); 2313 out.writeLong(mRealtimeUs); 2314 out.writeLong(runningRealtime); 2315 out.writeLong(mRealtimeStartUs); 2316 out.writeLong(mUnpluggedUptimeUs); 2317 out.writeLong(mUnpluggedRealtimeUs); 2318 } 2319 } 2320 2321 /** 2322 * State for keeping track of counting information. 2323 */ 2324 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 2325 final AtomicInteger mCount = new AtomicInteger(); 2326 final TimeBase mTimeBase; 2327 Counter(TimeBase timeBase, Parcel in)2328 public Counter(TimeBase timeBase, Parcel in) { 2329 mTimeBase = timeBase; 2330 mCount.set(in.readInt()); 2331 timeBase.add(this); 2332 } 2333 Counter(TimeBase timeBase)2334 public Counter(TimeBase timeBase) { 2335 mTimeBase = timeBase; 2336 timeBase.add(this); 2337 } 2338 writeToParcel(Parcel out)2339 public void writeToParcel(Parcel out) { 2340 out.writeInt(mCount.get()); 2341 } 2342 2343 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2344 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2345 } 2346 2347 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2348 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2349 } 2350 2351 @Override getCountLocked(int which)2352 public int getCountLocked(int which) { 2353 return mCount.get(); 2354 } 2355 logState(Printer pw, String prefix)2356 public void logState(Printer pw, String prefix) { 2357 pw.println(prefix + "mCount=" + mCount.get()); 2358 } 2359 2360 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()2361 public void stepAtomic() { 2362 if (mTimeBase.isRunning()) { 2363 mCount.incrementAndGet(); 2364 } 2365 } 2366 addAtomic(int delta)2367 void addAtomic(int delta) { 2368 if (mTimeBase.isRunning()) { 2369 mCount.addAndGet(delta); 2370 } 2371 } 2372 2373 /** 2374 * Clear state of this counter. 2375 */ 2376 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2377 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2378 mCount.set(0); 2379 if (detachIfReset) { 2380 detach(); 2381 } 2382 return true; 2383 } 2384 2385 @Override detach()2386 public void detach() { 2387 mTimeBase.remove(this); 2388 } 2389 2390 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)2391 public void writeSummaryFromParcelLocked(Parcel out) { 2392 out.writeInt(mCount.get()); 2393 } 2394 2395 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)2396 public void readSummaryFromParcelLocked(Parcel in) { 2397 mCount.set(in.readInt()); 2398 } 2399 } 2400 2401 @VisibleForTesting 2402 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 2403 final TimeBase mTimeBase; 2404 public long[] mCounts; 2405 LongSamplingCounterArray(TimeBase timeBase, Parcel in)2406 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 2407 mTimeBase = timeBase; 2408 mCounts = in.createLongArray(); 2409 timeBase.add(this); 2410 } 2411 LongSamplingCounterArray(TimeBase timeBase)2412 public LongSamplingCounterArray(TimeBase timeBase) { 2413 mTimeBase = timeBase; 2414 timeBase.add(this); 2415 } 2416 writeToParcel(Parcel out)2417 private void writeToParcel(Parcel out) { 2418 out.writeLongArray(mCounts); 2419 } 2420 2421 @Override onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs)2422 public void onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs) { 2423 } 2424 2425 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2426 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2427 } 2428 2429 @Override getCountsLocked(int which)2430 public long[] getCountsLocked(int which) { 2431 return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); 2432 } 2433 2434 @Override logState(Printer pw, String prefix)2435 public void logState(Printer pw, String prefix) { 2436 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); 2437 } 2438 addCountLocked(long[] counts)2439 public void addCountLocked(long[] counts) { 2440 addCountLocked(counts, mTimeBase.isRunning()); 2441 } 2442 addCountLocked(long[] counts, boolean isRunning)2443 public void addCountLocked(long[] counts, boolean isRunning) { 2444 if (counts == null) { 2445 return; 2446 } 2447 if (isRunning) { 2448 if (mCounts == null) { 2449 mCounts = new long[counts.length]; 2450 } 2451 for (int i = 0; i < counts.length; ++i) { 2452 mCounts[i] += counts[i]; 2453 } 2454 } 2455 } 2456 getSize()2457 public int getSize() { 2458 return mCounts == null ? 0 : mCounts.length; 2459 } 2460 2461 /** 2462 * Clear state of this counter. 2463 */ 2464 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2465 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2466 if (mCounts != null) { 2467 Arrays.fill(mCounts, 0); 2468 } 2469 if (detachIfReset) { 2470 detach(); 2471 } 2472 return true; 2473 } 2474 2475 @Override detach()2476 public void detach() { 2477 mTimeBase.remove(this); 2478 } 2479 writeSummaryToParcelLocked(Parcel out)2480 private void writeSummaryToParcelLocked(Parcel out) { 2481 out.writeLongArray(mCounts); 2482 } 2483 readSummaryFromParcelLocked(Parcel in)2484 private void readSummaryFromParcelLocked(Parcel in) { 2485 mCounts = in.createLongArray(); 2486 } 2487 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)2488 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 2489 if (counterArray != null) { 2490 out.writeInt(1); 2491 counterArray.writeToParcel(out); 2492 } else { 2493 out.writeInt(0); 2494 } 2495 } 2496 readFromParcel(Parcel in, TimeBase timeBase)2497 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 2498 if (in.readInt() != 0) { 2499 return new LongSamplingCounterArray(timeBase, in); 2500 } else { 2501 return null; 2502 } 2503 } 2504 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)2505 public static void writeSummaryToParcelLocked(Parcel out, 2506 LongSamplingCounterArray counterArray) { 2507 if (counterArray != null) { 2508 out.writeInt(1); 2509 counterArray.writeSummaryToParcelLocked(out); 2510 } else { 2511 out.writeInt(0); 2512 } 2513 } 2514 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)2515 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 2516 TimeBase timeBase) { 2517 if (in.readInt() != 0) { 2518 final LongSamplingCounterArray counterArray 2519 = new LongSamplingCounterArray(timeBase); 2520 counterArray.readSummaryFromParcelLocked(in); 2521 return counterArray; 2522 } else { 2523 return null; 2524 } 2525 } 2526 } 2527 2528 private static class TimeMultiStateCounter extends LongCounter implements TimeBaseObs { 2529 private final TimeBase mTimeBase; 2530 private final LongMultiStateCounter mCounter; 2531 TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs)2532 private TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs) { 2533 this(timeBase, new LongMultiStateCounter(stateCount), timestampMs); 2534 } 2535 TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter, long timestampMs)2536 private TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter, 2537 long timestampMs) { 2538 mTimeBase = timeBase; 2539 mCounter = counter; 2540 mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); 2541 timeBase.add(this); 2542 } 2543 2544 @Nullable readFromParcel(Parcel in, TimeBase timeBase, int stateCount, long timestampMs)2545 private static TimeMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase, 2546 int stateCount, long timestampMs) { 2547 LongMultiStateCounter counter = LongMultiStateCounter.CREATOR.createFromParcel(in); 2548 if (counter.getStateCount() != stateCount) { 2549 return null; 2550 } 2551 return new TimeMultiStateCounter(timeBase, counter, timestampMs); 2552 } 2553 writeToParcel(Parcel out)2554 private void writeToParcel(Parcel out) { 2555 mCounter.writeToParcel(out, 0); 2556 } 2557 2558 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2559 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2560 mCounter.setEnabled(true, elapsedRealtimeUs / 1000); 2561 } 2562 2563 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2564 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2565 mCounter.setEnabled(false, elapsedRealtimeUs / 1000); 2566 } 2567 getStateCount()2568 public int getStateCount() { 2569 return mCounter.getStateCount(); 2570 } 2571 setState(@atteryConsumer.ProcessState int processState, long elapsedRealtimeMs)2572 private void setState(@BatteryConsumer.ProcessState int processState, 2573 long elapsedRealtimeMs) { 2574 mCounter.setState(processState, elapsedRealtimeMs); 2575 } 2576 update(long value, long timestampMs)2577 private long update(long value, long timestampMs) { 2578 return mCounter.updateValue(value, timestampMs); 2579 } 2580 increment(long increment, long timestampMs)2581 private void increment(long increment, long timestampMs) { 2582 mCounter.incrementValue(increment, timestampMs); 2583 } 2584 2585 /** 2586 * Returns accumulated count for the specified state. 2587 */ getCountForProcessState(@atteryConsumer.ProcessState int procState)2588 public long getCountForProcessState(@BatteryConsumer.ProcessState int procState) { 2589 return mCounter.getCount(procState); 2590 } 2591 getTotalCountLocked()2592 public long getTotalCountLocked() { 2593 return mCounter.getTotalCount(); 2594 } 2595 2596 @Override getCountLocked(int statsType)2597 public long getCountLocked(int statsType) { 2598 return getTotalCountLocked(); 2599 } 2600 2601 @Override logState(Printer pw, String prefix)2602 public void logState(Printer pw, String prefix) { 2603 pw.println(prefix + "mCounter=" + mCounter); 2604 } 2605 2606 /** 2607 * Clears state of this counter. 2608 */ 2609 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2610 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2611 mCounter.reset(); 2612 if (detachIfReset) { 2613 detach(); 2614 } 2615 return true; 2616 } 2617 2618 @Override detach()2619 public void detach() { 2620 mTimeBase.remove(this); 2621 } 2622 } 2623 2624 private static class TimeInFreqMultiStateCounter implements TimeBaseObs { 2625 private final TimeBase mTimeBase; 2626 private final LongArrayMultiStateCounter mCounter; 2627 TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount, long timestampMs)2628 private TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount, 2629 long timestampMs) { 2630 this(timeBase, new LongArrayMultiStateCounter(stateCount, cpuFreqCount), timestampMs); 2631 } 2632 TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter, long timestampMs)2633 private TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter, 2634 long timestampMs) { 2635 mTimeBase = timeBase; 2636 mCounter = counter; 2637 mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); 2638 timeBase.add(this); 2639 } 2640 writeToParcel(Parcel out)2641 private void writeToParcel(Parcel out) { 2642 mCounter.writeToParcel(out, 0); 2643 } 2644 2645 @Nullable readFromParcel(Parcel in, TimeBase timeBase, int stateCount, int cpuFreqCount, long timestampMs)2646 private static TimeInFreqMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase, 2647 int stateCount, int cpuFreqCount, long timestampMs) { 2648 // Read the object from the Parcel, whether it's usable or not 2649 LongArrayMultiStateCounter counter = 2650 LongArrayMultiStateCounter.CREATOR.createFromParcel(in); 2651 if (counter.getStateCount() != stateCount 2652 || counter.getArrayLength() != cpuFreqCount) { 2653 return null; 2654 } 2655 return new TimeInFreqMultiStateCounter(timeBase, counter, timestampMs); 2656 } 2657 2658 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2659 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2660 mCounter.setEnabled(true, elapsedRealtimeUs / 1000); 2661 } 2662 2663 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2664 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2665 mCounter.setEnabled(false, elapsedRealtimeUs / 1000); 2666 } 2667 getCounter()2668 public LongArrayMultiStateCounter getCounter() { 2669 return mCounter; 2670 } 2671 getStateCount()2672 public int getStateCount() { 2673 return mCounter.getStateCount(); 2674 } 2675 setTrackingEnabled(boolean enabled, long timestampMs)2676 public void setTrackingEnabled(boolean enabled, long timestampMs) { 2677 mCounter.setEnabled(enabled && mTimeBase.isRunning(), timestampMs); 2678 } 2679 setState(int uidRunningState, long elapsedRealtimeMs)2680 private void setState(int uidRunningState, long elapsedRealtimeMs) { 2681 mCounter.setState(uidRunningState, elapsedRealtimeMs); 2682 } 2683 2684 /** 2685 * Returns accumulated counts for the specified state, or false if all counts are zero. 2686 */ getCountsLocked(long[] counts, int procState)2687 public boolean getCountsLocked(long[] counts, int procState) { 2688 if (counts.length != mCounter.getArrayLength()) { 2689 return false; 2690 } 2691 2692 mCounter.getCounts(counts, procState); 2693 2694 // Return counts only if at least one of the elements is non-zero. 2695 for (int i = counts.length - 1; i >= 0; --i) { 2696 if (counts[i] != 0) { 2697 return true; 2698 } 2699 } 2700 return false; 2701 } 2702 logState(Printer pw, String prefix)2703 public void logState(Printer pw, String prefix) { 2704 pw.println(prefix + "mCounter=" + mCounter); 2705 } 2706 2707 /** 2708 * Clears state of this counter. 2709 */ 2710 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2711 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2712 mCounter.reset(); 2713 if (detachIfReset) { 2714 detach(); 2715 } 2716 return true; 2717 } 2718 2719 @Override detach()2720 public void detach() { 2721 mTimeBase.remove(this); 2722 } 2723 } 2724 2725 @VisibleForTesting 2726 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 2727 final TimeBase mTimeBase; 2728 private long mCount; 2729 LongSamplingCounter(TimeBase timeBase, Parcel in)2730 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 2731 mTimeBase = timeBase; 2732 mCount = in.readLong(); 2733 timeBase.add(this); 2734 } 2735 LongSamplingCounter(TimeBase timeBase)2736 public LongSamplingCounter(TimeBase timeBase) { 2737 mTimeBase = timeBase; 2738 timeBase.add(this); 2739 } 2740 writeToParcel(Parcel out)2741 public void writeToParcel(Parcel out) { 2742 out.writeLong(mCount); 2743 } 2744 2745 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2746 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2747 } 2748 2749 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2750 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2751 } 2752 getCountLocked(int which)2753 public long getCountLocked(int which) { 2754 return mCount; 2755 } 2756 2757 @Override getCountForProcessState(int procState)2758 public long getCountForProcessState(int procState) { 2759 if (procState == BatteryConsumer.PROCESS_STATE_ANY) { 2760 return getCountLocked(STATS_SINCE_CHARGED); 2761 } 2762 return 0; 2763 } 2764 2765 @Override logState(Printer pw, String prefix)2766 public void logState(Printer pw, String prefix) { 2767 pw.println(prefix + "mCount=" + mCount); 2768 } 2769 addCountLocked(long count)2770 public void addCountLocked(long count) { 2771 addCountLocked(count, mTimeBase.isRunning()); 2772 } 2773 addCountLocked(long count, boolean isRunning)2774 public void addCountLocked(long count, boolean isRunning) { 2775 if (isRunning) { 2776 mCount += count; 2777 } 2778 } 2779 2780 /** 2781 * Clear state of this counter. 2782 */ 2783 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2784 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2785 mCount = 0; 2786 if (detachIfReset) { 2787 detach(); 2788 } 2789 return true; 2790 } 2791 2792 @Override detach()2793 public void detach() { 2794 mTimeBase.remove(this); 2795 } 2796 writeSummaryFromParcelLocked(Parcel out)2797 public void writeSummaryFromParcelLocked(Parcel out) { 2798 out.writeLong(mCount); 2799 } 2800 readSummaryFromParcelLocked(Parcel in)2801 public void readSummaryFromParcelLocked(Parcel in) { 2802 mCount = in.readLong(); 2803 } 2804 } 2805 2806 /** 2807 * State for keeping track of timing information. 2808 */ 2809 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 2810 protected final Clock mClock; 2811 protected final int mType; 2812 protected final TimeBase mTimeBase; 2813 2814 protected int mCount; 2815 2816 // Times are in microseconds for better accuracy when dividing by the 2817 // lock count, and are in "battery realtime" units. 2818 2819 /** 2820 * The total time we have accumulated since the start of the original 2821 * boot, to the last time something interesting happened in the 2822 * current run. 2823 */ 2824 protected long mTotalTimeUs; 2825 2826 /** 2827 * The total time this timer has been running until the latest mark has been set. 2828 * Subtract this from mTotalTimeUs to get the time spent running since the mark was set. 2829 */ 2830 protected long mTimeBeforeMarkUs; 2831 2832 /** 2833 * Constructs from a parcel. 2834 * @param type 2835 * @param timeBase 2836 * @param in 2837 */ Timer(Clock clock, int type, TimeBase timeBase, Parcel in)2838 public Timer(Clock clock, int type, TimeBase timeBase, Parcel in) { 2839 mClock = clock; 2840 mType = type; 2841 mTimeBase = timeBase; 2842 2843 mCount = in.readInt(); 2844 mTotalTimeUs = in.readLong(); 2845 mTimeBeforeMarkUs = in.readLong(); 2846 timeBase.add(this); 2847 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTimeUs); 2848 } 2849 Timer(Clock clock, int type, TimeBase timeBase)2850 public Timer(Clock clock, int type, TimeBase timeBase) { 2851 mClock = clock; 2852 mType = type; 2853 mTimeBase = timeBase; 2854 timeBase.add(this); 2855 } 2856 writeToParcel(Parcel out, long elapsedRealtimeUs)2857 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2858 if (DEBUG) { 2859 Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 2860 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2861 elapsedRealtimeUs)); 2862 } 2863 out.writeInt(computeCurrentCountLocked()); 2864 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2865 elapsedRealtimeUs)); 2866 out.writeLong(mTimeBeforeMarkUs); 2867 } 2868 computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)2869 protected abstract long computeRunTimeLocked(long curBatteryRealtime, 2870 long elapsedRealtimeUs); 2871 computeCurrentCountLocked()2872 protected abstract int computeCurrentCountLocked(); 2873 2874 /** 2875 * Clear state of this timer. Returns true if the timer is inactive 2876 * so can be completely dropped. 2877 */ 2878 @Override reset(boolean detachIfReset)2879 public boolean reset(boolean detachIfReset) { 2880 return reset(detachIfReset, mClock.elapsedRealtime() * 1000); 2881 } 2882 2883 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2884 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2885 mTotalTimeUs = mTimeBeforeMarkUs = 0; 2886 mCount = 0; 2887 if (detachIfReset) { 2888 detach(); 2889 } 2890 return true; 2891 } 2892 2893 @Override detach()2894 public void detach() { 2895 mTimeBase.remove(this); 2896 } 2897 2898 @Override onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, long baseRealtimeUs)2899 public void onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, 2900 long baseRealtimeUs) { 2901 } 2902 2903 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2904 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2905 if (DEBUG && mType < 0) { 2906 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtimeUs 2907 + " old mTotalTime=" + mTotalTimeUs); 2908 } 2909 mTotalTimeUs = computeRunTimeLocked(baseRealtimeUs, elapsedRealtimeUs); 2910 mCount = computeCurrentCountLocked(); 2911 if (DEBUG && mType < 0) { 2912 Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTimeUs); 2913 } 2914 } 2915 2916 /** 2917 * Writes a possibly null Timer to a Parcel. 2918 * 2919 * @param out the Parcel to be written to. 2920 * @param timer a Timer, or null. 2921 */ writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)2922 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 2923 if (timer == null) { 2924 out.writeInt(0); // indicates null 2925 return; 2926 } 2927 out.writeInt(1); // indicates non-null 2928 timer.writeToParcel(out, elapsedRealtimeUs); 2929 } 2930 2931 @Override getTotalTimeLocked(long elapsedRealtimeUs, int which)2932 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 2933 return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2934 elapsedRealtimeUs); 2935 } 2936 2937 @Override getCountLocked(int which)2938 public int getCountLocked(int which) { 2939 return computeCurrentCountLocked(); 2940 } 2941 2942 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)2943 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 2944 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2945 elapsedRealtimeUs); 2946 return val - mTimeBeforeMarkUs; 2947 } 2948 2949 @Override logState(Printer pw, String prefix)2950 public void logState(Printer pw, String prefix) { 2951 pw.println(prefix + "mCount=" + mCount); 2952 pw.println(prefix + "mTotalTime=" + mTotalTimeUs); 2953 } 2954 2955 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2956 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2957 long runTimeUs = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2958 elapsedRealtimeUs); 2959 out.writeLong(runTimeUs); 2960 out.writeInt(computeCurrentCountLocked()); 2961 } 2962 readSummaryFromParcelLocked(Parcel in)2963 public void readSummaryFromParcelLocked(Parcel in) { 2964 // Multiply by 1000 for backwards compatibility 2965 mTotalTimeUs = in.readLong(); 2966 mCount = in.readInt(); 2967 // When reading the summary, we set the mark to be the latest information. 2968 mTimeBeforeMarkUs = mTotalTimeUs; 2969 } 2970 } 2971 2972 /** 2973 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 2974 * method. The state of the timer according to its {@link TimeBase} will determine how much 2975 * of the value is recorded. 2976 * 2977 * If the value being recorded resets, {@link #endSample()} can be called in order to 2978 * account for the change. If the value passed in to {@link #update(long, int)} decreased 2979 * between calls, the {@link #endSample()} is automatically called and the new value is 2980 * expected to increase monotonically from that point on. 2981 */ 2982 public static class SamplingTimer extends Timer { 2983 2984 /** 2985 * The most recent reported count from /proc/wakelocks. 2986 */ 2987 int mCurrentReportedCount; 2988 2989 /** 2990 * The reported count from /proc/wakelocks when unplug() was last 2991 * called. 2992 */ 2993 int mBaseReportedCount; 2994 2995 /** 2996 * The most recent reported total_time from /proc/wakelocks. 2997 */ 2998 long mCurrentReportedTotalTimeUs; 2999 3000 /** 3001 * The reported total_time from /proc/wakelocks when unplug() was last 3002 * called. 3003 */ 3004 long mBaseReportedTotalTimeUs; 3005 3006 /** 3007 * Whether we are currently in a discharge cycle. 3008 */ 3009 boolean mTimeBaseRunning; 3010 3011 /** 3012 * Whether we are currently recording reported values. 3013 */ 3014 boolean mTrackingReportedValues; 3015 3016 /* 3017 * A sequence counter, incremented once for each update of the stats. 3018 */ 3019 int mUpdateVersion; 3020 3021 @VisibleForTesting SamplingTimer(Clock clock, TimeBase timeBase, Parcel in)3022 public SamplingTimer(Clock clock, TimeBase timeBase, Parcel in) { 3023 super(clock, 0, timeBase, in); 3024 mCurrentReportedCount = in.readInt(); 3025 mBaseReportedCount = in.readInt(); 3026 mCurrentReportedTotalTimeUs = in.readLong(); 3027 mBaseReportedTotalTimeUs = in.readLong(); 3028 mTrackingReportedValues = in.readInt() == 1; 3029 mTimeBaseRunning = timeBase.isRunning(); 3030 } 3031 3032 @VisibleForTesting SamplingTimer(Clock clock, TimeBase timeBase)3033 public SamplingTimer(Clock clock, TimeBase timeBase) { 3034 super(clock, 0, timeBase); 3035 mTrackingReportedValues = false; 3036 mTimeBaseRunning = timeBase.isRunning(); 3037 } 3038 3039 /** 3040 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 3041 * be less than the values used for a previous invocation. 3042 */ endSample()3043 public void endSample() { 3044 endSample(mClock.elapsedRealtime() * 1000); 3045 } 3046 3047 /** 3048 * @see #endSample() 3049 */ endSample(long elapsedRealtimeUs)3050 public void endSample(long elapsedRealtimeUs) { 3051 mTotalTimeUs = computeRunTimeLocked(0 /* unused by us */, elapsedRealtimeUs); 3052 mCount = computeCurrentCountLocked(); 3053 mBaseReportedTotalTimeUs = mCurrentReportedTotalTimeUs = 0; 3054 mBaseReportedCount = mCurrentReportedCount = 0; 3055 mTrackingReportedValues = false; 3056 } 3057 setUpdateVersion(int version)3058 public void setUpdateVersion(int version) { 3059 mUpdateVersion = version; 3060 } 3061 getUpdateVersion()3062 public int getUpdateVersion() { 3063 return mUpdateVersion; 3064 } 3065 3066 /** 3067 * Updates the current recorded values. These are meant to be monotonically increasing 3068 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 3069 * 3070 * If the values being recorded have been reset, the monotonically increasing requirement 3071 * will be broken. In this case, {@link #endSample()} is automatically called and 3072 * the total value of totalTimeUs and count are recorded, starting a new monotonically 3073 * increasing sample. 3074 * 3075 * @param totalTimeUs total time of sample in microseconds. 3076 * @param count total number of times the event being sampled occurred. 3077 */ update(long totalTimeUs, int count, long elapsedRealtimeUs)3078 public void update(long totalTimeUs, int count, long elapsedRealtimeUs) { 3079 update(totalTimeUs, 0, count, elapsedRealtimeUs); 3080 } 3081 3082 /** 3083 * Updates the current recorded values. See {@link #update(long, int, long)} 3084 * 3085 * @param activeTimeUs Time that the currently active wake lock has been held. 3086 */ update(long totalTimeUs, long activeTimeUs, int count, long elapsedRealtimeUs)3087 public void update(long totalTimeUs, long activeTimeUs, int count, 3088 long elapsedRealtimeUs) { 3089 if (mTimeBaseRunning && !mTrackingReportedValues) { 3090 // Updating the reported value for the first time. If the wake lock is currently 3091 // active, mark the time it was acquired as the base timestamp. 3092 mBaseReportedTotalTimeUs = totalTimeUs - activeTimeUs; 3093 mBaseReportedCount = activeTimeUs == 0 ? count : count - 1; 3094 } 3095 3096 mTrackingReportedValues = true; 3097 3098 if (totalTimeUs < mCurrentReportedTotalTimeUs || count < mCurrentReportedCount) { 3099 endSample(elapsedRealtimeUs); 3100 } 3101 3102 mCurrentReportedTotalTimeUs = totalTimeUs; 3103 mCurrentReportedCount = count; 3104 } 3105 3106 /** 3107 * Adds deltaTime and deltaCount to the current sample. 3108 * 3109 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 3110 * @param deltaCount additional number of times the event being sampled occurred. 3111 */ add(long deltaTimeUs, int deltaCount)3112 public void add(long deltaTimeUs, int deltaCount) { 3113 add(deltaTimeUs, deltaCount, mClock.elapsedRealtime() * 1000); 3114 } 3115 3116 /** 3117 * @see #add(long, int) 3118 */ add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs)3119 public void add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs) { 3120 update(mCurrentReportedTotalTimeUs + deltaTimeUs, mCurrentReportedCount + deltaCount, 3121 elapsedRealtimeUs); 3122 } 3123 3124 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3125 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3126 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3127 if (mTrackingReportedValues) { 3128 mBaseReportedTotalTimeUs = mCurrentReportedTotalTimeUs; 3129 mBaseReportedCount = mCurrentReportedCount; 3130 } 3131 mTimeBaseRunning = true; 3132 } 3133 3134 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3135 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3136 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3137 mTimeBaseRunning = false; 3138 } 3139 3140 @Override logState(Printer pw, String prefix)3141 public void logState(Printer pw, String prefix) { 3142 super.logState(pw, prefix); 3143 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 3144 + " mBaseReportedCount=" + mBaseReportedCount 3145 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTimeUs 3146 + " mBaseReportedTotalTimeUs=" + mBaseReportedTotalTimeUs); 3147 } 3148 3149 @Override computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)3150 protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) { 3151 return mTotalTimeUs + (mTimeBaseRunning && mTrackingReportedValues 3152 ? mCurrentReportedTotalTimeUs - mBaseReportedTotalTimeUs : 0); 3153 } 3154 3155 @Override computeCurrentCountLocked()3156 protected int computeCurrentCountLocked() { 3157 return mCount + (mTimeBaseRunning && mTrackingReportedValues 3158 ? mCurrentReportedCount - mBaseReportedCount : 0); 3159 } 3160 3161 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3162 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3163 super.writeToParcel(out, elapsedRealtimeUs); 3164 out.writeInt(mCurrentReportedCount); 3165 out.writeInt(mBaseReportedCount); 3166 out.writeLong(mCurrentReportedTotalTimeUs); 3167 out.writeLong(mBaseReportedTotalTimeUs); 3168 out.writeInt(mTrackingReportedValues ? 1 : 0); 3169 } 3170 3171 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3172 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3173 super.reset(detachIfReset, elapsedRealtimeUs); 3174 mTrackingReportedValues = false; 3175 mBaseReportedTotalTimeUs = 0; 3176 mBaseReportedCount = 0; 3177 return true; 3178 } 3179 } 3180 3181 /** 3182 * A timer that increments in batches. It does not run for durations, but just jumps 3183 * for a pre-determined amount. 3184 */ 3185 public static class BatchTimer extends Timer { 3186 final Uid mUid; 3187 3188 /** 3189 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 3190 */ 3191 long mLastAddedTimeUs; 3192 3193 /** 3194 * The last duration that we added to the timer. This is in microseconds. 3195 */ 3196 long mLastAddedDurationUs; 3197 3198 /** 3199 * Whether we are currently in a discharge cycle. 3200 */ 3201 boolean mInDischarge; 3202 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase, Parcel in)3203 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase, Parcel in) { 3204 super(clock, type, timeBase, in); 3205 mUid = uid; 3206 mLastAddedTimeUs = in.readLong(); 3207 mLastAddedDurationUs = in.readLong(); 3208 mInDischarge = timeBase.isRunning(); 3209 } 3210 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase)3211 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase) { 3212 super(clock, type, timeBase); 3213 mUid = uid; 3214 mInDischarge = timeBase.isRunning(); 3215 } 3216 3217 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3218 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3219 super.writeToParcel(out, elapsedRealtimeUs); 3220 out.writeLong(mLastAddedTimeUs); 3221 out.writeLong(mLastAddedDurationUs); 3222 } 3223 3224 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3225 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3226 recomputeLastDuration(elapsedRealtimeUs, false); 3227 mInDischarge = false; 3228 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3229 } 3230 3231 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3232 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3233 recomputeLastDuration(elapsedRealtimeUs, false); 3234 mInDischarge = true; 3235 // If we are still within the last added duration, then re-added whatever remains. 3236 if (mLastAddedTimeUs == elapsedRealtimeUs) { 3237 mTotalTimeUs += mLastAddedDurationUs; 3238 } 3239 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3240 } 3241 3242 @Override logState(Printer pw, String prefix)3243 public void logState(Printer pw, String prefix) { 3244 super.logState(pw, prefix); 3245 pw.println(prefix + "mLastAddedTime=" + mLastAddedTimeUs 3246 + " mLastAddedDuration=" + mLastAddedDurationUs); 3247 } 3248 computeOverage(long curTimeUs)3249 private long computeOverage(long curTimeUs) { 3250 if (mLastAddedTimeUs > 0) { 3251 return mLastAddedDurationUs - curTimeUs; 3252 } 3253 return 0; 3254 } 3255 recomputeLastDuration(long curTimeUs, boolean abort)3256 private void recomputeLastDuration(long curTimeUs, boolean abort) { 3257 final long overage = computeOverage(curTimeUs); 3258 if (overage > 0) { 3259 // Aborting before the duration ran out -- roll back the remaining 3260 // duration. Only do this if currently discharging; otherwise we didn't 3261 // actually add the time. 3262 if (mInDischarge) { 3263 mTotalTimeUs -= overage; 3264 } 3265 if (abort) { 3266 mLastAddedTimeUs = 0; 3267 } else { 3268 mLastAddedTimeUs = curTimeUs; 3269 mLastAddedDurationUs -= overage; 3270 } 3271 } 3272 } 3273 addDuration(long durationMs, long elapsedRealtimeMs)3274 public void addDuration(long durationMs, long elapsedRealtimeMs) { 3275 final long nowUs = elapsedRealtimeMs * 1000; 3276 recomputeLastDuration(nowUs, true); 3277 mLastAddedTimeUs = nowUs; 3278 mLastAddedDurationUs = durationMs * 1000; 3279 if (mInDischarge) { 3280 mTotalTimeUs += mLastAddedDurationUs; 3281 mCount++; 3282 } 3283 } 3284 abortLastDuration(long elapsedRealtimeMs)3285 public void abortLastDuration(long elapsedRealtimeMs) { 3286 final long nowUs = elapsedRealtimeMs * 1000; 3287 recomputeLastDuration(nowUs, true); 3288 } 3289 3290 @Override computeCurrentCountLocked()3291 protected int computeCurrentCountLocked() { 3292 return mCount; 3293 } 3294 3295 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)3296 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 3297 final long overage = computeOverage(elapsedRealtimeUs); 3298 if (overage > 0) { 3299 return mTotalTimeUs = overage; 3300 } 3301 return mTotalTimeUs; 3302 } 3303 3304 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3305 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3306 recomputeLastDuration(elapsedRealtimeUs, true); 3307 boolean stillActive = mLastAddedTimeUs == elapsedRealtimeUs; 3308 super.reset(!stillActive && detachIfReset, elapsedRealtimeUs); 3309 return !stillActive; 3310 } 3311 } 3312 3313 3314 /** 3315 * A StopwatchTimer that also tracks the total and max individual 3316 * time spent active according to the given timebase. Whereas 3317 * StopwatchTimer apportions the time amongst all in the pool, 3318 * the total and max durations are not apportioned. 3319 */ 3320 public static class DurationTimer extends StopwatchTimer { 3321 /** 3322 * The time (in ms) that the timer was last acquired or the time base 3323 * last (re-)started. Increasing the nesting depth does not reset this time. 3324 * 3325 * -1 if the timer is currently not running or the time base is not running. 3326 * 3327 * If written to a parcel, the start time is reset, as is mNesting in the base class 3328 * StopwatchTimer. 3329 */ 3330 long mStartTimeMs = -1; 3331 3332 /** 3333 * The longest time period (in ms) that the timer has been active. Not pooled. 3334 */ 3335 long mMaxDurationMs; 3336 3337 /** 3338 * The time (in ms) that that the timer has been active since most recent 3339 * stopRunningLocked() or reset(). Not pooled. 3340 */ 3341 long mCurrentDurationMs; 3342 3343 /** 3344 * The total time (in ms) that that the timer has been active since most recent reset() 3345 * prior to the current startRunningLocked. This is the sum of all past currentDurations 3346 * (but not including the present currentDuration) since reset. Not pooled. 3347 */ 3348 long mTotalDurationMs; 3349 DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)3350 public DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3351 TimeBase timeBase, Parcel in) { 3352 super(clock, uid, type, timerPool, timeBase, in); 3353 mMaxDurationMs = in.readLong(); 3354 mTotalDurationMs = in.readLong(); 3355 mCurrentDurationMs = in.readLong(); 3356 } 3357 DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)3358 public DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3359 TimeBase timeBase) { 3360 super(clock, uid, type, timerPool, timeBase); 3361 } 3362 3363 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3364 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3365 super.writeToParcel(out, elapsedRealtimeUs); 3366 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 3367 out.writeLong(mTotalDurationMs); 3368 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 3369 } 3370 3371 /** 3372 * Write the summary to the parcel. 3373 * 3374 * Since the time base is probably meaningless after we come back, reading 3375 * from this will have the effect of stopping the timer. So here all we write 3376 * is the max and total durations. 3377 */ 3378 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)3379 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 3380 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3381 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 3382 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 3383 } 3384 3385 /** 3386 * Read the summary parcel. 3387 * 3388 * Has the side effect of stopping the timer. 3389 */ 3390 @Override readSummaryFromParcelLocked(Parcel in)3391 public void readSummaryFromParcelLocked(Parcel in) { 3392 super.readSummaryFromParcelLocked(in); 3393 mMaxDurationMs = in.readLong(); 3394 mTotalDurationMs = in.readLong(); 3395 mStartTimeMs = -1; 3396 mCurrentDurationMs = 0; 3397 } 3398 3399 /** 3400 * The TimeBase time started (again). 3401 * 3402 * If the timer is also running, store the start time. 3403 */ onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3404 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3405 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3406 if (mNesting > 0) { 3407 mStartTimeMs = baseRealtimeUs / 1000; 3408 } 3409 } 3410 3411 /** 3412 * The TimeBase stopped running. 3413 * 3414 * If the timer is running, add the duration into mCurrentDurationMs. 3415 */ 3416 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3417 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3418 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3419 if (mNesting > 0) { 3420 // baseRealtimeUs has already been converted to the timebase's realtime. 3421 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 3422 } 3423 mStartTimeMs = -1; 3424 } 3425 3426 @Override logState(Printer pw, String prefix)3427 public void logState(Printer pw, String prefix) { 3428 super.logState(pw, prefix); 3429 } 3430 3431 @Override startRunningLocked(long elapsedRealtimeMs)3432 public void startRunningLocked(long elapsedRealtimeMs) { 3433 super.startRunningLocked(elapsedRealtimeMs); 3434 if (mNesting == 1 && mTimeBase.isRunning()) { 3435 // Just started 3436 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 3437 } 3438 } 3439 3440 /** 3441 * Decrements the mNesting ref-count on this timer. 3442 * 3443 * If it actually stopped (mNesting went to 0), then possibly update 3444 * mMaxDuration if the current duration was the longest ever. 3445 */ 3446 @Override stopRunningLocked(long elapsedRealtimeMs)3447 public void stopRunningLocked(long elapsedRealtimeMs) { 3448 if (mNesting == 1) { 3449 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 3450 mTotalDurationMs += durationMs; 3451 if (durationMs > mMaxDurationMs) { 3452 mMaxDurationMs = durationMs; 3453 } 3454 mStartTimeMs = -1; 3455 mCurrentDurationMs = 0; 3456 } 3457 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 3458 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 3459 super.stopRunningLocked(elapsedRealtimeMs); 3460 } 3461 3462 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3463 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3464 boolean result = super.reset(detachIfReset, elapsedRealtimeUs); 3465 mMaxDurationMs = 0; 3466 mTotalDurationMs = 0; 3467 mCurrentDurationMs = 0; 3468 if (mNesting > 0) { 3469 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeUs) / 1000; 3470 } else { 3471 mStartTimeMs = -1; 3472 } 3473 return result; 3474 } 3475 3476 /** 3477 * Returns the max duration that this timer has ever seen. 3478 * 3479 * Note that this time is NOT split between the timers in the timer group that 3480 * this timer is attached to. It is the TOTAL time. 3481 */ 3482 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)3483 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 3484 if (mNesting > 0) { 3485 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 3486 if (durationMs > mMaxDurationMs) { 3487 return durationMs; 3488 } 3489 } 3490 return mMaxDurationMs; 3491 } 3492 3493 /** 3494 * Returns the time since the timer was started. 3495 * Returns 0 if the timer is not currently running. 3496 * 3497 * Note that this time is NOT split between the timers in the timer group that 3498 * this timer is attached to. It is the TOTAL time. 3499 * 3500 * Note that if running timer is parceled and unparceled, this method will return 3501 * current duration value at the time of parceling even though timer may not be 3502 * currently running. 3503 */ 3504 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)3505 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 3506 long durationMs = mCurrentDurationMs; 3507 if (mNesting > 0 && mTimeBase.isRunning()) { 3508 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) 3509 - mStartTimeMs; 3510 } 3511 return durationMs; 3512 } 3513 3514 /** 3515 * Returns the total cumulative duration that this timer has been on since reset(). 3516 * If mTimerPool == null, this should be the same 3517 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 3518 * 3519 * Note that this time is NOT split between the timers in the timer group that 3520 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 3521 * the result will not be equivalent to getTotalTimeLocked. 3522 */ 3523 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)3524 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 3525 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 3526 } 3527 } 3528 3529 /** 3530 * State for keeping track of timing information. 3531 */ 3532 public static class StopwatchTimer extends Timer { 3533 final Uid mUid; 3534 final ArrayList<StopwatchTimer> mTimerPool; 3535 3536 int mNesting; 3537 3538 /** 3539 * The last time at which we updated the timer. If mNesting is > 0, 3540 * subtract this from the current battery time to find the amount of 3541 * time we have been running since we last computed an update. 3542 */ 3543 long mUpdateTimeUs; 3544 3545 /** 3546 * The total time at which the timer was acquired, to determine if it 3547 * was actually held for an interesting duration. If time base was not running when timer 3548 * was acquired, will be -1. 3549 */ 3550 long mAcquireTimeUs = -1; 3551 3552 long mTimeoutUs; 3553 3554 /** 3555 * For partial wake locks, keep track of whether we are in the list 3556 * to consume CPU cycles. 3557 */ 3558 @VisibleForTesting 3559 public boolean mInList; 3560 StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)3561 public StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3562 TimeBase timeBase, Parcel in) { 3563 super(clock, type, timeBase, in); 3564 mUid = uid; 3565 mTimerPool = timerPool; 3566 mUpdateTimeUs = in.readLong(); 3567 } 3568 StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)3569 public StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3570 TimeBase timeBase) { 3571 super(clock, type, timeBase); 3572 mUid = uid; 3573 mTimerPool = timerPool; 3574 } 3575 setTimeout(long timeoutUs)3576 public void setTimeout(long timeoutUs) { 3577 mTimeoutUs = timeoutUs; 3578 } 3579 writeToParcel(Parcel out, long elapsedRealtimeUs)3580 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3581 super.writeToParcel(out, elapsedRealtimeUs); 3582 out.writeLong(mUpdateTimeUs); 3583 } 3584 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3585 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3586 if (mNesting > 0) { 3587 if (DEBUG && mType < 0) { 3588 Log.v(TAG, "old mUpdateTime=" + mUpdateTimeUs); 3589 } 3590 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3591 mUpdateTimeUs = baseRealtimeUs; 3592 if (DEBUG && mType < 0) { 3593 Log.v(TAG, "new mUpdateTime=" + mUpdateTimeUs); 3594 } 3595 } 3596 } 3597 logState(Printer pw, String prefix)3598 public void logState(Printer pw, String prefix) { 3599 super.logState(pw, prefix); 3600 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTimeUs 3601 + " mAcquireTime=" + mAcquireTimeUs); 3602 } 3603 startRunningLocked(long elapsedRealtimeMs)3604 public void startRunningLocked(long elapsedRealtimeMs) { 3605 if (mNesting++ == 0) { 3606 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3607 mUpdateTimeUs = batteryRealtimeUs; 3608 if (mTimerPool != null) { 3609 // Accumulate time to all currently active timers before adding 3610 // this new one to the pool. 3611 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 3612 // Add this timer to the active pool 3613 mTimerPool.add(this); 3614 } 3615 if (mTimeBase.isRunning()) { 3616 // Increment the count 3617 mCount++; 3618 mAcquireTimeUs = mTotalTimeUs; 3619 } else { 3620 mAcquireTimeUs = -1; 3621 } 3622 if (DEBUG && mType < 0) { 3623 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTimeUs 3624 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 3625 + " mAcquireTime=" + mAcquireTimeUs); 3626 } 3627 } 3628 } 3629 isRunningLocked()3630 public boolean isRunningLocked() { 3631 return mNesting > 0; 3632 } 3633 stopRunningLocked(long elapsedRealtimeMs)3634 public void stopRunningLocked(long elapsedRealtimeMs) { 3635 // Ignore attempt to stop a timer that isn't running 3636 if (mNesting == 0) { 3637 return; 3638 } 3639 if (--mNesting == 0) { 3640 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3641 if (mTimerPool != null) { 3642 // Accumulate time to all active counters, scaled by the total 3643 // active in the pool, before taking this one out of the pool. 3644 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 3645 // Remove this timer from the active pool 3646 mTimerPool.remove(this); 3647 } else { 3648 mNesting = 1; 3649 mTotalTimeUs = computeRunTimeLocked(batteryRealtimeUs, 3650 elapsedRealtimeMs * 1000); 3651 mNesting = 0; 3652 } 3653 3654 if (DEBUG && mType < 0) { 3655 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTimeUs 3656 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 3657 + " mAcquireTime=" + mAcquireTimeUs); 3658 } 3659 3660 if (mAcquireTimeUs >= 0 && mTotalTimeUs == mAcquireTimeUs) { 3661 // If there was no change in the time, then discard this 3662 // count. A somewhat cheezy strategy, but hey. 3663 mCount--; 3664 } 3665 } 3666 } 3667 stopAllRunningLocked(long elapsedRealtimeMs)3668 public void stopAllRunningLocked(long elapsedRealtimeMs) { 3669 if (mNesting > 0) { 3670 mNesting = 1; 3671 stopRunningLocked(elapsedRealtimeMs); 3672 } 3673 } 3674 3675 // Update the total time for all other running Timers with the same type as this Timer 3676 // due to a change in timer count refreshTimersLocked(long batteryRealtimeUs, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)3677 private static long refreshTimersLocked(long batteryRealtimeUs, 3678 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 3679 long selfTimeUs = 0; 3680 final int N = pool.size(); 3681 for (int i=N-1; i>= 0; i--) { 3682 final StopwatchTimer t = pool.get(i); 3683 long heldTimeUs = batteryRealtimeUs - t.mUpdateTimeUs; 3684 if (heldTimeUs > 0) { 3685 final long myTimeUs = heldTimeUs / N; 3686 if (t == self) { 3687 selfTimeUs = myTimeUs; 3688 } 3689 t.mTotalTimeUs += myTimeUs; 3690 } 3691 t.mUpdateTimeUs = batteryRealtimeUs; 3692 } 3693 return selfTimeUs; 3694 } 3695 3696 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)3697 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 3698 if (mTimeoutUs > 0 && curBatteryRealtimeUs > mUpdateTimeUs + mTimeoutUs) { 3699 curBatteryRealtimeUs = mUpdateTimeUs + mTimeoutUs; 3700 } 3701 return mTotalTimeUs + (mNesting > 0 3702 ? (curBatteryRealtimeUs - mUpdateTimeUs) 3703 / (mTimerPool != null && mTimerPool.size() > 0 ? mTimerPool.size() : 1) 3704 : 0); 3705 } 3706 3707 @Override computeCurrentCountLocked()3708 protected int computeCurrentCountLocked() { 3709 return mCount; 3710 } 3711 3712 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3713 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3714 boolean canDetach = mNesting <= 0; 3715 super.reset(canDetach && detachIfReset, elapsedRealtimeUs); 3716 if (mNesting > 0) { 3717 mUpdateTimeUs = mTimeBase.getRealtime(elapsedRealtimeUs); 3718 } 3719 // To ensure mCount isn't decreased to -1 if timer is stopped later. 3720 mAcquireTimeUs = -1; 3721 return canDetach; 3722 } 3723 3724 @Override detach()3725 public void detach() { 3726 super.detach(); 3727 if (mTimerPool != null) { 3728 mTimerPool.remove(this); 3729 } 3730 } 3731 3732 @Override readSummaryFromParcelLocked(Parcel in)3733 public void readSummaryFromParcelLocked(Parcel in) { 3734 super.readSummaryFromParcelLocked(in); 3735 mNesting = 0; 3736 } 3737 3738 /** 3739 * Set the mark so that we can query later for the total time the timer has 3740 * accumulated since this point. The timer can be running or not. 3741 * 3742 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 3743 */ setMark(long elapsedRealtimeMs)3744 public void setMark(long elapsedRealtimeMs) { 3745 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3746 if (mNesting > 0) { 3747 // We are running. 3748 if (mTimerPool != null) { 3749 refreshTimersLocked(batteryRealtimeUs, mTimerPool, this); 3750 } else { 3751 mTotalTimeUs += batteryRealtimeUs - mUpdateTimeUs; 3752 mUpdateTimeUs = batteryRealtimeUs; 3753 } 3754 } 3755 mTimeBeforeMarkUs = mTotalTimeUs; 3756 } 3757 } 3758 3759 /** 3760 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 3761 * TimeBase is effectively a subset of the other. 3762 */ 3763 public static class DualTimer extends DurationTimer { 3764 // This class both is a DurationTimer and also holds a second DurationTimer. 3765 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 3766 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 3767 // STATS_SINCE_CHARGED). 3768 // mSubTimer typically tracks only part of the total time, such as background time, as 3769 // determined by a subTimeBase. It is NOT pooled. 3770 private final DurationTimer mSubTimer; 3771 3772 /** 3773 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 3774 * The main timer (this) is based on the given timeBase and timerPool. 3775 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 3776 * the main timer is. 3777 */ DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)3778 public DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3779 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 3780 super(clock, uid, type, timerPool, timeBase, in); 3781 mSubTimer = new DurationTimer(clock, uid, type, null, subTimeBase, in); 3782 } 3783 3784 /** 3785 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 3786 * The main timer (this) is based on the given timeBase and timerPool. 3787 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 3788 * the main timer is. 3789 */ DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)3790 public DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3791 TimeBase timeBase, TimeBase subTimeBase) { 3792 super(clock, uid, type, timerPool, timeBase); 3793 mSubTimer = new DurationTimer(clock, uid, type, null, subTimeBase); 3794 } 3795 3796 /** Get the secondary timer. */ 3797 @Override getSubTimer()3798 public DurationTimer getSubTimer() { 3799 return mSubTimer; 3800 } 3801 3802 @Override startRunningLocked(long elapsedRealtimeMs)3803 public void startRunningLocked(long elapsedRealtimeMs) { 3804 super.startRunningLocked(elapsedRealtimeMs); 3805 mSubTimer.startRunningLocked(elapsedRealtimeMs); 3806 } 3807 3808 @Override stopRunningLocked(long elapsedRealtimeMs)3809 public void stopRunningLocked(long elapsedRealtimeMs) { 3810 super.stopRunningLocked(elapsedRealtimeMs); 3811 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 3812 } 3813 3814 @Override stopAllRunningLocked(long elapsedRealtimeMs)3815 public void stopAllRunningLocked(long elapsedRealtimeMs) { 3816 super.stopAllRunningLocked(elapsedRealtimeMs); 3817 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 3818 } 3819 3820 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3821 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3822 boolean active = false; 3823 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 3824 active |= !mSubTimer.reset(false, elapsedRealtimeUs); 3825 active |= !super.reset(detachIfReset, elapsedRealtimeUs); 3826 return !active; 3827 } 3828 3829 @Override detach()3830 public void detach() { 3831 mSubTimer.detach(); 3832 super.detach(); 3833 } 3834 3835 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3836 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3837 super.writeToParcel(out, elapsedRealtimeUs); 3838 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 3839 } 3840 3841 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)3842 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 3843 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3844 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3845 } 3846 3847 @Override readSummaryFromParcelLocked(Parcel in)3848 public void readSummaryFromParcelLocked(Parcel in) { 3849 super.readSummaryFromParcelLocked(in); 3850 mSubTimer.readSummaryFromParcelLocked(in); 3851 } 3852 } 3853 3854 3855 public abstract class OverflowArrayMap<T> { 3856 private static final String OVERFLOW_NAME = "*overflow*"; 3857 3858 final int mUid; 3859 final ArrayMap<String, T> mMap = new ArrayMap<>(); 3860 T mCurOverflow; 3861 ArrayMap<String, MutableInt> mActiveOverflow; 3862 long mLastOverflowTimeMs; 3863 long mLastOverflowFinishTimeMs; 3864 long mLastClearTimeMs; 3865 long mLastCleanupTimeMs; 3866 OverflowArrayMap(int uid)3867 public OverflowArrayMap(int uid) { 3868 mUid = uid; 3869 } 3870 getMap()3871 public ArrayMap<String, T> getMap() { 3872 return mMap; 3873 } 3874 clear()3875 public void clear() { 3876 mLastClearTimeMs = SystemClock.elapsedRealtime(); 3877 mMap.clear(); 3878 mCurOverflow = null; 3879 mActiveOverflow = null; 3880 } 3881 add(String name, T obj)3882 public void add(String name, T obj) { 3883 if (name == null) { 3884 name = ""; 3885 } 3886 mMap.put(name, obj); 3887 if (OVERFLOW_NAME.equals(name)) { 3888 mCurOverflow = obj; 3889 } 3890 } 3891 cleanup(long elapsedRealtimeMs)3892 public void cleanup(long elapsedRealtimeMs) { 3893 mLastCleanupTimeMs = elapsedRealtimeMs; 3894 if (mActiveOverflow != null) { 3895 if (mActiveOverflow.size() == 0) { 3896 mActiveOverflow = null; 3897 } 3898 } 3899 if (mActiveOverflow == null) { 3900 // There is no currently active overflow, so we should no longer have 3901 // an overflow entry. 3902 if (mMap.containsKey(OVERFLOW_NAME)) { 3903 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 3904 + mMap.get(OVERFLOW_NAME)); 3905 mMap.remove(OVERFLOW_NAME); 3906 } 3907 mCurOverflow = null; 3908 } else { 3909 // There is currently active overflow, so we should still have an overflow entry. 3910 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 3911 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 3912 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 3913 } 3914 } 3915 } 3916 startObject(String name, long elapsedRealtimeMs)3917 public T startObject(String name, long elapsedRealtimeMs) { 3918 if (name == null) { 3919 name = ""; 3920 } 3921 T obj = mMap.get(name); 3922 if (obj != null) { 3923 return obj; 3924 } 3925 3926 // No object exists for the given name, but do we currently have it 3927 // running as part of the overflow? 3928 if (mActiveOverflow != null) { 3929 MutableInt over = mActiveOverflow.get(name); 3930 if (over != null) { 3931 // We are already actively counting this name in the overflow object. 3932 obj = mCurOverflow; 3933 if (obj == null) { 3934 // Shouldn't be here, but we'll try to recover. 3935 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 3936 obj = mCurOverflow = instantiateObject(); 3937 mMap.put(OVERFLOW_NAME, obj); 3938 } 3939 over.value++; 3940 return obj; 3941 } 3942 } 3943 3944 // No object exists for given name nor in the overflow; we need to make 3945 // a new one. 3946 final int N = mMap.size(); 3947 if (N >= MAX_WAKELOCKS_PER_UID) { 3948 // Went over the limit on number of objects to track; this one goes 3949 // in to the overflow. 3950 obj = mCurOverflow; 3951 if (obj == null) { 3952 // Need to start overflow now... 3953 obj = mCurOverflow = instantiateObject(); 3954 mMap.put(OVERFLOW_NAME, obj); 3955 } 3956 if (mActiveOverflow == null) { 3957 mActiveOverflow = new ArrayMap<>(); 3958 } 3959 mActiveOverflow.put(name, new MutableInt(1)); 3960 mLastOverflowTimeMs = elapsedRealtimeMs; 3961 return obj; 3962 } 3963 3964 // Normal case where we just need to make a new object. 3965 obj = instantiateObject(); 3966 mMap.put(name, obj); 3967 return obj; 3968 } 3969 stopObject(String name, long elapsedRealtimeMs)3970 public T stopObject(String name, long elapsedRealtimeMs) { 3971 if (name == null) { 3972 name = ""; 3973 } 3974 T obj = mMap.get(name); 3975 if (obj != null) { 3976 return obj; 3977 } 3978 3979 // No object exists for the given name, but do we currently have it 3980 // running as part of the overflow? 3981 if (mActiveOverflow != null) { 3982 MutableInt over = mActiveOverflow.get(name); 3983 if (over != null) { 3984 // We are already actively counting this name in the overflow object. 3985 obj = mCurOverflow; 3986 if (obj != null) { 3987 over.value--; 3988 if (over.value <= 0) { 3989 mActiveOverflow.remove(name); 3990 mLastOverflowFinishTimeMs = elapsedRealtimeMs; 3991 } 3992 return obj; 3993 } 3994 } 3995 } 3996 3997 // Huh, they are stopping an active operation but we can't find one! 3998 // That's not good. 3999 StringBuilder sb = new StringBuilder(); 4000 sb.append("Unable to find object for "); 4001 sb.append(name); 4002 sb.append(" in uid "); 4003 sb.append(mUid); 4004 sb.append(" mapsize="); 4005 sb.append(mMap.size()); 4006 sb.append(" activeoverflow="); 4007 sb.append(mActiveOverflow); 4008 sb.append(" curoverflow="); 4009 sb.append(mCurOverflow); 4010 long now = elapsedRealtimeMs; 4011 if (mLastOverflowTimeMs != 0) { 4012 sb.append(" lastOverflowTime="); 4013 TimeUtils.formatDuration(mLastOverflowTimeMs - now, sb); 4014 } 4015 if (mLastOverflowFinishTimeMs != 0) { 4016 sb.append(" lastOverflowFinishTime="); 4017 TimeUtils.formatDuration(mLastOverflowFinishTimeMs - now, sb); 4018 } 4019 if (mLastClearTimeMs != 0) { 4020 sb.append(" lastClearTime="); 4021 TimeUtils.formatDuration(mLastClearTimeMs - now, sb); 4022 } 4023 if (mLastCleanupTimeMs != 0) { 4024 sb.append(" lastCleanupTime="); 4025 TimeUtils.formatDuration(mLastCleanupTimeMs - now, sb); 4026 } 4027 Slog.wtf(TAG, sb.toString()); 4028 return null; 4029 } 4030 instantiateObject()4031 public abstract T instantiateObject(); 4032 } 4033 4034 @SuppressWarnings("ParcelableCreator") 4035 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 4036 implements Parcelable { 4037 private final Clock mClock; 4038 private final TimeBase mTimeBase; 4039 private int mNumTxStates; 4040 private int mProcessState; 4041 private TimeMultiStateCounter mIdleTimeMillis; 4042 private final LongSamplingCounter mScanTimeMillis; 4043 private final LongSamplingCounter mSleepTimeMillis; 4044 private TimeMultiStateCounter mRxTimeMillis; 4045 private TimeMultiStateCounter[] mTxTimeMillis; 4046 private final LongSamplingCounter mPowerDrainMaMs; 4047 private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs; 4048 ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates)4049 public ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates) { 4050 mClock = clock; 4051 mTimeBase = timeBase; 4052 mNumTxStates = numTxStates; 4053 mScanTimeMillis = new LongSamplingCounter(timeBase); 4054 mSleepTimeMillis = new LongSamplingCounter(timeBase); 4055 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 4056 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase); 4057 } 4058 readSummaryFromParcel(Parcel in)4059 public void readSummaryFromParcel(Parcel in) { 4060 mIdleTimeMillis = readTimeMultiStateCounter(in, mTimeBase); 4061 mScanTimeMillis.readSummaryFromParcelLocked(in); 4062 mSleepTimeMillis.readSummaryFromParcelLocked(in); 4063 mRxTimeMillis = readTimeMultiStateCounter(in, mTimeBase); 4064 mTxTimeMillis = readTimeMultiStateCounters(in, mTimeBase, mNumTxStates); 4065 4066 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 4067 mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in); 4068 } 4069 4070 @Override describeContents()4071 public int describeContents() { 4072 return 0; 4073 } 4074 writeSummaryToParcel(Parcel dest)4075 public void writeSummaryToParcel(Parcel dest) { 4076 writeTimeMultiStateCounter(dest, mIdleTimeMillis); 4077 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 4078 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 4079 writeTimeMultiStateCounter(dest, mRxTimeMillis); 4080 writeTimeMultiStateCounters(dest, mTxTimeMillis); 4081 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 4082 mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest); 4083 } 4084 4085 @Override writeToParcel(Parcel dest, int flags)4086 public void writeToParcel(Parcel dest, int flags) { 4087 writeTimeMultiStateCounter(dest, mIdleTimeMillis); 4088 mScanTimeMillis.writeToParcel(dest); 4089 mSleepTimeMillis.writeToParcel(dest); 4090 writeTimeMultiStateCounter(dest, mRxTimeMillis); 4091 writeTimeMultiStateCounters(dest, mTxTimeMillis); 4092 mPowerDrainMaMs.writeToParcel(dest); 4093 mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); 4094 } 4095 readTimeMultiStateCounter(Parcel in, TimeBase timeBase)4096 private TimeMultiStateCounter readTimeMultiStateCounter(Parcel in, TimeBase timeBase) { 4097 if (in.readBoolean()) { 4098 return TimeMultiStateCounter.readFromParcel(in, timeBase, 4099 BatteryConsumer.PROCESS_STATE_COUNT, mClock.elapsedRealtime()); 4100 } 4101 return null; 4102 } 4103 writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter)4104 private void writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter) { 4105 if (counter != null) { 4106 dest.writeBoolean(true); 4107 counter.writeToParcel(dest); 4108 } else { 4109 dest.writeBoolean(false); 4110 } 4111 } 4112 readTimeMultiStateCounters(Parcel in, TimeBase timeBase, int expectedNumCounters)4113 private TimeMultiStateCounter[] readTimeMultiStateCounters(Parcel in, TimeBase timeBase, 4114 int expectedNumCounters) { 4115 if (in.readBoolean()) { 4116 final int numCounters = in.readInt(); 4117 boolean valid = (numCounters == expectedNumCounters); 4118 // Need to read counters out of the Parcel, even if all or some of them are 4119 // invalid. 4120 TimeMultiStateCounter[] counters = new TimeMultiStateCounter[numCounters]; 4121 for (int i = 0; i < numCounters; i++) { 4122 final TimeMultiStateCounter counter = TimeMultiStateCounter.readFromParcel(in, 4123 timeBase, BatteryConsumer.PROCESS_STATE_COUNT, 4124 mClock.elapsedRealtime()); 4125 if (counter != null) { 4126 counters[i] = counter; 4127 } else { 4128 valid = false; 4129 } 4130 } 4131 if (valid) { 4132 return counters; 4133 } 4134 } 4135 return null; 4136 } 4137 writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters)4138 private void writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters) { 4139 if (counters != null) { 4140 dest.writeBoolean(true); 4141 dest.writeInt(counters.length); 4142 for (TimeMultiStateCounter counter : counters) { 4143 counter.writeToParcel(dest); 4144 } 4145 } else { 4146 dest.writeBoolean(false); 4147 } 4148 } 4149 reset(boolean detachIfReset, long elapsedRealtimeUs)4150 public void reset(boolean detachIfReset, long elapsedRealtimeUs) { 4151 resetIfNotNull(mIdleTimeMillis, detachIfReset, elapsedRealtimeUs); 4152 mScanTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 4153 mSleepTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 4154 resetIfNotNull(mRxTimeMillis, detachIfReset, elapsedRealtimeUs); 4155 resetIfNotNull(mTxTimeMillis, detachIfReset, elapsedRealtimeUs); 4156 mPowerDrainMaMs.reset(detachIfReset, elapsedRealtimeUs); 4157 mMonitoredRailChargeConsumedMaMs.reset(detachIfReset, elapsedRealtimeUs); 4158 } 4159 detach()4160 public void detach() { 4161 detachIfNotNull(mIdleTimeMillis); 4162 mScanTimeMillis.detach(); 4163 mSleepTimeMillis.detach(); 4164 detachIfNotNull(mRxTimeMillis); 4165 detachIfNotNull(mTxTimeMillis); 4166 mPowerDrainMaMs.detach(); 4167 mMonitoredRailChargeConsumedMaMs.detach(); 4168 } 4169 4170 /** 4171 * @return a LongSamplingCounter, measuring time spent in the idle state in 4172 * milliseconds. 4173 */ 4174 @Override getIdleTimeCounter()4175 public LongCounter getIdleTimeCounter() { 4176 if (mIdleTimeMillis == null) { 4177 return ZERO_LONG_COUNTER; 4178 } 4179 return mIdleTimeMillis; 4180 } 4181 getOrCreateIdleTimeCounter()4182 private TimeMultiStateCounter getOrCreateIdleTimeCounter() { 4183 if (mIdleTimeMillis == null) { 4184 mIdleTimeMillis = createTimeMultiStateCounter(); 4185 } 4186 return mIdleTimeMillis; 4187 } 4188 4189 /** 4190 * @return a LongSamplingCounter, measuring time spent in the scan state in 4191 * milliseconds. 4192 */ 4193 @Override getScanTimeCounter()4194 public LongSamplingCounter getScanTimeCounter() { 4195 return mScanTimeMillis; 4196 } 4197 4198 /** 4199 * @return a LongSamplingCounter, measuring time spent in the sleep state in 4200 * milliseconds. 4201 */ 4202 @Override getSleepTimeCounter()4203 public LongSamplingCounter getSleepTimeCounter() { 4204 return mSleepTimeMillis; 4205 } 4206 4207 /** 4208 * @return a LongSamplingCounter, measuring time spent in the receive state in 4209 * milliseconds. 4210 */ 4211 @Override getRxTimeCounter()4212 public LongCounter getRxTimeCounter() { 4213 if (mRxTimeMillis == null) { 4214 return ZERO_LONG_COUNTER; 4215 } 4216 return mRxTimeMillis; 4217 } 4218 getOrCreateRxTimeCounter()4219 private TimeMultiStateCounter getOrCreateRxTimeCounter() { 4220 if (mRxTimeMillis == null) { 4221 mRxTimeMillis = createTimeMultiStateCounter(); 4222 } 4223 return mRxTimeMillis; 4224 } 4225 4226 /** 4227 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 4228 * milliseconds. 4229 */ 4230 @Override getTxTimeCounters()4231 public LongCounter[] getTxTimeCounters() { 4232 if (mTxTimeMillis == null) { 4233 return ZERO_LONG_COUNTER_ARRAY; 4234 } 4235 return mTxTimeMillis; 4236 } 4237 getOrCreateTxTimeCounters()4238 private TimeMultiStateCounter[] getOrCreateTxTimeCounters() { 4239 if (mTxTimeMillis == null) { 4240 mTxTimeMillis = new TimeMultiStateCounter[mNumTxStates]; 4241 for (int i = 0; i < mNumTxStates; i++) { 4242 mTxTimeMillis[i] = createTimeMultiStateCounter(); 4243 } 4244 } 4245 return mTxTimeMillis; 4246 } 4247 createTimeMultiStateCounter()4248 private TimeMultiStateCounter createTimeMultiStateCounter() { 4249 final long timestampMs = mClock.elapsedRealtime(); 4250 TimeMultiStateCounter counter = new TimeMultiStateCounter(mTimeBase, 4251 BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 4252 counter.setState(mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 4253 timestampMs); 4254 counter.update(0, timestampMs); 4255 return counter; 4256 } 4257 4258 /** 4259 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 4260 */ 4261 @Override getPowerCounter()4262 public LongSamplingCounter getPowerCounter() { 4263 return mPowerDrainMaMs; 4264 } 4265 4266 /** 4267 * @return a LongSamplingCounter, measuring actual monitored rail energy consumed 4268 * milli-ampere milli-seconds (mAmS). 4269 */ 4270 @Override getMonitoredRailChargeConsumedMaMs()4271 public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() { 4272 return mMonitoredRailChargeConsumedMaMs; 4273 } 4274 setState(int processState, long elapsedTimeMs)4275 private void setState(int processState, long elapsedTimeMs) { 4276 mProcessState = processState; 4277 if (mIdleTimeMillis != null) { 4278 mIdleTimeMillis.setState(processState, elapsedTimeMs); 4279 } 4280 if (mRxTimeMillis != null) { 4281 mRxTimeMillis.setState(processState, elapsedTimeMs); 4282 } 4283 if (mTxTimeMillis != null) { 4284 for (int i = 0; i < mTxTimeMillis.length; i++) { 4285 mTxTimeMillis[i].setState(processState, elapsedTimeMs); 4286 } 4287 } 4288 } 4289 } 4290 4291 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)4292 public SamplingTimer getRpmTimerLocked(String name) { 4293 SamplingTimer rpmt = mRpmStats.get(name); 4294 if (rpmt == null) { 4295 rpmt = new SamplingTimer(mClock, mOnBatteryTimeBase); 4296 mRpmStats.put(name, rpmt); 4297 } 4298 return rpmt; 4299 } 4300 4301 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)4302 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 4303 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 4304 if (rpmt == null) { 4305 rpmt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 4306 mScreenOffRpmStats.put(name, rpmt); 4307 } 4308 return rpmt; 4309 } 4310 4311 /* 4312 * Get the wakeup reason counter, and create a new one if one 4313 * doesn't already exist. 4314 */ getWakeupReasonTimerLocked(String name)4315 public SamplingTimer getWakeupReasonTimerLocked(String name) { 4316 SamplingTimer timer = mWakeupReasonStats.get(name); 4317 if (timer == null) { 4318 timer = new SamplingTimer(mClock, mOnBatteryTimeBase); 4319 mWakeupReasonStats.put(name, timer); 4320 } 4321 return timer; 4322 } 4323 4324 /* 4325 * Get the KernelWakelockTimer associated with name, and create a new one if one 4326 * doesn't already exist. 4327 */ getKernelWakelockTimerLocked(String name)4328 public SamplingTimer getKernelWakelockTimerLocked(String name) { 4329 SamplingTimer kwlt = mKernelWakelockStats.get(name); 4330 if (kwlt == null) { 4331 kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 4332 mKernelWakelockStats.put(name, kwlt); 4333 } 4334 return kwlt; 4335 } 4336 getKernelMemoryTimerLocked(long bucket)4337 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 4338 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 4339 if (kmt == null) { 4340 kmt = new SamplingTimer(mClock, mOnBatteryTimeBase); 4341 mKernelMemoryStats.put(bucket, kmt); 4342 } 4343 return kmt; 4344 } 4345 4346 private class HistoryStepDetailsCalculatorImpl implements HistoryStepDetailsCalculator { 4347 private final HistoryStepDetails mDetails = new HistoryStepDetails(); 4348 4349 private boolean mHasHistoryStepDetails; 4350 private boolean mUpdateRequested; 4351 4352 /** 4353 * Total time (in milliseconds) spent executing in user code. 4354 */ 4355 private long mLastStepCpuUserTimeMs; 4356 private long mCurStepCpuUserTimeMs; 4357 /** 4358 * Total time (in milliseconds) spent executing in kernel code. 4359 */ 4360 private long mLastStepCpuSystemTimeMs; 4361 private long mCurStepCpuSystemTimeMs; 4362 /** 4363 * Times from /proc/stat (but measured in milliseconds). 4364 */ 4365 private long mLastStepStatUserTimeMs; 4366 private long mLastStepStatSystemTimeMs; 4367 private long mLastStepStatIOWaitTimeMs; 4368 private long mLastStepStatIrqTimeMs; 4369 private long mLastStepStatSoftIrqTimeMs; 4370 private long mLastStepStatIdleTimeMs; 4371 private long mCurStepStatUserTimeMs; 4372 private long mCurStepStatSystemTimeMs; 4373 private long mCurStepStatIOWaitTimeMs; 4374 private long mCurStepStatIrqTimeMs; 4375 private long mCurStepStatSoftIrqTimeMs; 4376 private long mCurStepStatIdleTimeMs; 4377 4378 @Override getHistoryStepDetails()4379 public HistoryStepDetails getHistoryStepDetails() { 4380 if (!mUpdateRequested) { 4381 mUpdateRequested = true; 4382 // Perform a CPU update right after we do this collection, so we have started 4383 // collecting good data for the next step. 4384 requestImmediateCpuUpdate(); 4385 4386 if (mPlatformIdleStateCallback != null) { 4387 mDetails.statSubsystemPowerState = 4388 mPlatformIdleStateCallback.getSubsystemLowPowerStats(); 4389 if (DEBUG) { 4390 Slog.i(TAG, 4391 "WRITE SubsystemPowerState:" + mDetails.statSubsystemPowerState); 4392 } 4393 } 4394 } 4395 4396 if (!mHasHistoryStepDetails) { 4397 // We are not generating a delta, so all we need to do is reset the stats 4398 // we will later be doing a delta from. 4399 final int uidCount = mUidStats.size(); 4400 for (int i = 0; i < uidCount; i++) { 4401 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4402 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 4403 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 4404 } 4405 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 4406 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 4407 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 4408 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 4409 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 4410 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 4411 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 4412 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 4413 return null; 4414 } else { 4415 if (DEBUG) { 4416 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTimeMs + " sys=" 4417 + mLastStepStatSystemTimeMs + " io=" + mLastStepStatIOWaitTimeMs 4418 + " irq=" + mLastStepStatIrqTimeMs + " sirq=" 4419 + mLastStepStatSoftIrqTimeMs + " idle=" + mLastStepStatIdleTimeMs); 4420 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTimeMs + " sys=" 4421 + mCurStepStatSystemTimeMs + " io=" + mCurStepStatIOWaitTimeMs 4422 + " irq=" + mCurStepStatIrqTimeMs + " sirq=" 4423 + mCurStepStatSoftIrqTimeMs + " idle=" + mCurStepStatIdleTimeMs); 4424 } 4425 mDetails.userTime = (int) (mCurStepCpuUserTimeMs - mLastStepCpuUserTimeMs); 4426 mDetails.systemTime = (int) (mCurStepCpuSystemTimeMs - mLastStepCpuSystemTimeMs); 4427 mDetails.statUserTime = (int) (mCurStepStatUserTimeMs - mLastStepStatUserTimeMs); 4428 mDetails.statSystemTime = 4429 (int) (mCurStepStatSystemTimeMs - mLastStepStatSystemTimeMs); 4430 mDetails.statIOWaitTime = 4431 (int) (mCurStepStatIOWaitTimeMs - mLastStepStatIOWaitTimeMs); 4432 mDetails.statIrqTime = (int) (mCurStepStatIrqTimeMs - mLastStepStatIrqTimeMs); 4433 mDetails.statSoftIrqTime = 4434 (int) (mCurStepStatSoftIrqTimeMs - mLastStepStatSoftIrqTimeMs); 4435 mDetails.statIdlTime = (int) (mCurStepStatIdleTimeMs - mLastStepStatIdleTimeMs); 4436 mDetails.appCpuUid1 = mDetails.appCpuUid2 = mDetails.appCpuUid3 = -1; 4437 mDetails.appCpuUTime1 = mDetails.appCpuUTime2 = mDetails.appCpuUTime3 = 0; 4438 mDetails.appCpuSTime1 = mDetails.appCpuSTime2 = mDetails.appCpuSTime3 = 0; 4439 final int uidCount = mUidStats.size(); 4440 for (int i = 0; i < uidCount; i++) { 4441 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4442 final int totalUTimeMs = 4443 (int) (uid.mCurStepUserTimeMs - uid.mLastStepUserTimeMs); 4444 final int totalSTimeMs = 4445 (int) (uid.mCurStepSystemTimeMs - uid.mLastStepSystemTimeMs); 4446 final int totalTimeMs = totalUTimeMs + totalSTimeMs; 4447 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 4448 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 4449 if (totalTimeMs <= (mDetails.appCpuUTime3 + mDetails.appCpuSTime3)) { 4450 continue; 4451 } 4452 if (totalTimeMs <= (mDetails.appCpuUTime2 + mDetails.appCpuSTime2)) { 4453 mDetails.appCpuUid3 = uid.mUid; 4454 mDetails.appCpuUTime3 = totalUTimeMs; 4455 mDetails.appCpuSTime3 = totalSTimeMs; 4456 } else { 4457 mDetails.appCpuUid3 = mDetails.appCpuUid2; 4458 mDetails.appCpuUTime3 = mDetails.appCpuUTime2; 4459 mDetails.appCpuSTime3 = mDetails.appCpuSTime2; 4460 if (totalTimeMs <= (mDetails.appCpuUTime1 + mDetails.appCpuSTime1)) { 4461 mDetails.appCpuUid2 = uid.mUid; 4462 mDetails.appCpuUTime2 = totalUTimeMs; 4463 mDetails.appCpuSTime2 = totalSTimeMs; 4464 } else { 4465 mDetails.appCpuUid2 = mDetails.appCpuUid1; 4466 mDetails.appCpuUTime2 = mDetails.appCpuUTime1; 4467 mDetails.appCpuSTime2 = mDetails.appCpuSTime1; 4468 mDetails.appCpuUid1 = uid.mUid; 4469 mDetails.appCpuUTime1 = totalUTimeMs; 4470 mDetails.appCpuSTime1 = totalSTimeMs; 4471 } 4472 } 4473 } 4474 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 4475 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 4476 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 4477 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 4478 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 4479 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 4480 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 4481 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 4482 return mDetails; 4483 } 4484 } 4485 addCpuStats(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs)4486 public void addCpuStats(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, 4487 int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, 4488 int statSoftIrqTimeMs, int statIdleTimeMs) { 4489 if (DEBUG) { 4490 Slog.d(TAG, "Adding cpu: tuser=" + totalUTimeMs + " tsys=" + totalSTimeMs 4491 + " user=" + statUserTimeMs + " sys=" + statSystemTimeMs 4492 + " io=" + statIOWaitTimeMs + " irq=" + statIrqTimeMs 4493 + " sirq=" + statSoftIrqTimeMs + " idle=" + statIdleTimeMs); 4494 } 4495 mCurStepCpuUserTimeMs += totalUTimeMs; 4496 mCurStepCpuSystemTimeMs += totalSTimeMs; 4497 mCurStepStatUserTimeMs += statUserTimeMs; 4498 mCurStepStatSystemTimeMs += statSystemTimeMs; 4499 mCurStepStatIOWaitTimeMs += statIOWaitTimeMs; 4500 mCurStepStatIrqTimeMs += statIrqTimeMs; 4501 mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs; 4502 mCurStepStatIdleTimeMs += statIdleTimeMs; 4503 } 4504 finishAddingCpuLocked()4505 public void finishAddingCpuLocked() { 4506 mHasHistoryStepDetails = true; 4507 mUpdateRequested = false; 4508 } 4509 4510 @Override clear()4511 public void clear() { 4512 mHasHistoryStepDetails = false; 4513 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs = 0; 4514 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs = 0; 4515 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs = 0; 4516 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs = 0; 4517 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs = 0; 4518 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs = 0; 4519 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs = 0; 4520 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs = 0; 4521 } 4522 } 4523 4524 @GuardedBy("this") 4525 @Override commitCurrentHistoryBatchLocked()4526 public void commitCurrentHistoryBatchLocked() { 4527 mHistory.commitCurrentHistoryBatchLocked(); 4528 } 4529 4530 @GuardedBy("this") createFakeHistoryEvents(long numEvents)4531 public void createFakeHistoryEvents(long numEvents) { 4532 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 4533 final long uptimeMs = mClock.uptimeMillis(); 4534 for(long i = 0; i < numEvents; i++) { 4535 noteLongPartialWakelockStart("name1", "historyName1", 1000, 4536 elapsedRealtimeMs, uptimeMs); 4537 noteLongPartialWakelockFinish("name1", "historyName1", 1000, 4538 elapsedRealtimeMs, uptimeMs); 4539 } 4540 } 4541 4542 @GuardedBy("this") recordHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)4543 public void recordHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 4544 String name, int uid) { 4545 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid); 4546 } 4547 4548 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, long realtimeUs)4549 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, 4550 long realtimeUs) { 4551 final boolean screenOff = !Display.isOnState(screenState); 4552 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 4553 final boolean updateOnBatteryScreenOffTimeBase = 4554 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 4555 4556 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 4557 if (updateOnBatteryScreenOffTimeBase) { 4558 updateKernelWakelocksLocked(realtimeUs); 4559 updateBatteryPropertiesLocked(); 4560 } 4561 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 4562 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 4563 // improved, remove the surrounding if{}. 4564 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 4565 // if either OnBattery or OnBatteryScreenOfftimebase changes. 4566 updateRpmStatsLocked(realtimeUs); 4567 } 4568 if (DEBUG_ENERGY_CPU) { 4569 Slog.d(TAG, "Updating cpu time because screen is now " 4570 + Display.stateToString(screenState) 4571 + " and battery is " + (unplugged ? "on" : "off")); 4572 } 4573 4574 mOnBatteryTimeBase.setRunning(unplugged, uptimeUs, realtimeUs); 4575 if (updateOnBatteryTimeBase) { 4576 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4577 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptimeUs, realtimeUs); 4578 } 4579 } 4580 if (updateOnBatteryScreenOffTimeBase) { 4581 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, 4582 uptimeUs, realtimeUs); 4583 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4584 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptimeUs, realtimeUs); 4585 } 4586 } 4587 } 4588 } 4589 4590 @GuardedBy("this") updateBatteryPropertiesLocked()4591 protected void updateBatteryPropertiesLocked() { 4592 try { 4593 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 4594 ServiceManager.getService("batteryproperties")); 4595 if (registrar != null) { 4596 registrar.scheduleUpdate(); 4597 } 4598 } catch (RemoteException e) { 4599 // Ignore. 4600 } 4601 } 4602 onIsolatedUidAdded(int isolatedUid, int parentUid)4603 private void onIsolatedUidAdded(int isolatedUid, int parentUid) { 4604 long realtime = mClock.elapsedRealtime(); 4605 long uptime = mClock.uptimeMillis(); 4606 synchronized (this) { 4607 getUidStatsLocked(parentUid, realtime, uptime).addIsolatedUid(isolatedUid); 4608 } 4609 } 4610 onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid)4611 private void onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid) { 4612 long realtime = mClock.elapsedRealtime(); 4613 mPowerStatsUidResolver.retainIsolatedUid(isolatedUid); 4614 synchronized (this) { 4615 mPendingRemovedUids.add(new UidToRemove(isolatedUid, realtime)); 4616 } 4617 if (mExternalSync != null) { 4618 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 4619 } 4620 } 4621 onAfterIsolatedUidRemoved(int isolatedUid, int parentUid)4622 private void onAfterIsolatedUidRemoved(int isolatedUid, int parentUid) { 4623 long realtime = mClock.elapsedRealtime(); 4624 long uptime = mClock.uptimeMillis(); 4625 synchronized (this) { 4626 getUidStatsLocked(parentUid, realtime, uptime).removeIsolatedUid(isolatedUid); 4627 } 4628 } 4629 4630 /** 4631 * Isolated uid should only be removed after all wakelocks associated with the uid are stopped 4632 * and the cpu time-in-state has been read one last time for the uid. 4633 */ 4634 @GuardedBy("this") releaseIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs)4635 public void releaseIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs) { 4636 mPowerStatsUidResolver.releaseIsolatedUid(isolatedUid); 4637 } 4638 mapUid(int uid)4639 private int mapUid(int uid) { 4640 if (Process.isSdkSandboxUid(uid)) { 4641 return Process.getAppUidForSdkSandboxUid(uid); 4642 } 4643 return mPowerStatsUidResolver.mapUid(uid); 4644 } 4645 mapIsolatedUid(int uid)4646 private int mapIsolatedUid(int uid) { 4647 return mPowerStatsUidResolver.mapUid(uid); 4648 } 4649 4650 @GuardedBy("this") noteEventLocked(int code, String name, int uid, long elapsedRealtimeMs, long uptimeMs)4651 public void noteEventLocked(int code, String name, int uid, 4652 long elapsedRealtimeMs, long uptimeMs) { 4653 uid = mapUid(uid); 4654 if (!mActiveEvents.updateState(code, name, uid, 0)) { 4655 return; 4656 } 4657 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid); 4658 } 4659 4660 @GuardedBy("this") noteCurrentTimeChangedLocked(long currentTimeMs, long elapsedRealtimeMs, long uptimeMs)4661 public void noteCurrentTimeChangedLocked(long currentTimeMs, 4662 long elapsedRealtimeMs, long uptimeMs) { 4663 mHistory.recordCurrentTimeChange(elapsedRealtimeMs, uptimeMs, currentTimeMs); 4664 adjustStartClockTime(currentTimeMs); 4665 } 4666 adjustStartClockTime(long currentTimeMs)4667 private void adjustStartClockTime(long currentTimeMs) { 4668 mStartClockTimeMs = 4669 currentTimeMs - (mClock.elapsedRealtime() - (mRealtimeStartUs / 1000)); 4670 } 4671 4672 @GuardedBy("this") noteProcessStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4673 public void noteProcessStartLocked(String name, int uid, 4674 long elapsedRealtimeMs, long uptimeMs) { 4675 uid = mapUid(uid); 4676 if (isOnBattery()) { 4677 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4678 u.getProcessStatsLocked(name).incStartsLocked(); 4679 } 4680 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 4681 return; 4682 } 4683 if (!mRecordAllHistory) { 4684 return; 4685 } 4686 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid); 4687 } 4688 4689 @GuardedBy("this") noteProcessCrashLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4690 public void noteProcessCrashLocked(String name, int uid, 4691 long elapsedRealtimeMs, long uptimeMs) { 4692 uid = mapUid(uid); 4693 if (isOnBattery()) { 4694 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4695 u.getProcessStatsLocked(name).incNumCrashesLocked(); 4696 } 4697 } 4698 4699 @GuardedBy("this") noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4700 public void noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4701 uid = mapUid(uid); 4702 if (isOnBattery()) { 4703 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4704 u.getProcessStatsLocked(name).incNumAnrsLocked(); 4705 } 4706 } 4707 4708 @GuardedBy("this") noteUidProcessStateLocked(int uid, int state)4709 public void noteUidProcessStateLocked(int uid, int state) { 4710 noteUidProcessStateLocked(uid, state, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4711 } 4712 4713 @GuardedBy("this") 4714 @SuppressWarnings("GuardedBy") // errorprone false positive on u.updateUidProcessStateLocked noteUidProcessStateLocked(int uid, int state, long elapsedRealtimeMs, long uptimeMs)4715 public void noteUidProcessStateLocked(int uid, int state, 4716 long elapsedRealtimeMs, long uptimeMs) { 4717 int parentUid = mapUid(uid); 4718 if (uid != parentUid) { 4719 if (Process.isIsolated(uid)) { 4720 // Isolated UIDs process state is already rolled up into parent, so no need to track 4721 // Otherwise the parent's process state will get downgraded incorrectly 4722 return; 4723 } 4724 } 4725 mFrameworkStatsLogger.uidProcessStateChanged(uid, state); 4726 getUidStatsLocked(parentUid, elapsedRealtimeMs, uptimeMs) 4727 .updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs); 4728 } 4729 4730 @GuardedBy("this") noteProcessFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4731 public void noteProcessFinishLocked(String name, int uid, 4732 long elapsedRealtimeMs, long uptimeMs) { 4733 uid = mapUid(uid); 4734 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4735 return; 4736 } 4737 if (!mRecordAllHistory) { 4738 return; 4739 } 4740 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH, name, uid); 4741 } 4742 4743 @GuardedBy("this") noteSyncStartLocked(String name, int uid)4744 public void noteSyncStartLocked(String name, int uid) { 4745 noteSyncStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4746 } 4747 4748 @GuardedBy("this") noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4749 public void noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4750 uid = mapUid(uid); 4751 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4752 .noteStartSyncLocked(name, elapsedRealtimeMs); 4753 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4754 return; 4755 } 4756 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid); 4757 } 4758 4759 @GuardedBy("this") noteSyncFinishLocked(String name, int uid)4760 public void noteSyncFinishLocked(String name, int uid) { 4761 noteSyncFinishLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4762 } 4763 4764 @GuardedBy("this") noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4765 public void noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4766 uid = mapUid(uid); 4767 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4768 .noteStopSyncLocked(name, elapsedRealtimeMs); 4769 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4770 return; 4771 } 4772 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH, name, uid); 4773 } 4774 4775 @GuardedBy("this") noteJobStartLocked(String name, int uid)4776 public void noteJobStartLocked(String name, int uid) { 4777 noteJobStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4778 } 4779 4780 @GuardedBy("this") noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4781 public void noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4782 uid = mapUid(uid); 4783 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4784 .noteStartJobLocked(name, elapsedRealtimeMs); 4785 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4786 return; 4787 } 4788 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid); 4789 } 4790 4791 @GuardedBy("this") noteJobFinishLocked(String name, int uid, int stopReason)4792 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4793 noteJobFinishLocked(name, uid, stopReason, 4794 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4795 } 4796 4797 @GuardedBy("this") noteJobFinishLocked(String name, int uid, int stopReason, long elapsedRealtimeMs, long uptimeMs)4798 public void noteJobFinishLocked(String name, int uid, int stopReason, 4799 long elapsedRealtimeMs, long uptimeMs) { 4800 uid = mapUid(uid); 4801 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4802 .noteStopJobLocked(name, elapsedRealtimeMs, stopReason); 4803 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4804 return; 4805 } 4806 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid); 4807 } 4808 4809 @GuardedBy("this") noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, long elapsedRealtimeMs, long uptimeMs)4810 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, 4811 long elapsedRealtimeMs, long uptimeMs) { 4812 uid = mapUid(uid); 4813 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4814 .noteJobsDeferredLocked(numDeferred, sinceLast); 4815 } 4816 4817 @GuardedBy("this") noteAlarmStartLocked(String name, WorkSource workSource, int uid)4818 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4819 noteAlarmStartLocked(name, workSource, uid, 4820 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4821 } 4822 4823 @GuardedBy("this") noteAlarmStartLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4824 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid, 4825 long elapsedRealtimeMs, long uptimeMs) { 4826 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid, 4827 elapsedRealtimeMs, uptimeMs); 4828 } 4829 4830 @GuardedBy("this") noteAlarmFinishLocked(String name, WorkSource workSource, int uid)4831 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 4832 noteAlarmFinishLocked(name, workSource, uid, 4833 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4834 } 4835 4836 @GuardedBy("this") noteAlarmFinishLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4837 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid, 4838 long elapsedRealtimeMs, long uptimeMs) { 4839 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid, 4840 elapsedRealtimeMs, uptimeMs); 4841 } 4842 4843 @GuardedBy("this") noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4844 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4845 int uid, long elapsedRealtimeMs, long uptimeMs) { 4846 if (!mRecordAllHistory) { 4847 return; 4848 } 4849 4850 if (workSource != null) { 4851 for (int i = 0; i < workSource.size(); ++i) { 4852 uid = mapUid(workSource.getUid(i)); 4853 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4854 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4855 } 4856 } 4857 4858 List<WorkChain> workChains = workSource.getWorkChains(); 4859 if (workChains != null) { 4860 for (int i = 0; i < workChains.size(); ++i) { 4861 uid = mapUid(workChains.get(i).getAttributionUid()); 4862 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4863 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4864 } 4865 } 4866 } 4867 } else { 4868 uid = mapUid(uid); 4869 4870 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4871 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4872 } 4873 } 4874 } 4875 4876 @GuardedBy("this") noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)4877 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4878 String tag) { 4879 noteWakupAlarmLocked(packageName, uid, workSource, tag, 4880 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4881 } 4882 4883 @GuardedBy("this") noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag, long elapsedRealtimeMs, long uptimeMs)4884 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4885 String tag, long elapsedRealtimeMs, long uptimeMs) { 4886 if (workSource != null) { 4887 for (int i = 0; i < workSource.size(); ++i) { 4888 uid = workSource.getUid(i); 4889 final String workSourceName = workSource.getPackageName(i); 4890 4891 if (isOnBattery()) { 4892 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 4893 workSourceName != null ? workSourceName : packageName, 4894 elapsedRealtimeMs, uptimeMs); 4895 pkg.noteWakeupAlarmLocked(tag); 4896 } 4897 } 4898 4899 List<WorkChain> workChains = workSource.getWorkChains(); 4900 if (workChains != null) { 4901 for (int i = 0; i < workChains.size(); ++i) { 4902 final WorkChain wc = workChains.get(i); 4903 uid = wc.getAttributionUid(); 4904 4905 if (isOnBattery()) { 4906 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4907 elapsedRealtimeMs, uptimeMs); 4908 pkg.noteWakeupAlarmLocked(tag); 4909 } 4910 } 4911 } 4912 } else { 4913 if (isOnBattery()) { 4914 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4915 elapsedRealtimeMs, uptimeMs); 4916 pkg.noteWakeupAlarmLocked(tag); 4917 } 4918 } 4919 } 4920 requestWakelockCpuUpdate()4921 private void requestWakelockCpuUpdate() { 4922 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 4923 } 4924 requestImmediateCpuUpdate()4925 private void requestImmediateCpuUpdate() { 4926 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 4927 } 4928 4929 @GuardedBy("this") setRecordAllHistoryLocked(boolean enabled)4930 public void setRecordAllHistoryLocked(boolean enabled) { 4931 mRecordAllHistory = enabled; 4932 if (!enabled) { 4933 // Clear out any existing state. 4934 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 4935 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 4936 // Record the currently running processes as stopping, now that we are no 4937 // longer tracking them. 4938 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4939 HistoryItem.EVENT_PROC); 4940 if (active != null) { 4941 long mSecRealtime = mClock.elapsedRealtime(); 4942 final long mSecUptime = mClock.uptimeMillis(); 4943 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4944 SparseIntArray uids = ent.getValue(); 4945 for (int j=0; j<uids.size(); j++) { 4946 mHistory.recordEvent(mSecRealtime, mSecUptime, 4947 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 4948 } 4949 } 4950 } 4951 } else { 4952 // Record the currently running processes as starting, now that we are tracking them. 4953 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4954 HistoryItem.EVENT_PROC); 4955 if (active != null) { 4956 long mSecRealtime = mClock.elapsedRealtime(); 4957 final long mSecUptime = mClock.uptimeMillis(); 4958 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4959 SparseIntArray uids = ent.getValue(); 4960 for (int j=0; j<uids.size(); j++) { 4961 mHistory.recordEvent(mSecRealtime, mSecUptime, HistoryItem.EVENT_PROC_START, 4962 ent.getKey(), uids.keyAt(j)); 4963 } 4964 } 4965 } 4966 } 4967 } 4968 setNoAutoReset(boolean enabled)4969 public void setNoAutoReset(boolean enabled) { 4970 mNoAutoReset = enabled; 4971 } 4972 4973 @GuardedBy("this") setPretendScreenOff(boolean pretendScreenOff)4974 public void setPretendScreenOff(boolean pretendScreenOff) { 4975 if (mPretendScreenOff != pretendScreenOff) { 4976 mPretendScreenOff = pretendScreenOff; 4977 final int primaryScreenState = mPerDisplayBatteryStats[0].screenState; 4978 noteScreenStateLocked(0, primaryScreenState, 4979 mClock.elapsedRealtime(), mClock.uptimeMillis(), 4980 mClock.currentTimeMillis()); 4981 } 4982 } 4983 4984 @GuardedBy("this") noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging)4985 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4986 int type, boolean unimportantForLogging) { 4987 noteStartWakeLocked(uid, pid, wc, name, historyName, type, unimportantForLogging, 4988 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4989 } 4990 4991 @GuardedBy("this") noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)4992 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4993 int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs) { 4994 final int mappedUid = mapUid(uid); 4995 if (type == WAKE_TYPE_PARTIAL) { 4996 // Only care about partial wake locks, since full wake locks 4997 // will be canceled when the user puts the screen to sleep. 4998 if (historyName == null) { 4999 historyName = name; 5000 } 5001 if (mRecordAllHistory) { 5002 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 5003 mappedUid, 0)) { 5004 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, 5005 HistoryItem.EVENT_WAKE_LOCK_START, historyName, mappedUid); 5006 } 5007 } 5008 if (mWakeLockNesting == 0) { 5009 mWakeLockImportant = !unimportantForLogging; 5010 mHistory.recordWakelockStartEvent(elapsedRealtimeMs, uptimeMs, historyName, 5011 mappedUid); 5012 } else if (!mWakeLockImportant && !unimportantForLogging) { 5013 if (mHistory.maybeUpdateWakelockTag(elapsedRealtimeMs, uptimeMs, historyName, 5014 mappedUid)) { 5015 mWakeLockImportant = true; 5016 } 5017 } 5018 mWakeLockNesting++; 5019 } 5020 if (mappedUid >= 0) { 5021 if (mappedUid != uid) { 5022 // Prevent the isolated uid mapping from being removed while the wakelock is 5023 // being held. 5024 mPowerStatsUidResolver.retainIsolatedUid(uid); 5025 } 5026 if (mOnBatteryScreenOffTimeBase.isRunning()) { 5027 // We only update the cpu time when a wake lock is acquired if the screen is off. 5028 // If the screen is on, we don't distribute the power amongst partial wakelocks. 5029 if (DEBUG_ENERGY_CPU) { 5030 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 5031 } 5032 requestWakelockCpuUpdate(); 5033 } 5034 5035 Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs); 5036 uidStats.noteStartWakeLocked(pid, name, type, elapsedRealtimeMs); 5037 5038 mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name, 5039 uidStats.mProcessState, true /* acquired */, 5040 getPowerManagerWakeLockLevel(type)); 5041 } 5042 } 5043 5044 @GuardedBy("this") noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type)5045 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5046 int type) { 5047 noteStopWakeLocked(uid, pid, wc, name, historyName, type, 5048 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5049 } 5050 5051 @GuardedBy("this") noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)5052 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5053 int type, long elapsedRealtimeMs, long uptimeMs) { 5054 final int mappedUid = mapUid(uid); 5055 if (type == WAKE_TYPE_PARTIAL) { 5056 mWakeLockNesting--; 5057 if (historyName == null) { 5058 historyName = name; 5059 } 5060 if (mRecordAllHistory) { 5061 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 5062 mappedUid, 0)) { 5063 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, 5064 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, mappedUid); 5065 } 5066 } 5067 if (mWakeLockNesting == 0) { 5068 mHistory.recordWakelockStopEvent(elapsedRealtimeMs, uptimeMs, historyName, 5069 mappedUid); 5070 } 5071 } 5072 if (mappedUid >= 0) { 5073 if (mOnBatteryScreenOffTimeBase.isRunning()) { 5074 if (DEBUG_ENERGY_CPU) { 5075 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 5076 } 5077 requestWakelockCpuUpdate(); 5078 } 5079 5080 Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs); 5081 uidStats.noteStopWakeLocked(pid, name, type, elapsedRealtimeMs); 5082 5083 mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name, 5084 uidStats.mProcessState, false/* acquired */, 5085 getPowerManagerWakeLockLevel(type)); 5086 5087 if (mappedUid != uid) { 5088 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 5089 releaseIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 5090 } 5091 } 5092 } 5093 5094 /** 5095 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 5096 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 5097 * These are estimations, since batterystats loses some of the original data. 5098 * TODO: Delete this. Instead, FrameworkStatsLog.write should be called from 5099 * PowerManager's Notifier. 5100 */ getPowerManagerWakeLockLevel(int batteryStatsWakelockType)5101 private int getPowerManagerWakeLockLevel(int batteryStatsWakelockType) { 5102 switch (batteryStatsWakelockType) { 5103 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 5104 case BatteryStats.WAKE_TYPE_PARTIAL: 5105 return PowerManager.PARTIAL_WAKE_LOCK; 5106 5107 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 5108 case BatteryStats.WAKE_TYPE_FULL: 5109 return PowerManager.FULL_WAKE_LOCK; 5110 5111 case BatteryStats.WAKE_TYPE_DRAW: 5112 return PowerManager.DRAW_WAKE_LOCK; 5113 5114 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 5115 case BatteryStats.WAKE_TYPE_WINDOW: 5116 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 5117 return -1; 5118 5119 default: 5120 Slog.e(TAG, "Illegal wakelock type in batterystats: " + batteryStatsWakelockType); 5121 return -1; 5122 } 5123 } 5124 5125 @GuardedBy("this") noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)5126 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 5127 String historyName, int type, boolean unimportantForLogging, 5128 long elapsedRealtimeMs, long uptimeMs) { 5129 final int N = ws.size(); 5130 for (int i=0; i<N; i++) { 5131 noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type, 5132 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 5133 } 5134 5135 List<WorkChain> wcs = ws.getWorkChains(); 5136 if (wcs != null) { 5137 for (int i = 0; i < wcs.size(); ++i) { 5138 final WorkChain wc = wcs.get(i); 5139 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 5140 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 5141 } 5142 } 5143 } 5144 5145 @GuardedBy("this") noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, WorkSource newWs, int newPid, String newName, String newHistoryName, int newType, boolean newUnimportantForLogging, long elapsedRealtimeMs, long uptimeMs)5146 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 5147 String historyName, int type, WorkSource newWs, int newPid, String newName, 5148 String newHistoryName, int newType, boolean newUnimportantForLogging, 5149 long elapsedRealtimeMs, long uptimeMs) { 5150 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 5151 5152 // For correct semantics, we start the need worksources first, so that we won't 5153 // make inappropriate history items as if all wake locks went away and new ones 5154 // appeared. This is okay because tracking of wake locks allows nesting. 5155 // 5156 // First the starts : 5157 final int NN = newWs.size(); 5158 for (int i=0; i<NN; i++) { 5159 noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType, 5160 newUnimportantForLogging, elapsedRealtimeMs, uptimeMs); 5161 } 5162 if (wcs != null) { 5163 List<WorkChain> newChains = wcs[0]; 5164 if (newChains != null) { 5165 for (int i = 0; i < newChains.size(); ++i) { 5166 final WorkChain newChain = newChains.get(i); 5167 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 5168 newHistoryName, newType, newUnimportantForLogging, elapsedRealtimeMs, 5169 uptimeMs); 5170 } 5171 } 5172 } 5173 5174 // Then the stops : 5175 final int NO = ws.size(); 5176 for (int i=0; i<NO; i++) { 5177 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 5178 uptimeMs); 5179 } 5180 if (wcs != null) { 5181 List<WorkChain> goneChains = wcs[1]; 5182 if (goneChains != null) { 5183 for (int i = 0; i < goneChains.size(); ++i) { 5184 final WorkChain goneChain = goneChains.get(i); 5185 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 5186 historyName, type, elapsedRealtimeMs, uptimeMs); 5187 } 5188 } 5189 } 5190 } 5191 5192 @GuardedBy("this") noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)5193 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 5194 String historyName, int type, long elapsedRealtimeMs, long uptimeMs) { 5195 final int N = ws.size(); 5196 for (int i=0; i<N; i++) { 5197 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 5198 uptimeMs); 5199 } 5200 5201 List<WorkChain> wcs = ws.getWorkChains(); 5202 if (wcs != null) { 5203 for (int i = 0; i < wcs.size(); ++i) { 5204 final WorkChain wc = wcs.get(i); 5205 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 5206 elapsedRealtimeMs, uptimeMs); 5207 } 5208 } 5209 } 5210 5211 @GuardedBy("this") noteLongPartialWakelockStart(String name, String historyName, int uid)5212 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 5213 noteLongPartialWakelockStart(name, historyName, uid, 5214 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5215 } 5216 5217 @GuardedBy("this") noteLongPartialWakelockStart(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5218 public void noteLongPartialWakelockStart(String name, String historyName, int uid, 5219 long elapsedRealtimeMs, long uptimeMs) { 5220 noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 5221 } 5222 5223 @GuardedBy("this") noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)5224 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 5225 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 5226 final int N = workSource.size(); 5227 for (int i = 0; i < N; ++i) { 5228 final int uid = mapUid(workSource.getUid(i)); 5229 noteLongPartialWakeLockStartInternal(name, historyName, uid, 5230 elapsedRealtimeMs, uptimeMs); 5231 } 5232 5233 final List<WorkChain> workChains = workSource.getWorkChains(); 5234 if (workChains != null) { 5235 for (int i = 0; i < workChains.size(); ++i) { 5236 final WorkChain workChain = workChains.get(i); 5237 final int uid = workChain.getAttributionUid(); 5238 noteLongPartialWakeLockStartInternal(name, historyName, uid, 5239 elapsedRealtimeMs, uptimeMs); 5240 } 5241 } 5242 } 5243 5244 @GuardedBy("this") noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5245 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, 5246 long elapsedRealtimeMs, long uptimeMs) { 5247 final int mappedUid = mapUid(uid); 5248 if (historyName == null) { 5249 historyName = name; 5250 } 5251 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, 5252 mappedUid, 0)) { 5253 return; 5254 } 5255 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 5256 historyName, mappedUid); 5257 if (mappedUid != uid) { 5258 // Prevent the isolated uid mapping from being removed while the wakelock is 5259 // being held. 5260 mPowerStatsUidResolver.retainIsolatedUid(uid); 5261 } 5262 } 5263 5264 @GuardedBy("this") noteLongPartialWakelockFinish(String name, String historyName, int uid)5265 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 5266 noteLongPartialWakelockFinish(name, historyName, uid, 5267 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5268 } 5269 5270 @GuardedBy("this") noteLongPartialWakelockFinish(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5271 public void noteLongPartialWakelockFinish(String name, String historyName, int uid, 5272 long elapsedRealtimeMs, long uptimeMs) { 5273 noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 5274 } 5275 5276 @GuardedBy("this") noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)5277 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 5278 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 5279 final int N = workSource.size(); 5280 for (int i = 0; i < N; ++i) { 5281 final int uid = mapUid(workSource.getUid(i)); 5282 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 5283 elapsedRealtimeMs, uptimeMs); 5284 } 5285 5286 final List<WorkChain> workChains = workSource.getWorkChains(); 5287 if (workChains != null) { 5288 for (int i = 0; i < workChains.size(); ++i) { 5289 final WorkChain workChain = workChains.get(i); 5290 final int uid = workChain.getAttributionUid(); 5291 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 5292 elapsedRealtimeMs, uptimeMs); 5293 } 5294 } 5295 } 5296 5297 @GuardedBy("this") noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5298 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, 5299 long elapsedRealtimeMs, long uptimeMs) { 5300 final int mappedUid = mapUid(uid); 5301 if (historyName == null) { 5302 historyName = name; 5303 } 5304 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, 5305 mappedUid, 0)) { 5306 return; 5307 } 5308 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 5309 historyName, mappedUid); 5310 if (mappedUid != uid) { 5311 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 5312 releaseIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 5313 } 5314 } 5315 5316 @GuardedBy("this") noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs)5317 public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) { 5318 if (mLastWakeupReason != null) { 5319 long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs; 5320 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 5321 timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds 5322 mFrameworkStatsLogger.kernelWakeupReported(deltaUptimeMs * 1000, mLastWakeupReason, 5323 mLastWakeupElapsedTimeMs); 5324 } 5325 mHistory.recordWakeupEvent(elapsedRealtimeMs, uptimeMs, reason); 5326 mLastWakeupReason = reason; 5327 mLastWakeupUptimeMs = uptimeMs; 5328 mLastWakeupElapsedTimeMs = elapsedRealtimeMs; 5329 } 5330 5331 @GuardedBy("this") startAddingCpuStatsLocked()5332 public boolean startAddingCpuStatsLocked() { 5333 mExternalSync.cancelCpuSyncDueToWakelockChange(); 5334 return mOnBatteryInternal; 5335 } 5336 5337 @GuardedBy("this") addCpuStatsLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs)5338 public void addCpuStatsLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, 5339 int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, 5340 int statSoftIrqTimeMs, int statIdleTimeMs) { 5341 mStepDetailsCalculator.addCpuStats(totalUTimeMs, totalSTimeMs, statUserTimeMs, 5342 statSystemTimeMs, statIOWaitTimeMs, statIrqTimeMs, 5343 statSoftIrqTimeMs, statIdleTimeMs); 5344 } 5345 5346 /** 5347 * Called after {@link #addCpuStatsLocked} has been invoked for all active apps. 5348 */ 5349 @GuardedBy("this") finishAddingCpuStatsLocked()5350 public void finishAddingCpuStatsLocked() { 5351 mStepDetailsCalculator.finishAddingCpuLocked(); 5352 } 5353 noteProcessDiedLocked(int uid, int pid)5354 public void noteProcessDiedLocked(int uid, int pid) { 5355 uid = mapUid(uid); 5356 Uid u = mUidStats.get(uid); 5357 if (u != null) { 5358 u.mPids.remove(pid); 5359 } 5360 } 5361 reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs)5362 public void reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs) { 5363 uid = mapUid(uid); 5364 Uid u = mUidStats.get(uid); 5365 if (u != null) { 5366 u.reportExcessiveCpuLocked(proc, overTimeMs, usedTimeMs); 5367 } 5368 } 5369 5370 int mSensorNesting; 5371 5372 @GuardedBy("this") noteStartSensorLocked(int uid, int sensor)5373 public void noteStartSensorLocked(int uid, int sensor) { 5374 noteStartSensorLocked(uid, sensor, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5375 } 5376 5377 @GuardedBy("this") noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)5378 public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 5379 uid = mapUid(uid); 5380 if (mSensorNesting == 0) { 5381 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5382 HistoryItem.STATE_SENSOR_ON_FLAG); 5383 } 5384 mSensorNesting++; 5385 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5386 .noteStartSensor(sensor, elapsedRealtimeMs); 5387 } 5388 5389 @GuardedBy("this") noteStopSensorLocked(int uid, int sensor)5390 public void noteStopSensorLocked(int uid, int sensor) { 5391 noteStopSensorLocked(uid, sensor, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5392 } 5393 5394 @GuardedBy("this") noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)5395 public void noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 5396 uid = mapUid(uid); 5397 mSensorNesting--; 5398 if (mSensorNesting == 0) { 5399 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5400 HistoryItem.STATE_SENSOR_ON_FLAG); 5401 } 5402 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5403 .noteStopSensor(sensor, elapsedRealtimeMs); 5404 } 5405 5406 int mGpsNesting; 5407 5408 @GuardedBy("this") noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)5409 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 5410 noteGpsChangedLocked(oldWs, newWs, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5411 } 5412 5413 @GuardedBy("this") noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)5414 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, 5415 long elapsedRealtimeMs, long uptimeMs) { 5416 for (int i = 0; i < newWs.size(); ++i) { 5417 noteStartGpsLocked(newWs.getUid(i), null, elapsedRealtimeMs, uptimeMs); 5418 } 5419 5420 for (int i = 0; i < oldWs.size(); ++i) { 5421 noteStopGpsLocked((oldWs.getUid(i)), null, elapsedRealtimeMs, uptimeMs); 5422 } 5423 5424 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 5425 if (wcs != null) { 5426 if (wcs[0] != null) { 5427 final List<WorkChain> newChains = wcs[0]; 5428 for (int i = 0; i < newChains.size(); ++i) { 5429 noteStartGpsLocked(-1, newChains.get(i), elapsedRealtimeMs, uptimeMs); 5430 } 5431 } 5432 5433 if (wcs[1] != null) { 5434 final List<WorkChain> goneChains = wcs[1]; 5435 for (int i = 0; i < goneChains.size(); ++i) { 5436 noteStopGpsLocked(-1, goneChains.get(i), elapsedRealtimeMs, uptimeMs); 5437 } 5438 } 5439 } 5440 } 5441 5442 @GuardedBy("this") noteStartGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)5443 private void noteStartGpsLocked(int uid, WorkChain workChain, 5444 long elapsedRealtimeMs, long uptimeMs) { 5445 if (workChain != null) { 5446 uid = workChain.getAttributionUid(); 5447 } 5448 final int mappedUid = mapUid(uid); 5449 if (mGpsNesting == 0) { 5450 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5451 HistoryItem.STATE_GPS_ON_FLAG, uid, "gnss"); 5452 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS)) { 5453 mGnssPowerStatsCollector.schedule(); 5454 } 5455 } 5456 mGpsNesting++; 5457 5458 mFrameworkStatsLogger.gpsScanStateChanged(mapIsolatedUid(uid), workChain, /* on */true); 5459 5460 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs).noteStartGps(elapsedRealtimeMs); 5461 } 5462 5463 @GuardedBy("this") noteStopGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)5464 private void noteStopGpsLocked(int uid, WorkChain workChain, 5465 long elapsedRealtimeMs, long uptimeMs) { 5466 if (workChain != null) { 5467 uid = workChain.getAttributionUid(); 5468 } 5469 final int mappedUid = mapUid(uid); 5470 mGpsNesting--; 5471 if (mGpsNesting == 0) { 5472 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5473 HistoryItem.STATE_GPS_ON_FLAG, uid, "gnss"); 5474 mHistory.recordGpsSignalQualityEvent(elapsedRealtimeMs, uptimeMs, 5475 GPS_SIGNAL_QUALITY_NONE); 5476 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 5477 mGpsSignalQualityBin = -1; 5478 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS)) { 5479 mGnssPowerStatsCollector.schedule(); 5480 } 5481 } 5482 5483 mFrameworkStatsLogger.gpsScanStateChanged(mapIsolatedUid(uid), workChain, /* on */ false); 5484 5485 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs).noteStopGps(elapsedRealtimeMs); 5486 } 5487 5488 @GuardedBy("this") noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs)5489 public void noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs) { 5490 if (mGpsNesting == 0) { 5491 return; 5492 } 5493 if (signalLevel < 0 || signalLevel >= mGpsSignalQualityTimer.length) { 5494 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 5495 return; 5496 } 5497 if (mGpsSignalQualityBin != signalLevel) { 5498 if (mGpsSignalQualityBin >= 0) { 5499 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtimeMs); 5500 } 5501 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 5502 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs); 5503 } 5504 mHistory.recordGpsSignalQualityEvent(elapsedRealtimeMs, uptimeMs, signalLevel); 5505 mGpsSignalQualityBin = signalLevel; 5506 } 5507 } 5508 5509 @GuardedBy("this") noteScreenStateLocked(int display, int state)5510 public void noteScreenStateLocked(int display, int state) { 5511 noteScreenStateLocked(display, state, mClock.elapsedRealtime(), mClock.uptimeMillis(), 5512 mClock.currentTimeMillis()); 5513 } 5514 5515 @GuardedBy("this") noteScreenStateLocked(int display, int displayState, long elapsedRealtimeMs, long uptimeMs, long currentTimeMs)5516 public void noteScreenStateLocked(int display, int displayState, 5517 long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) { 5518 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 5519 // original 4 are mapped to one of the originals. 5520 if (displayState > MAX_TRACKED_SCREEN_STATE) { 5521 if (Display.isOnState(displayState)) { 5522 displayState = Display.STATE_ON; 5523 } else if (Display.isDozeState(displayState)) { 5524 if (Display.isSuspendedState(displayState)) { 5525 displayState = Display.STATE_DOZE_SUSPEND; 5526 } else { 5527 displayState = Display.STATE_DOZE; 5528 } 5529 } else if (Display.isOffState(displayState)) { 5530 displayState = Display.STATE_OFF; 5531 } else { 5532 Slog.wtf(TAG, "Unknown screen state (not mapped): " + displayState); 5533 displayState = Display.STATE_UNKNOWN; 5534 } 5535 } 5536 // As of this point, displayState should be mapped to one of: 5537 // - Display.STATE_ON, 5538 // - Display.STATE_DOZE 5539 // - Display.STATE_DOZE_SUSPEND 5540 // - Display.STATE_OFF 5541 // - Display.STATE_UNKNOWN 5542 5543 int state; 5544 int overallBin = mScreenBrightnessBin; 5545 int externalUpdateFlag = 0; 5546 boolean shouldScheduleSync = false; 5547 final int numDisplay = mPerDisplayBatteryStats.length; 5548 if (display < 0 || display >= numDisplay) { 5549 Slog.wtf(TAG, "Unexpected note screen state for display " + display + " (only " 5550 + mPerDisplayBatteryStats.length + " displays exist...)"); 5551 return; 5552 } 5553 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5554 final int oldDisplayState = displayStats.screenState; 5555 5556 if (oldDisplayState == displayState) { 5557 // Nothing changed 5558 state = mScreenState; 5559 } else { 5560 displayStats.screenState = displayState; 5561 5562 // Stop timer for previous display state. 5563 switch (oldDisplayState) { 5564 case Display.STATE_ON: 5565 displayStats.screenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5566 final int bin = displayStats.screenBrightnessBin; 5567 if (bin >= 0) { 5568 displayStats.screenBrightnessTimers[bin].stopRunningLocked( 5569 elapsedRealtimeMs); 5570 } 5571 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5572 shouldScheduleSync = true; 5573 break; 5574 case Display.STATE_DOZE: 5575 // Transition from doze to doze suspend can be ignored. 5576 if (displayState == Display.STATE_DOZE_SUSPEND) break; 5577 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5578 shouldScheduleSync = true; 5579 break; 5580 case Display.STATE_DOZE_SUSPEND: 5581 // Transition from doze suspend to doze can be ignored. 5582 if (displayState == Display.STATE_DOZE) break; 5583 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5584 shouldScheduleSync = true; 5585 break; 5586 case Display.STATE_OFF: // fallthrough 5587 case Display.STATE_UNKNOWN: 5588 // Not tracked by timers. 5589 break; 5590 default: 5591 Slog.wtf(TAG, 5592 "Attempted to stop timer for unexpected display state " + display); 5593 } 5594 5595 // Start timer for new display state. 5596 switch (displayState) { 5597 case Display.STATE_ON: 5598 displayStats.screenOnTimer.startRunningLocked(elapsedRealtimeMs); 5599 final int bin = displayStats.screenBrightnessBin; 5600 if (bin >= 0) { 5601 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5602 elapsedRealtimeMs); 5603 } 5604 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5605 shouldScheduleSync = true; 5606 break; 5607 case Display.STATE_DOZE: 5608 // Transition from doze suspend to doze can be ignored. 5609 if (oldDisplayState == Display.STATE_DOZE_SUSPEND) break; 5610 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5611 shouldScheduleSync = true; 5612 break; 5613 case Display.STATE_DOZE_SUSPEND: 5614 // Transition from doze to doze suspend can be ignored. 5615 if (oldDisplayState == Display.STATE_DOZE) break; 5616 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5617 shouldScheduleSync = true; 5618 break; 5619 case Display.STATE_OFF: // fallthrough 5620 case Display.STATE_UNKNOWN: 5621 // Not tracked by timers. 5622 break; 5623 default: 5624 Slog.wtf(TAG, 5625 "Attempted to start timer for unexpected display state " + displayState 5626 + " for display " + display); 5627 } 5628 5629 if (shouldScheduleSync 5630 && mGlobalEnergyConsumerStats != null 5631 && mGlobalEnergyConsumerStats.isStandardBucketSupported( 5632 EnergyConsumerStats.POWER_BUCKET_SCREEN_ON)) { 5633 // Display energy consumption stats is available. Prepare to schedule an 5634 // external sync. 5635 externalUpdateFlag |= ExternalStatsSync.UPDATE_DISPLAY; 5636 } 5637 5638 // Reevaluate most important display screen state. 5639 state = Display.STATE_UNKNOWN; 5640 for (int i = 0; i < numDisplay; i++) { 5641 final int tempState = mPerDisplayBatteryStats[i].screenState; 5642 if (tempState == Display.STATE_ON 5643 || state == Display.STATE_ON) { 5644 state = Display.STATE_ON; 5645 } else if (tempState == Display.STATE_DOZE 5646 || state == Display.STATE_DOZE) { 5647 state = Display.STATE_DOZE; 5648 } else if (tempState == Display.STATE_DOZE_SUSPEND 5649 || state == Display.STATE_DOZE_SUSPEND) { 5650 state = Display.STATE_DOZE_SUSPEND; 5651 } else if (tempState == Display.STATE_OFF 5652 || state == Display.STATE_OFF) { 5653 state = Display.STATE_OFF; 5654 } 5655 } 5656 } 5657 5658 final boolean batteryRunning = mOnBatteryTimeBase.isRunning(); 5659 final boolean batteryScreenOffRunning = mOnBatteryScreenOffTimeBase.isRunning(); 5660 5661 state = mPretendScreenOff ? Display.STATE_OFF : state; 5662 if (mScreenState != state) { 5663 recordDailyStatsIfNeededLocked(true, currentTimeMs); 5664 final int oldState = mScreenState; 5665 mScreenState = state; 5666 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 5667 + ", newState=" + Display.stateToString(state)); 5668 5669 if (state != Display.STATE_UNKNOWN) { 5670 int stepState = state-1; 5671 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 5672 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 5673 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 5674 } else { 5675 Slog.wtf(TAG, "Unexpected screen state: " + state); 5676 } 5677 } 5678 5679 int startStates = 0; 5680 int stopStates = 0; 5681 if (Display.isDozeState(state) && !Display.isDozeState(oldState)) { 5682 startStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 5683 mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5684 } else if (Display.isDozeState(oldState) && !Display.isDozeState(state)) { 5685 stopStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 5686 mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5687 } 5688 if (Display.isOnState(state)) { 5689 startStates |= HistoryItem.STATE_SCREEN_ON_FLAG; 5690 mScreenOnTimer.startRunningLocked(elapsedRealtimeMs); 5691 if (mScreenBrightnessBin >= 0) { 5692 mScreenBrightnessTimer[mScreenBrightnessBin] 5693 .startRunningLocked(elapsedRealtimeMs); 5694 } 5695 } else if (Display.isOnState(oldState)) { 5696 stopStates |= HistoryItem.STATE_SCREEN_ON_FLAG; 5697 mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5698 if (mScreenBrightnessBin >= 0) { 5699 mScreenBrightnessTimer[mScreenBrightnessBin] 5700 .stopRunningLocked(elapsedRealtimeMs); 5701 } 5702 } 5703 if (startStates != 0 || stopStates != 0) { 5704 mHistory.recordStateChangeEvent(elapsedRealtimeMs, uptimeMs, startStates, 5705 stopStates); 5706 } 5707 5708 // Per screen state Cpu stats needed. Prepare to schedule an external sync. 5709 externalUpdateFlag |= ExternalStatsSync.UPDATE_CPU; 5710 shouldScheduleSync = true; 5711 5712 if (Display.isOnState(state)) { 5713 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 5714 uptimeMs * 1000, elapsedRealtimeMs * 1000); 5715 // Fake a wake lock, so we consider the device waked as long as the screen is on. 5716 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 5717 elapsedRealtimeMs, uptimeMs); 5718 } else if (Display.isOnState(oldState)) { 5719 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 5720 elapsedRealtimeMs, uptimeMs); 5721 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 5722 uptimeMs * 1000, elapsedRealtimeMs * 1000); 5723 } 5724 // Update discharge amounts. 5725 if (mOnBatteryInternal) { 5726 updateDischargeScreenLevelsLocked(oldState, state); 5727 } 5728 } 5729 5730 // Changing display states might have changed the screen used to determine the overall 5731 // brightness. 5732 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 5733 5734 if (shouldScheduleSync) { 5735 final int numDisplays = mPerDisplayBatteryStats.length; 5736 final int[] displayStates = new int[numDisplays]; 5737 for (int i = 0; i < numDisplays; i++) { 5738 displayStates[i] = mPerDisplayBatteryStats[i].screenState; 5739 } 5740 mExternalSync.scheduleSyncDueToScreenStateChange(externalUpdateFlag, 5741 batteryRunning, batteryScreenOffRunning, state, displayStates); 5742 } 5743 } 5744 5745 /** 5746 * Note screen brightness change for a display. 5747 */ 5748 @GuardedBy("this") noteScreenBrightnessLocked(int display, int brightness)5749 public void noteScreenBrightnessLocked(int display, int brightness) { 5750 noteScreenBrightnessLocked(display, brightness, mClock.elapsedRealtime(), 5751 mClock.uptimeMillis()); 5752 } 5753 5754 5755 /** 5756 * Note screen brightness change for a display. 5757 */ 5758 @GuardedBy("this") noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, long uptimeMs)5759 public void noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, 5760 long uptimeMs) { 5761 // Bin the brightness. 5762 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 5763 if (bin < 0) bin = 0; 5764 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 5765 5766 final int overallBin; 5767 5768 final int numDisplays = mPerDisplayBatteryStats.length; 5769 if (display < 0 || display >= numDisplays) { 5770 Slog.wtf(TAG, "Unexpected note screen brightness for display " + display + " (only " 5771 + mPerDisplayBatteryStats.length + " displays exist...)"); 5772 return; 5773 } 5774 5775 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5776 final int oldBin = displayStats.screenBrightnessBin; 5777 if (oldBin == bin) { 5778 // Nothing changed 5779 overallBin = mScreenBrightnessBin; 5780 } else { 5781 displayStats.screenBrightnessBin = bin; 5782 if (displayStats.screenState == Display.STATE_ON) { 5783 if (oldBin >= 0) { 5784 displayStats.screenBrightnessTimers[oldBin].stopRunningLocked( 5785 elapsedRealtimeMs); 5786 } 5787 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5788 elapsedRealtimeMs); 5789 } 5790 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5791 } 5792 5793 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 5794 } 5795 5796 @GuardedBy("this") evaluateOverallScreenBrightnessBinLocked()5797 private int evaluateOverallScreenBrightnessBinLocked() { 5798 int overallBin = -1; 5799 final int numDisplays = getDisplayCount(); 5800 for (int display = 0; display < numDisplays; display++) { 5801 final int displayBrightnessBin; 5802 if (mPerDisplayBatteryStats[display].screenState == Display.STATE_ON) { 5803 displayBrightnessBin = mPerDisplayBatteryStats[display].screenBrightnessBin; 5804 } else { 5805 displayBrightnessBin = -1; 5806 } 5807 if (displayBrightnessBin > overallBin) { 5808 overallBin = displayBrightnessBin; 5809 } 5810 } 5811 return overallBin; 5812 } 5813 5814 @GuardedBy("this") maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, long uptimeMs)5815 private void maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, 5816 long uptimeMs) { 5817 if (mScreenBrightnessBin != overallBin) { 5818 if (overallBin >= 0) { 5819 mHistory.recordScreenBrightnessEvent(elapsedRealtimeMs, uptimeMs, overallBin); 5820 } 5821 if (mScreenState == Display.STATE_ON) { 5822 if (mScreenBrightnessBin >= 0) { 5823 mScreenBrightnessTimer[mScreenBrightnessBin] 5824 .stopRunningLocked(elapsedRealtimeMs); 5825 } 5826 if (overallBin >= 0) { 5827 mScreenBrightnessTimer[overallBin] 5828 .startRunningLocked(elapsedRealtimeMs); 5829 } 5830 } 5831 mScreenBrightnessBin = overallBin; 5832 } 5833 } 5834 5835 @GuardedBy("this") noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event, long elapsedRealtimeMs, long uptimeMs)5836 public void noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event, 5837 long elapsedRealtimeMs, long uptimeMs) { 5838 if (mOnBatteryInternal) { 5839 uid = mapUid(uid); 5840 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteUserActivityLocked(event); 5841 } 5842 } 5843 5844 @GuardedBy("this") noteWakeUpLocked(String reason, int reasonUid, long elapsedRealtimeMs, long uptimeMs)5845 public void noteWakeUpLocked(String reason, int reasonUid, 5846 long elapsedRealtimeMs, long uptimeMs) { 5847 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP, reason, 5848 reasonUid); 5849 } 5850 5851 @GuardedBy("this") noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs)5852 public void noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs) { 5853 if (mInteractive != interactive) { 5854 mInteractive = interactive; 5855 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 5856 if (interactive) { 5857 mInteractiveTimer.startRunningLocked(elapsedRealtimeMs); 5858 } else { 5859 mInteractiveTimer.stopRunningLocked(elapsedRealtimeMs); 5860 } 5861 } 5862 } 5863 5864 @GuardedBy("this") noteConnectivityChangedLocked(int type, String extra, long elapsedRealtimeMs, long uptimeMs)5865 public void noteConnectivityChangedLocked(int type, String extra, 5866 long elapsedRealtimeMs, long uptimeMs) { 5867 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 5868 extra, type); 5869 mNumConnectivityChange++; 5870 } 5871 5872 @GuardedBy("this") noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5873 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 5874 final long uptimeMillis, int uid) { 5875 uid = mapUid(uid); 5876 mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5877 uid); 5878 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked(); 5879 } 5880 5881 /** 5882 * Updates the radio power state and returns true if an external stats collection should occur. 5883 */ 5884 @GuardedBy("this") noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)5885 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 5886 return noteMobileRadioPowerStateLocked(powerState, timestampNs, uid, 5887 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5888 } 5889 5890 @GuardedBy("this") noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)5891 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, 5892 long elapsedRealtimeMs, long uptimeMs) { 5893 if (mMobileRadioPowerState != powerState) { 5894 long realElapsedRealtimeMs; 5895 final boolean active = isActiveRadioPowerState(powerState); 5896 if (active) { 5897 if (uid > 0) { 5898 noteMobileRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 5899 } 5900 5901 mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 5902 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5903 HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG); 5904 } else { 5905 realElapsedRealtimeMs = timestampNs / (1000*1000); 5906 long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs; 5907 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 5908 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 5909 + " is before start time " + lastUpdateTimeMs); 5910 realElapsedRealtimeMs = elapsedRealtimeMs; 5911 } else if (realElapsedRealtimeMs < elapsedRealtimeMs) { 5912 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs 5913 - realElapsedRealtimeMs); 5914 } 5915 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5916 HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG); 5917 } 5918 mMobileRadioPowerState = powerState; 5919 5920 // Inform current RatBatteryStats that the modem active state might have changed. 5921 getRatBatteryStatsLocked(mActiveRat).noteActive(active, elapsedRealtimeMs); 5922 5923 if (active) { 5924 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtimeMs); 5925 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtimeMs); 5926 } else { 5927 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 5928 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 5929 5930 if (mMobileRadioPowerStatsCollector.isEnabled()) { 5931 mMobileRadioPowerStatsCollector.schedule(); 5932 } else { 5933 // Check if modem Activity info has been collected recently, don't bother 5934 // triggering another update. 5935 if (mLastModemActivityInfo == null 5936 || elapsedRealtimeMs >= mLastModemActivityInfo.getTimestampMillis() 5937 + MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS) { 5938 mExternalSync.scheduleSync("modem-data", 5939 BatteryExternalStatsWorker.UPDATE_RADIO); 5940 return true; 5941 } 5942 } 5943 } 5944 } 5945 return false; 5946 } 5947 isActiveRadioPowerState(int powerState)5948 private static boolean isActiveRadioPowerState(int powerState) { 5949 return powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5950 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5951 } 5952 5953 /** 5954 * Toggles the power save mode state. 5955 */ 5956 @GuardedBy("this") notePowerSaveModeLockedInit(boolean enabled, long elapsedRealtimeMs, long uptimeMs)5957 public void notePowerSaveModeLockedInit(boolean enabled, long elapsedRealtimeMs, 5958 long uptimeMs) { 5959 if (mPowerSaveModeEnabled != enabled) { 5960 notePowerSaveModeLocked(enabled, elapsedRealtimeMs, uptimeMs); 5961 } else { 5962 // Log an initial value for BATTERY_SAVER_MODE_STATE_CHANGED in order to 5963 // allow the atom to read all future state changes. 5964 mFrameworkStatsLogger.batterySaverModeChanged(enabled); 5965 } 5966 } 5967 5968 @GuardedBy("this") notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs)5969 public void notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs) { 5970 if (mPowerSaveModeEnabled != enabled) { 5971 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 5972 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 5973 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 5974 mPowerSaveModeEnabled = enabled; 5975 if (enabled) { 5976 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 5977 HistoryItem.STATE2_POWER_SAVE_FLAG); 5978 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs); 5979 } else { 5980 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 5981 HistoryItem.STATE2_POWER_SAVE_FLAG); 5982 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs); 5983 } 5984 mFrameworkStatsLogger.batterySaverModeChanged(enabled); 5985 } 5986 } 5987 5988 @GuardedBy("this") noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, long elapsedRealtimeMs, long uptimeMs)5989 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, 5990 long elapsedRealtimeMs, long uptimeMs) { 5991 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 5992 if (mDeviceIdling && !nowIdling && activeReason == null) { 5993 // We don't go out of general idling mode until explicitly taken out of 5994 // device idle through going active or significant motion. 5995 nowIdling = true; 5996 } 5997 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 5998 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 5999 // We don't go out of general light idling mode until explicitly taken out of 6000 // device idle through going active or significant motion. 6001 nowLightIdling = true; 6002 } 6003 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 6004 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE, 6005 activeReason, activeUid); 6006 } 6007 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 6008 int statsmode; 6009 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 6010 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 6011 else statsmode = DEVICE_IDLE_MODE_OFF; 6012 mFrameworkStatsLogger.deviceIdlingModeStateChanged(statsmode); 6013 } 6014 if (mDeviceIdling != nowIdling) { 6015 mDeviceIdling = nowIdling; 6016 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 6017 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 6018 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 6019 if (nowIdling) { 6020 mDeviceIdlingTimer.startRunningLocked(elapsedRealtimeMs); 6021 } else { 6022 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 6023 } 6024 } 6025 if (mDeviceLightIdling != nowLightIdling) { 6026 mDeviceLightIdling = nowLightIdling; 6027 if (nowLightIdling) { 6028 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtimeMs); 6029 } else { 6030 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 6031 } 6032 } 6033 if (mDeviceIdleMode != mode) { 6034 mHistory.recordDeviceIdleEvent(elapsedRealtimeMs, uptimeMs, mode); 6035 long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs; 6036 mLastIdleTimeStartMs = elapsedRealtimeMs; 6037 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 6038 if (lastDuration > mLongestLightIdleTimeMs) { 6039 mLongestLightIdleTimeMs = lastDuration; 6040 } 6041 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtimeMs); 6042 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 6043 if (lastDuration > mLongestFullIdleTimeMs) { 6044 mLongestFullIdleTimeMs = lastDuration; 6045 } 6046 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtimeMs); 6047 } 6048 if (mode == DEVICE_IDLE_MODE_LIGHT) { 6049 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtimeMs); 6050 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 6051 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtimeMs); 6052 } 6053 mDeviceIdleMode = mode; 6054 mFrameworkStatsLogger.deviceIdleModeStateChanged(mode); 6055 } 6056 } 6057 6058 @GuardedBy("this") notePackageInstalledLocked(String pkgName, long versionCode, long elapsedRealtimeMs, long uptimeMs)6059 public void notePackageInstalledLocked(String pkgName, long versionCode, 6060 long elapsedRealtimeMs, long uptimeMs) { 6061 // XXX need to figure out what to do with long version codes. 6062 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED, 6063 pkgName, (int)versionCode); 6064 PackageChange pc = new PackageChange(); 6065 pc.mPackageName = pkgName; 6066 pc.mUpdate = true; 6067 pc.mVersionCode = versionCode; 6068 addPackageChange(pc); 6069 } 6070 6071 @GuardedBy("this") notePackageUninstalledLocked(String pkgName, long elapsedRealtimeMs, long uptimeMs)6072 public void notePackageUninstalledLocked(String pkgName, 6073 long elapsedRealtimeMs, long uptimeMs) { 6074 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_UNINSTALLED, 6075 pkgName, 0); 6076 PackageChange pc = new PackageChange(); 6077 pc.mPackageName = pkgName; 6078 pc.mUpdate = true; 6079 addPackageChange(pc); 6080 } 6081 addPackageChange(PackageChange pc)6082 private void addPackageChange(PackageChange pc) { 6083 if (mDailyPackageChanges == null) { 6084 mDailyPackageChanges = new ArrayList<>(); 6085 } 6086 mDailyPackageChanges.add(pc); 6087 } 6088 6089 @GuardedBy("this") stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs)6090 void stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs) { 6091 for (int i = 0; i < mGpsSignalQualityTimer.length; i++) { 6092 if (i == except) { 6093 continue; 6094 } 6095 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 6096 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtimeMs); 6097 } 6098 } 6099 } 6100 6101 @GuardedBy("this") notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs)6102 public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) { 6103 if (!mPhoneOn) { 6104 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6105 HistoryItem.STATE2_PHONE_IN_CALL_FLAG); 6106 mPhoneOn = true; 6107 mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs); 6108 if (mConstants.PHONE_ON_EXTERNAL_STATS_COLLECTION) { 6109 scheduleSyncExternalStatsLocked("phone-on", ExternalStatsSync.UPDATE_RADIO); 6110 mMobileRadioPowerStatsCollector.schedule(); 6111 } 6112 } 6113 } 6114 6115 @GuardedBy("this") notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs)6116 public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) { 6117 if (mPhoneOn) { 6118 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6119 HistoryItem.STATE2_PHONE_IN_CALL_FLAG); 6120 mPhoneOn = false; 6121 mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs); 6122 scheduleSyncExternalStatsLocked("phone-off", ExternalStatsSync.UPDATE_RADIO); 6123 mMobileRadioPowerStatsCollector.schedule(); 6124 } 6125 } 6126 6127 @GuardedBy("this") registerUsbStateReceiver(Context context)6128 private void registerUsbStateReceiver(Context context) { 6129 final IntentFilter usbStateFilter = new IntentFilter(); 6130 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 6131 context.registerReceiver(new BroadcastReceiver() { 6132 @Override 6133 public void onReceive(Context context, Intent intent) { 6134 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 6135 synchronized (BatteryStatsImpl.this) { 6136 noteUsbConnectionStateLocked(state, mClock.elapsedRealtime(), 6137 mClock.uptimeMillis()); 6138 } 6139 } 6140 }, usbStateFilter); 6141 synchronized (this) { 6142 if (mUsbDataState == USB_DATA_UNKNOWN) { 6143 final Intent usbState = context.registerReceiver(null, usbStateFilter); 6144 final boolean initState = usbState != null && usbState.getBooleanExtra( 6145 UsbManager.USB_CONNECTED, false); 6146 noteUsbConnectionStateLocked(initState, mClock.elapsedRealtime(), 6147 mClock.uptimeMillis()); 6148 } 6149 } 6150 } 6151 6152 @GuardedBy("this") noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, long uptimeMs)6153 private void noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, 6154 long uptimeMs) { 6155 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 6156 if (mUsbDataState != newState) { 6157 mUsbDataState = newState; 6158 if (connected) { 6159 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6160 HistoryItem.STATE2_USB_DATA_LINK_FLAG); 6161 } else { 6162 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6163 HistoryItem.STATE2_USB_DATA_LINK_FLAG); 6164 } 6165 } 6166 } 6167 6168 @GuardedBy("this") stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)6169 void stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 6170 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 6171 if (i == except) { 6172 continue; 6173 } 6174 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 6175 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 6176 } 6177 } 6178 } 6179 6180 @GuardedBy("this") updateAllPhoneStateLocked(int state, int simState, int strengthBin, long elapsedRealtimeMs, long uptimeMs)6181 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin, 6182 long elapsedRealtimeMs, long uptimeMs) { 6183 boolean scanning = false; 6184 boolean newHistory = false; 6185 int addStateFlag = 0; 6186 int removeStateFlag = 0; 6187 int newState = -1; 6188 int newSignalStrength = -1; 6189 6190 mPhoneServiceStateRaw = state; 6191 mPhoneSimStateRaw = simState; 6192 mPhoneSignalStrengthBinRaw = strengthBin; 6193 6194 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 6195 // In this case we will always be STATE_OUT_OF_SERVICE, so need 6196 // to infer that we are scanning from other data. 6197 if (state == ServiceState.STATE_OUT_OF_SERVICE 6198 && strengthBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 6199 state = ServiceState.STATE_IN_SERVICE; 6200 } 6201 } 6202 6203 // If the phone is powered off, stop all timers. 6204 if (state == ServiceState.STATE_POWER_OFF) { 6205 strengthBin = -1; 6206 6207 // If we are in service, make sure the correct signal string timer is running. 6208 } else if (state == ServiceState.STATE_IN_SERVICE) { 6209 // Bin will be changed below. 6210 6211 // If we're out of service, we are in the lowest signal strength 6212 // bin and have the scanning bit set. 6213 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 6214 scanning = true; 6215 strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 6216 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 6217 addStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG; 6218 newHistory = true; 6219 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtimeMs); 6220 mFrameworkStatsLogger.phoneServiceStateChanged(state, simState, strengthBin); 6221 } 6222 } 6223 6224 if (!scanning) { 6225 // If we are no longer scanning, then stop the scanning timer. 6226 if (mPhoneSignalScanningTimer.isRunningLocked()) { 6227 removeStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG; 6228 newHistory = true; 6229 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs); 6230 mFrameworkStatsLogger.phoneServiceStateChanged(state, simState, strengthBin); 6231 } 6232 } 6233 6234 if (mPhoneServiceState != state) { 6235 newState = state; 6236 newHistory = true; 6237 mPhoneServiceState = state; 6238 } 6239 6240 if (mPhoneSignalStrengthBin != strengthBin) { 6241 if (mPhoneSignalStrengthBin >= 0) { 6242 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 6243 elapsedRealtimeMs); 6244 } 6245 if (strengthBin >= 0) { 6246 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 6247 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 6248 } 6249 newSignalStrength = strengthBin; 6250 newHistory = true; 6251 mFrameworkStatsLogger.phoneSignalStrengthChanged(strengthBin); 6252 } else { 6253 stopAllPhoneSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 6254 } 6255 mPhoneSignalStrengthBin = strengthBin; 6256 } 6257 6258 if (newHistory) { 6259 mHistory.recordPhoneStateChangeEvent(elapsedRealtimeMs, uptimeMs, 6260 addStateFlag, removeStateFlag, newState, newSignalStrength); 6261 } 6262 } 6263 6264 @GuardedBy("this") notePhoneStateLocked(int state, int simState, long elapsedRealtimeMs, long uptimeMs)6265 public void notePhoneStateLocked(int state, int simState, 6266 long elapsedRealtimeMs, long uptimeMs) { 6267 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw, 6268 elapsedRealtimeMs, uptimeMs); 6269 } 6270 6271 @GuardedBy("this") notePhoneSignalStrengthLocked(SignalStrength signalStrength, long elapsedRealtimeMs, long uptimeMs)6272 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength, 6273 long elapsedRealtimeMs, long uptimeMs) { 6274 final int overallSignalStrength = signalStrength.getLevel(); 6275 final SparseIntArray perRatSignalStrength = new SparseIntArray( 6276 BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT); 6277 6278 // Extract signal strength level for each RAT. 6279 final List<CellSignalStrength> cellSignalStrengths = 6280 signalStrength.getCellSignalStrengths(); 6281 final int size = cellSignalStrengths.size(); 6282 for (int i = 0; i < size; i++) { 6283 CellSignalStrength cellSignalStrength = cellSignalStrengths.get(i); 6284 // Map each CellSignalStrength to a BatteryStats.RadioAccessTechnology 6285 final int ratType; 6286 final int level; 6287 if (cellSignalStrength instanceof CellSignalStrengthNr) { 6288 ratType = RADIO_ACCESS_TECHNOLOGY_NR; 6289 level = cellSignalStrength.getLevel(); 6290 } else if (cellSignalStrength instanceof CellSignalStrengthLte) { 6291 ratType = RADIO_ACCESS_TECHNOLOGY_LTE; 6292 level = cellSignalStrength.getLevel(); 6293 } else { 6294 ratType = RADIO_ACCESS_TECHNOLOGY_OTHER; 6295 level = cellSignalStrength.getLevel(); 6296 } 6297 6298 // According to SignalStrength#getCellSignalStrengths(), multiple of the same 6299 // cellSignalStrength can be present. Just take the highest level one for each RAT. 6300 if (perRatSignalStrength.get(ratType, -1) < level) { 6301 perRatSignalStrength.put(ratType, level); 6302 } 6303 } 6304 6305 notePhoneSignalStrengthLocked(overallSignalStrength, perRatSignalStrength, 6306 elapsedRealtimeMs, uptimeMs); 6307 } 6308 6309 /** 6310 * Note phone signal strength change, including per RAT signal strength. 6311 * 6312 * @param signalStrength overall signal strength {@see SignalStrength#getLevel()} 6313 * @param perRatSignalStrength signal strength of available RATs 6314 */ 6315 @GuardedBy("this") notePhoneSignalStrengthLocked(int signalStrength, SparseIntArray perRatSignalStrength)6316 public void notePhoneSignalStrengthLocked(int signalStrength, 6317 SparseIntArray perRatSignalStrength) { 6318 notePhoneSignalStrengthLocked(signalStrength, perRatSignalStrength, 6319 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6320 } 6321 6322 /** 6323 * Note phone signal strength change, including per RAT signal strength. 6324 * 6325 * @param signalStrength overall signal strength {@see SignalStrength#getLevel()} 6326 * @param perRatSignalStrength signal strength of available RATs 6327 */ 6328 @GuardedBy("this") notePhoneSignalStrengthLocked(int signalStrength, SparseIntArray perRatSignalStrength, long elapsedRealtimeMs, long uptimeMs)6329 public void notePhoneSignalStrengthLocked(int signalStrength, 6330 SparseIntArray perRatSignalStrength, 6331 long elapsedRealtimeMs, long uptimeMs) { 6332 // Note each RAT's signal strength. 6333 final int size = perRatSignalStrength.size(); 6334 for (int i = 0; i < size; i++) { 6335 final int rat = perRatSignalStrength.keyAt(i); 6336 final int ratSignalStrength = perRatSignalStrength.valueAt(i); 6337 getRatBatteryStatsLocked(rat).noteSignalStrength(ratSignalStrength, elapsedRealtimeMs); 6338 } 6339 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, signalStrength, 6340 elapsedRealtimeMs, uptimeMs); 6341 } 6342 6343 @GuardedBy("this") notePhoneDataConnectionStateLocked(@etworkType int dataType, boolean hasData, @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, @ServiceState.FrequencyRange int nrFrequency)6344 public void notePhoneDataConnectionStateLocked(@NetworkType int dataType, boolean hasData, 6345 @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, 6346 @ServiceState.FrequencyRange int nrFrequency) { 6347 notePhoneDataConnectionStateLocked(dataType, hasData, serviceType, nrState, nrFrequency, 6348 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6349 } 6350 6351 @GuardedBy("this") notePhoneDataConnectionStateLocked(@etworkType int dataType, boolean hasData, @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, @ServiceState.FrequencyRange int nrFrequency, long elapsedRealtimeMs, long uptimeMs)6352 public void notePhoneDataConnectionStateLocked(@NetworkType int dataType, boolean hasData, 6353 @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, 6354 @ServiceState.FrequencyRange int nrFrequency, long elapsedRealtimeMs, long uptimeMs) { 6355 // BatteryStats uses 0 to represent no network type. 6356 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 6357 // Unknown is included in DATA_CONNECTION_OTHER. 6358 int bin = DATA_CONNECTION_OUT_OF_SERVICE; 6359 if (hasData) { 6360 if (dataType > 0 && dataType <= NUM_ALL_NETWORK_TYPES) { 6361 bin = dataType; 6362 } else { 6363 switch (serviceType) { 6364 case ServiceState.STATE_OUT_OF_SERVICE: 6365 bin = DATA_CONNECTION_OUT_OF_SERVICE; 6366 break; 6367 case ServiceState.STATE_EMERGENCY_ONLY: 6368 bin = DATA_CONNECTION_EMERGENCY_SERVICE; 6369 break; 6370 default: 6371 bin = DATA_CONNECTION_OTHER; 6372 break; 6373 } 6374 } 6375 } 6376 6377 6378 6379 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 6380 if (mPhoneDataConnectionType != bin) { 6381 mHistory.recordDataConnectionTypeChangeEvent(elapsedRealtimeMs, uptimeMs, bin); 6382 if (mPhoneDataConnectionType >= 0) { 6383 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 6384 elapsedRealtimeMs); 6385 } 6386 mPhoneDataConnectionType = bin; 6387 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtimeMs); 6388 } 6389 6390 if (mNrState != nrState) { 6391 mHistory.recordNrStateChangeEvent(elapsedRealtimeMs, uptimeMs, nrState); 6392 mNrState = nrState; 6393 } 6394 6395 final boolean newNrNsaActive = isNrNsa(bin, nrState); 6396 final boolean nrNsaActive = mNrNsaTimer.isRunningLocked(); 6397 if (newNrNsaActive != nrNsaActive) { 6398 if (newNrNsaActive) { 6399 mNrNsaTimer.startRunningLocked(elapsedRealtimeMs); 6400 } else { 6401 mNrNsaTimer.stopRunningLocked(elapsedRealtimeMs); 6402 } 6403 } 6404 6405 final int newRat = mapNetworkTypeToRadioAccessTechnology(bin, nrState); 6406 if (newRat == RADIO_ACCESS_TECHNOLOGY_NR) { 6407 // Note possible frequency change for the NR RAT. 6408 getRatBatteryStatsLocked(newRat).noteFrequencyRange(nrFrequency, elapsedRealtimeMs); 6409 } 6410 if (mActiveRat != newRat) { 6411 getRatBatteryStatsLocked(mActiveRat).noteActive(false, elapsedRealtimeMs); 6412 mActiveRat = newRat; 6413 } 6414 final boolean modemActive = mMobileRadioActiveTimer.isRunningLocked(); 6415 getRatBatteryStatsLocked(newRat).noteActive(modemActive, elapsedRealtimeMs); 6416 } 6417 6418 /** 6419 * Non-standalone (NSA) mode for 5G NR will have an LTE network type. If NR state is 6420 * connected while on an LTE network, the device is in NR NSA mode. 6421 */ isNrNsa(@etworkType int dataType, @NetworkRegistrationInfo.NRState int nrState)6422 private static boolean isNrNsa(@NetworkType int dataType, 6423 @NetworkRegistrationInfo.NRState int nrState) { 6424 return dataType == TelephonyManager.NETWORK_TYPE_LTE 6425 && nrState == NetworkRegistrationInfo.NR_STATE_CONNECTED; 6426 } 6427 6428 @RadioAccessTechnology mapNetworkTypeToRadioAccessTechnology(@etworkType int dataType, @NetworkRegistrationInfo.NRState int nrState)6429 private static int mapNetworkTypeToRadioAccessTechnology(@NetworkType int dataType, 6430 @NetworkRegistrationInfo.NRState int nrState) { 6431 if (isNrNsa(dataType, nrState)) { 6432 // Treat an NR NSA connection as RADIO_ACCESS_TECHNOLOGY_NR 6433 return RADIO_ACCESS_TECHNOLOGY_NR; 6434 } 6435 6436 switch (dataType) { 6437 case TelephonyManager.NETWORK_TYPE_NR: 6438 return RADIO_ACCESS_TECHNOLOGY_NR; 6439 case TelephonyManager.NETWORK_TYPE_LTE: 6440 return RADIO_ACCESS_TECHNOLOGY_LTE; 6441 case TelephonyManager.NETWORK_TYPE_UNKNOWN: //fallthrough 6442 case TelephonyManager.NETWORK_TYPE_GPRS: //fallthrough 6443 case TelephonyManager.NETWORK_TYPE_EDGE: //fallthrough 6444 case TelephonyManager.NETWORK_TYPE_UMTS: //fallthrough 6445 case TelephonyManager.NETWORK_TYPE_CDMA: //fallthrough 6446 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fallthrough 6447 case TelephonyManager.NETWORK_TYPE_EVDO_A: //fallthrough 6448 case TelephonyManager.NETWORK_TYPE_1xRTT: //fallthrough 6449 case TelephonyManager.NETWORK_TYPE_HSDPA: //fallthrough 6450 case TelephonyManager.NETWORK_TYPE_HSUPA: //fallthrough 6451 case TelephonyManager.NETWORK_TYPE_HSPA: //fallthrough 6452 case TelephonyManager.NETWORK_TYPE_IDEN: //fallthrough 6453 case TelephonyManager.NETWORK_TYPE_EVDO_B: //fallthrough 6454 case TelephonyManager.NETWORK_TYPE_EHRPD: //fallthrough 6455 case TelephonyManager.NETWORK_TYPE_HSPAP: //fallthrough 6456 case TelephonyManager.NETWORK_TYPE_GSM: //fallthrough 6457 case TelephonyManager.NETWORK_TYPE_TD_SCDMA: //fallthrough 6458 case TelephonyManager.NETWORK_TYPE_IWLAN: //fallthrough 6459 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6460 default: 6461 Slog.w(TAG, "Unhandled NetworkType (" + dataType + "), mapping to OTHER"); 6462 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6463 } 6464 } 6465 6466 @GuardedBy("this") noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs)6467 public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) { 6468 if (!mWifiOn) { 6469 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6470 HistoryItem.STATE2_WIFI_ON_FLAG); 6471 mWifiOn = true; 6472 mWifiOnTimer.startRunningLocked(elapsedRealtimeMs); 6473 if (mWifiPowerStatsCollector.isEnabled()) { 6474 mWifiPowerStatsCollector.schedule(); 6475 } else { 6476 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 6477 } 6478 } 6479 } 6480 6481 @GuardedBy("this") noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs)6482 public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) { 6483 if (mWifiOn) { 6484 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6485 HistoryItem.STATE2_WIFI_ON_FLAG); 6486 mWifiOn = false; 6487 mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs); 6488 if (mWifiPowerStatsCollector.isEnabled()) { 6489 mWifiPowerStatsCollector.schedule(); 6490 } else { 6491 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 6492 } 6493 } 6494 } 6495 6496 @GuardedBy("this") noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6497 public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6498 uid = mapUid(uid); 6499 if (mAudioOnNesting == 0) { 6500 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6501 HistoryItem.STATE_AUDIO_ON_FLAG, uid, "audio"); 6502 mAudioOnTimer.startRunningLocked(elapsedRealtimeMs); 6503 } 6504 mAudioOnNesting++; 6505 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_AUDIO)) { 6506 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6507 .noteAudioTurnedOnLocked(elapsedRealtimeMs); 6508 } 6509 } 6510 6511 @GuardedBy("this") noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6512 public void noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6513 if (mAudioOnNesting == 0) { 6514 return; 6515 } 6516 uid = mapUid(uid); 6517 if (--mAudioOnNesting == 0) { 6518 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6519 HistoryItem.STATE_AUDIO_ON_FLAG, uid, "audio"); 6520 mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs); 6521 } 6522 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_AUDIO)) { 6523 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6524 .noteAudioTurnedOffLocked(elapsedRealtimeMs); 6525 } 6526 } 6527 6528 @GuardedBy("this") noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6529 public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6530 uid = mapUid(uid); 6531 if (mVideoOnNesting == 0) { 6532 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6533 HistoryItem.STATE2_VIDEO_ON_FLAG, uid, "video"); 6534 mVideoOnTimer.startRunningLocked(elapsedRealtimeMs); 6535 } 6536 mVideoOnNesting++; 6537 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_VIDEO)) { 6538 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6539 .noteVideoTurnedOnLocked(elapsedRealtimeMs); 6540 } 6541 } 6542 6543 @GuardedBy("this") noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6544 public void noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6545 if (mVideoOnNesting == 0) { 6546 return; 6547 } 6548 uid = mapUid(uid); 6549 if (--mVideoOnNesting == 0) { 6550 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6551 HistoryItem.STATE2_VIDEO_ON_FLAG, uid, "video"); 6552 mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs); 6553 } 6554 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_VIDEO)) { 6555 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6556 .noteVideoTurnedOffLocked(elapsedRealtimeMs); 6557 } 6558 } 6559 6560 @GuardedBy("this") noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs)6561 public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) { 6562 if (mAudioOnNesting > 0) { 6563 mAudioOnNesting = 0; 6564 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6565 HistoryItem.STATE_AUDIO_ON_FLAG); 6566 mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6567 for (int i=0; i<mUidStats.size(); i++) { 6568 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6569 uid.noteResetAudioLocked(elapsedRealtimeMs); 6570 } 6571 } 6572 } 6573 6574 @GuardedBy("this") noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs)6575 public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) { 6576 if (mVideoOnNesting > 0) { 6577 mVideoOnNesting = 0; 6578 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6579 HistoryItem.STATE2_VIDEO_ON_FLAG); 6580 mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6581 for (int i=0; i<mUidStats.size(); i++) { 6582 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6583 uid.noteResetVideoLocked(elapsedRealtimeMs); 6584 } 6585 } 6586 } 6587 6588 @GuardedBy("this") noteActivityResumedLocked(int uid)6589 public void noteActivityResumedLocked(int uid) { 6590 noteActivityResumedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6591 } 6592 6593 @GuardedBy("this") noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6594 public void noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6595 uid = mapUid(uid); 6596 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6597 .noteActivityResumedLocked(elapsedRealtimeMs); 6598 } 6599 6600 @GuardedBy("this") noteActivityPausedLocked(int uid)6601 public void noteActivityPausedLocked(int uid) { 6602 noteActivityPausedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6603 } 6604 6605 @GuardedBy("this") noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6606 public void noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6607 uid = mapUid(uid); 6608 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6609 .noteActivityPausedLocked(elapsedRealtimeMs); 6610 } 6611 6612 @GuardedBy("this") noteVibratorOnLocked(int uid, long durationMillis, long elapsedRealtimeMs, long uptimeMs)6613 public void noteVibratorOnLocked(int uid, long durationMillis, 6614 long elapsedRealtimeMs, long uptimeMs) { 6615 uid = mapUid(uid); 6616 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6617 .noteVibratorOnLocked(durationMillis, elapsedRealtimeMs); 6618 } 6619 6620 @GuardedBy("this") noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6621 public void noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6622 uid = mapUid(uid); 6623 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6624 .noteVibratorOffLocked(elapsedRealtimeMs); 6625 } 6626 6627 @GuardedBy("this") noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6628 public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6629 uid = mapUid(uid); 6630 if (mFlashlightOnNesting++ == 0) { 6631 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6632 HistoryItem.STATE2_FLASHLIGHT_FLAG, uid, "flashlight"); 6633 mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs); 6634 } 6635 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) { 6636 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6637 .noteFlashlightTurnedOnLocked(elapsedRealtimeMs); 6638 } 6639 } 6640 6641 @GuardedBy("this") noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6642 public void noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6643 if (mFlashlightOnNesting == 0) { 6644 return; 6645 } 6646 uid = mapUid(uid); 6647 if (--mFlashlightOnNesting == 0) { 6648 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6649 HistoryItem.STATE2_FLASHLIGHT_FLAG, uid, "flashlight"); 6650 mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs); 6651 } 6652 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) { 6653 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6654 .noteFlashlightTurnedOffLocked(elapsedRealtimeMs); 6655 } 6656 } 6657 6658 @GuardedBy("this") noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6659 public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6660 uid = mapUid(uid); 6661 if (mCameraOnNesting++ == 0) { 6662 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6663 HistoryItem.STATE2_CAMERA_FLAG, uid, "camera"); 6664 mCameraOnTimer.startRunningLocked(elapsedRealtimeMs); 6665 } 6666 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6667 .noteCameraTurnedOnLocked(elapsedRealtimeMs); 6668 6669 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CAMERA)) { 6670 mCameraPowerStatsCollector.schedule(); 6671 } else { 6672 scheduleSyncExternalStatsLocked("camera-on", ExternalStatsSync.UPDATE_CAMERA); 6673 } 6674 } 6675 6676 @GuardedBy("this") noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6677 public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6678 if (mCameraOnNesting == 0) { 6679 return; 6680 } 6681 uid = mapUid(uid); 6682 if (--mCameraOnNesting == 0) { 6683 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6684 HistoryItem.STATE2_CAMERA_FLAG, uid, "camera"); 6685 mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs); 6686 } 6687 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6688 .noteCameraTurnedOffLocked(elapsedRealtimeMs); 6689 6690 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CAMERA)) { 6691 mCameraPowerStatsCollector.schedule(); 6692 } else { 6693 scheduleSyncExternalStatsLocked("camera-off", ExternalStatsSync.UPDATE_CAMERA); 6694 } 6695 } 6696 6697 @GuardedBy("this") noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs)6698 public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) { 6699 if (mCameraOnNesting > 0) { 6700 mCameraOnNesting = 0; 6701 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6702 HistoryItem.STATE2_CAMERA_FLAG); 6703 mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6704 for (int i=0; i<mUidStats.size(); i++) { 6705 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6706 uid.noteResetCameraLocked(elapsedRealtimeMs); 6707 } 6708 } 6709 6710 scheduleSyncExternalStatsLocked("camera-reset", ExternalStatsSync.UPDATE_CAMERA); 6711 } 6712 6713 @GuardedBy("this") noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs)6714 public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) { 6715 if (mFlashlightOnNesting > 0) { 6716 mFlashlightOnNesting = 0; 6717 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6718 HistoryItem.STATE2_FLASHLIGHT_FLAG); 6719 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6720 for (int i=0; i<mUidStats.size(); i++) { 6721 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6722 uid.noteResetFlashlightLocked(elapsedRealtimeMs); 6723 } 6724 } 6725 } 6726 6727 @GuardedBy("this") noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6728 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 6729 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 6730 if (workChain != null) { 6731 uid = workChain.getAttributionUid(); 6732 } 6733 uid = mapUid(uid); 6734 if (mBluetoothScanNesting == 0) { 6735 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6736 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6737 mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs); 6738 } 6739 mBluetoothScanNesting++; 6740 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6741 .noteBluetoothScanStartedLocked(elapsedRealtimeMs, isUnoptimized); 6742 } 6743 6744 @GuardedBy("this") noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)6745 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 6746 noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized, 6747 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6748 } 6749 6750 @GuardedBy("this") noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6751 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 6752 long elapsedRealtimeMs, long uptimeMs) { 6753 final int N = ws.size(); 6754 for (int i = 0; i < N; i++) { 6755 noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized, 6756 elapsedRealtimeMs, uptimeMs); 6757 } 6758 6759 final List<WorkChain> workChains = ws.getWorkChains(); 6760 if (workChains != null) { 6761 for (int i = 0; i < workChains.size(); ++i) { 6762 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized, 6763 elapsedRealtimeMs, uptimeMs); 6764 } 6765 } 6766 } 6767 6768 @GuardedBy("this") noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6769 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 6770 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 6771 if (workChain != null) { 6772 uid = workChain.getAttributionUid(); 6773 } 6774 uid = mapUid(uid); 6775 mBluetoothScanNesting--; 6776 if (mBluetoothScanNesting == 0) { 6777 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6778 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6779 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 6780 } 6781 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6782 .noteBluetoothScanStoppedLocked(elapsedRealtimeMs, isUnoptimized); 6783 } 6784 6785 @GuardedBy("this") noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)6786 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 6787 noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized, 6788 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6789 } 6790 6791 @GuardedBy("this") noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6792 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 6793 long elapsedRealtimeMs, long uptimeMs) { 6794 final int N = ws.size(); 6795 for (int i = 0; i < N; i++) { 6796 noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized, 6797 elapsedRealtimeMs, uptimeMs); 6798 } 6799 6800 final List<WorkChain> workChains = ws.getWorkChains(); 6801 if (workChains != null) { 6802 for (int i = 0; i < workChains.size(); ++i) { 6803 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized, 6804 elapsedRealtimeMs, uptimeMs); 6805 } 6806 } 6807 } 6808 6809 @GuardedBy("this") noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs)6810 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) { 6811 if (mBluetoothScanNesting > 0) { 6812 mBluetoothScanNesting = 0; 6813 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6814 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6815 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 6816 for (int i=0; i<mUidStats.size(); i++) { 6817 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6818 uid.noteResetBluetoothScanLocked(elapsedRealtimeMs); 6819 } 6820 } 6821 } 6822 6823 @GuardedBy("this") noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)6824 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 6825 noteBluetoothScanResultsFromSourceLocked(ws, numNewResults, 6826 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6827 } 6828 6829 @GuardedBy("this") noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, long elapsedRealtimeMs, long uptimeMs)6830 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, 6831 long elapsedRealtimeMs, long uptimeMs) { 6832 final int N = ws.size(); 6833 for (int i = 0; i < N; i++) { 6834 int uid = mapUid(ws.getUid(i)); 6835 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6836 .noteBluetoothScanResultsLocked(numNewResults); 6837 } 6838 6839 final List<WorkChain> workChains = ws.getWorkChains(); 6840 if (workChains != null) { 6841 for (int i = 0; i < workChains.size(); ++i) { 6842 final WorkChain wc = workChains.get(i); 6843 int uid = mapUid(wc.getAttributionUid()); 6844 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6845 .noteBluetoothScanResultsLocked(numNewResults); 6846 } 6847 } 6848 } 6849 retrieveBluetoothScanTimesLocked( BluetoothPowerStatsCollector.BluetoothStatsRetriever.Callback callback)6850 private void retrieveBluetoothScanTimesLocked( 6851 BluetoothPowerStatsCollector.BluetoothStatsRetriever.Callback callback) { 6852 long elapsedTimeUs = mClock.elapsedRealtime() * 1000; 6853 for (int i = mUidStats.size() - 1; i >= 0; i--) { 6854 Uid uidStats = mUidStats.valueAt(i); 6855 if (uidStats.mBluetoothScanTimer == null) { 6856 continue; 6857 } 6858 6859 long scanTimeUs = mBluetoothScanTimer.getTotalTimeLocked(elapsedTimeUs, 6860 STATS_SINCE_CHARGED); 6861 if (scanTimeUs != 0) { 6862 int uid = mUidStats.keyAt(i); 6863 callback.onBluetoothScanTime(uid, (scanTimeUs + 500) / 1000); 6864 } 6865 } 6866 } 6867 6868 @GuardedBy("this") noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)6869 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 6870 final long uptimeMillis, int uid) { 6871 uid = mapUid(uid); 6872 mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 6873 uid); 6874 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked(); 6875 } 6876 6877 @GuardedBy("this") noteWifiRadioPowerState(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)6878 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid, 6879 long elapsedRealtimeMs, long uptimeMs) { 6880 if (mWifiRadioPowerState != powerState) { 6881 final boolean active = 6882 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 6883 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 6884 if (active) { 6885 if (uid > 0) { 6886 noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 6887 } 6888 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6889 HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG); 6890 mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs); 6891 } else { 6892 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6893 HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG); 6894 mWifiActiveTimer.stopRunningLocked(timestampNs / (1000 * 1000)); 6895 } 6896 mWifiRadioPowerState = powerState; 6897 } 6898 } 6899 6900 @GuardedBy("this") noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6901 public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6902 if (!mGlobalWifiRunning) { 6903 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6904 HistoryItem.STATE2_WIFI_RUNNING_FLAG); 6905 mGlobalWifiRunning = true; 6906 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 6907 int N = ws.size(); 6908 for (int i=0; i<N; i++) { 6909 int uid = mapUid(ws.getUid(i)); 6910 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6911 .noteWifiRunningLocked(elapsedRealtimeMs); 6912 } 6913 6914 List<WorkChain> workChains = ws.getWorkChains(); 6915 if (workChains != null) { 6916 for (int i = 0; i < workChains.size(); ++i) { 6917 int uid = mapUid(workChains.get(i).getAttributionUid()); 6918 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6919 .noteWifiRunningLocked(elapsedRealtimeMs); 6920 } 6921 } 6922 if (mWifiPowerStatsCollector.isEnabled()) { 6923 mWifiPowerStatsCollector.schedule(); 6924 } else { 6925 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 6926 } 6927 } else { 6928 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 6929 } 6930 } 6931 6932 @GuardedBy("this") noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)6933 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, 6934 long elapsedRealtimeMs, long uptimeMs) { 6935 if (mGlobalWifiRunning) { 6936 int N = oldWs.size(); 6937 for (int i=0; i<N; i++) { 6938 int uid = mapUid(oldWs.getUid(i)); 6939 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6940 .noteWifiStoppedLocked(elapsedRealtimeMs); 6941 } 6942 6943 List<WorkChain> workChains = oldWs.getWorkChains(); 6944 if (workChains != null) { 6945 for (int i = 0; i < workChains.size(); ++i) { 6946 int uid = mapUid(workChains.get(i).getAttributionUid()); 6947 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6948 .noteWifiStoppedLocked(elapsedRealtimeMs); 6949 } 6950 } 6951 6952 N = newWs.size(); 6953 for (int i=0; i<N; i++) { 6954 int uid = mapUid(newWs.getUid(i)); 6955 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6956 .noteWifiRunningLocked(elapsedRealtimeMs); 6957 } 6958 6959 workChains = newWs.getWorkChains(); 6960 if (workChains != null) { 6961 for (int i = 0; i < workChains.size(); ++i) { 6962 int uid = mapUid(workChains.get(i).getAttributionUid()); 6963 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6964 .noteWifiRunningLocked(elapsedRealtimeMs); 6965 } 6966 } 6967 } else { 6968 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 6969 } 6970 } 6971 6972 @GuardedBy("this") noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6973 public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6974 if (mGlobalWifiRunning) { 6975 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6976 HistoryItem.STATE2_WIFI_RUNNING_FLAG); 6977 mGlobalWifiRunning = false; 6978 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 6979 int N = ws.size(); 6980 for (int i=0; i<N; i++) { 6981 int uid = mapUid(ws.getUid(i)); 6982 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6983 .noteWifiStoppedLocked(elapsedRealtimeMs); 6984 } 6985 6986 List<WorkChain> workChains = ws.getWorkChains(); 6987 if (workChains != null) { 6988 for (int i = 0; i < workChains.size(); ++i) { 6989 int uid = mapUid(workChains.get(i).getAttributionUid()); 6990 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6991 .noteWifiStoppedLocked(elapsedRealtimeMs); 6992 } 6993 } 6994 6995 if (mWifiPowerStatsCollector.isEnabled()) { 6996 mWifiPowerStatsCollector.schedule(); 6997 } else { 6998 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 6999 } 7000 } else { 7001 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 7002 } 7003 } 7004 7005 @GuardedBy("this") noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs)7006 public void noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs) { 7007 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 7008 if (mWifiState != wifiState) { 7009 if (mWifiState >= 0) { 7010 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtimeMs); 7011 } 7012 mWifiState = wifiState; 7013 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtimeMs); 7014 if (mWifiPowerStatsCollector.isEnabled()) { 7015 mWifiPowerStatsCollector.schedule(); 7016 } else { 7017 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 7018 } 7019 } 7020 } 7021 7022 @GuardedBy("this") noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, long elapsedRealtimeMs, long uptimeMs)7023 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, 7024 long elapsedRealtimeMs, long uptimeMs) { 7025 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 7026 if (mWifiSupplState != supplState) { 7027 if (mWifiSupplState >= 0) { 7028 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtimeMs); 7029 } 7030 mWifiSupplState = supplState; 7031 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs); 7032 mHistory.recordWifiSupplicantStateChangeEvent(elapsedRealtimeMs, uptimeMs, supplState); 7033 } 7034 } 7035 7036 @GuardedBy("this") stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)7037 void stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 7038 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 7039 if (i == except) { 7040 continue; 7041 } 7042 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 7043 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 7044 } 7045 } 7046 } 7047 7048 @GuardedBy("this") noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs)7049 public void noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs) { 7050 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 7051 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 7052 if (mWifiSignalStrengthBin != strengthBin) { 7053 if (mWifiSignalStrengthBin >= 0) { 7054 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 7055 elapsedRealtimeMs); 7056 } 7057 if (strengthBin >= 0) { 7058 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 7059 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 7060 } 7061 mHistory.recordWifiSignalStrengthChangeEvent(elapsedRealtimeMs, uptimeMs, 7062 strengthBin); 7063 } else { 7064 stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 7065 } 7066 mWifiSignalStrengthBin = strengthBin; 7067 } 7068 } 7069 7070 private int mWifiFullLockNesting = 0; 7071 7072 @GuardedBy("this") noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7073 public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7074 if (mWifiFullLockNesting == 0) { 7075 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 7076 HistoryItem.STATE_WIFI_FULL_LOCK_FLAG); 7077 } 7078 mWifiFullLockNesting++; 7079 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7080 .noteFullWifiLockAcquiredLocked(elapsedRealtimeMs); 7081 } 7082 7083 @GuardedBy("this") noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7084 public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7085 mWifiFullLockNesting--; 7086 if (mWifiFullLockNesting == 0) { 7087 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 7088 HistoryItem.STATE_WIFI_FULL_LOCK_FLAG); 7089 } 7090 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7091 .noteFullWifiLockReleasedLocked(elapsedRealtimeMs); 7092 } 7093 7094 int mWifiScanNesting = 0; 7095 7096 @GuardedBy("this") noteWifiScanStartedLocked(int uid)7097 public void noteWifiScanStartedLocked(int uid) { 7098 noteWifiScanStartedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7099 } 7100 7101 @GuardedBy("this") noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7102 public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7103 if (mWifiScanNesting == 0) { 7104 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 7105 HistoryItem.STATE_WIFI_SCAN_FLAG); 7106 } 7107 mWifiScanNesting++; 7108 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7109 .noteWifiScanStartedLocked(elapsedRealtimeMs); 7110 } 7111 7112 @GuardedBy("this") noteWifiScanStoppedLocked(int uid)7113 public void noteWifiScanStoppedLocked(int uid) { 7114 noteWifiScanStoppedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7115 } 7116 7117 @GuardedBy("this") noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7118 public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7119 mWifiScanNesting--; 7120 if (mWifiScanNesting == 0) { 7121 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 7122 HistoryItem.STATE_WIFI_SCAN_FLAG); 7123 } 7124 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7125 .noteWifiScanStoppedLocked(elapsedRealtimeMs); 7126 } 7127 noteWifiBatchedScanStartedLocked(int uid, int csph, long elapsedRealtimeMs, long uptimeMs)7128 public void noteWifiBatchedScanStartedLocked(int uid, int csph, 7129 long elapsedRealtimeMs, long uptimeMs) { 7130 uid = mapUid(uid); 7131 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7132 .noteWifiBatchedScanStartedLocked(csph, elapsedRealtimeMs); 7133 } 7134 noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7135 public void noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7136 uid = mapUid(uid); 7137 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7138 .noteWifiBatchedScanStoppedLocked(elapsedRealtimeMs); 7139 } 7140 retrieveWifiScanTimesLocked( WifiPowerStatsCollector.WifiStatsRetriever.Callback callback)7141 private void retrieveWifiScanTimesLocked( 7142 WifiPowerStatsCollector.WifiStatsRetriever.Callback callback) { 7143 long elapsedTimeUs = mClock.elapsedRealtime() * 1000; 7144 for (int i = mUidStats.size() - 1; i >= 0; i--) { 7145 int uid = mUidStats.keyAt(i); 7146 Uid uidStats = mUidStats.valueAt(i); 7147 long scanTimeUs = uidStats.getWifiScanTime(elapsedTimeUs, STATS_SINCE_CHARGED); 7148 long batchScanTimeUs = 0; 7149 for (int bucket = 0; bucket < NUM_WIFI_BATCHED_SCAN_BINS; bucket++) { 7150 batchScanTimeUs += uidStats.getWifiBatchedScanTime(bucket, elapsedTimeUs, 7151 STATS_SINCE_CHARGED); 7152 } 7153 if (scanTimeUs != 0 || batchScanTimeUs != 0) { 7154 callback.onWifiScanTime(uid, (scanTimeUs + 500) / 1000, 7155 (batchScanTimeUs + 500) / 1000); 7156 } 7157 } 7158 } 7159 7160 private int mWifiMulticastNesting = 0; 7161 7162 @GuardedBy("this") noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7163 public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7164 uid = mapUid(uid); 7165 if (mWifiMulticastNesting == 0) { 7166 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 7167 HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG); 7168 // Start Wifi Multicast overall timer 7169 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 7170 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs); 7171 } 7172 } 7173 mWifiMulticastNesting++; 7174 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7175 .noteWifiMulticastEnabledLocked(elapsedRealtimeMs); 7176 } 7177 7178 @GuardedBy("this") noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7179 public void noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7180 uid = mapUid(uid); 7181 mWifiMulticastNesting--; 7182 if (mWifiMulticastNesting == 0) { 7183 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 7184 HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG); 7185 7186 // Stop Wifi Multicast overall timer 7187 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 7188 if (DEBUG) Slog.v(TAG, "Multicast Overall Timer Stopped"); 7189 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 7190 } 7191 } 7192 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7193 .noteWifiMulticastDisabledLocked(elapsedRealtimeMs); 7194 } 7195 7196 @GuardedBy("this") noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7197 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, 7198 long elapsedRealtimeMs, long uptimeMs) { 7199 int N = ws.size(); 7200 for (int i=0; i<N; i++) { 7201 final int uid = mapUid(ws.getUid(i)); 7202 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 7203 } 7204 7205 final List<WorkChain> workChains = ws.getWorkChains(); 7206 if (workChains != null) { 7207 for (int i = 0; i < workChains.size(); ++i) { 7208 final WorkChain workChain = workChains.get(i); 7209 final int uid = mapUid(workChain.getAttributionUid()); 7210 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 7211 } 7212 } 7213 } 7214 7215 @GuardedBy("this") noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7216 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, 7217 long elapsedRealtimeMs, long uptimeMs) { 7218 int N = ws.size(); 7219 for (int i=0; i<N; i++) { 7220 final int uid = mapUid(ws.getUid(i)); 7221 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 7222 } 7223 7224 final List<WorkChain> workChains = ws.getWorkChains(); 7225 if (workChains != null) { 7226 for (int i = 0; i < workChains.size(); ++i) { 7227 final WorkChain workChain = workChains.get(i); 7228 final int uid = mapUid(workChain.getAttributionUid()); 7229 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 7230 } 7231 } 7232 } 7233 7234 @GuardedBy("this") noteWifiScanStartedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7235 public void noteWifiScanStartedFromSourceLocked(WorkSource ws, 7236 long elapsedRealtimeMs, long uptimeMs) { 7237 int N = ws.size(); 7238 for (int i=0; i<N; i++) { 7239 final int uid = mapUid(ws.getUid(i)); 7240 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 7241 } 7242 7243 final List<WorkChain> workChains = ws.getWorkChains(); 7244 if (workChains != null) { 7245 for (int i = 0; i < workChains.size(); ++i) { 7246 final WorkChain workChain = workChains.get(i); 7247 final int uid = mapUid(workChain.getAttributionUid()); 7248 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 7249 } 7250 } 7251 } 7252 7253 @GuardedBy("this") noteWifiScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7254 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws, 7255 long elapsedRealtimeMs, long uptimeMs) { 7256 int N = ws.size(); 7257 for (int i=0; i<N; i++) { 7258 final int uid = mapUid(ws.getUid(i)); 7259 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 7260 } 7261 7262 final List<WorkChain> workChains = ws.getWorkChains(); 7263 if (workChains != null) { 7264 for (int i = 0; i < workChains.size(); ++i) { 7265 final WorkChain workChain = workChains.get(i); 7266 final int uid = mapUid(workChain.getAttributionUid()); 7267 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 7268 } 7269 } 7270 } 7271 7272 @GuardedBy("this") noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, long elapsedRealtimeMs, long uptimeMs)7273 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, 7274 long elapsedRealtimeMs, long uptimeMs) { 7275 int N = ws.size(); 7276 for (int i=0; i<N; i++) { 7277 noteWifiBatchedScanStartedLocked(ws.getUid(i), csph, elapsedRealtimeMs, uptimeMs); 7278 } 7279 7280 final List<WorkChain> workChains = ws.getWorkChains(); 7281 if (workChains != null) { 7282 for (int i = 0; i < workChains.size(); ++i) { 7283 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph, 7284 elapsedRealtimeMs, uptimeMs); 7285 } 7286 } 7287 } 7288 7289 @GuardedBy("this") noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7290 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, 7291 long elapsedRealtimeMs, long uptimeMs) { 7292 int N = ws.size(); 7293 for (int i=0; i<N; i++) { 7294 noteWifiBatchedScanStoppedLocked(ws.getUid(i), elapsedRealtimeMs, uptimeMs); 7295 } 7296 7297 final List<WorkChain> workChains = ws.getWorkChains(); 7298 if (workChains != null) { 7299 for (int i = 0; i < workChains.size(); ++i) { 7300 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid(), 7301 elapsedRealtimeMs, uptimeMs); 7302 } 7303 } 7304 } 7305 includeInStringArray(String[] array, String str)7306 private static String[] includeInStringArray(String[] array, String str) { 7307 if (ArrayUtils.indexOf(array, str) >= 0) { 7308 return array; 7309 } 7310 String[] newArray = new String[array.length+1]; 7311 System.arraycopy(array, 0, newArray, 0, array.length); 7312 newArray[array.length] = str; 7313 return newArray; 7314 } 7315 excludeFromStringArray(String[] array, String str)7316 private static String[] excludeFromStringArray(String[] array, String str) { 7317 int index = ArrayUtils.indexOf(array, str); 7318 if (index >= 0) { 7319 String[] newArray = new String[array.length-1]; 7320 if (index > 0) { 7321 System.arraycopy(array, 0, newArray, 0, index); 7322 } 7323 if (index < array.length-1) { 7324 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 7325 } 7326 return newArray; 7327 } 7328 return array; 7329 } 7330 7331 /** @hide */ noteNetworkInterfaceForTransports(String iface, int[] transportTypes)7332 public void noteNetworkInterfaceForTransports(String iface, int[] transportTypes) { 7333 if (TextUtils.isEmpty(iface)) return; 7334 final int displayTransport = getDisplayTransport(transportTypes); 7335 7336 synchronized (mModemNetworkLock) { 7337 if (displayTransport == TRANSPORT_CELLULAR) { 7338 mModemIfaces = includeInStringArray(mModemIfaces, iface); 7339 if (DEBUG) { 7340 Slog.d(TAG, "Note mobile iface " + iface + ": " 7341 + Arrays.toString(mModemIfaces)); 7342 } 7343 } else { 7344 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 7345 if (DEBUG) { 7346 Slog.d(TAG, "Note non-mobile iface " + iface + ": " 7347 + Arrays.toString(mModemIfaces)); 7348 } 7349 } 7350 } 7351 7352 synchronized (mWifiNetworkLock) { 7353 if (displayTransport == TRANSPORT_WIFI) { 7354 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 7355 if (DEBUG) { 7356 Slog.d(TAG, "Note wifi iface " + iface + ": " + Arrays.toString(mWifiIfaces)); 7357 } 7358 } else { 7359 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 7360 if (DEBUG) { 7361 Slog.d(TAG, "Note non-wifi iface " + iface + ": " 7362 + Arrays.toString(mWifiIfaces)); 7363 } 7364 } 7365 } 7366 } 7367 7368 /** 7369 * Records timing data related to an incoming Binder call in order to attribute 7370 * the power consumption to the calling app. 7371 */ noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)7372 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 7373 Collection<BinderCallsStats.CallStat> callStats) { 7374 noteBinderCallStats(workSourceUid, incrementalCallCount, callStats, 7375 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7376 } 7377 noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats, long elapsedRealtimeMs, long uptimeMs)7378 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 7379 Collection<BinderCallsStats.CallStat> callStats, 7380 long elapsedRealtimeMs, long uptimeMs) { 7381 synchronized (this) { 7382 getUidStatsLocked(workSourceUid, elapsedRealtimeMs, uptimeMs) 7383 .noteBinderCallStatsLocked(incrementalCallCount, callStats); 7384 } 7385 } 7386 7387 /** 7388 * Takes note of native IDs of threads taking incoming binder calls. The CPU time 7389 * of these threads is attributed to the apps making those binder calls. 7390 */ noteBinderThreadNativeIds(int[] binderThreadNativeTids)7391 public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) { 7392 mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids); 7393 } 7394 7395 /** 7396 * Estimates the proportion of system server CPU activity handling incoming binder calls 7397 * that can be attributed to each app 7398 */ 7399 @VisibleForTesting updateSystemServiceCallStats()7400 public void updateSystemServiceCallStats() { 7401 // Start off by computing the average duration of recorded binder calls, 7402 // regardless of which binder or transaction. We will use this as a fallback 7403 // for calls that were not sampled at all. 7404 int totalRecordedCallCount = 0; 7405 long totalRecordedCallTimeMicros = 0; 7406 for (int i = 0; i < mUidStats.size(); i++) { 7407 Uid uid = mUidStats.valueAt(i); 7408 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 7409 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 7410 BinderCallStats stats = binderCallStats.valueAt(j); 7411 totalRecordedCallCount += stats.recordedCallCount; 7412 totalRecordedCallTimeMicros += stats.recordedCpuTimeMicros; 7413 } 7414 } 7415 7416 long totalSystemServiceTimeMicros = 0; 7417 7418 // For every UID, use recorded durations of sampled binder calls to estimate 7419 // the total time the system server spent handling requests from this UID. 7420 for (int i = 0; i < mUidStats.size(); i++) { 7421 Uid uid = mUidStats.valueAt(i); 7422 7423 long totalTimeForUidUs = 0; 7424 int totalCallCountForUid = 0; 7425 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 7426 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 7427 BinderCallStats stats = binderCallStats.valueAt(j); 7428 totalCallCountForUid += stats.callCount; 7429 if (stats.recordedCallCount > 0) { 7430 totalTimeForUidUs += 7431 stats.callCount * stats.recordedCpuTimeMicros / stats.recordedCallCount; 7432 } else if (totalRecordedCallCount > 0) { 7433 totalTimeForUidUs += 7434 stats.callCount * totalRecordedCallTimeMicros / totalRecordedCallCount; 7435 } 7436 } 7437 7438 if (totalCallCountForUid < uid.mBinderCallCount && totalRecordedCallCount > 0) { 7439 // Estimate remaining calls, which were not tracked because of binder call 7440 // stats sampling 7441 totalTimeForUidUs += 7442 (uid.mBinderCallCount - totalCallCountForUid) * totalRecordedCallTimeMicros 7443 / totalRecordedCallCount; 7444 } 7445 7446 uid.mSystemServiceTimeUs = totalTimeForUidUs; 7447 totalSystemServiceTimeMicros += totalTimeForUidUs; 7448 } 7449 7450 for (int i = 0; i < mUidStats.size(); i++) { 7451 Uid uid = mUidStats.valueAt(i); 7452 if (totalSystemServiceTimeMicros > 0) { 7453 uid.mProportionalSystemServiceUsage = 7454 (double) uid.mSystemServiceTimeUs / totalSystemServiceTimeMicros; 7455 } else { 7456 uid.mProportionalSystemServiceUsage = 0; 7457 } 7458 } 7459 } 7460 getWifiIfaces()7461 public String[] getWifiIfaces() { 7462 synchronized (mWifiNetworkLock) { 7463 return mWifiIfaces; 7464 } 7465 } 7466 getMobileIfaces()7467 public String[] getMobileIfaces() { 7468 synchronized (mModemNetworkLock) { 7469 return mModemIfaces; 7470 } 7471 } 7472 getScreenOnTime(long elapsedRealtimeUs, int which)7473 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 7474 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7475 } 7476 getScreenOnCount(int which)7477 @Override public int getScreenOnCount(int which) { 7478 return mScreenOnTimer.getCountLocked(which); 7479 } 7480 getScreenDozeTime(long elapsedRealtimeUs, int which)7481 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 7482 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7483 } 7484 getScreenDozeCount(int which)7485 @Override public int getScreenDozeCount(int which) { 7486 return mScreenDozeTimer.getCountLocked(which); 7487 } 7488 getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)7489 @Override public long getScreenBrightnessTime(int brightnessBin, 7490 long elapsedRealtimeUs, int which) { 7491 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 7492 elapsedRealtimeUs, which); 7493 } 7494 getScreenBrightnessTimer(int brightnessBin)7495 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 7496 return mScreenBrightnessTimer[brightnessBin]; 7497 } 7498 7499 @Override getDisplayCount()7500 public int getDisplayCount() { 7501 return mPerDisplayBatteryStats.length; 7502 } 7503 7504 @Override getDisplayScreenOnTime(int display, long elapsedRealtimeUs)7505 public long getDisplayScreenOnTime(int display, long elapsedRealtimeUs) { 7506 return mPerDisplayBatteryStats[display].screenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, 7507 STATS_SINCE_CHARGED); 7508 } 7509 7510 @Override getDisplayScreenDozeTime(int display, long elapsedRealtimeUs)7511 public long getDisplayScreenDozeTime(int display, long elapsedRealtimeUs) { 7512 return mPerDisplayBatteryStats[display].screenDozeTimer.getTotalTimeLocked( 7513 elapsedRealtimeUs, STATS_SINCE_CHARGED); 7514 } 7515 7516 @Override getDisplayScreenBrightnessTime(int display, int brightnessBin, long elapsedRealtimeUs)7517 public long getDisplayScreenBrightnessTime(int display, int brightnessBin, 7518 long elapsedRealtimeUs) { 7519 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 7520 return displayStats.screenBrightnessTimers[brightnessBin].getTotalTimeLocked( 7521 elapsedRealtimeUs, STATS_SINCE_CHARGED); 7522 } 7523 getInteractiveTime(long elapsedRealtimeUs, int which)7524 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 7525 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7526 } 7527 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)7528 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 7529 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7530 } 7531 getPowerSaveModeEnabledCount(int which)7532 @Override public int getPowerSaveModeEnabledCount(int which) { 7533 return mPowerSaveModeEnabledTimer.getCountLocked(which); 7534 } 7535 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)7536 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 7537 int which) { 7538 switch (mode) { 7539 case DEVICE_IDLE_MODE_LIGHT: 7540 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7541 case DEVICE_IDLE_MODE_DEEP: 7542 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7543 } 7544 return 0; 7545 } 7546 getDeviceIdleModeCount(int mode, int which)7547 @Override public int getDeviceIdleModeCount(int mode, int which) { 7548 switch (mode) { 7549 case DEVICE_IDLE_MODE_LIGHT: 7550 return mDeviceIdleModeLightTimer.getCountLocked(which); 7551 case DEVICE_IDLE_MODE_DEEP: 7552 return mDeviceIdleModeFullTimer.getCountLocked(which); 7553 } 7554 return 0; 7555 } 7556 getLongestDeviceIdleModeTime(int mode)7557 @Override public long getLongestDeviceIdleModeTime(int mode) { 7558 switch (mode) { 7559 case DEVICE_IDLE_MODE_LIGHT: 7560 return mLongestLightIdleTimeMs; 7561 case DEVICE_IDLE_MODE_DEEP: 7562 return mLongestFullIdleTimeMs; 7563 } 7564 return 0; 7565 } 7566 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)7567 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 7568 switch (mode) { 7569 case DEVICE_IDLE_MODE_LIGHT: 7570 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7571 case DEVICE_IDLE_MODE_DEEP: 7572 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7573 } 7574 return 0; 7575 } 7576 getDeviceIdlingCount(int mode, int which)7577 @Override public int getDeviceIdlingCount(int mode, int which) { 7578 switch (mode) { 7579 case DEVICE_IDLE_MODE_LIGHT: 7580 return mDeviceLightIdlingTimer.getCountLocked(which); 7581 case DEVICE_IDLE_MODE_DEEP: 7582 return mDeviceIdlingTimer.getCountLocked(which); 7583 } 7584 return 0; 7585 } 7586 getNumConnectivityChange(int which)7587 @Override public int getNumConnectivityChange(int which) { 7588 return mNumConnectivityChange; 7589 } 7590 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)7591 @Override public long getGpsSignalQualityTime(int strengthBin, 7592 long elapsedRealtimeUs, int which) { 7593 if (strengthBin < 0 || strengthBin >= mGpsSignalQualityTimer.length) { 7594 return 0; 7595 } 7596 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 7597 elapsedRealtimeUs, which); 7598 } 7599 getGpsBatteryDrainMaMs()7600 @Override public long getGpsBatteryDrainMaMs() { 7601 final double opVolt = mPowerProfile.getAveragePower( 7602 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 7603 if (opVolt == 0) { 7604 return 0; 7605 } 7606 double energyUsedMaMs = 0.0; 7607 final int which = STATS_SINCE_CHARGED; 7608 final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000; 7609 for(int i=0; i < mGpsSignalQualityTimer.length; i++) { 7610 energyUsedMaMs 7611 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 7612 * (getGpsSignalQualityTime(i, rawRealtimeUs, which) / 1000); 7613 } 7614 return (long) energyUsedMaMs; 7615 } 7616 getPhoneOnTime(long elapsedRealtimeUs, int which)7617 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 7618 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7619 } 7620 getPhoneOnCount(int which)7621 @Override public int getPhoneOnCount(int which) { 7622 return mPhoneOnTimer.getCountLocked(which); 7623 } 7624 getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)7625 @Override public long getPhoneSignalStrengthTime(int strengthBin, 7626 long elapsedRealtimeUs, int which) { 7627 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 7628 elapsedRealtimeUs, which); 7629 } 7630 getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)7631 @Override public long getPhoneSignalScanningTime( 7632 long elapsedRealtimeUs, int which) { 7633 return mPhoneSignalScanningTimer.getTotalTimeLocked( 7634 elapsedRealtimeUs, which); 7635 } 7636 getPhoneSignalScanningTimer()7637 @Override public Timer getPhoneSignalScanningTimer() { 7638 return mPhoneSignalScanningTimer; 7639 } 7640 getPhoneSignalStrengthCount(int strengthBin, int which)7641 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 7642 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 7643 } 7644 getPhoneSignalStrengthTimer(int strengthBin)7645 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 7646 return mPhoneSignalStrengthsTimer[strengthBin]; 7647 } 7648 getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)7649 @Override public long getPhoneDataConnectionTime(int dataType, 7650 long elapsedRealtimeUs, int which) { 7651 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 7652 elapsedRealtimeUs, which); 7653 } 7654 getPhoneDataConnectionCount(int dataType, int which)7655 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 7656 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 7657 } 7658 getPhoneDataConnectionTimer(int dataType)7659 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 7660 return mPhoneDataConnectionsTimer[dataType]; 7661 } 7662 getNrNsaTime(long elapsedRealtimeUs)7663 @Override public long getNrNsaTime(long elapsedRealtimeUs) { 7664 return mNrNsaTimer.getTotalTimeLocked(elapsedRealtimeUs, STATS_SINCE_CHARGED); 7665 } 7666 getActiveRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)7667 @Override public long getActiveRadioDurationMs(@RadioAccessTechnology int rat, 7668 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, 7669 long elapsedRealtimeMs) { 7670 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7671 if (stats == null) return 0L; 7672 7673 final int freqCount = stats.perStateTimers.length; 7674 if (frequencyRange < 0 || frequencyRange >= freqCount) return 0L; 7675 7676 final StopwatchTimer[] strengthTimers = stats.perStateTimers[frequencyRange]; 7677 final int strengthCount = strengthTimers.length; 7678 if (signalStrength < 0 || signalStrength >= strengthCount) return 0L; 7679 7680 return stats.perStateTimers[frequencyRange][signalStrength].getTotalTimeLocked( 7681 elapsedRealtimeMs * 1000, STATS_SINCE_CHARGED) / 1000; 7682 } 7683 7684 @Override getActiveTxRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)7685 public long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat, 7686 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, 7687 long elapsedRealtimeMs) { 7688 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7689 if (stats == null) return DURATION_UNAVAILABLE; 7690 7691 final LongSamplingCounter counter = stats.getTxDurationCounter(frequencyRange, 7692 signalStrength, false); 7693 if (counter == null) return DURATION_UNAVAILABLE; 7694 7695 return counter.getCountLocked(STATS_SINCE_CHARGED); 7696 } 7697 7698 @Override getActiveRxRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs)7699 public long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat, 7700 @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs) { 7701 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7702 if (stats == null) return DURATION_UNAVAILABLE; 7703 7704 final LongSamplingCounter counter = stats.getRxDurationCounter(frequencyRange, false); 7705 if (counter == null) return DURATION_UNAVAILABLE; 7706 7707 return counter.getCountLocked(STATS_SINCE_CHARGED); 7708 } 7709 getMobileRadioActiveTime(long elapsedRealtimeUs, int which)7710 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 7711 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7712 } 7713 getMobileRadioActiveCount(int which)7714 @Override public int getMobileRadioActiveCount(int which) { 7715 return mMobileRadioActiveTimer.getCountLocked(which); 7716 } 7717 getMobileRadioActiveAdjustedTime(int which)7718 @Override public long getMobileRadioActiveAdjustedTime(int which) { 7719 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 7720 } 7721 getMobileRadioActiveUnknownTime(int which)7722 @Override public long getMobileRadioActiveUnknownTime(int which) { 7723 return mMobileRadioActiveUnknownTime.getCountLocked(which); 7724 } 7725 getMobileRadioActiveUnknownCount(int which)7726 @Override public int getMobileRadioActiveUnknownCount(int which) { 7727 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 7728 } 7729 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)7730 @Override public long getWifiMulticastWakelockTime( 7731 long elapsedRealtimeUs, int which) { 7732 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 7733 elapsedRealtimeUs, which); 7734 } 7735 getWifiMulticastWakelockCount(int which)7736 @Override public int getWifiMulticastWakelockCount(int which) { 7737 return mWifiMulticastWakelockTimer.getCountLocked(which); 7738 } 7739 getWifiOnTime(long elapsedRealtimeUs, int which)7740 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 7741 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7742 } 7743 getWifiActiveTime(long elapsedRealtimeUs, int which)7744 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 7745 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7746 } 7747 getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)7748 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 7749 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7750 } 7751 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)7752 @Override public long getWifiStateTime(int wifiState, 7753 long elapsedRealtimeUs, int which) { 7754 return mWifiStateTimer[wifiState].getTotalTimeLocked( 7755 elapsedRealtimeUs, which); 7756 } 7757 getWifiStateCount(int wifiState, int which)7758 @Override public int getWifiStateCount(int wifiState, int which) { 7759 return mWifiStateTimer[wifiState].getCountLocked(which); 7760 } 7761 getWifiStateTimer(int wifiState)7762 @Override public Timer getWifiStateTimer(int wifiState) { 7763 return mWifiStateTimer[wifiState]; 7764 } 7765 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)7766 @Override public long getWifiSupplStateTime(int state, 7767 long elapsedRealtimeUs, int which) { 7768 return mWifiSupplStateTimer[state].getTotalTimeLocked( 7769 elapsedRealtimeUs, which); 7770 } 7771 getWifiSupplStateCount(int state, int which)7772 @Override public int getWifiSupplStateCount(int state, int which) { 7773 return mWifiSupplStateTimer[state].getCountLocked(which); 7774 } 7775 getWifiSupplStateTimer(int state)7776 @Override public Timer getWifiSupplStateTimer(int state) { 7777 return mWifiSupplStateTimer[state]; 7778 } 7779 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)7780 @Override public long getWifiSignalStrengthTime(int strengthBin, 7781 long elapsedRealtimeUs, int which) { 7782 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 7783 elapsedRealtimeUs, which); 7784 } 7785 getWifiSignalStrengthCount(int strengthBin, int which)7786 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 7787 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 7788 } 7789 getWifiSignalStrengthTimer(int strengthBin)7790 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 7791 return mWifiSignalStrengthsTimer[strengthBin]; 7792 } 7793 7794 @Override getBluetoothControllerActivity()7795 public ControllerActivityCounter getBluetoothControllerActivity() { 7796 return mBluetoothActivity; 7797 } 7798 7799 @Override getWifiControllerActivity()7800 public ControllerActivityCounter getWifiControllerActivity() { 7801 return mWifiActivity; 7802 } 7803 7804 @Override getModemControllerActivity()7805 public ControllerActivityCounter getModemControllerActivity() { 7806 return mModemActivity; 7807 } 7808 7809 @Override hasBluetoothActivityReporting()7810 public boolean hasBluetoothActivityReporting() { 7811 return mHasBluetoothReporting; 7812 } 7813 7814 @Override hasWifiActivityReporting()7815 public boolean hasWifiActivityReporting() { 7816 return mHasWifiReporting; 7817 } 7818 7819 @Override hasModemActivityReporting()7820 public boolean hasModemActivityReporting() { 7821 return mHasModemReporting; 7822 } 7823 7824 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)7825 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 7826 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7827 } 7828 7829 @Override getFlashlightOnCount(int which)7830 public long getFlashlightOnCount(int which) { 7831 return mFlashlightOnTimer.getCountLocked(which); 7832 } 7833 7834 @Override getCameraOnTime(long elapsedRealtimeUs, int which)7835 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 7836 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7837 } 7838 7839 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)7840 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 7841 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7842 } 7843 7844 @Override getNetworkActivityBytes(int type, int which)7845 public long getNetworkActivityBytes(int type, int which) { 7846 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 7847 return mNetworkByteActivityCounters[type].getCountLocked(which); 7848 } else { 7849 return 0; 7850 } 7851 } 7852 7853 @Override getNetworkActivityPackets(int type, int which)7854 public long getNetworkActivityPackets(int type, int which) { 7855 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 7856 return mNetworkPacketActivityCounters[type].getCountLocked(which); 7857 } else { 7858 return 0; 7859 } 7860 } 7861 7862 @GuardedBy("this") 7863 @Override getBluetoothEnergyConsumptionUC()7864 public long getBluetoothEnergyConsumptionUC() { 7865 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH); 7866 } 7867 7868 @GuardedBy("this") 7869 @Override getCpuEnergyConsumptionUC()7870 public long getCpuEnergyConsumptionUC() { 7871 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU); 7872 } 7873 7874 @GuardedBy("this") 7875 @Override getGnssEnergyConsumptionUC()7876 public long getGnssEnergyConsumptionUC() { 7877 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_GNSS); 7878 } 7879 7880 @GuardedBy("this") 7881 @Override getMobileRadioEnergyConsumptionUC()7882 public long getMobileRadioEnergyConsumptionUC() { 7883 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 7884 } 7885 7886 @GuardedBy("this") 7887 @Override getPhoneEnergyConsumptionUC()7888 public long getPhoneEnergyConsumptionUC() { 7889 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_PHONE); 7890 } 7891 7892 @GuardedBy("this") 7893 @Override getScreenOnEnergyConsumptionUC()7894 public long getScreenOnEnergyConsumptionUC() { 7895 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON); 7896 } 7897 7898 @GuardedBy("this") 7899 @Override getScreenDozeEnergyConsumptionUC()7900 public long getScreenDozeEnergyConsumptionUC() { 7901 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_DOZE); 7902 } 7903 7904 @GuardedBy("this") 7905 @Override getWifiEnergyConsumptionUC()7906 public long getWifiEnergyConsumptionUC() { 7907 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI); 7908 } 7909 7910 @GuardedBy("this") 7911 @Override getCameraEnergyConsumptionUC()7912 public long getCameraEnergyConsumptionUC() { 7913 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CAMERA); 7914 } 7915 7916 /** 7917 * Returns the consumption (in microcoulombs) that the given standard power bucket consumed. 7918 * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable 7919 * 7920 * @param bucket standard power bucket of interest 7921 * @return charge (in microcoulombs) used for this power bucket 7922 */ 7923 @GuardedBy("this") getPowerBucketConsumptionUC(@tandardPowerBucket int bucket)7924 private long getPowerBucketConsumptionUC(@StandardPowerBucket int bucket) { 7925 if (mGlobalEnergyConsumerStats == null) { 7926 return POWER_DATA_UNAVAILABLE; 7927 } 7928 return mGlobalEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket); 7929 } 7930 7931 @GuardedBy("this") 7932 @Override getCustomEnergyConsumerBatteryConsumptionUC()7933 public @Nullable long[] getCustomEnergyConsumerBatteryConsumptionUC() { 7934 if (mGlobalEnergyConsumerStats == null) { 7935 return null; 7936 } 7937 return mGlobalEnergyConsumerStats.getAccumulatedCustomBucketCharges(); 7938 } 7939 7940 /** 7941 * Returns the names of custom power components. 7942 */ 7943 @Override getCustomEnergyConsumerNames()7944 public @NonNull String[] getCustomEnergyConsumerNames() { 7945 synchronized (this) { 7946 if (mEnergyConsumerStatsConfig == null) { 7947 return new String[0]; 7948 } 7949 final String[] names = mEnergyConsumerStatsConfig.getCustomBucketNames(); 7950 for (int i = 0; i < names.length; i++) { 7951 if (TextUtils.isEmpty(names[i])) { 7952 names[i] = "CUSTOM_" + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i; 7953 } 7954 } 7955 return names; 7956 } 7957 } 7958 7959 @Override getStartClockTime()7960 public long getStartClockTime() { 7961 synchronized (this) { 7962 final long currentTimeMs = mClock.currentTimeMillis(); 7963 if ((currentTimeMs > MILLISECONDS_IN_YEAR 7964 && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR)) 7965 || (mStartClockTimeMs > currentTimeMs)) { 7966 // If the start clock time has changed by more than a year, then presumably 7967 // the previous time was completely bogus. So we are going to figure out a 7968 // new time based on how much time has elapsed since we started counting. 7969 mHistory.recordCurrentTimeChange(mClock.elapsedRealtime(), mClock.uptimeMillis(), 7970 currentTimeMs); 7971 adjustStartClockTime(currentTimeMs); 7972 } 7973 return mStartClockTimeMs; 7974 } 7975 } 7976 7977 /** 7978 * Returns the monotonic time when the BatteryStats session started. 7979 */ getMonotonicStartTime()7980 public long getMonotonicStartTime() { 7981 return mMonotonicStartTime; 7982 } 7983 7984 /** 7985 * Returns the monotonic time when the BatteryStats session ended, or 7986 * {@link MonotonicClock#UNDEFINED} if the session is still ongoing. 7987 */ getMonotonicEndTime()7988 public long getMonotonicEndTime() { 7989 return mMonotonicEndTime; 7990 } 7991 getStartPlatformVersion()7992 @Override public String getStartPlatformVersion() { 7993 return mStartPlatformVersion; 7994 } 7995 getEndPlatformVersion()7996 @Override public String getEndPlatformVersion() { 7997 return mEndPlatformVersion; 7998 } 7999 getParcelVersion()8000 @Override public int getParcelVersion() { 8001 return VERSION; 8002 } 8003 getIsOnBattery()8004 @Override public boolean getIsOnBattery() { 8005 return mOnBattery; 8006 } 8007 getStatsStartRealtime()8008 @Override public long getStatsStartRealtime() { 8009 return mRealtimeStartUs; 8010 } 8011 getUidStats()8012 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 8013 return mUidStats; 8014 } 8015 resetIfNotNull(T t, boolean detachIfReset, long elapsedRealtimeUs)8016 private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset, 8017 long elapsedRealtimeUs) { 8018 if (t != null) { 8019 return t.reset(detachIfReset, elapsedRealtimeUs); 8020 } 8021 return true; 8022 } 8023 resetIfNotNull(T[] t, boolean detachIfReset, long elapsedRealtimeUs)8024 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset, 8025 long elapsedRealtimeUs) { 8026 if (t != null) { 8027 boolean ret = true; 8028 for (int i = 0; i < t.length; i++) { 8029 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 8030 } 8031 return ret; 8032 } 8033 return true; 8034 } 8035 resetIfNotNull(T[][] t, boolean detachIfReset, long elapsedRealtimeUs)8036 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset, 8037 long elapsedRealtimeUs) { 8038 if (t != null) { 8039 boolean ret = true; 8040 for (int i = 0; i < t.length; i++) { 8041 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 8042 } 8043 return ret; 8044 } 8045 return true; 8046 } 8047 resetIfNotNull(ControllerActivityCounterImpl counter, boolean detachIfReset, long elapsedRealtimeUs)8048 private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, 8049 boolean detachIfReset, long elapsedRealtimeUs) { 8050 if (counter != null) { 8051 counter.reset(detachIfReset, elapsedRealtimeUs); 8052 } 8053 return true; 8054 } 8055 detachIfNotNull(T t)8056 private static <T extends TimeBaseObs> void detachIfNotNull(T t) { 8057 if (t != null) { 8058 t.detach(); 8059 } 8060 } 8061 detachIfNotNull(T[] t)8062 private static <T extends TimeBaseObs> void detachIfNotNull(T[] t) { 8063 if (t != null) { 8064 for (int i = 0; i < t.length; i++) { 8065 detachIfNotNull(t[i]); 8066 } 8067 } 8068 } 8069 detachIfNotNull(T[][] t)8070 private static <T extends TimeBaseObs> void detachIfNotNull(T[][] t) { 8071 if (t != null) { 8072 for (int i = 0; i < t.length; i++) { 8073 detachIfNotNull(t[i]); 8074 } 8075 } 8076 } 8077 detachIfNotNull(ControllerActivityCounterImpl counter)8078 private static void detachIfNotNull(ControllerActivityCounterImpl counter) { 8079 if (counter != null) { 8080 counter.detach(); 8081 } 8082 } 8083 8084 /** 8085 * Accumulates stats for a specific binder transaction. 8086 */ 8087 @VisibleForTesting 8088 protected static class BinderCallStats { 8089 public Class<? extends Binder> binderClass; 8090 public int transactionCode; 8091 public String methodName; 8092 8093 public long callCount; 8094 public long recordedCallCount; 8095 public long recordedCpuTimeMicros; 8096 8097 8098 @Override hashCode()8099 public int hashCode() { 8100 return binderClass.hashCode() * 31 + transactionCode; 8101 } 8102 8103 @Override equals(Object obj)8104 public boolean equals(Object obj) { 8105 if (!(obj instanceof BinderCallStats)) { 8106 return false; 8107 } 8108 BinderCallStats bcsk = (BinderCallStats) obj; 8109 return binderClass.equals(bcsk.binderClass) && transactionCode == bcsk.transactionCode; 8110 } 8111 getClassName()8112 public String getClassName() { 8113 return binderClass.getName(); 8114 } 8115 getMethodName()8116 public String getMethodName() { 8117 return methodName; 8118 } 8119 8120 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) ensureMethodName(BinderTransactionNameResolver resolver)8121 public void ensureMethodName(BinderTransactionNameResolver resolver) { 8122 if (methodName == null) { 8123 methodName = resolver.getMethodName(binderClass, transactionCode); 8124 } 8125 } 8126 8127 @Override toString()8128 public String toString() { 8129 return "BinderCallStats{" 8130 + binderClass 8131 + " transaction=" + transactionCode 8132 + " callCount=" + callCount 8133 + " recordedCallCount=" + recordedCallCount 8134 + " recorderCpuTimeMicros=" + recordedCpuTimeMicros 8135 + "}"; 8136 } 8137 } 8138 8139 /** 8140 * The statistics associated with a particular uid. 8141 */ 8142 public static class Uid extends BatteryStats.Uid { 8143 /** 8144 * BatteryStatsImpl that we are associated with. 8145 */ 8146 protected BatteryStatsImpl mBsi; 8147 8148 final int mUid; 8149 8150 /** TimeBase for when uid is in background and device is on battery. */ 8151 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 8152 public final TimeBase mOnBatteryBackgroundTimeBase; 8153 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 8154 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 8155 8156 boolean mWifiRunning; 8157 StopwatchTimer mWifiRunningTimer; 8158 8159 boolean mFullWifiLockOut; 8160 StopwatchTimer mFullWifiLockTimer; 8161 8162 boolean mWifiScanStarted; 8163 DualTimer mWifiScanTimer; 8164 8165 static final int NO_BATCHED_SCAN_STARTED = -1; 8166 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8167 StopwatchTimer[] mWifiBatchedScanTimer; 8168 8169 int mWifiMulticastWakelockCount; 8170 StopwatchTimer mWifiMulticastTimer; 8171 8172 StopwatchTimer mAudioTurnedOnTimer; 8173 StopwatchTimer mVideoTurnedOnTimer; 8174 StopwatchTimer mFlashlightTurnedOnTimer; 8175 StopwatchTimer mCameraTurnedOnTimer; 8176 StopwatchTimer mForegroundActivityTimer; 8177 StopwatchTimer mForegroundServiceTimer; 8178 /** Total time spent by the uid holding any partial wakelocks. */ 8179 DualTimer mAggregatedPartialWakelockTimer; 8180 DualTimer mBluetoothScanTimer; 8181 DualTimer mBluetoothUnoptimizedScanTimer; 8182 Counter mBluetoothScanResultCounter; 8183 Counter mBluetoothScanResultBgCounter; 8184 8185 int mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 8186 StopwatchTimer[] mProcessStateTimer; 8187 8188 boolean mInForegroundService = false; 8189 8190 BatchTimer mVibratorOnTimer; 8191 8192 Counter[] mUserActivityCounters; 8193 8194 LongSamplingCounter[] mNetworkByteActivityCounters; 8195 LongSamplingCounter[] mNetworkPacketActivityCounters; 8196 TimeMultiStateCounter mMobileRadioActiveTime; 8197 LongSamplingCounter mMobileRadioActiveCount; 8198 8199 /** 8200 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 8201 */ 8202 private LongSamplingCounter mMobileRadioApWakeupCount; 8203 8204 /** 8205 * How many times this UID woke up the Application Processor due to a Wifi packet. 8206 */ 8207 private LongSamplingCounter mWifiRadioApWakeupCount; 8208 8209 /** 8210 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 8211 * Can be null if the UID has had no such activity. 8212 */ 8213 private ControllerActivityCounterImpl mWifiControllerActivity; 8214 8215 /** 8216 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 8217 * Can be null if the UID has had no such activity. 8218 */ 8219 private ControllerActivityCounterImpl mBluetoothControllerActivity; 8220 8221 /** 8222 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 8223 * Can be null if the UID has had no such activity. 8224 */ 8225 private ControllerActivityCounterImpl mModemControllerActivity; 8226 8227 /** 8228 * The CPU times we had at the last history details update. 8229 */ 8230 long mLastStepUserTimeMs; 8231 long mLastStepSystemTimeMs; 8232 long mCurStepUserTimeMs; 8233 long mCurStepSystemTimeMs; 8234 8235 LongSamplingCounter mUserCpuTime; 8236 LongSamplingCounter mSystemCpuTime; 8237 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 8238 TimeMultiStateCounter mCpuActiveTimeMs; 8239 8240 LongSamplingCounterArray mCpuFreqTimeMs; 8241 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 8242 LongSamplingCounterArray mCpuClusterTimesMs; 8243 8244 TimeInFreqMultiStateCounter mProcStateTimeMs; 8245 TimeInFreqMultiStateCounter mProcStateScreenOffTimeMs; 8246 8247 SparseArray<ChildUid> mChildUids; 8248 8249 /** 8250 * The statistics we have collected for this uid's wake locks. 8251 */ 8252 final OverflowArrayMap<Wakelock> mWakelockStats; 8253 8254 /** 8255 * The statistics we have collected for this uid's syncs. 8256 */ 8257 final OverflowArrayMap<DualTimer> mSyncStats; 8258 8259 /** 8260 * The statistics we have collected for this uid's jobs. 8261 */ 8262 final OverflowArrayMap<DualTimer> mJobStats; 8263 8264 /** 8265 * Count of the jobs that have completed and the reasons why they completed. 8266 */ 8267 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 8268 8269 /** 8270 * Count of app launch events that had associated deferred job counts or info about 8271 * last time a job was run. 8272 */ 8273 Counter mJobsDeferredEventCount; 8274 8275 /** 8276 * Count of deferred jobs that were pending when the app was launched or brought to 8277 * the foreground through a user interaction. 8278 */ 8279 Counter mJobsDeferredCount; 8280 8281 /** 8282 * Sum of time since the last time a job was run for this app before it was launched. 8283 */ 8284 LongSamplingCounter mJobsFreshnessTimeMs; 8285 8286 /** 8287 * Array of counts of instances where the time since the last job was run for the app 8288 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 8289 */ 8290 final Counter[] mJobsFreshnessBuckets; 8291 8292 /** 8293 * The statistics we have collected for this uid's sensor activations. 8294 */ 8295 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 8296 8297 /** 8298 * The statistics we have collected for this uid's processes. 8299 */ 8300 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 8301 8302 /** 8303 * The statistics we have collected for this uid's processes. 8304 */ 8305 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 8306 8307 /** 8308 * The transient wake stats we have collected for this uid's pids. 8309 */ 8310 final SparseArray<Pid> mPids = new SparseArray<>(); 8311 8312 /** 8313 * Grand total of system server binder calls made by this uid. 8314 */ 8315 private long mBinderCallCount; 8316 8317 /** 8318 * Detailed information about system server binder calls made by this uid. 8319 */ 8320 private final ArraySet<BinderCallStats> mBinderCallStats = new ArraySet<>(); 8321 8322 /** 8323 * EnergyConsumer consumption by this uid while on battery. 8324 * Its '<b>custom</b> power buckets' correspond to the 8325 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 8326 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 8327 * 8328 * Will be null if energy consumer data is completely unavailable (in which case 8329 * {@link #mGlobalEnergyConsumerStats} will also be null) or if the power usage by this uid 8330 * is 0 for every bucket. 8331 */ 8332 private EnergyConsumerStats mUidEnergyConsumerStats; 8333 8334 /** 8335 * Estimated total time spent by the system server handling requests from this uid. 8336 */ 8337 private long mSystemServiceTimeUs; 8338 8339 /** 8340 * Estimated proportion of system server binder call CPU cost for this uid. 8341 */ 8342 private double mProportionalSystemServiceUsage; 8343 Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs)8344 public Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs) { 8345 mBsi = bsi; 8346 mUid = uid; 8347 8348 /* Observer list of TimeBase object in Uid is short */ 8349 mOnBatteryBackgroundTimeBase = new TimeBase(false); 8350 mOnBatteryBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 8351 /* Observer list of TimeBase object in Uid is short */ 8352 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); 8353 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 8354 8355 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8356 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8357 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 8358 8359 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 8360 @Override public Wakelock instantiateObject() { 8361 return new Wakelock(mBsi, Uid.this); 8362 } 8363 }; 8364 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 8365 @Override public DualTimer instantiateObject() { 8366 return new DualTimer(mBsi.mClock, Uid.this, SYNC, null, 8367 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8368 } 8369 }; 8370 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 8371 @Override public DualTimer instantiateObject() { 8372 return new DualTimer(mBsi.mClock, Uid.this, JOB, null, 8373 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8374 } 8375 }; 8376 8377 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, this, WIFI_RUNNING, 8378 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 8379 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, this, FULL_WIFI_LOCK, 8380 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 8381 mWifiScanTimer = new DualTimer(mBsi.mClock, this, WIFI_SCAN, 8382 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8383 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 8384 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, this, WIFI_MULTICAST_ENABLED, 8385 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 8386 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 8387 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 8388 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 8389 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8390 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 8391 } 8392 8393 @GuardedBy("mBsi") 8394 @VisibleForTesting setProcessStateForTest(int procState, long elapsedTimeMs)8395 public void setProcessStateForTest(int procState, long elapsedTimeMs) { 8396 mProcessState = procState; 8397 getProcStateTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs); 8398 getProcStateScreenOffTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs); 8399 final int batteryConsumerProcessState = 8400 mapUidProcessStateToBatteryConsumerProcessState(procState); 8401 getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); 8402 getMobileRadioActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); 8403 final ControllerActivityCounterImpl wifiControllerActivity = 8404 getWifiControllerActivity(); 8405 if (wifiControllerActivity != null) { 8406 wifiControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs); 8407 } 8408 final ControllerActivityCounterImpl bluetoothControllerActivity = 8409 getBluetoothControllerActivity(); 8410 if (bluetoothControllerActivity != null) { 8411 bluetoothControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs); 8412 } 8413 final EnergyConsumerStats energyStats = 8414 getOrCreateEnergyConsumerStatsIfSupportedLocked(); 8415 if (energyStats != null) { 8416 energyStats.setState(batteryConsumerProcessState, elapsedTimeMs); 8417 } 8418 } 8419 8420 @Override getCpuFreqTimes(int which)8421 public long[] getCpuFreqTimes(int which) { 8422 return nullIfAllZeros(mCpuFreqTimeMs, which); 8423 } 8424 8425 @Override getScreenOffCpuFreqTimes(int which)8426 public long[] getScreenOffCpuFreqTimes(int which) { 8427 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 8428 } 8429 getCpuActiveTimeCounter()8430 private TimeMultiStateCounter getCpuActiveTimeCounter() { 8431 if (mCpuActiveTimeMs == null) { 8432 final long timestampMs = mBsi.mClock.elapsedRealtime(); 8433 mCpuActiveTimeMs = new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, 8434 BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 8435 mCpuActiveTimeMs.setState( 8436 mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 8437 timestampMs); 8438 } 8439 return mCpuActiveTimeMs; 8440 } 8441 8442 @Override getCpuActiveTime()8443 public long getCpuActiveTime() { 8444 if (mCpuActiveTimeMs == null) { 8445 return 0; 8446 } 8447 8448 long activeTime = 0; 8449 for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { 8450 activeTime += mCpuActiveTimeMs.getCountForProcessState(procState); 8451 } 8452 return activeTime; 8453 } 8454 8455 @Override getCpuActiveTime(int procState)8456 public long getCpuActiveTime(int procState) { 8457 if (mCpuActiveTimeMs == null 8458 || procState < 0 || procState >= BatteryConsumer.PROCESS_STATE_COUNT) { 8459 return 0; 8460 } 8461 8462 return mCpuActiveTimeMs.getCountForProcessState(procState); 8463 } 8464 8465 @Override getCpuClusterTimes()8466 public long[] getCpuClusterTimes() { 8467 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 8468 } 8469 8470 @GuardedBy("mBsi") 8471 @Override getCpuFreqTimes(long[] timesInFreqMs, int procState)8472 public boolean getCpuFreqTimes(long[] timesInFreqMs, int procState) { 8473 if (procState < 0 || procState >= NUM_PROCESS_STATE) { 8474 return false; 8475 } 8476 if (mProcStateTimeMs == null) { 8477 return false; 8478 } 8479 if (!mBsi.mPerProcStateCpuTimesAvailable) { 8480 mProcStateTimeMs = null; 8481 return false; 8482 } 8483 return mProcStateTimeMs.getCountsLocked(timesInFreqMs, procState); 8484 } 8485 8486 @GuardedBy("mBsi") 8487 @Override getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState)8488 public boolean getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState) { 8489 if (procState < 0 || procState >= NUM_PROCESS_STATE) { 8490 return false; 8491 } 8492 if (mProcStateScreenOffTimeMs == null) { 8493 return false; 8494 } 8495 if (!mBsi.mPerProcStateCpuTimesAvailable) { 8496 mProcStateScreenOffTimeMs = null; 8497 return false; 8498 } 8499 return mProcStateScreenOffTimeMs.getCountsLocked(timesInFreqMs, procState); 8500 } 8501 getBinderCallCount()8502 public long getBinderCallCount() { 8503 return mBinderCallCount; 8504 } 8505 8506 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) getBinderCallStats()8507 public ArraySet<BinderCallStats> getBinderCallStats() { 8508 return mBinderCallStats; 8509 } 8510 8511 @Override getProportionalSystemServiceUsage()8512 public double getProportionalSystemServiceUsage() { 8513 return mProportionalSystemServiceUsage; 8514 } 8515 8516 /** 8517 * Adds isolated UID to the list of children. 8518 */ addIsolatedUid(int isolatedUid)8519 public void addIsolatedUid(int isolatedUid) { 8520 if (mChildUids == null) { 8521 mChildUids = new SparseArray<>(); 8522 } else if (mChildUids.indexOfKey(isolatedUid) >= 0) { 8523 return; 8524 } 8525 mChildUids.put(isolatedUid, new ChildUid()); 8526 } 8527 8528 /** 8529 * Removes isolated UID from the list of children. 8530 */ removeIsolatedUid(int isolatedUid)8531 public void removeIsolatedUid(int isolatedUid) { 8532 final int idx = mChildUids == null ? -1 : mChildUids.indexOfKey(isolatedUid); 8533 if (idx < 0) { 8534 return; 8535 } 8536 mChildUids.remove(idx); 8537 } 8538 8539 @GuardedBy("mBsi") getChildUid(int childUid)8540 ChildUid getChildUid(int childUid) { 8541 return mChildUids == null ? null : mChildUids.get(childUid); 8542 } 8543 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)8544 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 8545 if (cpuTimesMs == null) { 8546 return null; 8547 } 8548 final long[] counts = cpuTimesMs.getCountsLocked(which); 8549 if (counts == null) { 8550 return null; 8551 } 8552 // Return counts only if at least one of the elements is non-zero. 8553 for (int i = counts.length - 1; i >= 0; --i) { 8554 if (counts[i] != 0) { 8555 return counts; 8556 } 8557 } 8558 return null; 8559 } 8560 8561 @GuardedBy("mBsi") ensureMultiStateCounters(long timestampMs)8562 private void ensureMultiStateCounters(long timestampMs) { 8563 if (mBsi.mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 8564 throw new IllegalStateException("Multi-state counters used in streamlined mode"); 8565 } 8566 8567 if (mProcStateTimeMs == null) { 8568 mProcStateTimeMs = 8569 new TimeInFreqMultiStateCounter(mBsi.mOnBatteryTimeBase, 8570 PROC_STATE_TIME_COUNTER_STATE_COUNT, 8571 mBsi.mCpuScalingPolicies.getScalingStepCount(), 8572 timestampMs); 8573 } 8574 if (mProcStateScreenOffTimeMs == null) { 8575 mProcStateScreenOffTimeMs = 8576 new TimeInFreqMultiStateCounter(mBsi.mOnBatteryScreenOffTimeBase, 8577 PROC_STATE_TIME_COUNTER_STATE_COUNT, 8578 mBsi.mCpuScalingPolicies.getScalingStepCount(), 8579 timestampMs); 8580 } 8581 } 8582 8583 @GuardedBy("mBsi") getProcStateTimeCounter(long timestampMs)8584 private TimeInFreqMultiStateCounter getProcStateTimeCounter(long timestampMs) { 8585 ensureMultiStateCounters(timestampMs); 8586 return mProcStateTimeMs; 8587 } 8588 8589 @GuardedBy("mBsi") getProcStateScreenOffTimeCounter(long timestampMs)8590 private TimeInFreqMultiStateCounter getProcStateScreenOffTimeCounter(long timestampMs) { 8591 ensureMultiStateCounters(timestampMs); 8592 return mProcStateScreenOffTimeMs; 8593 } 8594 8595 @Override getAggregatedPartialWakelockTimer()8596 public Timer getAggregatedPartialWakelockTimer() { 8597 return mAggregatedPartialWakelockTimer; 8598 } 8599 8600 @Override getWakelockStats()8601 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 8602 return mWakelockStats.getMap(); 8603 } 8604 8605 @Override getMulticastWakelockStats()8606 public Timer getMulticastWakelockStats() { 8607 return mWifiMulticastTimer; 8608 } 8609 8610 @Override getSyncStats()8611 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 8612 return mSyncStats.getMap(); 8613 } 8614 8615 @Override getJobStats()8616 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 8617 return mJobStats.getMap(); 8618 } 8619 8620 @Override getJobCompletionStats()8621 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 8622 return mJobCompletions; 8623 } 8624 8625 @Override getSensorStats()8626 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 8627 return mSensorStats; 8628 } 8629 8630 @Override getProcessStats()8631 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 8632 return mProcessStats; 8633 } 8634 8635 @Override getPackageStats()8636 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 8637 return mPackageStats; 8638 } 8639 8640 @Override getUid()8641 public int getUid() { 8642 return mUid; 8643 } 8644 8645 @Override noteWifiRunningLocked(long elapsedRealtimeMs)8646 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 8647 if (!mWifiRunning) { 8648 mWifiRunning = true; 8649 if (mWifiRunningTimer == null) { 8650 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, Uid.this, WIFI_RUNNING, 8651 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 8652 } 8653 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 8654 } 8655 } 8656 8657 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)8658 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 8659 if (mWifiRunning) { 8660 mWifiRunning = false; 8661 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 8662 } 8663 } 8664 8665 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)8666 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 8667 if (!mFullWifiLockOut) { 8668 mFullWifiLockOut = true; 8669 if (mFullWifiLockTimer == null) { 8670 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, Uid.this, FULL_WIFI_LOCK, 8671 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 8672 } 8673 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 8674 } 8675 } 8676 8677 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)8678 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 8679 if (mFullWifiLockOut) { 8680 mFullWifiLockOut = false; 8681 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 8682 } 8683 } 8684 8685 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)8686 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 8687 if (!mWifiScanStarted) { 8688 mWifiScanStarted = true; 8689 if (mWifiScanTimer == null) { 8690 mWifiScanTimer = new DualTimer(mBsi.mClock, Uid.this, WIFI_SCAN, 8691 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 8692 mOnBatteryBackgroundTimeBase); 8693 } 8694 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 8695 } 8696 } 8697 8698 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)8699 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 8700 if (mWifiScanStarted) { 8701 mWifiScanStarted = false; 8702 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 8703 } 8704 } 8705 8706 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)8707 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 8708 int bin = 0; 8709 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 8710 csph = csph >> 3; 8711 bin++; 8712 } 8713 8714 if (mWifiBatchedScanBinStarted == bin) return; 8715 8716 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 8717 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 8718 stopRunningLocked(elapsedRealtimeMs); 8719 } 8720 mWifiBatchedScanBinStarted = bin; 8721 if (mWifiBatchedScanTimer[bin] == null) { 8722 makeWifiBatchedScanBin(bin, null); 8723 } 8724 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 8725 } 8726 8727 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)8728 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 8729 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 8730 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 8731 stopRunningLocked(elapsedRealtimeMs); 8732 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8733 } 8734 } 8735 8736 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)8737 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 8738 if (mWifiMulticastWakelockCount == 0) { 8739 if (mWifiMulticastTimer == null) { 8740 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 8741 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 8742 } 8743 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 8744 } 8745 mWifiMulticastWakelockCount++; 8746 } 8747 8748 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)8749 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 8750 if (mWifiMulticastWakelockCount == 0) { 8751 return; 8752 } 8753 8754 mWifiMulticastWakelockCount--; 8755 if (mWifiMulticastWakelockCount == 0) { 8756 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 8757 } 8758 } 8759 8760 @Override getWifiControllerActivity()8761 public ControllerActivityCounterImpl getWifiControllerActivity() { 8762 return mWifiControllerActivity; 8763 } 8764 8765 @Override getBluetoothControllerActivity()8766 public ControllerActivityCounterImpl getBluetoothControllerActivity() { 8767 return mBluetoothControllerActivity; 8768 } 8769 8770 @Override getModemControllerActivity()8771 public ControllerActivityCounter getModemControllerActivity() { 8772 return mModemControllerActivity; 8773 } 8774 getOrCreateWifiControllerActivityLocked()8775 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 8776 if (mWifiControllerActivity == null) { 8777 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8778 mBsi.mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 8779 } 8780 return mWifiControllerActivity; 8781 } 8782 getOrCreateBluetoothControllerActivityLocked()8783 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 8784 if (mBluetoothControllerActivity == null) { 8785 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8786 mBsi.mOnBatteryTimeBase, NUM_BT_TX_LEVELS); 8787 } 8788 return mBluetoothControllerActivity; 8789 } 8790 getOrCreateModemControllerActivityLocked()8791 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 8792 if (mModemControllerActivity == null) { 8793 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8794 mBsi.mOnBatteryTimeBase, mBsi.MODEM_TX_POWER_LEVEL_COUNT); 8795 } 8796 return mModemControllerActivity; 8797 } 8798 8799 @GuardedBy("mBsi") getOrCreateEnergyConsumerStatsLocked()8800 private EnergyConsumerStats getOrCreateEnergyConsumerStatsLocked() { 8801 if (mUidEnergyConsumerStats == null) { 8802 mUidEnergyConsumerStats = new EnergyConsumerStats(mBsi.mEnergyConsumerStatsConfig); 8803 } 8804 return mUidEnergyConsumerStats; 8805 } 8806 8807 @GuardedBy("mBsi") getOrCreateEnergyConsumerStatsIfSupportedLocked()8808 private EnergyConsumerStats getOrCreateEnergyConsumerStatsIfSupportedLocked() { 8809 if (mUidEnergyConsumerStats == null && mBsi.mEnergyConsumerStatsConfig != null) { 8810 mUidEnergyConsumerStats = new EnergyConsumerStats(mBsi.mEnergyConsumerStatsConfig); 8811 } 8812 return mUidEnergyConsumerStats; 8813 } 8814 8815 /** Adds the given charge to the given standard power bucket for this uid. */ 8816 @GuardedBy("mBsi") addChargeToStandardBucketLocked(long chargeDeltaUC, @StandardPowerBucket int powerBucket, long timestampMs)8817 private void addChargeToStandardBucketLocked(long chargeDeltaUC, 8818 @StandardPowerBucket int powerBucket, long timestampMs) { 8819 final EnergyConsumerStats energyConsumerStats = 8820 getOrCreateEnergyConsumerStatsLocked(); 8821 energyConsumerStats.updateStandardBucket(powerBucket, chargeDeltaUC, timestampMs); 8822 } 8823 8824 /** Adds the given charge to the given custom power bucket for this uid. */ 8825 @GuardedBy("mBsi") addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket)8826 private void addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket) { 8827 getOrCreateEnergyConsumerStatsLocked().updateCustomBucket(powerBucket, chargeDeltaUC, 8828 mBsi.mClock.elapsedRealtime()); 8829 } 8830 8831 /** 8832 * Returns the battery consumption (in microcoulomb) of this uid for a standard power bucket 8833 * of interest. 8834 * @param bucket standard power bucket of interest 8835 * @return consumption (in microcolombs) used by this uid for this power bucket 8836 */ 8837 @GuardedBy("mBsi") getEnergyConsumptionUC(@tandardPowerBucket int bucket)8838 public long getEnergyConsumptionUC(@StandardPowerBucket int bucket) { 8839 if (mBsi.mGlobalEnergyConsumerStats == null 8840 || !mBsi.mGlobalEnergyConsumerStats.isStandardBucketSupported(bucket)) { 8841 return POWER_DATA_UNAVAILABLE; 8842 } 8843 if (mUidEnergyConsumerStats == null) { 8844 return 0L; // It is supported, but was never filled, so it must be 0 8845 } 8846 return mUidEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket); 8847 } 8848 8849 /** 8850 * Returns the battery consumption (in microcoulombs) of this uid for a standard power 8851 * bucket and a process state, such as Uid.PROCESS_STATE_TOP. 8852 */ 8853 @GuardedBy("mBsi") getEnergyConsumptionUC(@tandardPowerBucket int bucket, int processState)8854 public long getEnergyConsumptionUC(@StandardPowerBucket int bucket, 8855 int processState) { 8856 if (mBsi.mGlobalEnergyConsumerStats == null 8857 || !mBsi.mGlobalEnergyConsumerStats.isStandardBucketSupported(bucket)) { 8858 return POWER_DATA_UNAVAILABLE; 8859 } 8860 if (mUidEnergyConsumerStats == null) { 8861 return 0L; // It is supported, but was never filled, so it must be 0 8862 } 8863 return mUidEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket, processState); 8864 } 8865 8866 @GuardedBy("mBsi") 8867 @Override getCustomEnergyConsumerBatteryConsumptionUC()8868 public long[] getCustomEnergyConsumerBatteryConsumptionUC() { 8869 if (mBsi.mGlobalEnergyConsumerStats == null) { 8870 return null; 8871 } 8872 if (mUidEnergyConsumerStats == null) { 8873 // Custom buckets may exist. But all values for this uid are 0 so we report all 0s. 8874 return new long[mBsi.mGlobalEnergyConsumerStats.getNumberCustomPowerBuckets()]; 8875 } 8876 return mUidEnergyConsumerStats.getAccumulatedCustomBucketCharges(); 8877 } 8878 8879 @GuardedBy("mBsi") 8880 @Override getBluetoothEnergyConsumptionUC()8881 public long getBluetoothEnergyConsumptionUC() { 8882 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH); 8883 } 8884 8885 @GuardedBy("mBsi") 8886 @Override getBluetoothEnergyConsumptionUC( @atteryConsumer.ProcessState int processState)8887 public long getBluetoothEnergyConsumptionUC( 8888 @BatteryConsumer.ProcessState int processState) { 8889 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 8890 processState); 8891 } 8892 8893 @GuardedBy("mBsi") 8894 @Override getCpuEnergyConsumptionUC()8895 public long getCpuEnergyConsumptionUC() { 8896 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU); 8897 } 8898 8899 @GuardedBy("mBsi") 8900 @Override getCpuEnergyConsumptionUC( @atteryConsumer.ProcessState int processState)8901 public long getCpuEnergyConsumptionUC( 8902 @BatteryConsumer.ProcessState int processState) { 8903 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU, 8904 processState); 8905 } 8906 8907 @GuardedBy("mBsi") 8908 @Override getGnssEnergyConsumptionUC()8909 public long getGnssEnergyConsumptionUC() { 8910 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_GNSS); 8911 } 8912 8913 @GuardedBy("mBsi") 8914 @Override getMobileRadioEnergyConsumptionUC()8915 public long getMobileRadioEnergyConsumptionUC() { 8916 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 8917 } 8918 8919 @GuardedBy("mBsi") 8920 @Override getMobileRadioEnergyConsumptionUC(int processState)8921 public long getMobileRadioEnergyConsumptionUC(int processState) { 8922 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 8923 processState); 8924 } 8925 8926 @GuardedBy("mBsi") 8927 @Override getScreenOnEnergyConsumptionUC()8928 public long getScreenOnEnergyConsumptionUC() { 8929 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON); 8930 } 8931 8932 @GuardedBy("mBsi") 8933 @Override getWifiEnergyConsumptionUC()8934 public long getWifiEnergyConsumptionUC() { 8935 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI); 8936 } 8937 8938 @GuardedBy("mBsi") 8939 @Override getWifiEnergyConsumptionUC(int processState)8940 public long getWifiEnergyConsumptionUC(int processState) { 8941 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI, 8942 processState); 8943 } 8944 8945 @GuardedBy("mBsi") 8946 @Override getCameraEnergyConsumptionUC()8947 public long getCameraEnergyConsumptionUC() { 8948 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CAMERA); 8949 } 8950 8951 /** 8952 * Gets the minimum of the uid's foreground activity time and its PROCESS_STATE_TOP time 8953 * since last marked. Also sets the mark time for both these timers. 8954 * 8955 * @see CpuPowerCalculator 8956 * 8957 * @param doCalc if true, then calculate the minimum; else don't bother and return 0. Either 8958 * way, the mark is set. 8959 */ markProcessForegroundTimeUs(long elapsedRealtimeMs, boolean doCalc)8960 private long markProcessForegroundTimeUs(long elapsedRealtimeMs, 8961 boolean doCalc) { 8962 long fgTimeUs = 0; 8963 final StopwatchTimer fgTimer = mForegroundActivityTimer; 8964 if (fgTimer != null) { 8965 if (doCalc) fgTimeUs = fgTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8966 fgTimer.setMark(elapsedRealtimeMs); 8967 } 8968 8969 long topTimeUs = 0; 8970 final StopwatchTimer topTimer = mProcessStateTimer[PROCESS_STATE_TOP]; 8971 if (topTimer != null) { 8972 if (doCalc) topTimeUs = topTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8973 topTimer.setMark(elapsedRealtimeMs); 8974 } 8975 8976 // Return the min of the two 8977 return (topTimeUs < fgTimeUs) ? topTimeUs : fgTimeUs; 8978 } 8979 8980 8981 /** 8982 * Gets the uid's time spent using the GNSS since last marked. Also sets the mark time for 8983 * the GNSS timer. 8984 */ markGnssTimeUs(long elapsedRealtimeMs)8985 private long markGnssTimeUs(long elapsedRealtimeMs) { 8986 final Sensor sensor = mSensorStats.get(Sensor.GPS); 8987 if (sensor == null) { 8988 return 0; 8989 } 8990 8991 final StopwatchTimer timer = sensor.mTimer; 8992 if (timer == null) { 8993 return 0; 8994 } 8995 8996 final long gnssTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8997 timer.setMark(elapsedRealtimeMs); 8998 return gnssTimeUs; 8999 } 9000 9001 /** 9002 * Gets the uid's time spent using the camera since last marked. Also sets the mark time for 9003 * the camera timer. 9004 */ markCameraTimeUs(long elapsedRealtimeMs)9005 private long markCameraTimeUs(long elapsedRealtimeMs) { 9006 final StopwatchTimer timer = mCameraTurnedOnTimer; 9007 if (timer == null) { 9008 return 0; 9009 } 9010 final long cameraTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 9011 timer.setMark(elapsedRealtimeMs); 9012 return cameraTimeUs; 9013 } 9014 createAudioTurnedOnTimerLocked()9015 public StopwatchTimer createAudioTurnedOnTimerLocked() { 9016 if (mAudioTurnedOnTimer == null) { 9017 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, AUDIO_TURNED_ON, 9018 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9019 } 9020 return mAudioTurnedOnTimer; 9021 } 9022 noteAudioTurnedOnLocked(long elapsedRealtimeMs)9023 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 9024 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9025 } 9026 noteAudioTurnedOffLocked(long elapsedRealtimeMs)9027 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 9028 if (mAudioTurnedOnTimer != null) { 9029 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9030 } 9031 } 9032 noteResetAudioLocked(long elapsedRealtimeMs)9033 public void noteResetAudioLocked(long elapsedRealtimeMs) { 9034 if (mAudioTurnedOnTimer != null) { 9035 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9036 } 9037 } 9038 createVideoTurnedOnTimerLocked()9039 public StopwatchTimer createVideoTurnedOnTimerLocked() { 9040 if (mVideoTurnedOnTimer == null) { 9041 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, VIDEO_TURNED_ON, 9042 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9043 } 9044 return mVideoTurnedOnTimer; 9045 } 9046 noteVideoTurnedOnLocked(long elapsedRealtimeMs)9047 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 9048 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9049 } 9050 noteVideoTurnedOffLocked(long elapsedRealtimeMs)9051 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 9052 if (mVideoTurnedOnTimer != null) { 9053 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9054 } 9055 } 9056 noteResetVideoLocked(long elapsedRealtimeMs)9057 public void noteResetVideoLocked(long elapsedRealtimeMs) { 9058 if (mVideoTurnedOnTimer != null) { 9059 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9060 } 9061 } 9062 createFlashlightTurnedOnTimerLocked()9063 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 9064 if (mFlashlightTurnedOnTimer == null) { 9065 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9066 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9067 } 9068 return mFlashlightTurnedOnTimer; 9069 } 9070 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)9071 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 9072 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9073 } 9074 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)9075 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 9076 if (mFlashlightTurnedOnTimer != null) { 9077 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9078 } 9079 } 9080 noteResetFlashlightLocked(long elapsedRealtimeMs)9081 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 9082 if (mFlashlightTurnedOnTimer != null) { 9083 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9084 } 9085 } 9086 createCameraTurnedOnTimerLocked()9087 public StopwatchTimer createCameraTurnedOnTimerLocked() { 9088 if (mCameraTurnedOnTimer == null) { 9089 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, CAMERA_TURNED_ON, 9090 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9091 } 9092 return mCameraTurnedOnTimer; 9093 } 9094 noteCameraTurnedOnLocked(long elapsedRealtimeMs)9095 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 9096 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9097 } 9098 noteCameraTurnedOffLocked(long elapsedRealtimeMs)9099 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 9100 if (mCameraTurnedOnTimer != null) { 9101 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9102 } 9103 } 9104 noteResetCameraLocked(long elapsedRealtimeMs)9105 public void noteResetCameraLocked(long elapsedRealtimeMs) { 9106 if (mCameraTurnedOnTimer != null) { 9107 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9108 } 9109 } 9110 createForegroundActivityTimerLocked()9111 public StopwatchTimer createForegroundActivityTimerLocked() { 9112 if (mForegroundActivityTimer == null) { 9113 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9114 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 9115 } 9116 return mForegroundActivityTimer; 9117 } 9118 createForegroundServiceTimerLocked()9119 public StopwatchTimer createForegroundServiceTimerLocked() { 9120 if (mForegroundServiceTimer == null) { 9121 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9122 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 9123 } 9124 return mForegroundServiceTimer; 9125 } 9126 createAggregatedPartialWakelockTimerLocked()9127 public DualTimer createAggregatedPartialWakelockTimerLocked() { 9128 if (mAggregatedPartialWakelockTimer == null) { 9129 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClock, this, 9130 AGGREGATED_WAKE_TYPE_PARTIAL, null, 9131 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 9132 } 9133 return mAggregatedPartialWakelockTimer; 9134 } 9135 createBluetoothScanTimerLocked()9136 public DualTimer createBluetoothScanTimerLocked() { 9137 if (mBluetoothScanTimer == null) { 9138 mBluetoothScanTimer = new DualTimer(mBsi.mClock, Uid.this, BLUETOOTH_SCAN_ON, 9139 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 9140 mOnBatteryBackgroundTimeBase); 9141 } 9142 return mBluetoothScanTimer; 9143 } 9144 createBluetoothUnoptimizedScanTimerLocked()9145 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 9146 if (mBluetoothUnoptimizedScanTimer == null) { 9147 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClock, Uid.this, 9148 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 9149 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 9150 } 9151 return mBluetoothUnoptimizedScanTimer; 9152 } 9153 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)9154 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 9155 boolean isUnoptimized) { 9156 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 9157 if (isUnoptimized) { 9158 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 9159 } 9160 } 9161 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)9162 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 9163 if (mBluetoothScanTimer != null) { 9164 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 9165 } 9166 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 9167 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 9168 } 9169 } 9170 noteResetBluetoothScanLocked(long elapsedRealtimeMs)9171 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 9172 if (mBluetoothScanTimer != null) { 9173 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 9174 } 9175 if (mBluetoothUnoptimizedScanTimer != null) { 9176 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 9177 } 9178 } 9179 createBluetoothScanResultCounterLocked()9180 public Counter createBluetoothScanResultCounterLocked() { 9181 if (mBluetoothScanResultCounter == null) { 9182 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 9183 } 9184 return mBluetoothScanResultCounter; 9185 } 9186 createBluetoothScanResultBgCounterLocked()9187 public Counter createBluetoothScanResultBgCounterLocked() { 9188 if (mBluetoothScanResultBgCounter == null) { 9189 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 9190 } 9191 return mBluetoothScanResultBgCounter; 9192 } 9193 noteBluetoothScanResultsLocked(int numNewResults)9194 public void noteBluetoothScanResultsLocked(int numNewResults) { 9195 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 9196 // Uses background timebase, so the count will only be incremented if uid in background. 9197 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 9198 } 9199 9200 @Override noteActivityResumedLocked(long elapsedRealtimeMs)9201 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 9202 // We always start, since we want multiple foreground PIDs to nest 9203 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 9204 } 9205 9206 @Override noteActivityPausedLocked(long elapsedRealtimeMs)9207 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 9208 if (mForegroundActivityTimer != null) { 9209 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 9210 } 9211 } 9212 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)9213 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 9214 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 9215 } 9216 noteForegroundServicePausedLocked(long elapsedRealtimeMs)9217 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 9218 if (mForegroundServiceTimer != null) { 9219 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 9220 } 9221 } 9222 createVibratorOnTimerLocked()9223 public BatchTimer createVibratorOnTimerLocked() { 9224 if (mVibratorOnTimer == null) { 9225 mVibratorOnTimer = new BatchTimer(mBsi.mClock, Uid.this, VIBRATOR_ON, 9226 mBsi.mOnBatteryTimeBase); 9227 } 9228 return mVibratorOnTimer; 9229 } 9230 noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs)9231 public void noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs) { 9232 createVibratorOnTimerLocked().addDuration(durationMillis, elapsedRealtimeMs); 9233 } 9234 noteVibratorOffLocked(long elapsedRealtimeMs)9235 public void noteVibratorOffLocked(long elapsedRealtimeMs) { 9236 if (mVibratorOnTimer != null) { 9237 mVibratorOnTimer.abortLastDuration(elapsedRealtimeMs); 9238 } 9239 } 9240 9241 @Override getWifiRunningTime(long elapsedRealtimeUs, int which)9242 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 9243 if (mWifiRunningTimer == null) { 9244 return 0; 9245 } 9246 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9247 } 9248 9249 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)9250 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 9251 if (mFullWifiLockTimer == null) { 9252 return 0; 9253 } 9254 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9255 } 9256 9257 @Override getWifiScanTime(long elapsedRealtimeUs, int which)9258 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 9259 if (mWifiScanTimer == null) { 9260 return 0; 9261 } 9262 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9263 } 9264 9265 @Override getWifiScanCount(int which)9266 public int getWifiScanCount(int which) { 9267 if (mWifiScanTimer == null) { 9268 return 0; 9269 } 9270 return mWifiScanTimer.getCountLocked(which); 9271 } 9272 9273 @Override getWifiScanTimer()9274 public Timer getWifiScanTimer() { 9275 return mWifiScanTimer; 9276 } 9277 9278 @Override getWifiScanBackgroundCount(int which)9279 public int getWifiScanBackgroundCount(int which) { 9280 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 9281 return 0; 9282 } 9283 return mWifiScanTimer.getSubTimer().getCountLocked(which); 9284 } 9285 9286 @Override getWifiScanActualTime(final long elapsedRealtimeUs)9287 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 9288 if (mWifiScanTimer == null) { 9289 return 0; 9290 } 9291 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 9292 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 9293 } 9294 9295 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)9296 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 9297 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 9298 return 0; 9299 } 9300 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 9301 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 9302 } 9303 9304 @Override getWifiScanBackgroundTimer()9305 public Timer getWifiScanBackgroundTimer() { 9306 if (mWifiScanTimer == null) { 9307 return null; 9308 } 9309 return mWifiScanTimer.getSubTimer(); 9310 } 9311 9312 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)9313 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 9314 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 9315 if (mWifiBatchedScanTimer[csphBin] == null) { 9316 return 0; 9317 } 9318 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 9319 } 9320 9321 @Override getWifiBatchedScanCount(int csphBin, int which)9322 public int getWifiBatchedScanCount(int csphBin, int which) { 9323 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 9324 if (mWifiBatchedScanTimer[csphBin] == null) { 9325 return 0; 9326 } 9327 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 9328 } 9329 9330 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)9331 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 9332 if (mWifiMulticastTimer == null) { 9333 return 0; 9334 } 9335 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9336 } 9337 9338 @Override getAudioTurnedOnTimer()9339 public Timer getAudioTurnedOnTimer() { 9340 return mAudioTurnedOnTimer; 9341 } 9342 9343 @Override getVideoTurnedOnTimer()9344 public Timer getVideoTurnedOnTimer() { 9345 return mVideoTurnedOnTimer; 9346 } 9347 9348 @Override getFlashlightTurnedOnTimer()9349 public Timer getFlashlightTurnedOnTimer() { 9350 return mFlashlightTurnedOnTimer; 9351 } 9352 9353 @Override getCameraTurnedOnTimer()9354 public Timer getCameraTurnedOnTimer() { 9355 return mCameraTurnedOnTimer; 9356 } 9357 9358 @Override getForegroundActivityTimer()9359 public Timer getForegroundActivityTimer() { 9360 return mForegroundActivityTimer; 9361 } 9362 9363 @Override getForegroundServiceTimer()9364 public Timer getForegroundServiceTimer() { 9365 return mForegroundServiceTimer; 9366 } 9367 9368 @Override getBluetoothScanTimer()9369 public Timer getBluetoothScanTimer() { 9370 return mBluetoothScanTimer; 9371 } 9372 9373 @Override getBluetoothScanBackgroundTimer()9374 public Timer getBluetoothScanBackgroundTimer() { 9375 if (mBluetoothScanTimer == null) { 9376 return null; 9377 } 9378 return mBluetoothScanTimer.getSubTimer(); 9379 } 9380 9381 @Override getBluetoothUnoptimizedScanTimer()9382 public Timer getBluetoothUnoptimizedScanTimer() { 9383 return mBluetoothUnoptimizedScanTimer; 9384 } 9385 9386 @Override getBluetoothUnoptimizedScanBackgroundTimer()9387 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 9388 if (mBluetoothUnoptimizedScanTimer == null) { 9389 return null; 9390 } 9391 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 9392 } 9393 9394 @Override getBluetoothScanResultCounter()9395 public Counter getBluetoothScanResultCounter() { 9396 return mBluetoothScanResultCounter; 9397 } 9398 9399 @Override getBluetoothScanResultBgCounter()9400 public Counter getBluetoothScanResultBgCounter() { 9401 return mBluetoothScanResultBgCounter; 9402 } 9403 makeProcessState(int i, Parcel in)9404 void makeProcessState(int i, Parcel in) { 9405 if (i < 0 || i >= NUM_PROCESS_STATE) return; 9406 9407 detachIfNotNull(mProcessStateTimer[i]); 9408 if (in == null) { 9409 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClock, this, PROCESS_STATE, null, 9410 mBsi.mOnBatteryTimeBase); 9411 } else { 9412 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClock, this, PROCESS_STATE, null, 9413 mBsi.mOnBatteryTimeBase, in); 9414 } 9415 } 9416 9417 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)9418 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 9419 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 9420 if (mProcessStateTimer[state] == null) { 9421 return 0; 9422 } 9423 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 9424 } 9425 9426 @Override getProcessStateTimer(int state)9427 public Timer getProcessStateTimer(int state) { 9428 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 9429 return mProcessStateTimer[state]; 9430 } 9431 9432 @Override getVibratorOnTimer()9433 public Timer getVibratorOnTimer() { 9434 return mVibratorOnTimer; 9435 } 9436 9437 @Override noteUserActivityLocked(@owerManager.UserActivityEvent int event)9438 public void noteUserActivityLocked(@PowerManager.UserActivityEvent int event) { 9439 if (mUserActivityCounters == null) { 9440 initUserActivityLocked(); 9441 } 9442 if (event >= 0 && event < NUM_USER_ACTIVITY_TYPES) { 9443 mUserActivityCounters[event].stepAtomic(); 9444 } else { 9445 Slog.w(TAG, "Unknown user activity type " + event + " was specified.", 9446 new Throwable()); 9447 } 9448 } 9449 9450 @Override hasUserActivity()9451 public boolean hasUserActivity() { 9452 return mUserActivityCounters != null; 9453 } 9454 9455 @Override getUserActivityCount(int type, int which)9456 public int getUserActivityCount(int type, int which) { 9457 if (mUserActivityCounters == null) { 9458 return 0; 9459 } 9460 return mUserActivityCounters[type].getCountLocked(which); 9461 } 9462 makeWifiBatchedScanBin(int i, Parcel in)9463 void makeWifiBatchedScanBin(int i, Parcel in) { 9464 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 9465 9466 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 9467 if (collected == null) { 9468 collected = new ArrayList<StopwatchTimer>(); 9469 mBsi.mWifiBatchedScanTimers.put(i, collected); 9470 } 9471 detachIfNotNull(mWifiBatchedScanTimer[i]); 9472 if (in == null) { 9473 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClock, this, WIFI_BATCHED_SCAN, 9474 collected, mBsi.mOnBatteryTimeBase); 9475 } else { 9476 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClock, this, WIFI_BATCHED_SCAN, 9477 collected, mBsi.mOnBatteryTimeBase, in); 9478 } 9479 } 9480 9481 initUserActivityLocked()9482 void initUserActivityLocked() { 9483 detachIfNotNull(mUserActivityCounters); 9484 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 9485 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 9486 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 9487 } 9488 } 9489 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)9490 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 9491 ensureNetworkActivityLocked(); 9492 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 9493 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 9494 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 9495 } else { 9496 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 9497 new Throwable()); 9498 } 9499 } 9500 noteMobileRadioActiveTimeLocked(long batteryUptimeDeltaUs, long elapsedTimeMs)9501 void noteMobileRadioActiveTimeLocked(long batteryUptimeDeltaUs, long elapsedTimeMs) { 9502 ensureNetworkActivityLocked(); 9503 getMobileRadioActiveTimeCounter().increment(batteryUptimeDeltaUs, elapsedTimeMs); 9504 mMobileRadioActiveCount.addCountLocked(1); 9505 } 9506 getMobileRadioActiveTimeCounter()9507 private TimeMultiStateCounter getMobileRadioActiveTimeCounter() { 9508 if (mMobileRadioActiveTime == null) { 9509 final long timestampMs = mBsi.mClock.elapsedRealtime(); 9510 mMobileRadioActiveTime = new TimeMultiStateCounter( 9511 mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 9512 mMobileRadioActiveTime.setState( 9513 mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 9514 timestampMs); 9515 mMobileRadioActiveTime.update(0, timestampMs); 9516 } 9517 return mMobileRadioActiveTime; 9518 } 9519 9520 @Override hasNetworkActivity()9521 public boolean hasNetworkActivity() { 9522 return mNetworkByteActivityCounters != null; 9523 } 9524 9525 @Override getNetworkActivityBytes(int type, int which)9526 public long getNetworkActivityBytes(int type, int which) { 9527 if (mNetworkByteActivityCounters != null && type >= 0 9528 && type < mNetworkByteActivityCounters.length) { 9529 return mNetworkByteActivityCounters[type].getCountLocked(which); 9530 } else { 9531 return 0; 9532 } 9533 } 9534 9535 @Override getNetworkActivityPackets(int type, int which)9536 public long getNetworkActivityPackets(int type, int which) { 9537 if (mNetworkPacketActivityCounters != null && type >= 0 9538 && type < mNetworkPacketActivityCounters.length) { 9539 return mNetworkPacketActivityCounters[type].getCountLocked(which); 9540 } else { 9541 return 0; 9542 } 9543 } 9544 9545 @Override getMobileRadioActiveTime(int which)9546 public long getMobileRadioActiveTime(int which) { 9547 return getMobileRadioActiveTimeInProcessState(BatteryConsumer.PROCESS_STATE_ANY); 9548 } 9549 9550 @Override getMobileRadioActiveTimeInProcessState( @atteryConsumer.ProcessState int processState)9551 public long getMobileRadioActiveTimeInProcessState( 9552 @BatteryConsumer.ProcessState int processState) { 9553 if (mMobileRadioActiveTime == null) { 9554 return 0; 9555 } 9556 if (processState == BatteryConsumer.PROCESS_STATE_ANY) { 9557 return mMobileRadioActiveTime.getTotalCountLocked(); 9558 } else { 9559 return mMobileRadioActiveTime.getCountForProcessState(processState); 9560 } 9561 } 9562 9563 @Override getMobileRadioActiveCount(int which)9564 public int getMobileRadioActiveCount(int which) { 9565 return mMobileRadioActiveCount != null 9566 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 9567 } 9568 9569 @Override getUserCpuTimeUs(int which)9570 public long getUserCpuTimeUs(int which) { 9571 return mUserCpuTime.getCountLocked(which); 9572 } 9573 9574 @Override getSystemCpuTimeUs(int which)9575 public long getSystemCpuTimeUs(int which) { 9576 return mSystemCpuTime.getCountLocked(which); 9577 } 9578 9579 @Override 9580 @Deprecated getTimeAtCpuSpeed(int cluster, int step, int which)9581 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 9582 if (mCpuClusterSpeedTimesUs != null) { 9583 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 9584 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 9585 if (cpuSpeedTimesUs != null) { 9586 if (step >= 0 && step < cpuSpeedTimesUs.length) { 9587 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 9588 if (c != null) { 9589 return c.getCountLocked(which); 9590 } 9591 } 9592 } 9593 } 9594 } 9595 return 0; 9596 } 9597 noteMobileRadioApWakeupLocked()9598 public void noteMobileRadioApWakeupLocked() { 9599 if (mMobileRadioApWakeupCount == null) { 9600 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9601 } 9602 mMobileRadioApWakeupCount.addCountLocked(1); 9603 } 9604 9605 @Override getMobileRadioApWakeupCount(int which)9606 public long getMobileRadioApWakeupCount(int which) { 9607 if (mMobileRadioApWakeupCount != null) { 9608 return mMobileRadioApWakeupCount.getCountLocked(which); 9609 } 9610 return 0; 9611 } 9612 noteWifiRadioApWakeupLocked()9613 public void noteWifiRadioApWakeupLocked() { 9614 if (mWifiRadioApWakeupCount == null) { 9615 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9616 } 9617 mWifiRadioApWakeupCount.addCountLocked(1); 9618 } 9619 9620 @Override getWifiRadioApWakeupCount(int which)9621 public long getWifiRadioApWakeupCount(int which) { 9622 if (mWifiRadioApWakeupCount != null) { 9623 return mWifiRadioApWakeupCount.getCountLocked(which); 9624 } 9625 return 0; 9626 } 9627 9628 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)9629 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 9630 sb.setLength(0); 9631 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 9632 if (deferredEventCount == 0) { 9633 return; 9634 } 9635 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 9636 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 9637 sb.append(deferredEventCount); sb.append(','); 9638 sb.append(deferredCount); sb.append(','); 9639 sb.append(totalLatency); 9640 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9641 if (mJobsFreshnessBuckets[i] == null) { 9642 sb.append(",0"); 9643 } else { 9644 sb.append(","); 9645 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 9646 } 9647 } 9648 } 9649 9650 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)9651 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 9652 sb.setLength(0); 9653 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 9654 if (deferredEventCount == 0) { 9655 return; 9656 } 9657 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 9658 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 9659 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 9660 sb.append("count="); sb.append(deferredCount); sb.append(", "); 9661 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 9662 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9663 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 9664 if (mJobsFreshnessBuckets[i] == null) { 9665 sb.append("0"); 9666 } else { 9667 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 9668 } 9669 sb.append(" "); 9670 } 9671 } 9672 ensureNetworkActivityLocked()9673 void ensureNetworkActivityLocked() { 9674 if (mNetworkByteActivityCounters != null) { 9675 return; 9676 } 9677 9678 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9679 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9680 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9681 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9682 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9683 } 9684 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9685 } 9686 9687 /** 9688 * Clear all stats for this uid. Returns true if the uid is completely 9689 * inactive so can be dropped. 9690 */ 9691 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptimeUs, long realtimeUs, int resetReason)9692 public boolean reset(long uptimeUs, long realtimeUs, int resetReason) { 9693 boolean active = false; 9694 9695 mOnBatteryBackgroundTimeBase.init(uptimeUs, realtimeUs); 9696 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeUs, realtimeUs); 9697 9698 if (mWifiRunningTimer != null) { 9699 active |= !mWifiRunningTimer.reset(false, realtimeUs); 9700 active |= mWifiRunning; 9701 } 9702 if (mFullWifiLockTimer != null) { 9703 active |= !mFullWifiLockTimer.reset(false, realtimeUs); 9704 active |= mFullWifiLockOut; 9705 } 9706 if (mWifiScanTimer != null) { 9707 active |= !mWifiScanTimer.reset(false, realtimeUs); 9708 active |= mWifiScanStarted; 9709 } 9710 if (mWifiBatchedScanTimer != null) { 9711 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 9712 if (mWifiBatchedScanTimer[i] != null) { 9713 active |= !mWifiBatchedScanTimer[i].reset(false, realtimeUs); 9714 } 9715 } 9716 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 9717 } 9718 if (mWifiMulticastTimer != null) { 9719 active |= !mWifiMulticastTimer.reset(false, realtimeUs); 9720 active |= (mWifiMulticastWakelockCount > 0); 9721 } 9722 9723 active |= !resetIfNotNull(mAudioTurnedOnTimer, false, realtimeUs); 9724 active |= !resetIfNotNull(mVideoTurnedOnTimer, false, realtimeUs); 9725 active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false, realtimeUs); 9726 active |= !resetIfNotNull(mCameraTurnedOnTimer, false, realtimeUs); 9727 active |= !resetIfNotNull(mForegroundActivityTimer, false, realtimeUs); 9728 active |= !resetIfNotNull(mForegroundServiceTimer, false, realtimeUs); 9729 active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false, realtimeUs); 9730 active |= !resetIfNotNull(mBluetoothScanTimer, false, realtimeUs); 9731 active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false, realtimeUs); 9732 9733 resetIfNotNull(mBluetoothScanResultCounter, false, realtimeUs); 9734 resetIfNotNull(mBluetoothScanResultBgCounter, false, realtimeUs); 9735 9736 if (mProcessStateTimer != null) { 9737 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 9738 active |= !resetIfNotNull(mProcessStateTimer[i], false, realtimeUs); 9739 } 9740 active |= (mProcessState != Uid.PROCESS_STATE_NONEXISTENT); 9741 } 9742 if (mVibratorOnTimer != null) { 9743 if (mVibratorOnTimer.reset(false, realtimeUs)) { 9744 mVibratorOnTimer.detach(); 9745 mVibratorOnTimer = null; 9746 } else { 9747 active = true; 9748 } 9749 } 9750 9751 resetIfNotNull(mUserActivityCounters, false, realtimeUs); 9752 9753 resetIfNotNull(mNetworkByteActivityCounters, false, realtimeUs); 9754 resetIfNotNull(mNetworkPacketActivityCounters, false, realtimeUs); 9755 resetIfNotNull(mMobileRadioActiveTime, false, realtimeUs); 9756 resetIfNotNull(mMobileRadioActiveCount, false, realtimeUs); 9757 9758 resetIfNotNull(mWifiControllerActivity, false, realtimeUs); 9759 resetIfNotNull(mBluetoothControllerActivity, false, realtimeUs); 9760 resetIfNotNull(mModemControllerActivity, false, realtimeUs); 9761 9762 if (resetReason == RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE) { 9763 mUidEnergyConsumerStats = null; 9764 } else { 9765 EnergyConsumerStats.resetIfNotNull(mUidEnergyConsumerStats); 9766 } 9767 9768 resetIfNotNull(mUserCpuTime, false, realtimeUs); 9769 resetIfNotNull(mSystemCpuTime, false, realtimeUs); 9770 9771 resetIfNotNull(mCpuClusterSpeedTimesUs, false, realtimeUs); 9772 9773 resetIfNotNull(mCpuFreqTimeMs, false, realtimeUs /* unused */); 9774 resetIfNotNull(mScreenOffCpuFreqTimeMs, false, realtimeUs /* unused */); 9775 9776 9777 resetIfNotNull(mCpuActiveTimeMs, false, realtimeUs /* unused */); 9778 resetIfNotNull(mCpuClusterTimesMs, false, realtimeUs /* unused */); 9779 9780 resetIfNotNull(mProcStateTimeMs, false, realtimeUs /* unused */); 9781 9782 resetIfNotNull(mProcStateScreenOffTimeMs, false, realtimeUs /* unused */); 9783 9784 resetIfNotNull(mMobileRadioApWakeupCount, false, realtimeUs); 9785 9786 resetIfNotNull(mWifiRadioApWakeupCount, false, realtimeUs); 9787 9788 9789 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9790 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 9791 Wakelock wl = wakeStats.valueAt(iw); 9792 if (wl.reset(realtimeUs)) { 9793 wakeStats.removeAt(iw); 9794 } else { 9795 active = true; 9796 } 9797 } 9798 final long realtimeMs = realtimeUs / 1000; 9799 mWakelockStats.cleanup(realtimeMs); 9800 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9801 for (int is=syncStats.size()-1; is>=0; is--) { 9802 DualTimer timer = syncStats.valueAt(is); 9803 if (timer.reset(false, realtimeUs)) { 9804 syncStats.removeAt(is); 9805 timer.detach(); 9806 } else { 9807 active = true; 9808 } 9809 } 9810 mSyncStats.cleanup(realtimeMs); 9811 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9812 for (int ij=jobStats.size()-1; ij>=0; ij--) { 9813 DualTimer timer = jobStats.valueAt(ij); 9814 if (timer.reset(false, realtimeUs)) { 9815 jobStats.removeAt(ij); 9816 timer.detach(); 9817 } else { 9818 active = true; 9819 } 9820 } 9821 mJobStats.cleanup(realtimeMs); 9822 mJobCompletions.clear(); 9823 9824 resetIfNotNull(mJobsDeferredEventCount, false, realtimeUs); 9825 resetIfNotNull(mJobsDeferredCount, false, realtimeUs); 9826 resetIfNotNull(mJobsFreshnessTimeMs, false, realtimeUs /* unused */); 9827 resetIfNotNull(mJobsFreshnessBuckets, false, realtimeUs); 9828 9829 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 9830 Sensor s = mSensorStats.valueAt(ise); 9831 if (s.reset(realtimeUs)) { 9832 mSensorStats.removeAt(ise); 9833 } else { 9834 active = true; 9835 } 9836 } 9837 9838 for (int ip = mProcessStats.size() - 1; ip >= 0; ip--) { 9839 Proc proc = mProcessStats.valueAt(ip); 9840 proc.detach(); 9841 } 9842 mProcessStats.clear(); 9843 9844 for (int i = mPids.size() - 1; i >= 0; i--) { 9845 Pid pid = mPids.valueAt(i); 9846 if (pid.mWakeNesting > 0) { 9847 active = true; 9848 } else { 9849 mPids.removeAt(i); 9850 } 9851 } 9852 9853 9854 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 9855 Pkg p = mPackageStats.valueAt(i); 9856 p.detach(); 9857 } 9858 mPackageStats.clear(); 9859 9860 mBinderCallCount = 0; 9861 mBinderCallStats.clear(); 9862 9863 mProportionalSystemServiceUsage = 0; 9864 9865 mLastStepUserTimeMs = mLastStepSystemTimeMs = 0; 9866 mCurStepUserTimeMs = mCurStepSystemTimeMs = 0; 9867 9868 9869 return !active; 9870 } 9871 9872 /** 9873 * This method MUST be called whenever the Uid object is destructed, otherwise it is a 9874 * memory leak in {@link TimeBase#mObservers} list. 9875 * Typically the Uid object is destructed when it is removed from 9876 * {@link BatteryStatsImpl#mUidStats} 9877 */ detachFromTimeBase()9878 void detachFromTimeBase() { 9879 detachIfNotNull(mWifiRunningTimer); 9880 detachIfNotNull(mFullWifiLockTimer); 9881 detachIfNotNull(mWifiScanTimer); 9882 detachIfNotNull(mWifiBatchedScanTimer); 9883 detachIfNotNull(mWifiMulticastTimer); 9884 detachIfNotNull(mAudioTurnedOnTimer); 9885 detachIfNotNull(mVideoTurnedOnTimer); 9886 detachIfNotNull(mFlashlightTurnedOnTimer); 9887 9888 detachIfNotNull(mCameraTurnedOnTimer); 9889 detachIfNotNull(mForegroundActivityTimer); 9890 detachIfNotNull(mForegroundServiceTimer); 9891 9892 detachIfNotNull(mAggregatedPartialWakelockTimer); 9893 9894 detachIfNotNull(mBluetoothScanTimer); 9895 detachIfNotNull(mBluetoothUnoptimizedScanTimer); 9896 detachIfNotNull(mBluetoothScanResultCounter); 9897 detachIfNotNull(mBluetoothScanResultBgCounter); 9898 9899 detachIfNotNull(mProcessStateTimer); 9900 9901 detachIfNotNull(mVibratorOnTimer); 9902 9903 detachIfNotNull(mUserActivityCounters); 9904 9905 detachIfNotNull(mNetworkByteActivityCounters); 9906 detachIfNotNull(mNetworkPacketActivityCounters); 9907 9908 detachIfNotNull(mMobileRadioActiveTime); 9909 detachIfNotNull(mMobileRadioActiveCount); 9910 detachIfNotNull(mMobileRadioApWakeupCount); 9911 detachIfNotNull(mWifiRadioApWakeupCount); 9912 9913 detachIfNotNull(mWifiControllerActivity); 9914 detachIfNotNull(mBluetoothControllerActivity); 9915 detachIfNotNull(mModemControllerActivity); 9916 9917 mPids.clear(); 9918 9919 detachIfNotNull(mUserCpuTime); 9920 detachIfNotNull(mSystemCpuTime); 9921 9922 detachIfNotNull(mCpuClusterSpeedTimesUs); 9923 9924 detachIfNotNull(mCpuActiveTimeMs); 9925 detachIfNotNull(mCpuFreqTimeMs); 9926 9927 detachIfNotNull(mScreenOffCpuFreqTimeMs); 9928 9929 detachIfNotNull(mCpuClusterTimesMs); 9930 9931 detachIfNotNull(mProcStateTimeMs); 9932 9933 detachIfNotNull(mProcStateScreenOffTimeMs); 9934 9935 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9936 for (int iw = wakeStats.size() - 1; iw >= 0; iw--) { 9937 Wakelock wl = wakeStats.valueAt(iw); 9938 wl.detachFromTimeBase(); 9939 } 9940 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9941 for (int is = syncStats.size() - 1; is >= 0; is--) { 9942 DualTimer timer = syncStats.valueAt(is); 9943 detachIfNotNull(timer); 9944 } 9945 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9946 for (int ij = jobStats.size() - 1; ij >= 0; ij--) { 9947 DualTimer timer = jobStats.valueAt(ij); 9948 detachIfNotNull(timer); 9949 } 9950 9951 detachIfNotNull(mJobsDeferredEventCount); 9952 detachIfNotNull(mJobsDeferredCount); 9953 detachIfNotNull(mJobsFreshnessTimeMs); 9954 detachIfNotNull(mJobsFreshnessBuckets); 9955 9956 9957 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 9958 Sensor s = mSensorStats.valueAt(ise); 9959 s.detachFromTimeBase(); 9960 } 9961 9962 for (int ip= mProcessStats.size() - 1; ip >= 0; ip--) { 9963 Proc proc = mProcessStats.valueAt(ip); 9964 proc.detach(); 9965 } 9966 mProcessStats.clear(); 9967 9968 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 9969 Pkg p = mPackageStats.valueAt(i); 9970 p.detach(); 9971 } 9972 mPackageStats.clear(); 9973 } 9974 writeJobCompletionsToParcelLocked(Parcel out)9975 void writeJobCompletionsToParcelLocked(Parcel out) { 9976 int NJC = mJobCompletions.size(); 9977 out.writeInt(NJC); 9978 for (int ijc=0; ijc<NJC; ijc++) { 9979 out.writeString(mJobCompletions.keyAt(ijc)); 9980 SparseIntArray types = mJobCompletions.valueAt(ijc); 9981 int NT = types.size(); 9982 out.writeInt(NT); 9983 for (int it=0; it<NT; it++) { 9984 out.writeInt(types.keyAt(it)); 9985 out.writeInt(types.valueAt(it)); 9986 } 9987 } 9988 } 9989 readJobCompletionsFromParcelLocked(Parcel in)9990 void readJobCompletionsFromParcelLocked(Parcel in) { 9991 int numJobCompletions = in.readInt(); 9992 mJobCompletions.clear(); 9993 for (int j = 0; j < numJobCompletions; j++) { 9994 String jobName = in.readString(); 9995 int numTypes = in.readInt(); 9996 if (numTypes > 0) { 9997 SparseIntArray types = new SparseIntArray(); 9998 for (int k = 0; k < numTypes; k++) { 9999 int type = in.readInt(); 10000 int count = in.readInt(); 10001 types.put(type, count); 10002 } 10003 mJobCompletions.put(jobName, types); 10004 } 10005 } 10006 } 10007 noteJobsDeferredLocked(int numDeferred, long sinceLast)10008 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 10009 mJobsDeferredEventCount.addAtomic(1); 10010 mJobsDeferredCount.addAtomic(numDeferred); 10011 if (sinceLast != 0) { 10012 // Add the total time, which can be divided by the event count to get an average 10013 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 10014 // Also keep track of how many times there were in these different buckets. 10015 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 10016 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 10017 if (mJobsFreshnessBuckets[i] == null) { 10018 mJobsFreshnessBuckets[i] = new Counter( 10019 mBsi.mOnBatteryTimeBase); 10020 } 10021 mJobsFreshnessBuckets[i].addAtomic(1); 10022 break; 10023 } 10024 } 10025 } 10026 } 10027 10028 // Reusable object used as a key to lookup values in mBinderCallStats 10029 private static BinderCallStats sTempBinderCallStats = new BinderCallStats(); 10030 10031 /** 10032 * Notes incoming binder call stats associated with this work source UID. 10033 */ noteBinderCallStatsLocked(long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)10034 public void noteBinderCallStatsLocked(long incrementalCallCount, 10035 Collection<BinderCallsStats.CallStat> callStats) { 10036 if (DEBUG) { 10037 Slog.d(TAG, "noteBinderCalls() workSourceUid = [" + mUid + "], " 10038 + " incrementalCallCount: " + incrementalCallCount + " callStats = [" 10039 + new ArrayList<>(callStats) + "]"); 10040 } 10041 mBinderCallCount += incrementalCallCount; 10042 for (BinderCallsStats.CallStat stat : callStats) { 10043 BinderCallStats bcs; 10044 sTempBinderCallStats.binderClass = stat.binderClass; 10045 sTempBinderCallStats.transactionCode = stat.transactionCode; 10046 int index = mBinderCallStats.indexOf(sTempBinderCallStats); 10047 if (index >= 0) { 10048 bcs = mBinderCallStats.valueAt(index); 10049 } else { 10050 bcs = new BinderCallStats(); 10051 bcs.binderClass = stat.binderClass; 10052 bcs.transactionCode = stat.transactionCode; 10053 mBinderCallStats.add(bcs); 10054 } 10055 10056 bcs.callCount += stat.incrementalCallCount; 10057 bcs.recordedCallCount = stat.recordedCallCount; 10058 bcs.recordedCpuTimeMicros = stat.cpuTimeMicros; 10059 } 10060 } 10061 10062 /** 10063 * The statistics associated with a particular wake lock. 10064 */ 10065 public static class Wakelock extends BatteryStats.Uid.Wakelock { 10066 /** 10067 * BatteryStatsImpl that we are associated with. 10068 */ 10069 protected BatteryStatsImpl mBsi; 10070 10071 /** 10072 * BatteryStatsImpl that we are associated with. 10073 */ 10074 protected Uid mUid; 10075 10076 /** 10077 * How long (in ms) this uid has been keeping the device partially awake. 10078 * Tracks both the total time and the time while the app was in the background. 10079 */ 10080 DualTimer mTimerPartial; 10081 10082 /** 10083 * How long (in ms) this uid has been keeping the device fully awake. 10084 */ 10085 StopwatchTimer mTimerFull; 10086 10087 /** 10088 * How long (in ms) this uid has had a window keeping the device awake. 10089 */ 10090 StopwatchTimer mTimerWindow; 10091 10092 /** 10093 * How long (in ms) this uid has had a draw wake lock. 10094 */ 10095 StopwatchTimer mTimerDraw; 10096 Wakelock(BatteryStatsImpl bsi, Uid uid)10097 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 10098 mBsi = bsi; 10099 mUid = uid; 10100 } 10101 10102 /** 10103 * Reads a possibly null Timer from a Parcel. The timer is associated with the 10104 * proper timer pool from the given BatteryStatsImpl object. 10105 * 10106 * @param in the Parcel to be read from. 10107 * return a new Timer, or null. 10108 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)10109 private StopwatchTimer readStopwatchTimerFromParcel(int type, 10110 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 10111 if (in.readInt() == 0) { 10112 return null; 10113 } 10114 10115 return new StopwatchTimer(mBsi.mClock, mUid, type, pool, timeBase, in); 10116 } 10117 10118 /** 10119 * Reads a possibly null Timer from a Parcel. The timer is associated with the 10120 * proper timer pool from the given BatteryStatsImpl object. 10121 * 10122 * @param in the Parcel to be read from. 10123 * return a new Timer, or null. 10124 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10125 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 10126 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10127 if (in.readInt() == 0) { 10128 return null; 10129 } 10130 10131 return new DualTimer(mBsi.mClock, mUid, type, pool, timeBase, bgTimeBase, in); 10132 } 10133 reset(long elapsedRealtimeUs)10134 boolean reset(long elapsedRealtimeUs) { 10135 boolean wlactive = false; 10136 10137 wlactive |= !resetIfNotNull(mTimerFull, false, elapsedRealtimeUs); 10138 wlactive |= !resetIfNotNull(mTimerPartial, false, elapsedRealtimeUs); 10139 wlactive |= !resetIfNotNull(mTimerWindow, false, elapsedRealtimeUs); 10140 wlactive |= !resetIfNotNull(mTimerDraw, false, elapsedRealtimeUs); 10141 10142 if (!wlactive) { 10143 detachIfNotNull(mTimerFull); 10144 mTimerFull = null; 10145 10146 detachIfNotNull(mTimerPartial); 10147 mTimerPartial = null; 10148 10149 detachIfNotNull(mTimerWindow); 10150 mTimerWindow = null; 10151 10152 detachIfNotNull(mTimerDraw); 10153 mTimerDraw = null; 10154 } 10155 return !wlactive; 10156 } 10157 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)10158 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 10159 TimeBase screenOffBgTimeBase, Parcel in) { 10160 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 10161 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 10162 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 10163 mBsi.mFullTimers, timeBase, in); 10164 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 10165 mBsi.mWindowTimers, timeBase, in); 10166 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 10167 mBsi.mDrawTimers, timeBase, in); 10168 } 10169 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)10170 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 10171 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 10172 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 10173 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 10174 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 10175 } 10176 10177 @Override getWakeTime(int type)10178 public Timer getWakeTime(int type) { 10179 switch (type) { 10180 case WAKE_TYPE_FULL: return mTimerFull; 10181 case WAKE_TYPE_PARTIAL: return mTimerPartial; 10182 case WAKE_TYPE_WINDOW: return mTimerWindow; 10183 case WAKE_TYPE_DRAW: return mTimerDraw; 10184 default: throw new IllegalArgumentException("type = " + type); 10185 } 10186 } 10187 detachFromTimeBase()10188 public void detachFromTimeBase() { 10189 detachIfNotNull(mTimerPartial); 10190 detachIfNotNull(mTimerFull); 10191 detachIfNotNull(mTimerWindow); 10192 detachIfNotNull(mTimerDraw); 10193 } 10194 } 10195 10196 public static class Sensor extends BatteryStats.Uid.Sensor { 10197 /** 10198 * BatteryStatsImpl that we are associated with. 10199 */ 10200 protected BatteryStatsImpl mBsi; 10201 10202 /** 10203 * Uid that we are associated with. 10204 */ 10205 protected Uid mUid; 10206 10207 final int mHandle; 10208 DualTimer mTimer; 10209 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)10210 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 10211 mBsi = bsi; 10212 mUid = uid; 10213 mHandle = handle; 10214 } 10215 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10216 private DualTimer readTimersFromParcel( 10217 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10218 if (in.readInt() == 0) { 10219 return null; 10220 } 10221 10222 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 10223 if (pool == null) { 10224 pool = new ArrayList<StopwatchTimer>(); 10225 mBsi.mSensorTimers.put(mHandle, pool); 10226 } 10227 return new DualTimer(mBsi.mClock, mUid, 0, pool, timeBase, bgTimeBase, in); 10228 } 10229 reset(long elapsedRealtimeUs)10230 boolean reset(long elapsedRealtimeUs) { 10231 if (mTimer.reset(true, elapsedRealtimeUs)) { 10232 mTimer = null; 10233 return true; 10234 } 10235 return false; 10236 } 10237 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10238 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10239 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 10240 } 10241 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)10242 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 10243 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 10244 } 10245 10246 @Override getSensorTime()10247 public Timer getSensorTime() { 10248 return mTimer; 10249 } 10250 10251 @Override getSensorBackgroundTime()10252 public Timer getSensorBackgroundTime() { 10253 if (mTimer == null) { 10254 return null; 10255 } 10256 return mTimer.getSubTimer(); 10257 } 10258 10259 @Override getHandle()10260 public int getHandle() { 10261 return mHandle; 10262 } 10263 detachFromTimeBase()10264 public void detachFromTimeBase() { 10265 detachIfNotNull(mTimer); 10266 } 10267 } 10268 10269 /** 10270 * The statistics associated with a particular process. 10271 */ 10272 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 10273 /** 10274 * BatteryStatsImpl that we are associated with. 10275 */ 10276 protected BatteryStatsImpl mBsi; 10277 10278 /** 10279 * The name of this process. 10280 */ 10281 final String mName; 10282 10283 /** 10284 * Remains true until removed from the stats. 10285 */ 10286 boolean mActive = true; 10287 10288 /** 10289 * Total time (in ms) spent executing in user code. 10290 */ 10291 long mUserTimeMs; 10292 10293 /** 10294 * Total time (in ms) spent executing in kernel code. 10295 */ 10296 long mSystemTimeMs; 10297 10298 /** 10299 * Amount of time (in ms) the process was running in the foreground. 10300 */ 10301 long mForegroundTimeMs; 10302 10303 /** 10304 * Number of times the process has been started. 10305 */ 10306 int mStarts; 10307 10308 /** 10309 * Number of times the process has crashed. 10310 */ 10311 int mNumCrashes; 10312 10313 /** 10314 * Number of times the process has had an ANR. 10315 */ 10316 int mNumAnrs; 10317 10318 ArrayList<ExcessivePower> mExcessivePower; 10319 Proc(BatteryStatsImpl bsi, String name)10320 public Proc(BatteryStatsImpl bsi, String name) { 10321 mBsi = bsi; 10322 mName = name; 10323 mBsi.mOnBatteryTimeBase.add(this); 10324 } 10325 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10326 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10327 long baseRealtimeUs) { 10328 } 10329 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10330 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10331 long baseRealtimeUs) { 10332 } 10333 10334 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10335 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10336 if (detachIfReset) { 10337 this.detach(); 10338 } 10339 return true; 10340 } 10341 10342 @Override detach()10343 public void detach() { 10344 mActive = false; 10345 mBsi.mOnBatteryTimeBase.remove(this); 10346 } 10347 countExcessivePowers()10348 public int countExcessivePowers() { 10349 return mExcessivePower != null ? mExcessivePower.size() : 0; 10350 } 10351 getExcessivePower(int i)10352 public ExcessivePower getExcessivePower(int i) { 10353 if (mExcessivePower != null) { 10354 return mExcessivePower.get(i); 10355 } 10356 return null; 10357 } 10358 addExcessiveCpu(long overTimeMs, long usedTimeMs)10359 public void addExcessiveCpu(long overTimeMs, long usedTimeMs) { 10360 if (mExcessivePower == null) { 10361 mExcessivePower = new ArrayList<ExcessivePower>(); 10362 } 10363 ExcessivePower ew = new ExcessivePower(); 10364 ew.type = ExcessivePower.TYPE_CPU; 10365 ew.overTime = overTimeMs; 10366 ew.usedTime = usedTimeMs; 10367 mExcessivePower.add(ew); 10368 } 10369 writeExcessivePowerToParcelLocked(Parcel out)10370 void writeExcessivePowerToParcelLocked(Parcel out) { 10371 if (mExcessivePower == null) { 10372 out.writeInt(0); 10373 return; 10374 } 10375 10376 final int N = mExcessivePower.size(); 10377 out.writeInt(N); 10378 for (int i=0; i<N; i++) { 10379 ExcessivePower ew = mExcessivePower.get(i); 10380 out.writeInt(ew.type); 10381 out.writeLong(ew.overTime); 10382 out.writeLong(ew.usedTime); 10383 } 10384 } 10385 readExcessivePowerFromParcelLocked(Parcel in)10386 void readExcessivePowerFromParcelLocked(Parcel in) { 10387 final int N = in.readInt(); 10388 if (N == 0) { 10389 mExcessivePower = null; 10390 return; 10391 } 10392 10393 if (N > 10000) { 10394 throw new ParcelFormatException( 10395 "File corrupt: too many excessive power entries " + N); 10396 } 10397 10398 mExcessivePower = new ArrayList<>(); 10399 for (int i=0; i<N; i++) { 10400 ExcessivePower ew = new ExcessivePower(); 10401 ew.type = in.readInt(); 10402 ew.overTime = in.readLong(); 10403 ew.usedTime = in.readLong(); 10404 mExcessivePower.add(ew); 10405 } 10406 } 10407 writeToParcelLocked(Parcel out)10408 void writeToParcelLocked(Parcel out) { 10409 out.writeLong(mUserTimeMs); 10410 out.writeLong(mSystemTimeMs); 10411 out.writeLong(mForegroundTimeMs); 10412 out.writeInt(mStarts); 10413 out.writeInt(mNumCrashes); 10414 out.writeInt(mNumAnrs); 10415 writeExcessivePowerToParcelLocked(out); 10416 } 10417 readFromParcelLocked(Parcel in)10418 void readFromParcelLocked(Parcel in) { 10419 mUserTimeMs = in.readLong(); 10420 mSystemTimeMs = in.readLong(); 10421 mForegroundTimeMs = in.readLong(); 10422 mStarts = in.readInt(); 10423 mNumCrashes = in.readInt(); 10424 mNumAnrs = in.readInt(); 10425 readExcessivePowerFromParcelLocked(in); 10426 } 10427 addCpuTimeLocked(int utimeMs, int stimeMs)10428 public void addCpuTimeLocked(int utimeMs, int stimeMs) { 10429 addCpuTimeLocked(utimeMs, stimeMs, mBsi.mOnBatteryTimeBase.isRunning()); 10430 } 10431 addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning)10432 public void addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning) { 10433 if (isRunning) { 10434 mUserTimeMs += utimeMs; 10435 mSystemTimeMs += stimeMs; 10436 } 10437 } 10438 addForegroundTimeLocked(long ttimeMs)10439 public void addForegroundTimeLocked(long ttimeMs) { 10440 mForegroundTimeMs += ttimeMs; 10441 } 10442 incStartsLocked()10443 public void incStartsLocked() { 10444 mStarts++; 10445 } 10446 incNumCrashesLocked()10447 public void incNumCrashesLocked() { 10448 mNumCrashes++; 10449 } 10450 incNumAnrsLocked()10451 public void incNumAnrsLocked() { 10452 mNumAnrs++; 10453 } 10454 10455 @Override isActive()10456 public boolean isActive() { 10457 return mActive; 10458 } 10459 10460 @Override getUserTime(int which)10461 public long getUserTime(int which) { 10462 return mUserTimeMs; 10463 } 10464 10465 @Override getSystemTime(int which)10466 public long getSystemTime(int which) { 10467 return mSystemTimeMs; 10468 } 10469 10470 @Override getForegroundTime(int which)10471 public long getForegroundTime(int which) { 10472 return mForegroundTimeMs; 10473 } 10474 10475 @Override getStarts(int which)10476 public int getStarts(int which) { 10477 return mStarts; 10478 } 10479 10480 @Override getNumCrashes(int which)10481 public int getNumCrashes(int which) { 10482 return mNumCrashes; 10483 } 10484 10485 @Override getNumAnrs(int which)10486 public int getNumAnrs(int which) { 10487 return mNumAnrs; 10488 } 10489 } 10490 10491 /** 10492 * The statistics associated with a particular package. 10493 */ 10494 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 10495 /** 10496 * BatteryStatsImpl that we are associated with. 10497 */ 10498 protected BatteryStatsImpl mBsi; 10499 10500 /** 10501 * Number of times wakeup alarms have occurred for this app. 10502 * On screen-off timebase starting in report v25. 10503 */ 10504 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 10505 10506 /** 10507 * The statics we have collected for this package's services. 10508 */ 10509 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 10510 Pkg(BatteryStatsImpl bsi)10511 public Pkg(BatteryStatsImpl bsi) { 10512 mBsi = bsi; 10513 mBsi.mOnBatteryScreenOffTimeBase.add(this); 10514 } 10515 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10516 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10517 long baseRealtimeUs) { 10518 } 10519 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10520 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10521 long baseRealtimeUs) { 10522 } 10523 10524 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10525 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10526 if (detachIfReset) { 10527 this.detach(); 10528 } 10529 return true; 10530 } 10531 10532 @Override detach()10533 public void detach() { 10534 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 10535 for (int j = mWakeupAlarms.size() - 1; j >= 0; j--) { 10536 detachIfNotNull(mWakeupAlarms.valueAt(j)); 10537 } 10538 for (int j = mServiceStats.size() - 1; j >= 0; j--) { 10539 detachIfNotNull(mServiceStats.valueAt(j)); 10540 } 10541 } 10542 readFromParcelLocked(Parcel in)10543 void readFromParcelLocked(Parcel in) { 10544 int numWA = in.readInt(); 10545 mWakeupAlarms.clear(); 10546 for (int i=0; i<numWA; i++) { 10547 String tag = in.readString(); 10548 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 10549 } 10550 10551 int numServs = in.readInt(); 10552 mServiceStats.clear(); 10553 for (int m = 0; m < numServs; m++) { 10554 String serviceName = in.readString(); 10555 Uid.Pkg.Serv serv = new Serv(mBsi); 10556 mServiceStats.put(serviceName, serv); 10557 10558 serv.readFromParcelLocked(in); 10559 } 10560 } 10561 writeToParcelLocked(Parcel out)10562 void writeToParcelLocked(Parcel out) { 10563 int numWA = mWakeupAlarms.size(); 10564 out.writeInt(numWA); 10565 for (int i=0; i<numWA; i++) { 10566 out.writeString(mWakeupAlarms.keyAt(i)); 10567 mWakeupAlarms.valueAt(i).writeToParcel(out); 10568 } 10569 10570 final int NS = mServiceStats.size(); 10571 out.writeInt(NS); 10572 for (int i=0; i<NS; i++) { 10573 out.writeString(mServiceStats.keyAt(i)); 10574 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 10575 serv.writeToParcelLocked(out); 10576 } 10577 } 10578 10579 @Override getWakeupAlarmStats()10580 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 10581 return mWakeupAlarms; 10582 } 10583 noteWakeupAlarmLocked(String tag)10584 public void noteWakeupAlarmLocked(String tag) { 10585 Counter c = mWakeupAlarms.get(tag); 10586 if (c == null) { 10587 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 10588 mWakeupAlarms.put(tag, c); 10589 } 10590 c.stepAtomic(); 10591 } 10592 10593 @Override getServiceStats()10594 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 10595 return mServiceStats; 10596 } 10597 10598 /** 10599 * The statistics associated with a particular service. 10600 */ 10601 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 10602 /** 10603 * BatteryStatsImpl that we are associated with. 10604 */ 10605 protected BatteryStatsImpl mBsi; 10606 10607 /** 10608 * The android package in which this service resides. 10609 */ 10610 protected Pkg mPkg; 10611 10612 /** 10613 * Total time (ms in battery uptime) the service has been left started. 10614 */ 10615 protected long mStartTimeMs; 10616 10617 /** 10618 * If service has been started and not yet stopped, this is 10619 * when it was started. 10620 */ 10621 protected long mRunningSinceMs; 10622 10623 /** 10624 * True if we are currently running. 10625 */ 10626 protected boolean mRunning; 10627 10628 /** 10629 * Total number of times startService() has been called. 10630 */ 10631 protected int mStarts; 10632 10633 /** 10634 * Total time (ms in battery uptime) the service has been left launched. 10635 */ 10636 protected long mLaunchedTimeMs; 10637 10638 /** 10639 * If service has been launched and not yet exited, this is 10640 * when it was launched (ms in battery uptime). 10641 */ 10642 protected long mLaunchedSinceMs; 10643 10644 /** 10645 * True if we are currently launched. 10646 */ 10647 protected boolean mLaunched; 10648 10649 /** 10650 * Total number times the service has been launched. 10651 */ 10652 protected int mLaunches; 10653 10654 /** 10655 * Construct a Serv. Also adds it to the on-battery time base as a listener. 10656 */ Serv(BatteryStatsImpl bsi)10657 public Serv(BatteryStatsImpl bsi) { 10658 mBsi = bsi; 10659 mBsi.mOnBatteryTimeBase.add(this); 10660 } 10661 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10662 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10663 long baseRealtimeUs) { 10664 } 10665 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10666 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10667 long baseRealtimeUs) { 10668 } 10669 10670 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10671 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10672 if (detachIfReset) { 10673 this.detach(); 10674 } 10675 return true; 10676 } 10677 10678 /** 10679 * Remove this Serv as a listener from the time base. 10680 Ms*/ 10681 @Override detach()10682 public void detach() { 10683 mBsi.mOnBatteryTimeBase.remove(this); 10684 } 10685 readFromParcelLocked(Parcel in)10686 public void readFromParcelLocked(Parcel in) { 10687 mStartTimeMs = in.readLong(); 10688 mRunningSinceMs = in.readLong(); 10689 mRunning = in.readInt() != 0; 10690 mStarts = in.readInt(); 10691 mLaunchedTimeMs = in.readLong(); 10692 mLaunchedSinceMs = in.readLong(); 10693 mLaunched = in.readInt() != 0; 10694 mLaunches = in.readInt(); 10695 } 10696 writeToParcelLocked(Parcel out)10697 public void writeToParcelLocked(Parcel out) { 10698 out.writeLong(mStartTimeMs); 10699 out.writeLong(mRunningSinceMs); 10700 out.writeInt(mRunning ? 1 : 0); 10701 out.writeInt(mStarts); 10702 out.writeLong(mLaunchedTimeMs); 10703 out.writeLong(mLaunchedSinceMs); 10704 out.writeInt(mLaunched ? 1 : 0); 10705 out.writeInt(mLaunches); 10706 } 10707 getLaunchTimeToNowLocked(long batteryUptimeMs)10708 public long getLaunchTimeToNowLocked(long batteryUptimeMs) { 10709 if (!mLaunched) return mLaunchedTimeMs; 10710 return mLaunchedTimeMs + batteryUptimeMs - mLaunchedSinceMs; 10711 } 10712 getStartTimeToNowLocked(long batteryUptimeMs)10713 public long getStartTimeToNowLocked(long batteryUptimeMs) { 10714 if (!mRunning) return mStartTimeMs; 10715 return mStartTimeMs + batteryUptimeMs - mRunningSinceMs; 10716 } 10717 startLaunchedLocked()10718 public void startLaunchedLocked() { 10719 startLaunchedLocked(mBsi.mClock.uptimeMillis()); 10720 } 10721 startLaunchedLocked(long uptimeMs)10722 public void startLaunchedLocked(long uptimeMs) { 10723 if (!mLaunched) { 10724 mLaunches++; 10725 mLaunchedSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10726 mLaunched = true; 10727 } 10728 } 10729 stopLaunchedLocked()10730 public void stopLaunchedLocked() { 10731 stopLaunchedLocked(mBsi.mClock.uptimeMillis()); 10732 } 10733 stopLaunchedLocked(long uptimeMs)10734 public void stopLaunchedLocked(long uptimeMs) { 10735 if (mLaunched) { 10736 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10737 - mLaunchedSinceMs; 10738 if (timeMs > 0) { 10739 mLaunchedTimeMs += timeMs; 10740 } else { 10741 mLaunches--; 10742 } 10743 mLaunched = false; 10744 } 10745 } 10746 startRunningLocked()10747 public void startRunningLocked() { 10748 startRunningLocked(mBsi.mClock.uptimeMillis()); 10749 } 10750 startRunningLocked(long uptimeMs)10751 public void startRunningLocked(long uptimeMs) { 10752 if (!mRunning) { 10753 mStarts++; 10754 mRunningSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10755 mRunning = true; 10756 } 10757 } 10758 stopRunningLocked()10759 public void stopRunningLocked() { 10760 stopRunningLocked(mBsi.mClock.uptimeMillis()); 10761 } 10762 stopRunningLocked(long uptimeMs)10763 public void stopRunningLocked(long uptimeMs) { 10764 if (mRunning) { 10765 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10766 - mRunningSinceMs; 10767 if (timeMs > 0) { 10768 mStartTimeMs += timeMs; 10769 } else { 10770 mStarts--; 10771 } 10772 mRunning = false; 10773 } 10774 } 10775 getBatteryStats()10776 public BatteryStatsImpl getBatteryStats() { 10777 return mBsi; 10778 } 10779 10780 @Override getLaunches(int which)10781 public int getLaunches(int which) { 10782 return mLaunches; 10783 } 10784 10785 @Override getStartTime(long now, int which)10786 public long getStartTime(long now, int which) { 10787 return getStartTimeToNowLocked(now); 10788 } 10789 10790 @Override getStarts(int which)10791 public int getStarts(int which) { 10792 return mStarts; 10793 } 10794 } 10795 newServiceStatsLocked()10796 final Serv newServiceStatsLocked() { 10797 return new Serv(mBsi); 10798 } 10799 } 10800 10801 private class ChildUid { 10802 public final TimeMultiStateCounter cpuActiveCounter; 10803 public final LongArrayMultiStateCounter cpuTimeInFreqCounter; 10804 ChildUid()10805 ChildUid() { 10806 final long timestampMs = mBsi.mClock.elapsedRealtime(); 10807 cpuActiveCounter = 10808 new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, 1, timestampMs); 10809 cpuActiveCounter.setState(0, timestampMs); 10810 10811 if (mBsi.trackPerProcStateCpuTimes()) { 10812 final int cpuFreqCount = mBsi.mCpuScalingPolicies.getScalingStepCount(); 10813 10814 cpuTimeInFreqCounter = new LongArrayMultiStateCounter(1, cpuFreqCount); 10815 10816 // Set initial values to all 0. This is a child UID and we want to include 10817 // the entirety of its CPU time-in-freq stats into the parent's stats. 10818 cpuTimeInFreqCounter.updateValues( 10819 new LongArrayMultiStateCounter.LongArrayContainer(cpuFreqCount), 10820 timestampMs); 10821 } else { 10822 cpuTimeInFreqCounter = null; 10823 } 10824 } 10825 } 10826 10827 /** 10828 * Retrieve the statistics object for a particular process, creating 10829 * if needed. 10830 */ getProcessStatsLocked(String name)10831 public Proc getProcessStatsLocked(String name) { 10832 Proc ps = mProcessStats.get(name); 10833 if (ps == null) { 10834 ps = new Proc(mBsi, name); 10835 mProcessStats.put(name, ps); 10836 } 10837 10838 return ps; 10839 } 10840 10841 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState, long elapsedRealtimeMs, long uptimeMs)10842 public void updateUidProcessStateLocked(int procState, 10843 long elapsedRealtimeMs, long uptimeMs) { 10844 int uidRunningState; 10845 // Make special note of Foreground Services 10846 final boolean userAwareService = ActivityManager.isForegroundService(procState); 10847 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 10848 10849 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 10850 return; 10851 } 10852 10853 if (mProcessState != uidRunningState) { 10854 if (mProcessState != Uid.PROCESS_STATE_NONEXISTENT) { 10855 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 10856 } 10857 if (uidRunningState != Uid.PROCESS_STATE_NONEXISTENT) { 10858 if (mProcessStateTimer[uidRunningState] == null) { 10859 makeProcessState(uidRunningState, null); 10860 } 10861 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 10862 } 10863 10864 if (!mBsi.mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU) 10865 && mBsi.trackPerProcStateCpuTimes()) { 10866 mBsi.updateProcStateCpuTimesLocked(mUid, elapsedRealtimeMs, uptimeMs); 10867 10868 LongArrayMultiStateCounter onBatteryCounter = 10869 getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 10870 LongArrayMultiStateCounter onBatteryScreenOffCounter = 10871 getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 10872 10873 onBatteryCounter.setState(uidRunningState, elapsedRealtimeMs); 10874 onBatteryScreenOffCounter.setState(uidRunningState, elapsedRealtimeMs); 10875 } 10876 10877 final int prevBatteryConsumerProcessState = 10878 mapUidProcessStateToBatteryConsumerProcessState(mProcessState); 10879 10880 mProcessState = uidRunningState; 10881 10882 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10883 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10884 10885 final int batteryConsumerProcessState = 10886 mapUidProcessStateToBatteryConsumerProcessState(uidRunningState); 10887 if (mBsi.mSystemReady && mBsi.mPowerStatsCollectorEnabled.get( 10888 BatteryConsumer.POWER_COMPONENT_CPU)) { 10889 mBsi.mHistory.recordProcessStateChange(elapsedRealtimeMs, uptimeMs, mUid, 10890 batteryConsumerProcessState); 10891 } 10892 getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedRealtimeMs); 10893 10894 getMobileRadioActiveTimeCounter() 10895 .setState(batteryConsumerProcessState, elapsedRealtimeMs); 10896 10897 final ControllerActivityCounterImpl wifiControllerActivity = 10898 getWifiControllerActivity(); 10899 if (wifiControllerActivity != null) { 10900 wifiControllerActivity.setState(batteryConsumerProcessState, elapsedRealtimeMs); 10901 } 10902 10903 final ControllerActivityCounterImpl bluetoothControllerActivity = 10904 getBluetoothControllerActivity(); 10905 if (bluetoothControllerActivity != null) { 10906 bluetoothControllerActivity.setState(batteryConsumerProcessState, 10907 elapsedRealtimeMs); 10908 } 10909 10910 final EnergyConsumerStats energyStats = 10911 getOrCreateEnergyConsumerStatsIfSupportedLocked(); 10912 if (energyStats != null) { 10913 energyStats.setState(batteryConsumerProcessState, elapsedRealtimeMs); 10914 } 10915 maybeScheduleExternalStatsSync(prevBatteryConsumerProcessState, 10916 batteryConsumerProcessState); 10917 } 10918 10919 if (userAwareService != mInForegroundService) { 10920 if (userAwareService) { 10921 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 10922 } else { 10923 noteForegroundServicePausedLocked(elapsedRealtimeMs); 10924 } 10925 mInForegroundService = userAwareService; 10926 } 10927 } 10928 10929 @GuardedBy("mBsi") maybeScheduleExternalStatsSync( @atteryConsumer.ProcessState int oldProcessState, @BatteryConsumer.ProcessState int newProcessState)10930 private void maybeScheduleExternalStatsSync( 10931 @BatteryConsumer.ProcessState int oldProcessState, 10932 @BatteryConsumer.ProcessState int newProcessState) { 10933 if (oldProcessState == newProcessState) { 10934 return; 10935 } 10936 // Transitions between BACKGROUND and such non-foreground states like cached 10937 // or nonexistent do not warrant doing a sync. If some of the stats for those 10938 // proc states bleed into the PROCESS_STATE_BACKGROUND, that's ok. 10939 if ((oldProcessState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED 10940 && newProcessState == BatteryConsumer.PROCESS_STATE_BACKGROUND) 10941 || (oldProcessState == BatteryConsumer.PROCESS_STATE_BACKGROUND 10942 && newProcessState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED)) { 10943 return; 10944 } 10945 10946 int flags = ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE; 10947 // Skip querying for inactive radio, where power usage is probably negligible. 10948 if (!BatteryStatsImpl.isActiveRadioPowerState(mBsi.mMobileRadioPowerState)) { 10949 flags &= ~ExternalStatsSync.UPDATE_RADIO; 10950 } 10951 10952 mBsi.mExternalSync.scheduleSyncDueToProcessStateChange(flags, 10953 mBsi.mConstants.PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 10954 } 10955 10956 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()10957 public boolean isInBackground() { 10958 // Note that PROCESS_STATE_CACHED and Uid.PROCESS_STATE_NONEXISTENT is 10959 // also considered to be 'background' for our purposes, because it's not foreground. 10960 return mProcessState >= PROCESS_STATE_BACKGROUND; 10961 } 10962 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)10963 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 10964 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 10965 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 10966 } 10967 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)10968 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 10969 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 10970 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 10971 } 10972 getPidStats()10973 public SparseArray<? extends Pid> getPidStats() { 10974 return mPids; 10975 } 10976 getPidStatsLocked(int pid)10977 public Pid getPidStatsLocked(int pid) { 10978 Pid p = mPids.get(pid); 10979 if (p == null) { 10980 p = new Pid(); 10981 mPids.put(pid, p); 10982 } 10983 return p; 10984 } 10985 10986 /** 10987 * Retrieve the statistics object for a particular service, creating 10988 * if needed. 10989 */ getPackageStatsLocked(String name)10990 public Pkg getPackageStatsLocked(String name) { 10991 Pkg ps = mPackageStats.get(name); 10992 if (ps == null) { 10993 ps = new Pkg(mBsi); 10994 mPackageStats.put(name, ps); 10995 } 10996 10997 return ps; 10998 } 10999 11000 /** 11001 * Retrieve the statistics object for a particular service, creating 11002 * if needed. 11003 */ getServiceStatsLocked(String pkg, String serv)11004 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 11005 Pkg ps = getPackageStatsLocked(pkg); 11006 Pkg.Serv ss = ps.mServiceStats.get(serv); 11007 if (ss == null) { 11008 ss = ps.newServiceStatsLocked(); 11009 ps.mServiceStats.put(serv, ss); 11010 } 11011 11012 return ss; 11013 } 11014 readSyncSummaryFromParcelLocked(String name, Parcel in)11015 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 11016 DualTimer timer = mSyncStats.instantiateObject(); 11017 timer.readSummaryFromParcelLocked(in); 11018 mSyncStats.add(name, timer); 11019 } 11020 readJobSummaryFromParcelLocked(String name, Parcel in)11021 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 11022 DualTimer timer = mJobStats.instantiateObject(); 11023 timer.readSummaryFromParcelLocked(in); 11024 mJobStats.add(name, timer); 11025 } 11026 readWakeSummaryFromParcelLocked(String wlName, Parcel in)11027 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 11028 Wakelock wl = new Wakelock(mBsi, this); 11029 mWakelockStats.add(wlName, wl); 11030 if (in.readInt() != 0) { 11031 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 11032 } 11033 if (in.readInt() != 0) { 11034 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 11035 } 11036 if (in.readInt() != 0) { 11037 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 11038 } 11039 if (in.readInt() != 0) { 11040 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 11041 } 11042 } 11043 getSensorTimerLocked(int sensor, boolean create)11044 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 11045 Sensor se = mSensorStats.get(sensor); 11046 if (se == null) { 11047 if (!create) { 11048 return null; 11049 } 11050 se = new Sensor(mBsi, this, sensor); 11051 mSensorStats.put(sensor, se); 11052 } 11053 DualTimer t = se.mTimer; 11054 if (t != null) { 11055 return t; 11056 } 11057 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 11058 if (timers == null) { 11059 timers = new ArrayList<StopwatchTimer>(); 11060 mBsi.mSensorTimers.put(sensor, timers); 11061 } 11062 t = new DualTimer(mBsi.mClock, this, BatteryStats.SENSOR, timers, 11063 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 11064 se.mTimer = t; 11065 return t; 11066 } 11067 noteStartSyncLocked(String name, long elapsedRealtimeMs)11068 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 11069 DualTimer t = mSyncStats.startObject(name, elapsedRealtimeMs); 11070 if (t != null) { 11071 t.startRunningLocked(elapsedRealtimeMs); 11072 } 11073 } 11074 noteStopSyncLocked(String name, long elapsedRealtimeMs)11075 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 11076 DualTimer t = mSyncStats.stopObject(name, elapsedRealtimeMs); 11077 if (t != null) { 11078 t.stopRunningLocked(elapsedRealtimeMs); 11079 } 11080 } 11081 noteStartJobLocked(String name, long elapsedRealtimeMs)11082 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 11083 DualTimer t = mJobStats.startObject(name, elapsedRealtimeMs); 11084 if (t != null) { 11085 t.startRunningLocked(elapsedRealtimeMs); 11086 } 11087 } 11088 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)11089 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 11090 DualTimer t = mJobStats.stopObject(name, elapsedRealtimeMs); 11091 if (t != null) { 11092 t.stopRunningLocked(elapsedRealtimeMs); 11093 } 11094 if (mBsi.mOnBatteryTimeBase.isRunning()) { 11095 SparseIntArray types = mJobCompletions.get(name); 11096 if (types == null) { 11097 types = new SparseIntArray(); 11098 mJobCompletions.put(name, types); 11099 } 11100 int last = types.get(stopReason, 0); 11101 types.put(stopReason, last + 1); 11102 } 11103 } 11104 getWakelockTimerLocked(Wakelock wl, int type)11105 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 11106 if (wl == null) { 11107 return null; 11108 } 11109 switch (type) { 11110 case WAKE_TYPE_PARTIAL: { 11111 DualTimer t = wl.mTimerPartial; 11112 if (t == null) { 11113 t = new DualTimer(mBsi.mClock, this, WAKE_TYPE_PARTIAL, 11114 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 11115 mOnBatteryScreenOffBackgroundTimeBase); 11116 wl.mTimerPartial = t; 11117 } 11118 return t; 11119 } 11120 case WAKE_TYPE_FULL: { 11121 StopwatchTimer t = wl.mTimerFull; 11122 if (t == null) { 11123 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_FULL, 11124 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 11125 wl.mTimerFull = t; 11126 } 11127 return t; 11128 } 11129 case WAKE_TYPE_WINDOW: { 11130 StopwatchTimer t = wl.mTimerWindow; 11131 if (t == null) { 11132 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_WINDOW, 11133 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 11134 wl.mTimerWindow = t; 11135 } 11136 return t; 11137 } 11138 case WAKE_TYPE_DRAW: { 11139 StopwatchTimer t = wl.mTimerDraw; 11140 if (t == null) { 11141 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_DRAW, 11142 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 11143 wl.mTimerDraw = t; 11144 } 11145 return t; 11146 } 11147 default: 11148 throw new IllegalArgumentException("type=" + type); 11149 } 11150 } 11151 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)11152 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 11153 Wakelock wl = mWakelockStats.startObject(name, elapsedRealtimeMs); 11154 if (wl != null) { 11155 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 11156 } 11157 if (type == WAKE_TYPE_PARTIAL) { 11158 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 11159 if (pid >= 0) { 11160 Pid p = getPidStatsLocked(pid); 11161 if (p.mWakeNesting++ == 0) { 11162 p.mWakeStartMs = elapsedRealtimeMs; 11163 } 11164 } 11165 } 11166 } 11167 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)11168 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 11169 Wakelock wl = mWakelockStats.stopObject(name, elapsedRealtimeMs); 11170 if (wl != null) { 11171 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 11172 wlt.stopRunningLocked(elapsedRealtimeMs); 11173 } 11174 if (type == WAKE_TYPE_PARTIAL) { 11175 if (mAggregatedPartialWakelockTimer != null) { 11176 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 11177 } 11178 if (pid >= 0) { 11179 Pid p = mPids.get(pid); 11180 if (p != null && p.mWakeNesting > 0) { 11181 if (p.mWakeNesting-- == 1) { 11182 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 11183 p.mWakeStartMs = 0; 11184 } 11185 } 11186 } 11187 } 11188 } 11189 reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs)11190 public void reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs) { 11191 Proc p = getProcessStatsLocked(proc); 11192 if (p != null) { 11193 p.addExcessiveCpu(overTimeMs, usedTimeMs); 11194 } 11195 } 11196 noteStartSensor(int sensor, long elapsedRealtimeMs)11197 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 11198 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 11199 t.startRunningLocked(elapsedRealtimeMs); 11200 } 11201 noteStopSensor(int sensor, long elapsedRealtimeMs)11202 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 11203 // Don't create a timer if one doesn't already exist 11204 DualTimer t = getSensorTimerLocked(sensor, false); 11205 if (t != null) { 11206 t.stopRunningLocked(elapsedRealtimeMs); 11207 } 11208 } 11209 noteStartGps(long elapsedRealtimeMs)11210 public void noteStartGps(long elapsedRealtimeMs) { 11211 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 11212 } 11213 noteStopGps(long elapsedRealtimeMs)11214 public void noteStopGps(long elapsedRealtimeMs) { 11215 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 11216 } 11217 } 11218 11219 @GuardedBy("this") getCpuScalingPolicies()11220 public CpuScalingPolicies getCpuScalingPolicies() { 11221 return mCpuScalingPolicies; 11222 } 11223 11224 @GuardedBy("this") getCpuTimeInFreqContainer()11225 private LongArrayMultiStateCounter.LongArrayContainer getCpuTimeInFreqContainer() { 11226 if (mTmpCpuTimeInFreq == null) { 11227 mTmpCpuTimeInFreq = 11228 new LongArrayMultiStateCounter.LongArrayContainer( 11229 mCpuScalingPolicies.getScalingStepCount()); 11230 } 11231 return mTmpCpuTimeInFreq; 11232 } 11233 BatteryStatsImpl(@onNull BatteryStatsConfig config, @NonNull Clock clock, @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback, @Nullable EnergyStatsRetriever energyStatsRetriever, @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile, @NonNull CpuScalingPolicies cpuScalingPolicies, @NonNull PowerStatsUidResolver powerStatsUidResolver)11234 public BatteryStatsImpl(@NonNull BatteryStatsConfig config, @NonNull Clock clock, 11235 @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, 11236 @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback, 11237 @Nullable EnergyStatsRetriever energyStatsRetriever, 11238 @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile, 11239 @NonNull CpuScalingPolicies cpuScalingPolicies, 11240 @NonNull PowerStatsUidResolver powerStatsUidResolver) { 11241 this(config, clock, monotonicClock, systemDir, handler, platformIdleStateCallback, 11242 energyStatsRetriever, userInfoProvider, powerProfile, cpuScalingPolicies, 11243 powerStatsUidResolver, new FrameworkStatsLogger(), 11244 new BatteryStatsHistory.TraceDelegate(), new BatteryStatsHistory.EventLogger()); 11245 } 11246 BatteryStatsImpl(@onNull BatteryStatsConfig config, @NonNull Clock clock, @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback, @Nullable EnergyStatsRetriever energyStatsRetriever, @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile, @NonNull CpuScalingPolicies cpuScalingPolicies, @NonNull PowerStatsUidResolver powerStatsUidResolver, @NonNull FrameworkStatsLogger frameworkStatsLogger, @NonNull BatteryStatsHistory.TraceDelegate traceDelegate, @NonNull BatteryStatsHistory.EventLogger eventLogger)11247 public BatteryStatsImpl(@NonNull BatteryStatsConfig config, @NonNull Clock clock, 11248 @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, 11249 @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback, 11250 @Nullable EnergyStatsRetriever energyStatsRetriever, 11251 @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile, 11252 @NonNull CpuScalingPolicies cpuScalingPolicies, 11253 @NonNull PowerStatsUidResolver powerStatsUidResolver, 11254 @NonNull FrameworkStatsLogger frameworkStatsLogger, 11255 @NonNull BatteryStatsHistory.TraceDelegate traceDelegate, 11256 @NonNull BatteryStatsHistory.EventLogger eventLogger) { 11257 mClock = clock; 11258 initKernelStatsReaders(); 11259 11260 mBatteryStatsConfig = config; 11261 mMonotonicClock = monotonicClock; 11262 mHandler = new MyHandler(handler.getLooper()); 11263 mConstants = new Constants(mHandler); 11264 11265 mPowerProfile = powerProfile; 11266 mCpuScalingPolicies = cpuScalingPolicies; 11267 mPowerStatsUidResolver = powerStatsUidResolver; 11268 mFrameworkStatsLogger = frameworkStatsLogger; 11269 11270 initPowerProfile(); 11271 11272 if (systemDir != null) { 11273 mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); 11274 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 11275 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 11276 } else { 11277 mStatsFile = null; 11278 mCheckinFile = null; 11279 mDailyFile = null; 11280 } 11281 11282 mHistory = new BatteryStatsHistory(null /* historyBuffer */, systemDir, 11283 mConstants.MAX_HISTORY_FILES, mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, 11284 mClock, mMonotonicClock, traceDelegate, eventLogger); 11285 11286 mCpuPowerStatsCollector = new CpuPowerStatsCollector(mPowerStatsCollectorInjector); 11287 mCpuPowerStatsCollector.addConsumer(this::recordPowerStats); 11288 11289 mMobileRadioPowerStatsCollector = new MobileRadioPowerStatsCollector( 11290 mPowerStatsCollectorInjector); 11291 mMobileRadioPowerStatsCollector.addConsumer(this::recordPowerStats); 11292 11293 mWifiPowerStatsCollector = new WifiPowerStatsCollector(mPowerStatsCollectorInjector); 11294 mWifiPowerStatsCollector.addConsumer(this::recordPowerStats); 11295 11296 mBluetoothPowerStatsCollector = new BluetoothPowerStatsCollector( 11297 mPowerStatsCollectorInjector); 11298 mBluetoothPowerStatsCollector.addConsumer(this::recordPowerStats); 11299 11300 mCameraPowerStatsCollector = new CameraPowerStatsCollector(mPowerStatsCollectorInjector); 11301 mCameraPowerStatsCollector.addConsumer(this::recordPowerStats); 11302 11303 mGnssPowerStatsCollector = new GnssPowerStatsCollector(mPowerStatsCollectorInjector); 11304 mGnssPowerStatsCollector.addConsumer(this::recordPowerStats); 11305 11306 mStartCount++; 11307 initTimersAndCounters(); 11308 mOnBattery = mOnBatteryInternal = false; 11309 long uptimeUs = mClock.uptimeMillis() * 1000; 11310 long realtimeUs = mClock.elapsedRealtime() * 1000; 11311 initTimes(uptimeUs, realtimeUs); 11312 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 11313 initDischarge(realtimeUs); 11314 updateDailyDeadlineLocked(); 11315 mPlatformIdleStateCallback = platformIdleStateCallback; 11316 mEnergyConsumerRetriever = energyStatsRetriever; 11317 mUserInfoProvider = userInfoProvider; 11318 11319 mPowerStatsUidResolver.addListener(new PowerStatsUidResolver.Listener() { 11320 @Override 11321 public void onIsolatedUidAdded(int isolatedUid, int parentUid) { 11322 BatteryStatsImpl.this.onIsolatedUidAdded(isolatedUid, parentUid); 11323 } 11324 11325 @Override 11326 public void onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid) { 11327 BatteryStatsImpl.this.onBeforeIsolatedUidRemoved(isolatedUid, parentUid); 11328 } 11329 11330 @Override 11331 public void onAfterIsolatedUidRemoved(int isolatedUid, int parentUid) { 11332 BatteryStatsImpl.this.onAfterIsolatedUidRemoved(isolatedUid, parentUid); 11333 } 11334 }); 11335 11336 // Notify statsd that the system is initially not in doze. 11337 mDeviceIdleMode = DEVICE_IDLE_MODE_OFF; 11338 mFrameworkStatsLogger.deviceIdleModeStateChanged(mDeviceIdleMode); 11339 } 11340 recordPowerStats(PowerStats stats)11341 private void recordPowerStats(PowerStats stats) { 11342 if (stats.durationMs > 0) { 11343 synchronized (this) { 11344 mHistory.recordPowerStats(mClock.elapsedRealtime(), mClock.uptimeMillis(), stats); 11345 } 11346 } 11347 } 11348 11349 @VisibleForTesting initTimersAndCounters()11350 protected void initTimersAndCounters() { 11351 mScreenOnTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase); 11352 mScreenDozeTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase); 11353 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11354 mScreenBrightnessTimer[i] = new StopwatchTimer(mClock, null, -100 - i, null, 11355 mOnBatteryTimeBase); 11356 } 11357 11358 mPerDisplayBatteryStats = new DisplayBatteryStats[1]; 11359 mPerDisplayBatteryStats[0] = new DisplayBatteryStats(mClock, mOnBatteryTimeBase); 11360 11361 mInteractiveTimer = new StopwatchTimer(mClock, null, -10, null, mOnBatteryTimeBase); 11362 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClock, null, -2, null, 11363 mOnBatteryTimeBase); 11364 mDeviceIdleModeLightTimer = new StopwatchTimer(mClock, null, -11, null, 11365 mOnBatteryTimeBase); 11366 mDeviceIdleModeFullTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase); 11367 mDeviceLightIdlingTimer = new StopwatchTimer(mClock, null, -15, null, mOnBatteryTimeBase); 11368 mDeviceIdlingTimer = new StopwatchTimer(mClock, null, -12, null, mOnBatteryTimeBase); 11369 mPhoneOnTimer = new StopwatchTimer(mClock, null, -3, null, mOnBatteryTimeBase); 11370 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 11371 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -200 - i, null, 11372 mOnBatteryTimeBase); 11373 } 11374 mPhoneSignalScanningTimer = new StopwatchTimer(mClock, null, -200 + 1, null, 11375 mOnBatteryTimeBase); 11376 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11377 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClock, null, -300 - i, null, 11378 mOnBatteryTimeBase); 11379 } 11380 mNrNsaTimer = new StopwatchTimer(mClock, null, -200 + 2, null, mOnBatteryTimeBase); 11381 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11382 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 11383 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 11384 } 11385 mWifiActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 11386 NUM_WIFI_TX_LEVELS); 11387 mBluetoothActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 11388 NUM_BT_TX_LEVELS); 11389 mModemActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 11390 MODEM_TX_POWER_LEVEL_COUNT); 11391 mMobileRadioActiveTimer = new StopwatchTimer(mClock, null, -400, null, mOnBatteryTimeBase); 11392 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClock, null, -401, null, 11393 mOnBatteryTimeBase); 11394 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 11395 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 11396 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 11397 mWifiMulticastWakelockTimer = new StopwatchTimer(mClock, null, 11398 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 11399 mWifiOnTimer = new StopwatchTimer(mClock, null, -4, null, mOnBatteryTimeBase); 11400 mGlobalWifiRunningTimer = new StopwatchTimer(mClock, null, -5, null, mOnBatteryTimeBase); 11401 for (int i=0; i<NUM_WIFI_STATES; i++) { 11402 mWifiStateTimer[i] = new StopwatchTimer(mClock, null, -600 - i, null, 11403 mOnBatteryTimeBase); 11404 } 11405 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11406 mWifiSupplStateTimer[i] = new StopwatchTimer(mClock, null, -700 - i, null, 11407 mOnBatteryTimeBase); 11408 } 11409 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11410 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -800 - i, null, 11411 mOnBatteryTimeBase); 11412 } 11413 mWifiActiveTimer = new StopwatchTimer(mClock, null, -900, null, mOnBatteryTimeBase); 11414 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 11415 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClock, null, -1000 - i, null, 11416 mOnBatteryTimeBase); 11417 } 11418 mAudioOnTimer = new StopwatchTimer(mClock, null, -7, null, mOnBatteryTimeBase); 11419 mVideoOnTimer = new StopwatchTimer(mClock, null, -8, null, mOnBatteryTimeBase); 11420 mFlashlightOnTimer = new StopwatchTimer(mClock, null, -9, null, mOnBatteryTimeBase); 11421 mCameraOnTimer = new StopwatchTimer(mClock, null, -13, null, mOnBatteryTimeBase); 11422 mBluetoothScanTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase); 11423 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 11424 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11425 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11426 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11427 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11428 mDischargeUnplugLevel = 0; 11429 mDischargePlugLevel = -1; 11430 mDischargeCurrentLevel = 0; 11431 mBatteryLevel = 0; 11432 } 11433 initPowerProfile()11434 private void initPowerProfile() { 11435 int[] policies = mCpuScalingPolicies.getPolicies(); 11436 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[policies.length]; 11437 for (int i = 0; i < policies.length; i++) { 11438 int[] cpus = mCpuScalingPolicies.getRelatedCpus(policies[i]); 11439 int[] freqs = mCpuScalingPolicies.getFrequencies(policies[i]); 11440 // We need to initialize the KernelCpuSpeedReaders to read from 11441 // the first cpu of each core. Once we have the CpuScalingPolicy, we have access to this 11442 // information. 11443 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(cpus[0], freqs.length); 11444 } 11445 11446 // Initialize CPU power bracket map, which combines CPU states (cluster/freq pairs) 11447 // into a small number of brackets 11448 mCpuPowerBracketMap = new int[mCpuScalingPolicies.getScalingStepCount()]; 11449 int index = 0; 11450 for (int policy : policies) { 11451 int steps = mCpuScalingPolicies.getFrequencies(policy).length; 11452 for (int step = 0; step < steps; step++) { 11453 mCpuPowerBracketMap[index++] = 11454 mPowerProfile.getCpuPowerBracketForScalingStep(policy, step); 11455 } 11456 } 11457 11458 if (mEstimatedBatteryCapacityMah == -1) { 11459 // Initialize the estimated battery capacity to a known preset one. 11460 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 11461 } 11462 11463 setDisplayCountLocked(mPowerProfile.getNumDisplays()); 11464 } 11465 getPowerProfile()11466 PowerProfile getPowerProfile() { 11467 return mPowerProfile; 11468 } 11469 11470 /** 11471 * Starts tracking CPU time-in-state for threads of the system server process, 11472 * keeping a separate account of threads receiving incoming binder calls. 11473 */ startTrackingSystemServerCpuTime()11474 public void startTrackingSystemServerCpuTime() { 11475 mSystemServerCpuThreadReader.startTrackingThreadCpuTime(); 11476 } 11477 getSystemServiceCpuThreadTimes()11478 public SystemServiceCpuThreadTimes getSystemServiceCpuThreadTimes() { 11479 return mSystemServerCpuThreadReader.readAbsolute(); 11480 } 11481 setCallback(BatteryCallback cb)11482 public void setCallback(BatteryCallback cb) { 11483 mCallback = cb; 11484 } 11485 setRadioScanningTimeoutLocked(long timeoutUs)11486 public void setRadioScanningTimeoutLocked(long timeoutUs) { 11487 if (mPhoneSignalScanningTimer != null) { 11488 mPhoneSignalScanningTimer.setTimeout(timeoutUs); 11489 } 11490 } 11491 setExternalStatsSyncLocked(ExternalStatsSync sync)11492 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 11493 mExternalSync = sync; 11494 } 11495 11496 /** 11497 * Initialize and set multi display timers and states. 11498 */ setDisplayCountLocked(int numDisplays)11499 public void setDisplayCountLocked(int numDisplays) { 11500 mPerDisplayBatteryStats = new DisplayBatteryStats[numDisplays]; 11501 for (int i = 0; i < numDisplays; i++) { 11502 mPerDisplayBatteryStats[i] = new DisplayBatteryStats(mClock, mOnBatteryTimeBase); 11503 } 11504 } 11505 updateDailyDeadlineLocked()11506 public void updateDailyDeadlineLocked() { 11507 // Get the current time. 11508 long currentTimeMs = mDailyStartTimeMs = mClock.currentTimeMillis(); 11509 Calendar calDeadline = Calendar.getInstance(); 11510 calDeadline.setTimeInMillis(currentTimeMs); 11511 11512 // Move time up to the next day, ranging from 1am to 3pm. 11513 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 11514 calDeadline.set(Calendar.MILLISECOND, 0); 11515 calDeadline.set(Calendar.SECOND, 0); 11516 calDeadline.set(Calendar.MINUTE, 0); 11517 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 11518 mNextMinDailyDeadlineMs = calDeadline.getTimeInMillis(); 11519 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 11520 mNextMaxDailyDeadlineMs = calDeadline.getTimeInMillis(); 11521 } 11522 recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs)11523 public void recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs) { 11524 if (currentTimeMs >= mNextMaxDailyDeadlineMs) { 11525 recordDailyStatsLocked(); 11526 } else if (settled && currentTimeMs >= mNextMinDailyDeadlineMs) { 11527 recordDailyStatsLocked(); 11528 } else if (currentTimeMs < (mDailyStartTimeMs - (1000 * 60 * 60 * 24))) { 11529 recordDailyStatsLocked(); 11530 } 11531 } 11532 recordDailyStatsLocked()11533 public void recordDailyStatsLocked() { 11534 DailyItem item = new DailyItem(); 11535 item.mStartTime = mDailyStartTimeMs; 11536 item.mEndTime = mClock.currentTimeMillis(); 11537 boolean hasData = false; 11538 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 11539 hasData = true; 11540 item.mDischargeSteps = new LevelStepTracker( 11541 mDailyDischargeStepTracker.mNumStepDurations, 11542 mDailyDischargeStepTracker.mStepDurations); 11543 } 11544 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 11545 hasData = true; 11546 item.mChargeSteps = new LevelStepTracker( 11547 mDailyChargeStepTracker.mNumStepDurations, 11548 mDailyChargeStepTracker.mStepDurations); 11549 } 11550 if (mDailyPackageChanges != null) { 11551 hasData = true; 11552 item.mPackageChanges = mDailyPackageChanges; 11553 mDailyPackageChanges = null; 11554 } 11555 mDailyDischargeStepTracker.init(); 11556 mDailyChargeStepTracker.init(); 11557 updateDailyDeadlineLocked(); 11558 11559 if (hasData) { 11560 final long startTimeMs = SystemClock.uptimeMillis(); 11561 mDailyItems.add(item); 11562 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 11563 mDailyItems.remove(0); 11564 } 11565 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 11566 try { 11567 TypedXmlSerializer out = Xml.resolveSerializer(memStream); 11568 writeDailyItemsLocked(out); 11569 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 11570 BackgroundThread.getHandler().post(new Runnable() { 11571 @Override 11572 public void run() { 11573 synchronized (mCheckinFile) { 11574 final long startTimeMs2 = SystemClock.uptimeMillis(); 11575 FileOutputStream stream = null; 11576 try { 11577 stream = mDailyFile.startWrite(); 11578 memStream.writeTo(stream); 11579 stream.flush(); 11580 mDailyFile.finishWrite(stream); 11581 mFrameworkStatsLogger.writeCommitSysConfigFile("batterystats-daily", 11582 initialTimeMs + SystemClock.uptimeMillis() - startTimeMs2); 11583 } catch (IOException e) { 11584 Slog.w("BatteryStats", 11585 "Error writing battery daily items", e); 11586 mDailyFile.failWrite(stream); 11587 } 11588 } 11589 } 11590 }); 11591 } catch (IOException e) { 11592 } 11593 } 11594 } 11595 writeDailyItemsLocked(TypedXmlSerializer out)11596 private void writeDailyItemsLocked(TypedXmlSerializer out) throws IOException { 11597 StringBuilder sb = new StringBuilder(64); 11598 out.startDocument(null, true); 11599 out.startTag(null, "daily-items"); 11600 for (int i=0; i<mDailyItems.size(); i++) { 11601 final DailyItem dit = mDailyItems.get(i); 11602 out.startTag(null, "item"); 11603 out.attributeLong(null, "start", dit.mStartTime); 11604 out.attributeLong(null, "end", dit.mEndTime); 11605 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 11606 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 11607 if (dit.mPackageChanges != null) { 11608 for (int j=0; j<dit.mPackageChanges.size(); j++) { 11609 PackageChange pc = dit.mPackageChanges.get(j); 11610 if (pc.mUpdate) { 11611 out.startTag(null, "upd"); 11612 out.attribute(null, "pkg", pc.mPackageName); 11613 out.attributeLong(null, "ver", pc.mVersionCode); 11614 out.endTag(null, "upd"); 11615 } else { 11616 out.startTag(null, "rem"); 11617 out.attribute(null, "pkg", pc.mPackageName); 11618 out.endTag(null, "rem"); 11619 } 11620 } 11621 } 11622 out.endTag(null, "item"); 11623 } 11624 out.endTag(null, "daily-items"); 11625 out.endDocument(); 11626 } 11627 writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)11628 private void writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, 11629 StringBuilder tmpBuilder) throws IOException { 11630 if (steps != null) { 11631 out.startTag(null, tag); 11632 out.attributeInt(null, "n", steps.mNumStepDurations); 11633 for (int i=0; i<steps.mNumStepDurations; i++) { 11634 out.startTag(null, "s"); 11635 tmpBuilder.setLength(0); 11636 steps.encodeEntryAt(i, tmpBuilder); 11637 out.attribute(null, "v", tmpBuilder.toString()); 11638 out.endTag(null, "s"); 11639 } 11640 out.endTag(null, tag); 11641 } 11642 } 11643 11644 @GuardedBy("this") readDailyStatsLocked()11645 public void readDailyStatsLocked() { 11646 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 11647 mDailyItems.clear(); 11648 FileInputStream stream; 11649 try { 11650 stream = mDailyFile.openRead(); 11651 } catch (FileNotFoundException e) { 11652 return; 11653 } 11654 try { 11655 TypedXmlPullParser parser = Xml.resolvePullParser(stream); 11656 readDailyItemsLocked(parser); 11657 } catch (IOException e) { 11658 } finally { 11659 try { 11660 stream.close(); 11661 } catch (IOException e) { 11662 } 11663 } 11664 } 11665 readDailyItemsLocked(TypedXmlPullParser parser)11666 private void readDailyItemsLocked(TypedXmlPullParser parser) { 11667 try { 11668 int type; 11669 while ((type = parser.next()) != XmlPullParser.START_TAG 11670 && type != XmlPullParser.END_DOCUMENT) { 11671 ; 11672 } 11673 11674 if (type != XmlPullParser.START_TAG) { 11675 throw new IllegalStateException("no start tag found"); 11676 } 11677 11678 int outerDepth = parser.getDepth(); 11679 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11680 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11681 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11682 continue; 11683 } 11684 11685 String tagName = parser.getName(); 11686 if (tagName.equals("item")) { 11687 readDailyItemTagLocked(parser); 11688 } else { 11689 Slog.w(TAG, "Unknown element under <daily-items>: " 11690 + parser.getName()); 11691 XmlUtils.skipCurrentTag(parser); 11692 } 11693 } 11694 11695 } catch (IllegalStateException e) { 11696 Slog.w(TAG, "Failed parsing daily " + e); 11697 } catch (NullPointerException e) { 11698 Slog.w(TAG, "Failed parsing daily " + e); 11699 } catch (NumberFormatException e) { 11700 Slog.w(TAG, "Failed parsing daily " + e); 11701 } catch (XmlPullParserException e) { 11702 Slog.w(TAG, "Failed parsing daily " + e); 11703 } catch (IOException e) { 11704 Slog.w(TAG, "Failed parsing daily " + e); 11705 } catch (IndexOutOfBoundsException e) { 11706 Slog.w(TAG, "Failed parsing daily " + e); 11707 } 11708 } 11709 readDailyItemTagLocked(TypedXmlPullParser parser)11710 void readDailyItemTagLocked(TypedXmlPullParser parser) throws NumberFormatException, 11711 XmlPullParserException, IOException { 11712 DailyItem dit = new DailyItem(); 11713 dit.mStartTime = parser.getAttributeLong(null, "start", 0); 11714 dit.mEndTime = parser.getAttributeLong(null, "end", 0); 11715 int outerDepth = parser.getDepth(); 11716 int type; 11717 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11718 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11719 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11720 continue; 11721 } 11722 11723 String tagName = parser.getName(); 11724 if (tagName.equals("dis")) { 11725 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 11726 } else if (tagName.equals("chg")) { 11727 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 11728 } else if (tagName.equals("upd")) { 11729 if (dit.mPackageChanges == null) { 11730 dit.mPackageChanges = new ArrayList<>(); 11731 } 11732 PackageChange pc = new PackageChange(); 11733 pc.mUpdate = true; 11734 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11735 pc.mVersionCode = parser.getAttributeLong(null, "ver", 0); 11736 dit.mPackageChanges.add(pc); 11737 XmlUtils.skipCurrentTag(parser); 11738 } else if (tagName.equals("rem")) { 11739 if (dit.mPackageChanges == null) { 11740 dit.mPackageChanges = new ArrayList<>(); 11741 } 11742 PackageChange pc = new PackageChange(); 11743 pc.mUpdate = false; 11744 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11745 dit.mPackageChanges.add(pc); 11746 XmlUtils.skipCurrentTag(parser); 11747 } else { 11748 Slog.w(TAG, "Unknown element under <item>: " 11749 + parser.getName()); 11750 XmlUtils.skipCurrentTag(parser); 11751 } 11752 } 11753 mDailyItems.add(dit); 11754 } 11755 readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, String tag)11756 void readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, 11757 String tag) 11758 throws NumberFormatException, XmlPullParserException, IOException { 11759 final int num = parser.getAttributeInt(null, "n", -1); 11760 if (num == -1) { 11761 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 11762 XmlUtils.skipCurrentTag(parser); 11763 return; 11764 } 11765 LevelStepTracker steps = new LevelStepTracker(num); 11766 if (isCharge) { 11767 dit.mChargeSteps = steps; 11768 } else { 11769 dit.mDischargeSteps = steps; 11770 } 11771 int i = 0; 11772 int outerDepth = parser.getDepth(); 11773 int type; 11774 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11775 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11776 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11777 continue; 11778 } 11779 11780 String tagName = parser.getName(); 11781 if ("s".equals(tagName)) { 11782 if (i < num) { 11783 String valueAttr = parser.getAttributeValue(null, "v"); 11784 if (valueAttr != null) { 11785 steps.decodeEntryAt(i, valueAttr); 11786 i++; 11787 } 11788 } 11789 } else { 11790 Slog.w(TAG, "Unknown element under <" + tag + ">: " 11791 + parser.getName()); 11792 XmlUtils.skipCurrentTag(parser); 11793 } 11794 } 11795 steps.mNumStepDurations = i; 11796 } 11797 11798 @Override getDailyItemLocked(int daysAgo)11799 public DailyItem getDailyItemLocked(int daysAgo) { 11800 int index = mDailyItems.size()-1-daysAgo; 11801 return index >= 0 ? mDailyItems.get(index) : null; 11802 } 11803 11804 @Override getCurrentDailyStartTime()11805 public long getCurrentDailyStartTime() { 11806 return mDailyStartTimeMs; 11807 } 11808 11809 @Override getNextMinDailyDeadline()11810 public long getNextMinDailyDeadline() { 11811 return mNextMinDailyDeadlineMs; 11812 } 11813 11814 @Override getNextMaxDailyDeadline()11815 public long getNextMaxDailyDeadline() { 11816 return mNextMaxDailyDeadlineMs; 11817 } 11818 11819 @GuardedBy("this") getHistoryTotalSize()11820 public int getHistoryTotalSize() { 11821 return mConstants.MAX_HISTORY_BUFFER * mConstants.MAX_HISTORY_FILES; 11822 } 11823 getHistoryUsedSize()11824 public int getHistoryUsedSize() { 11825 return mHistory.getHistoryUsedSize(); 11826 } 11827 11828 /** 11829 * Creates an iterator for battery stats history. 11830 */ 11831 @Override iterateBatteryStatsHistory(long startTimeMs, long endTimeMs)11832 public BatteryStatsHistoryIterator iterateBatteryStatsHistory(long startTimeMs, 11833 long endTimeMs) { 11834 return mHistory.iterate(startTimeMs, endTimeMs); 11835 } 11836 11837 @Override getHistoryStringPoolSize()11838 public int getHistoryStringPoolSize() { 11839 return mHistory.getHistoryStringPoolSize(); 11840 } 11841 11842 @Override getHistoryStringPoolBytes()11843 public int getHistoryStringPoolBytes() { 11844 return mHistory.getHistoryStringPoolBytes(); 11845 } 11846 11847 @Override getHistoryTagPoolString(int index)11848 public String getHistoryTagPoolString(int index) { 11849 return mHistory.getHistoryTagPoolString(index); 11850 } 11851 11852 @Override getHistoryTagPoolUid(int index)11853 public int getHistoryTagPoolUid(int index) { 11854 return mHistory.getHistoryTagPoolUid(index); 11855 } 11856 11857 @Override getStartCount()11858 public int getStartCount() { 11859 return mStartCount; 11860 } 11861 isOnBattery()11862 public boolean isOnBattery() { 11863 return mOnBattery; 11864 } 11865 isCharging()11866 public boolean isCharging() { 11867 return mCharging; 11868 } 11869 initTimes(long uptimeUs, long realtimeUs)11870 void initTimes(long uptimeUs, long realtimeUs) { 11871 mStartClockTimeMs = mClock.currentTimeMillis(); 11872 mOnBatteryTimeBase.init(uptimeUs, realtimeUs); 11873 mOnBatteryScreenOffTimeBase.init(uptimeUs, realtimeUs); 11874 mRealtimeUs = 0; 11875 mUptimeUs = 0; 11876 mRealtimeStartUs = realtimeUs; 11877 mUptimeStartUs = uptimeUs; 11878 mMonotonicStartTime = mMonotonicClock.monotonicTime(); 11879 } 11880 initDischarge(long elapsedRealtimeUs)11881 void initDischarge(long elapsedRealtimeUs) { 11882 mLowDischargeAmountSinceCharge = 0; 11883 mHighDischargeAmountSinceCharge = 0; 11884 mDischargeAmountScreenOn = 0; 11885 mDischargeAmountScreenOnSinceCharge = 0; 11886 mDischargeAmountScreenOff = 0; 11887 mDischargeAmountScreenOffSinceCharge = 0; 11888 mDischargeAmountScreenDoze = 0; 11889 mDischargeAmountScreenDozeSinceCharge = 0; 11890 mDischargeStepTracker.init(); 11891 mChargeStepTracker.init(); 11892 mDischargeScreenOffCounter.reset(false, elapsedRealtimeUs); 11893 mDischargeScreenDozeCounter.reset(false, elapsedRealtimeUs); 11894 mDischargeLightDozeCounter.reset(false, elapsedRealtimeUs); 11895 mDischargeDeepDozeCounter.reset(false, elapsedRealtimeUs); 11896 mDischargeCounter.reset(false, elapsedRealtimeUs); 11897 } 11898 11899 /** 11900 * Associates the BatteryStatsImpl object with a BatteryUsageStatsProvider and PowerStatsStore 11901 * to allow for a snapshot of battery usage stats to be taken and stored just before battery 11902 * reset. 11903 */ saveBatteryUsageStatsOnReset( @onNull BatteryUsageStatsProvider batteryUsageStatsProvider, @NonNull PowerStatsStore powerStatsStore)11904 public void saveBatteryUsageStatsOnReset( 11905 @NonNull BatteryUsageStatsProvider batteryUsageStatsProvider, 11906 @NonNull PowerStatsStore powerStatsStore) { 11907 mSaveBatteryUsageStatsOnReset = true; 11908 mBatteryUsageStatsProvider = batteryUsageStatsProvider; 11909 mPowerStatsStore = powerStatsStore; 11910 } 11911 11912 @GuardedBy("this") resetAllStatsAndHistoryLocked(int reason)11913 public void resetAllStatsAndHistoryLocked(int reason) { 11914 final long mSecUptime = mClock.uptimeMillis(); 11915 long uptimeUs = mSecUptime * 1000; 11916 long mSecRealtime = mClock.elapsedRealtime(); 11917 long realtimeUs = mSecRealtime * 1000; 11918 resetAllStatsLocked(mSecUptime, mSecRealtime, reason); 11919 pullPendingStateUpdatesLocked(); 11920 mHistory.writeHistoryItem(mSecRealtime, mSecUptime); 11921 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel = mBatteryLevel; 11922 mOnBatteryTimeBase.reset(uptimeUs, realtimeUs); 11923 mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs); 11924 if (!mBatteryPluggedIn) { 11925 if (Display.isOnState(mScreenState)) { 11926 mDischargeScreenOnUnplugLevel = mBatteryLevel; 11927 mDischargeScreenDozeUnplugLevel = 0; 11928 mDischargeScreenOffUnplugLevel = 0; 11929 } else if (Display.isDozeState(mScreenState)) { 11930 mDischargeScreenOnUnplugLevel = 0; 11931 mDischargeScreenDozeUnplugLevel = mBatteryLevel; 11932 mDischargeScreenOffUnplugLevel = 0; 11933 } else { 11934 mDischargeScreenOnUnplugLevel = 0; 11935 mDischargeScreenDozeUnplugLevel = 0; 11936 mDischargeScreenOffUnplugLevel = mBatteryLevel; 11937 } 11938 mDischargeAmountScreenOn = 0; 11939 mDischargeAmountScreenOff = 0; 11940 mDischargeAmountScreenDoze = 0; 11941 } 11942 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 11943 } 11944 11945 @GuardedBy("this") resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, int resetReason)11946 private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, 11947 int resetReason) { 11948 saveBatteryUsageStatsOnReset(resetReason); 11949 11950 final long uptimeUs = uptimeMillis * 1000; 11951 final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000; 11952 mStartCount = 0; 11953 initTimes(uptimeUs, elapsedRealtimeUs); 11954 mScreenOnTimer.reset(false, elapsedRealtimeUs); 11955 mScreenDozeTimer.reset(false, elapsedRealtimeUs); 11956 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11957 mScreenBrightnessTimer[i].reset(false, elapsedRealtimeUs); 11958 } 11959 11960 final int numDisplays = mPerDisplayBatteryStats.length; 11961 for (int i = 0; i < numDisplays; i++) { 11962 mPerDisplayBatteryStats[i].reset(elapsedRealtimeUs); 11963 } 11964 11965 if (mPowerProfile != null) { 11966 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 11967 } else { 11968 mEstimatedBatteryCapacityMah = -1; 11969 } 11970 mLastLearnedBatteryCapacityUah = -1; 11971 mMinLearnedBatteryCapacityUah = -1; 11972 mMaxLearnedBatteryCapacityUah = -1; 11973 mInteractiveTimer.reset(false, elapsedRealtimeUs); 11974 mPowerSaveModeEnabledTimer.reset(false, elapsedRealtimeUs); 11975 mLastIdleTimeStartMs = elapsedRealtimeMillis; 11976 mLongestLightIdleTimeMs = 0; 11977 mLongestFullIdleTimeMs = 0; 11978 mDeviceIdleModeLightTimer.reset(false, elapsedRealtimeUs); 11979 mDeviceIdleModeFullTimer.reset(false, elapsedRealtimeUs); 11980 mDeviceLightIdlingTimer.reset(false, elapsedRealtimeUs); 11981 mDeviceIdlingTimer.reset(false, elapsedRealtimeUs); 11982 mPhoneOnTimer.reset(false, elapsedRealtimeUs); 11983 mAudioOnTimer.reset(false, elapsedRealtimeUs); 11984 mVideoOnTimer.reset(false, elapsedRealtimeUs); 11985 mFlashlightOnTimer.reset(false, elapsedRealtimeUs); 11986 mCameraOnTimer.reset(false, elapsedRealtimeUs); 11987 mBluetoothScanTimer.reset(false, elapsedRealtimeUs); 11988 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 11989 mPhoneSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 11990 } 11991 mPhoneSignalScanningTimer.reset(false, elapsedRealtimeUs); 11992 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11993 mPhoneDataConnectionsTimer[i].reset(false, elapsedRealtimeUs); 11994 } 11995 mNrNsaTimer.reset(false, elapsedRealtimeUs); 11996 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11997 mNetworkByteActivityCounters[i].reset(false, elapsedRealtimeUs); 11998 mNetworkPacketActivityCounters[i].reset(false, elapsedRealtimeUs); 11999 } 12000 for (int i = 0; i < RADIO_ACCESS_TECHNOLOGY_COUNT; i++) { 12001 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[i]; 12002 if (stats == null) continue; 12003 stats.reset(elapsedRealtimeUs); 12004 } 12005 mMobileRadioActiveTimer.reset(false, elapsedRealtimeUs); 12006 mMobileRadioActivePerAppTimer.reset(false, elapsedRealtimeUs); 12007 mMobileRadioActiveAdjustedTime.reset(false, elapsedRealtimeUs); 12008 mMobileRadioActiveUnknownTime.reset(false, elapsedRealtimeUs); 12009 mMobileRadioActiveUnknownCount.reset(false, elapsedRealtimeUs); 12010 mWifiOnTimer.reset(false, elapsedRealtimeUs); 12011 mGlobalWifiRunningTimer.reset(false, elapsedRealtimeUs); 12012 for (int i=0; i<NUM_WIFI_STATES; i++) { 12013 mWifiStateTimer[i].reset(false, elapsedRealtimeUs); 12014 } 12015 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 12016 mWifiSupplStateTimer[i].reset(false, elapsedRealtimeUs); 12017 } 12018 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 12019 mWifiSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 12020 } 12021 mWifiMulticastWakelockTimer.reset(false, elapsedRealtimeUs); 12022 mWifiActiveTimer.reset(false, elapsedRealtimeUs); 12023 mWifiActivity.reset(false, elapsedRealtimeUs); 12024 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 12025 mGpsSignalQualityTimer[i].reset(false, elapsedRealtimeUs); 12026 } 12027 mBluetoothActivity.reset(false, elapsedRealtimeUs); 12028 mModemActivity.reset(false, elapsedRealtimeUs); 12029 mNumConnectivityChange = 0; 12030 12031 for (int i=0; i<mUidStats.size(); i++) { 12032 if (mUidStats.valueAt(i).reset(uptimeUs, elapsedRealtimeUs, resetReason)) { 12033 mUidStats.valueAt(i).detachFromTimeBase(); 12034 mUidStats.remove(mUidStats.keyAt(i)); 12035 i--; 12036 } 12037 } 12038 12039 if (mRpmStats.size() > 0) { 12040 for (SamplingTimer timer : mRpmStats.values()) { 12041 mOnBatteryTimeBase.remove(timer); 12042 } 12043 mRpmStats.clear(); 12044 } 12045 if (mScreenOffRpmStats.size() > 0) { 12046 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 12047 mOnBatteryScreenOffTimeBase.remove(timer); 12048 } 12049 mScreenOffRpmStats.clear(); 12050 } 12051 12052 if (mKernelWakelockStats.size() > 0) { 12053 for (SamplingTimer timer : mKernelWakelockStats.values()) { 12054 mOnBatteryScreenOffTimeBase.remove(timer); 12055 } 12056 mKernelWakelockStats.clear(); 12057 } 12058 12059 if (mKernelMemoryStats.size() > 0) { 12060 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 12061 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 12062 } 12063 mKernelMemoryStats.clear(); 12064 } 12065 12066 if (mWakeupReasonStats.size() > 0) { 12067 for (SamplingTimer timer : mWakeupReasonStats.values()) { 12068 mOnBatteryTimeBase.remove(timer); 12069 } 12070 mWakeupReasonStats.clear(); 12071 } 12072 12073 if (mTmpRailStats != null) { 12074 mTmpRailStats.reset(); 12075 } 12076 12077 EnergyConsumerStats.resetIfNotNull(mGlobalEnergyConsumerStats); 12078 12079 if (!Flags.disableSystemServicePowerAttr()) { 12080 resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs); 12081 } 12082 12083 mNumAllUidCpuTimeReads = 0; 12084 mNumUidsRemoved = 0; 12085 12086 initDischarge(elapsedRealtimeUs); 12087 12088 mHistory.reset(); 12089 12090 // Store the empty state to disk to ensure consistency 12091 writeSyncLocked(); 12092 12093 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 12094 schedulePowerStatsSampleCollection(); 12095 } 12096 12097 // Flush external data, gathering snapshots, but don't process it since it is pre-reset data 12098 mIgnoreNextExternalStats = true; 12099 mExternalSync.scheduleSync("reset", ExternalStatsSync.UPDATE_ON_RESET); 12100 12101 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 12102 } 12103 saveBatteryUsageStatsOnReset(int resetReason)12104 private void saveBatteryUsageStatsOnReset(int resetReason) { 12105 if (!mSaveBatteryUsageStatsOnReset 12106 || resetReason == BatteryStatsImpl.RESET_REASON_CORRUPT_FILE) { 12107 return; 12108 } 12109 12110 final BatteryUsageStats batteryUsageStats; 12111 synchronized (this) { 12112 batteryUsageStats = mBatteryUsageStatsProvider.getBatteryUsageStats(this, 12113 new BatteryUsageStatsQuery.Builder() 12114 .setMaxStatsAgeMs(0) 12115 .includePowerModels() 12116 .includeProcessStateData() 12117 .build()); 12118 } 12119 12120 // TODO(b/188068523): BatteryUsageStats should use monotonic time for start and end 12121 // Once that change is made, we will be able to use the BatteryUsageStats' monotonic 12122 // start time 12123 long monotonicStartTime = 12124 mMonotonicClock.monotonicTime() - batteryUsageStats.getStatsDuration(); 12125 mHandler.post(() -> { 12126 mPowerStatsStore.storeBatteryUsageStats(monotonicStartTime, batteryUsageStats); 12127 try { 12128 batteryUsageStats.close(); 12129 } catch (IOException e) { 12130 Log.e(TAG, "Cannot close BatteryUsageStats", e); 12131 } 12132 }); 12133 } 12134 12135 @GuardedBy("this") initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)12136 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 12137 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 12138 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 12139 // Not recording process starts/stops. 12140 continue; 12141 } 12142 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 12143 if (active == null) { 12144 continue; 12145 } 12146 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 12147 SparseIntArray uids = ent.getValue(); 12148 for (int j=0; j<uids.size(); j++) { 12149 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 12150 uids.keyAt(j)); 12151 } 12152 } 12153 } 12154 } 12155 12156 @GuardedBy("this") updateDischargeScreenLevelsLocked(int oldState, int newState)12157 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 12158 updateOldDischargeScreenLevelLocked(oldState); 12159 updateNewDischargeScreenLevelLocked(newState); 12160 } 12161 12162 @GuardedBy("this") updateOldDischargeScreenLevelLocked(int state)12163 private void updateOldDischargeScreenLevelLocked(int state) { 12164 if (Display.isOnState(state)) { 12165 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 12166 if (diff > 0) { 12167 mDischargeAmountScreenOn += diff; 12168 mDischargeAmountScreenOnSinceCharge += diff; 12169 } 12170 } else if (Display.isDozeState(state)) { 12171 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 12172 if (diff > 0) { 12173 mDischargeAmountScreenDoze += diff; 12174 mDischargeAmountScreenDozeSinceCharge += diff; 12175 } 12176 } else if (Display.isOffState(state)) { 12177 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 12178 if (diff > 0) { 12179 mDischargeAmountScreenOff += diff; 12180 mDischargeAmountScreenOffSinceCharge += diff; 12181 } 12182 } 12183 } 12184 12185 @GuardedBy("this") updateNewDischargeScreenLevelLocked(int state)12186 private void updateNewDischargeScreenLevelLocked(int state) { 12187 if (Display.isOnState(state)) { 12188 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 12189 mDischargeScreenOffUnplugLevel = 0; 12190 mDischargeScreenDozeUnplugLevel = 0; 12191 } else if (Display.isDozeState(state)) { 12192 mDischargeScreenOnUnplugLevel = 0; 12193 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 12194 mDischargeScreenOffUnplugLevel = 0; 12195 } else if (Display.isOffState(state)) { 12196 mDischargeScreenOnUnplugLevel = 0; 12197 mDischargeScreenDozeUnplugLevel = 0; 12198 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 12199 } 12200 } 12201 12202 @GuardedBy("this") pullPendingStateUpdatesLocked()12203 public void pullPendingStateUpdatesLocked() { 12204 if (mOnBatteryInternal) { 12205 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 12206 } 12207 } 12208 12209 private final Object mWifiNetworkLock = new Object(); 12210 12211 @GuardedBy("mWifiNetworkLock") 12212 private String[] mWifiIfaces = EmptyArray.STRING; 12213 12214 @GuardedBy("mWifiNetworkLock") 12215 private NetworkStats mLastWifiNetworkStats; 12216 12217 private final Object mModemNetworkLock = new Object(); 12218 12219 @GuardedBy("mModemNetworkLock") 12220 private String[] mModemIfaces = EmptyArray.STRING; 12221 12222 @GuardedBy("mModemNetworkLock") 12223 private NetworkStats mLastModemNetworkStats; 12224 12225 @VisibleForTesting readMobileNetworkStatsLocked( @onNull NetworkStatsManager networkStatsManager)12226 protected NetworkStats readMobileNetworkStatsLocked( 12227 @NonNull NetworkStatsManager networkStatsManager) { 12228 return networkStatsManager.getMobileUidStats(); 12229 } 12230 12231 @VisibleForTesting readWifiNetworkStatsLocked( @onNull NetworkStatsManager networkStatsManager)12232 protected NetworkStats readWifiNetworkStatsLocked( 12233 @NonNull NetworkStatsManager networkStatsManager) { 12234 return networkStatsManager.getWifiUidStats(); 12235 } 12236 12237 static class NetworkStatsDelta { 12238 int mUid; 12239 int mSet; 12240 long mRxBytes; 12241 long mRxPackets; 12242 long mTxBytes; 12243 long mTxPackets; 12244 getUid()12245 public int getUid() { 12246 return mUid; 12247 } 12248 12249 getSet()12250 public int getSet() { 12251 return mSet; 12252 } 12253 getRxBytes()12254 public long getRxBytes() { 12255 return mRxBytes; 12256 } 12257 getRxPackets()12258 public long getRxPackets() { 12259 return mRxPackets; 12260 } 12261 getTxBytes()12262 public long getTxBytes() { 12263 return mTxBytes; 12264 } 12265 getTxPackets()12266 public long getTxPackets() { 12267 return mTxPackets; 12268 } 12269 12270 @Override toString()12271 public String toString() { 12272 return "NetworkStatsDelta{mUid=" + mUid + ", mSet=" + mSet + ", mRxBytes=" + mRxBytes 12273 + ", mRxPackets=" + mRxPackets + ", mTxBytes=" + mTxBytes + ", mTxPackets=" 12274 + mTxPackets + '}'; 12275 } 12276 } 12277 computeDelta(NetworkStats currentStats, NetworkStats lastStats)12278 static List<NetworkStatsDelta> computeDelta(NetworkStats currentStats, 12279 NetworkStats lastStats) { 12280 List<NetworkStatsDelta> deltaList = new ArrayList<>(); 12281 for (NetworkStats.Entry entry : currentStats) { 12282 NetworkStatsDelta delta = new NetworkStatsDelta(); 12283 delta.mUid = entry.getUid(); 12284 delta.mSet = entry.getSet(); 12285 NetworkStats.Entry lastEntry = null; 12286 if (lastStats != null) { 12287 for (NetworkStats.Entry e : lastStats) { 12288 if (e.getUid() == entry.getUid() && e.getSet() == entry.getSet() 12289 && e.getTag() == entry.getTag() 12290 && e.getMetered() == entry.getMetered() 12291 && e.getRoaming() == entry.getRoaming() 12292 && e.getDefaultNetwork() == entry.getDefaultNetwork() 12293 /*&& Objects.equals(e.getIface(), entry.getIface())*/) { 12294 lastEntry = e; 12295 break; 12296 } 12297 } 12298 } 12299 if (lastEntry != null) { 12300 delta.mRxBytes = Math.max(0, entry.getRxBytes() - lastEntry.getRxBytes()); 12301 delta.mRxPackets = Math.max(0, entry.getRxPackets() - lastEntry.getRxPackets()); 12302 delta.mTxBytes = Math.max(0, entry.getTxBytes() - lastEntry.getTxBytes()); 12303 delta.mTxPackets = Math.max(0, entry.getTxPackets() - lastEntry.getTxPackets()); 12304 } else { 12305 delta.mRxBytes = entry.getRxBytes(); 12306 delta.mRxPackets = entry.getRxPackets(); 12307 delta.mTxBytes = entry.getTxBytes(); 12308 delta.mTxPackets = entry.getTxPackets(); 12309 } 12310 deltaList.add(delta); 12311 } 12312 12313 return deltaList; 12314 } 12315 12316 /** 12317 * Distribute WiFi energy info and network traffic to apps. 12318 * @param info The energy information from the WiFi controller. 12319 */ 12320 @GuardedBy("this") updateWifiState(@ullable final WifiActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, @NonNull NetworkStatsManager networkStatsManager)12321 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info, 12322 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, 12323 @NonNull NetworkStatsManager networkStatsManager) { 12324 if (mWifiPowerStatsCollector.isEnabled()) { 12325 return; 12326 } 12327 12328 if (DEBUG_ENERGY) { 12329 synchronized (mWifiNetworkLock) { 12330 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 12331 } 12332 } 12333 12334 // Grab a separate lock to acquire the network stats, which may do I/O. 12335 List<NetworkStatsDelta> delta; 12336 synchronized (mWifiNetworkLock) { 12337 final NetworkStats latestStats = readWifiNetworkStatsLocked(networkStatsManager); 12338 if (latestStats != null) { 12339 delta = computeDelta(latestStats, mLastWifiNetworkStats); 12340 mLastWifiNetworkStats = latestStats; 12341 } else { 12342 delta = null; 12343 } 12344 } 12345 12346 synchronized (this) { 12347 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12348 if (mIgnoreNextExternalStats) { 12349 // TODO: Strictly speaking, we should re-mark all 5 timers for each uid (and the 12350 // global one) here like we do for display. But I'm not sure it's worth the 12351 // complicated code for a codepath that shouldn't ever actually happen in real 12352 // life. 12353 } 12354 return; 12355 } 12356 12357 final SparseDoubleArray uidEstimatedConsumptionMah = 12358 (mGlobalEnergyConsumerStats != null 12359 && mWifiPowerCalculator != null && consumedChargeUC > 0) ? 12360 new SparseDoubleArray() : null; 12361 double totalEstimatedConsumptionMah = 0; 12362 12363 SparseLongArray rxPackets = new SparseLongArray(); 12364 SparseLongArray txPackets = new SparseLongArray(); 12365 SparseLongArray rxTimesMs = new SparseLongArray(); 12366 SparseLongArray txTimesMs = new SparseLongArray(); 12367 long totalTxPackets = 0; 12368 long totalRxPackets = 0; 12369 if (delta != null) { 12370 for (NetworkStatsDelta entry : delta) { 12371 if (DEBUG_ENERGY) { 12372 Slog.d(TAG, "Wifi uid " + entry.getUid() 12373 + ": delta rx=" + entry.getRxBytes() 12374 + " tx=" + entry.getTxBytes() 12375 + " rxPackets=" + entry.getRxPackets() 12376 + " txPackets=" + entry.getTxPackets()); 12377 } 12378 12379 if (entry.getRxBytes() == 0 && entry.getTxBytes() == 0) { 12380 // Skip the lookup below since there is no work to do. 12381 continue; 12382 } 12383 12384 final int uid = mapUid(entry.getUid()); 12385 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 12386 if (entry.getRxBytes() != 0) { 12387 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.getRxBytes(), 12388 entry.getRxPackets()); 12389 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 12390 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.getRxBytes(), 12391 entry.getRxPackets()); 12392 } 12393 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 12394 entry.getRxBytes()); 12395 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 12396 entry.getRxPackets()); 12397 12398 rxPackets.incrementValue(uid, entry.getRxPackets()); 12399 12400 // Sum the total number of packets so that the Rx Power can 12401 // be evenly distributed amongst the apps. 12402 totalRxPackets += entry.getRxPackets(); 12403 } 12404 12405 if (entry.getTxBytes() != 0) { 12406 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.getTxBytes(), 12407 entry.getTxPackets()); 12408 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 12409 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.getTxBytes(), 12410 entry.getTxPackets()); 12411 } 12412 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 12413 entry.getTxBytes()); 12414 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 12415 entry.getTxPackets()); 12416 12417 txPackets.incrementValue(uid, entry.getTxPackets()); 12418 12419 // Sum the total number of packets so that the Tx Power can 12420 // be evenly distributed amongst the apps. 12421 totalTxPackets += entry.getTxPackets(); 12422 } 12423 12424 // Calculate consumed energy for this uid. Only do so if WifiReporting isn't 12425 // enabled (if it is, we'll do it later instead using info). 12426 if (uidEstimatedConsumptionMah != null && info == null && !mHasWifiReporting) { 12427 final long uidRunningMs = u.mWifiRunningTimer 12428 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12429 if (uidRunningMs > 0) u.mWifiRunningTimer.setMark(elapsedRealtimeMs); 12430 12431 final long uidScanMs = u.mWifiScanTimer 12432 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12433 if (uidScanMs > 0) u.mWifiScanTimer.setMark(elapsedRealtimeMs); 12434 12435 long uidBatchScanMs = 0; 12436 for (int bn = 0; bn < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bn++) { 12437 if (u.mWifiBatchedScanTimer[bn] != null) { 12438 long bnMs = u.mWifiBatchedScanTimer[bn] 12439 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12440 if (bnMs > 0) { 12441 u.mWifiBatchedScanTimer[bn].setMark(elapsedRealtimeMs); 12442 } 12443 uidBatchScanMs += bnMs; 12444 } 12445 } 12446 12447 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 12448 mWifiPowerCalculator.calcPowerWithoutControllerDataMah( 12449 entry.getRxPackets(), entry.getTxPackets(), 12450 uidRunningMs, uidScanMs, uidBatchScanMs)); 12451 } 12452 } 12453 delta = null; 12454 } 12455 12456 if (info != null) { 12457 mHasWifiReporting = true; 12458 12459 // Measured in mAms 12460 final long txTimeMs = info.getControllerTxDurationMillis(); 12461 final long rxTimeMs = info.getControllerRxDurationMillis(); 12462 final long scanTimeMs = info.getControllerScanDurationMillis(); 12463 final long idleTimeMs = info.getControllerIdleDurationMillis(); 12464 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 12465 12466 long leftOverRxTimeMs = rxTimeMs; 12467 long leftOverTxTimeMs = txTimeMs; 12468 12469 if (DEBUG_ENERGY) { 12470 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 12471 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 12472 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 12473 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 12474 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 12475 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 12476 } 12477 12478 long totalWifiLockTimeMs = 0; 12479 long totalScanTimeMs = 0; 12480 12481 // On the first pass, collect some totals so that we can normalize power 12482 // calculations if we need to. 12483 final int uidStatsSize = mUidStats.size(); 12484 for (int i = 0; i < uidStatsSize; i++) { 12485 final Uid uid = mUidStats.valueAt(i); 12486 12487 // Sum the total scan power for all apps. 12488 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 12489 elapsedRealtimeMs * 1000) / 1000; 12490 12491 // Sum the total time holding wifi lock for all apps. 12492 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 12493 elapsedRealtimeMs * 1000) / 1000; 12494 } 12495 12496 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 12497 Slog.d(TAG, 12498 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 12499 + rxTimeMs + " ms). Normalizing scan time."); 12500 } 12501 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 12502 Slog.d(TAG, 12503 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 12504 + txTimeMs + " ms). Normalizing scan time."); 12505 } 12506 12507 // Actually assign and distribute power usage to apps. 12508 for (int i = 0; i < uidStatsSize; i++) { 12509 final Uid uid = mUidStats.valueAt(i); 12510 12511 final long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 12512 elapsedRealtimeMs * 1000) / 1000; 12513 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 12514 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 12515 if (scanTimeSinceMarkMs > 0) { 12516 // Set the new mark so that next time we get new data since this point. 12517 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 12518 12519 // Our total scan time is more than the reported Tx/Rx time. 12520 // This is possible because the cost of a scan is approximate. 12521 // Let's normalize the result so that we evenly blame each app 12522 // scanning. 12523 // 12524 // This means that we may have apps that transmitted/received packets not be 12525 // blamed for this, but this is fine as scans are relatively more expensive. 12526 if (totalScanTimeMs > rxTimeMs) { 12527 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 12528 totalScanTimeMs; 12529 } 12530 if (totalScanTimeMs > txTimeMs) { 12531 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 12532 totalScanTimeMs; 12533 } 12534 12535 if (DEBUG_ENERGY) { 12536 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 12537 + scanRxTimeSinceMarkMs + " ms Tx:" 12538 + scanTxTimeSinceMarkMs + " ms)"); 12539 } 12540 12541 rxTimesMs.incrementValue(uid.getUid(), scanRxTimeSinceMarkMs); 12542 txTimesMs.incrementValue(uid.getUid(), scanTxTimeSinceMarkMs); 12543 12544 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 12545 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 12546 } 12547 12548 // Distribute evenly the power consumed while Idle to each app holding a WiFi 12549 // lock. 12550 long myIdleTimeMs = 0; 12551 final long wifiLockTimeSinceMarkMs = 12552 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 12553 elapsedRealtimeMs * 1000) / 1000; 12554 if (wifiLockTimeSinceMarkMs > 0) { 12555 // Set the new mark so that next time we get new data since this point. 12556 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 12557 12558 myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) / totalWifiLockTimeMs; 12559 if (DEBUG_ENERGY) { 12560 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 12561 + myIdleTimeMs + " ms"); 12562 } 12563 uid.getOrCreateWifiControllerActivityLocked().getOrCreateIdleTimeCounter() 12564 .increment(myIdleTimeMs, elapsedRealtimeMs); 12565 } 12566 12567 if (uidEstimatedConsumptionMah != null) { 12568 double uidEstMah = mWifiPowerCalculator.calcPowerFromControllerDataMah( 12569 scanRxTimeSinceMarkMs, scanTxTimeSinceMarkMs, myIdleTimeMs); 12570 uidEstimatedConsumptionMah.incrementValue(uid.getUid(), uidEstMah); 12571 } 12572 } 12573 12574 if (DEBUG_ENERGY) { 12575 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 12576 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 12577 } 12578 12579 // Distribute the remaining Tx power appropriately between all apps that transmitted 12580 // packets. 12581 for (int i = 0; i < txPackets.size(); i++) { 12582 final int uid = txPackets.keyAt(i); 12583 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 12584 / totalTxPackets; 12585 txTimesMs.incrementValue(uid, myTxTimeMs); 12586 } 12587 12588 // Distribute the remaining Rx power appropriately between all apps that received 12589 // packets. 12590 for (int i = 0; i < rxPackets.size(); i++) { 12591 final int uid = rxPackets.keyAt(i); 12592 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 12593 / totalRxPackets; 12594 rxTimesMs.incrementValue(uid, myRxTimeMs); 12595 } 12596 12597 for (int i = 0; i < txTimesMs.size(); i++) { 12598 final int uid = txTimesMs.keyAt(i); 12599 final long myTxTimeMs = txTimesMs.valueAt(i); 12600 if (DEBUG_ENERGY) { 12601 Slog.d(TAG, " TxTime for UID " + uid + ": " + myTxTimeMs + " ms"); 12602 } 12603 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 12604 .getOrCreateWifiControllerActivityLocked() 12605 .getOrCreateTxTimeCounters()[0] 12606 .increment(myTxTimeMs, elapsedRealtimeMs); 12607 if (uidEstimatedConsumptionMah != null) { 12608 uidEstimatedConsumptionMah.incrementValue(uid, 12609 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12610 0, myTxTimeMs, 0)); 12611 } 12612 } 12613 12614 for (int i = 0; i < rxTimesMs.size(); i++) { 12615 final int uid = rxTimesMs.keyAt(i); 12616 final long myRxTimeMs = rxTimesMs.valueAt(i); 12617 if (DEBUG_ENERGY) { 12618 Slog.d(TAG, " RxTime for UID " + uid + ": " + myRxTimeMs + " ms"); 12619 } 12620 12621 getUidStatsLocked(rxTimesMs.keyAt(i), elapsedRealtimeMs, uptimeMs) 12622 .getOrCreateWifiControllerActivityLocked() 12623 .getOrCreateRxTimeCounter() 12624 .increment(myRxTimeMs, elapsedRealtimeMs); 12625 if (uidEstimatedConsumptionMah != null) { 12626 uidEstimatedConsumptionMah.incrementValue(uid, 12627 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12628 myRxTimeMs, 0, 0)); 12629 } 12630 } 12631 12632 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 12633 12634 // Update WiFi controller stats. 12635 mWifiActivity.getOrCreateRxTimeCounter().increment( 12636 info.getControllerRxDurationMillis(), elapsedRealtimeMs); 12637 mWifiActivity.getOrCreateTxTimeCounters()[0].increment( 12638 info.getControllerTxDurationMillis(), elapsedRealtimeMs); 12639 mWifiActivity.getScanTimeCounter().addCountLocked( 12640 info.getControllerScanDurationMillis()); 12641 mWifiActivity.getOrCreateIdleTimeCounter().increment( 12642 info.getControllerIdleDurationMillis(), elapsedRealtimeMs); 12643 12644 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12645 final double opVolt = mPowerProfile.getAveragePower( 12646 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12647 double controllerMaMs = 0; 12648 if (opVolt != 0) { 12649 // We store the power drain as mAms. 12650 controllerMaMs = info.getControllerEnergyUsedMicroJoules() / opVolt; 12651 mWifiActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 12652 } 12653 // Converting uWs to mAms. 12654 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 12655 long monitoredRailChargeConsumedMaMs = mTmpRailStats != null 12656 ? (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt) 12657 : 0L; 12658 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 12659 monitoredRailChargeConsumedMaMs); 12660 mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs, 12661 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR)); 12662 if (mTmpRailStats != null) { 12663 mTmpRailStats.resetWifiTotalEnergyUsed(); 12664 } 12665 12666 if (uidEstimatedConsumptionMah != null) { 12667 totalEstimatedConsumptionMah = Math.max(controllerMaMs / MILLISECONDS_IN_HOUR, 12668 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12669 rxTimeMs, txTimeMs, idleTimeMs)); 12670 } 12671 } 12672 12673 // Update the EnergyConsumerStats information. 12674 if (uidEstimatedConsumptionMah != null) { 12675 mGlobalEnergyConsumerStats.updateStandardBucket( 12676 EnergyConsumerStats.POWER_BUCKET_WIFI, consumedChargeUC); 12677 12678 // Now calculate the consumption for each uid, according to its proportional usage. 12679 if (!mHasWifiReporting) { 12680 final long globalTimeMs = mGlobalWifiRunningTimer 12681 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12682 mGlobalWifiRunningTimer.setMark(elapsedRealtimeMs); 12683 totalEstimatedConsumptionMah = mWifiPowerCalculator 12684 .calcGlobalPowerWithoutControllerDataMah(globalTimeMs); 12685 } 12686 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_WIFI, 12687 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedConsumptionMah, 12688 elapsedRealtimeMs); 12689 } 12690 } 12691 } 12692 12693 private ModemActivityInfo mLastModemActivityInfo = null; 12694 12695 /** 12696 * Distribute Cell radio energy info and network traffic to apps. 12697 */ noteModemControllerActivity(@ullable final ModemActivityInfo activityInfo, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, @NonNull NetworkStatsManager networkStatsManager)12698 public void noteModemControllerActivity(@Nullable final ModemActivityInfo activityInfo, 12699 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, 12700 @NonNull NetworkStatsManager networkStatsManager) { 12701 if (DEBUG_ENERGY) { 12702 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 12703 } 12704 ModemActivityInfo deltaInfo = mLastModemActivityInfo == null 12705 ? (activityInfo == null ? null : activityInfo.getDelta(activityInfo)) 12706 : mLastModemActivityInfo.getDelta(activityInfo); 12707 mLastModemActivityInfo = activityInfo; 12708 12709 // Add modem tx power to history. 12710 addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs); 12711 12712 // Grab a separate lock to acquire the network stats, which may do I/O. 12713 List<NetworkStatsDelta> delta = null; 12714 synchronized (mModemNetworkLock) { 12715 final NetworkStats latestStats = readMobileNetworkStatsLocked(networkStatsManager); 12716 if (latestStats != null) { 12717 delta = computeDelta(latestStats, mLastModemNetworkStats); 12718 mLastModemNetworkStats = latestStats; 12719 } 12720 } 12721 12722 synchronized (this) { 12723 final long totalRadioDurationMs = 12724 mMobileRadioActiveTimer.getTimeSinceMarkLocked( 12725 elapsedRealtimeMs * 1000) / 1000; 12726 mMobileRadioActiveTimer.setMark(elapsedRealtimeMs); 12727 final long phoneOnDurationMs = Math.min(totalRadioDurationMs, 12728 mPhoneOnTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000); 12729 mPhoneOnTimer.setMark(elapsedRealtimeMs); 12730 12731 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12732 return; 12733 } 12734 12735 final SparseDoubleArray uidEstimatedConsumptionMah; 12736 final long dataConsumedChargeUC; 12737 if (consumedChargeUC > 0 && isMobileRadioEnergyConsumerSupportedLocked()) { 12738 final long phoneConsumedChargeUC; 12739 if (totalRadioDurationMs == 0) { 12740 phoneConsumedChargeUC = 0; 12741 } else { 12742 // Crudely attribute power consumption. Added (totalRadioDurationMs / 2) to the 12743 // numerator for long rounding. 12744 phoneConsumedChargeUC = 12745 (consumedChargeUC * phoneOnDurationMs + totalRadioDurationMs / 2) 12746 / totalRadioDurationMs; 12747 } 12748 dataConsumedChargeUC = consumedChargeUC - phoneConsumedChargeUC; 12749 12750 mGlobalEnergyConsumerStats.updateStandardBucket( 12751 EnergyConsumerStats.POWER_BUCKET_PHONE, phoneConsumedChargeUC); 12752 mGlobalEnergyConsumerStats.updateStandardBucket( 12753 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, dataConsumedChargeUC); 12754 uidEstimatedConsumptionMah = new SparseDoubleArray(); 12755 } else { 12756 uidEstimatedConsumptionMah = null; 12757 dataConsumedChargeUC = POWER_DATA_UNAVAILABLE; 12758 } 12759 12760 RxTxConsumption rxTxConsumption = null; 12761 boolean attributeWithModemActivityInfo = false; 12762 if (deltaInfo != null) { 12763 mHasModemReporting = true; 12764 mModemActivity.getOrCreateIdleTimeCounter() 12765 .increment(deltaInfo.getIdleTimeMillis(), elapsedRealtimeMs); 12766 mModemActivity.getSleepTimeCounter().addCountLocked( 12767 deltaInfo.getSleepTimeMillis()); 12768 mModemActivity.getOrCreateRxTimeCounter() 12769 .increment(deltaInfo.getReceiveTimeMillis(), elapsedRealtimeMs); 12770 for (int lvl = 0; lvl < MODEM_TX_POWER_LEVEL_COUNT; lvl++) { 12771 mModemActivity.getOrCreateTxTimeCounters()[lvl] 12772 .increment(deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl), 12773 elapsedRealtimeMs); 12774 } 12775 12776 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12777 final double opVolt = mPowerProfile.getAveragePower( 12778 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12779 if (opVolt != 0) { 12780 double energyUsed = 12781 deltaInfo.getSleepTimeMillis() * 12782 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 12783 + deltaInfo.getIdleTimeMillis() * 12784 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 12785 + deltaInfo.getReceiveTimeMillis() * 12786 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 12787 for (int i = 0; i < Math.min(MODEM_TX_POWER_LEVEL_COUNT, 12788 CELL_SIGNAL_STRENGTH_LEVEL_COUNT); i++) { 12789 energyUsed += deltaInfo.getTransmitDurationMillisAtPowerLevel(i) 12790 * mPowerProfile.getAveragePower( 12791 PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 12792 } 12793 12794 // We store the power drain as mAms. 12795 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 12796 // Converting uWs to mAms. 12797 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 12798 long monitoredRailChargeConsumedMaMs = 12799 (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt); 12800 mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 12801 monitoredRailChargeConsumedMaMs); 12802 mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs, 12803 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR)); 12804 mTmpRailStats.resetCellularTotalEnergyUsed(); 12805 } 12806 12807 rxTxConsumption = incrementPerRatDataLocked(deltaInfo, elapsedRealtimeMs); 12808 12809 attributeWithModemActivityInfo = mConstants.PER_UID_MODEM_MODEL 12810 == PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX 12811 && rxTxConsumption != null; 12812 } 12813 long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 12814 elapsedRealtimeMs * 1000); 12815 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 12816 12817 long totalRxPackets = 0; 12818 long totalTxPackets = 0; 12819 if (delta != null) { 12820 for (NetworkStatsDelta entry : delta) { 12821 if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { 12822 continue; 12823 } 12824 12825 if (DEBUG_ENERGY) { 12826 Slog.d(TAG, "Mobile uid " + entry.getUid() + ": delta rx=" 12827 + entry.getRxBytes() + " tx=" + entry.getTxBytes() 12828 + " rxPackets=" + entry.getRxPackets() 12829 + " txPackets=" + entry.getTxPackets()); 12830 } 12831 12832 totalRxPackets += entry.getRxPackets(); 12833 totalTxPackets += entry.getTxPackets(); 12834 12835 final Uid u = getUidStatsLocked( 12836 mapUid(entry.getUid()), elapsedRealtimeMs, uptimeMs); 12837 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.getRxBytes(), 12838 entry.getRxPackets()); 12839 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.getTxBytes(), 12840 entry.getTxPackets()); 12841 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 12842 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 12843 entry.getRxBytes(), entry.getRxPackets()); 12844 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 12845 entry.getTxBytes(), entry.getTxPackets()); 12846 } 12847 12848 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 12849 entry.getRxBytes()); 12850 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12851 entry.getTxBytes()); 12852 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 12853 entry.getRxPackets()); 12854 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12855 entry.getTxPackets()); 12856 } 12857 12858 // Now distribute proportional blame to the apps that did networking. 12859 long totalPackets = totalRxPackets + totalTxPackets; 12860 if (totalPackets > 0) { 12861 for (NetworkStatsDelta entry : delta) { 12862 if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { 12863 continue; 12864 } 12865 12866 final Uid u = getUidStatsLocked(mapUid(entry.getUid()), 12867 elapsedRealtimeMs, uptimeMs); 12868 12869 // Distribute total radio active time in to this app. 12870 final long appPackets = entry.getRxPackets() + entry.getTxPackets(); 12871 final long appRadioTimeUs = 12872 (totalAppRadioTimeUs * appPackets) / totalPackets; 12873 u.noteMobileRadioActiveTimeLocked(appRadioTimeUs, elapsedRealtimeMs); 12874 12875 if (uidEstimatedConsumptionMah != null) { 12876 final double uidConsumptionMah; 12877 if (attributeWithModemActivityInfo) { 12878 // Distribute measured mobile radio charge consumption based on 12879 // rx/tx packets and estimated rx/tx charge consumption. 12880 uidConsumptionMah = smearModemActivityInfoRxTxConsumptionMah( 12881 rxTxConsumption, entry.getRxPackets(), entry.getTxPackets(), 12882 totalRxPackets, totalTxPackets); 12883 } else { 12884 // Distribute mobile radio charge consumption based on app radio 12885 // active time 12886 uidConsumptionMah = 12887 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12888 appRadioTimeUs / 1000); 12889 } 12890 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 12891 uidConsumptionMah); 12892 } 12893 12894 // Remove this app from the totals, so that we don't lose any time 12895 // due to rounding. 12896 totalAppRadioTimeUs -= appRadioTimeUs; 12897 totalPackets -= appPackets; 12898 12899 if (deltaInfo != null) { 12900 ControllerActivityCounterImpl activityCounter = 12901 u.getOrCreateModemControllerActivityLocked(); 12902 if (totalRxPackets > 0 && entry.getRxPackets() > 0) { 12903 final long rxMs = (entry.getRxPackets() 12904 * deltaInfo.getReceiveTimeMillis()) / totalRxPackets; 12905 activityCounter.getOrCreateRxTimeCounter() 12906 .increment(rxMs, elapsedRealtimeMs); 12907 } 12908 12909 if (totalTxPackets > 0 && entry.getTxPackets() > 0) { 12910 for (int lvl = 0; lvl < MODEM_TX_POWER_LEVEL_COUNT; 12911 lvl++) { 12912 long txMs = entry.getTxPackets() 12913 * deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl); 12914 txMs /= totalTxPackets; 12915 activityCounter.getOrCreateTxTimeCounters()[lvl] 12916 .increment(txMs, elapsedRealtimeMs); 12917 } 12918 } 12919 } 12920 } 12921 } 12922 12923 if (totalAppRadioTimeUs > 0) { 12924 // Whoops, there is some radio time we can't blame on an app! 12925 mMobileRadioActiveUnknownTime.addCountLocked(totalAppRadioTimeUs); 12926 mMobileRadioActiveUnknownCount.addCountLocked(1); 12927 } 12928 12929 // Update the EnergyConsumerStats information. 12930 if (uidEstimatedConsumptionMah != null) { 12931 double totalEstimatedConsumptionMah = 0.0; 12932 if (attributeWithModemActivityInfo) { 12933 // Estimate inactive modem power consumption and combine with previously 12934 // estimated active power consumption for an estimate of total modem 12935 // power consumption. 12936 final long sleepTimeMs = deltaInfo.getSleepTimeMillis(); 12937 final long idleTimeMs = deltaInfo.getIdleTimeMillis(); 12938 final double inactiveConsumptionMah = 12939 mMobileRadioPowerCalculator.calcInactiveStatePowerMah(sleepTimeMs, 12940 idleTimeMs); 12941 totalEstimatedConsumptionMah += inactiveConsumptionMah; 12942 totalEstimatedConsumptionMah += rxTxConsumption.rxConsumptionMah; 12943 totalEstimatedConsumptionMah += rxTxConsumption.txConsumptionMah; 12944 } else { 12945 // Estimate total active radio power consumption since last mark. 12946 totalEstimatedConsumptionMah += 12947 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12948 totalRadioDurationMs); 12949 12950 // Estimate idle power consumption at each signal strength level 12951 final int numSignalStrengthLevels = mPhoneSignalStrengthsTimer.length; 12952 for (int lvl = 0; lvl < numSignalStrengthLevels; lvl++) { 12953 final long strengthLevelDurationMs = 12954 mPhoneSignalStrengthsTimer[lvl].getTimeSinceMarkLocked( 12955 elapsedRealtimeMs * 1000) / 1000; 12956 mPhoneSignalStrengthsTimer[lvl].setMark(elapsedRealtimeMs); 12957 12958 totalEstimatedConsumptionMah += 12959 mMobileRadioPowerCalculator.calcIdlePowerAtSignalStrengthMah( 12960 strengthLevelDurationMs, lvl); 12961 } 12962 12963 // Estimate total active radio power consumption since last mark. 12964 final long scanTimeMs = mPhoneSignalScanningTimer.getTimeSinceMarkLocked( 12965 elapsedRealtimeMs * 1000) / 1000; 12966 mPhoneSignalScanningTimer.setMark(elapsedRealtimeMs); 12967 totalEstimatedConsumptionMah += 12968 mMobileRadioPowerCalculator.calcScanTimePowerMah(scanTimeMs); 12969 } 12970 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 12971 dataConsumedChargeUC, uidEstimatedConsumptionMah, 12972 totalEstimatedConsumptionMah, elapsedRealtimeMs); 12973 } 12974 } 12975 } 12976 } 12977 12978 private static class RxTxConsumption { 12979 public final double rxConsumptionMah; 12980 public final long rxDurationMs; 12981 public final double txConsumptionMah; 12982 public final long txDurationMs; 12983 12984 /** 12985 * Represents the ratio between time spent transmitting and the total active time. 12986 */ 12987 public final double txToTotalRatio; 12988 RxTxConsumption(double rxMah, long rxMs, double txMah, long txMs)12989 RxTxConsumption(double rxMah, long rxMs, double txMah, long txMs) { 12990 rxConsumptionMah = rxMah; 12991 rxDurationMs = rxMs; 12992 txConsumptionMah = txMah; 12993 txDurationMs = txMs; 12994 12995 final long activeDurationMs = txDurationMs + rxDurationMs; 12996 if (activeDurationMs == 0) { 12997 txToTotalRatio = 0.0; 12998 } else { 12999 txToTotalRatio = ((double) txDurationMs) / activeDurationMs; 13000 } 13001 } 13002 } 13003 13004 @GuardedBy("this") 13005 @Nullable incrementPerRatDataLocked(ModemActivityInfo deltaInfo, long elapsedRealtimeMs)13006 private RxTxConsumption incrementPerRatDataLocked(ModemActivityInfo deltaInfo, 13007 long elapsedRealtimeMs) { 13008 double rxConsumptionMah = 0.0; 13009 long rxDurationMs = 0; 13010 double txConsumptionMah = 0.0; 13011 long txDurationMs = 0; 13012 13013 final int infoSize = deltaInfo.getSpecificInfoLength(); 13014 if (infoSize == 1 && deltaInfo.getSpecificInfoRat(0) 13015 == AccessNetworkConstants.AccessNetworkType.UNKNOWN 13016 && deltaInfo.getSpecificInfoFrequencyRange(0) 13017 == ServiceState.FREQUENCY_RANGE_UNKNOWN) { 13018 // Specific info data unavailable. Proportionally smear Rx and Tx times across each RAT. 13019 final int levelCount = CELL_SIGNAL_STRENGTH_LEVEL_COUNT; 13020 long[] perSignalStrengthActiveTimeMs = new long[levelCount]; 13021 long totalActiveTimeMs = 0; 13022 13023 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13024 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13025 if (ratStats == null) continue; 13026 13027 final int freqCount = ratStats.getFrequencyRangeCount(); 13028 for (int freq = 0; freq < freqCount; freq++) { 13029 for (int level = 0; level < levelCount; level++) { 13030 final long durationMs = ratStats.getTimeSinceMark(freq, level, 13031 elapsedRealtimeMs); 13032 perSignalStrengthActiveTimeMs[level] += durationMs; 13033 totalActiveTimeMs += durationMs; 13034 } 13035 } 13036 } 13037 if (totalActiveTimeMs != 0) { 13038 // Smear the provided Tx/Rx durations across each RAT, frequency, and signal 13039 // strength. 13040 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13041 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13042 if (ratStats == null) continue; 13043 13044 final int freqCount = ratStats.getFrequencyRangeCount(); 13045 for (int freq = 0; freq < freqCount; freq++) { 13046 long frequencyDurationMs = 0; 13047 for (int level = 0; level < levelCount; level++) { 13048 final long durationMs = ratStats.getTimeSinceMark(freq, level, 13049 elapsedRealtimeMs); 13050 final long totalLvlDurationMs = 13051 perSignalStrengthActiveTimeMs[level]; 13052 if (totalLvlDurationMs == 0) continue; 13053 final long totalTxLvlDurations = 13054 deltaInfo.getTransmitDurationMillisAtPowerLevel(level); 13055 // Smear HAL provided Tx power level duration based on active modem 13056 // duration in a given state. (Add totalLvlDurationMs / 2 before 13057 // the integer division with totalLvlDurationMs for rounding.) 13058 final long proportionalTxDurationMs = 13059 (durationMs * totalTxLvlDurations 13060 + (totalLvlDurationMs / 2)) / totalLvlDurationMs; 13061 ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs); 13062 frequencyDurationMs += durationMs; 13063 13064 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13065 // Accumulate the power cost of time spent transmitting in a 13066 // particular state. 13067 final double txStatePowerConsumptionMah = 13068 mMobileRadioPowerCalculator.calcTxStatePowerMah(rat, freq, 13069 level, proportionalTxDurationMs); 13070 txConsumptionMah += txStatePowerConsumptionMah; 13071 txDurationMs += proportionalTxDurationMs; 13072 } 13073 } 13074 final long totalRxDuration = deltaInfo.getReceiveTimeMillis(); 13075 // Smear HAL provided Rx power duration based on active modem 13076 // duration in a given state. (Add totalActiveTimeMs / 2 before the 13077 // integer division with totalActiveTimeMs for rounding.) 13078 final long proportionalRxDurationMs = 13079 (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs 13080 / 2)) / totalActiveTimeMs; 13081 ratStats.incrementRxDuration(freq, proportionalRxDurationMs); 13082 13083 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13084 // Accumulate the power cost of time spent receiving in a particular 13085 // state. 13086 final double rxStatePowerConsumptionMah = 13087 mMobileRadioPowerCalculator.calcRxStatePowerMah(rat, freq, 13088 proportionalRxDurationMs); 13089 rxConsumptionMah += rxStatePowerConsumptionMah; 13090 rxDurationMs += proportionalRxDurationMs; 13091 } 13092 } 13093 13094 } 13095 } 13096 } else { 13097 // Specific data available. 13098 for (int index = 0; index < infoSize; index++) { 13099 final int rat = deltaInfo.getSpecificInfoRat(index); 13100 final int freq = deltaInfo.getSpecificInfoFrequencyRange(index); 13101 13102 // Map RadioAccessNetworkType to course grain RadioAccessTechnology. 13103 final int ratBucket = mapRadioAccessNetworkTypeToRadioAccessTechnology(rat); 13104 final RadioAccessTechnologyBatteryStats ratStats = getRatBatteryStatsLocked( 13105 ratBucket); 13106 13107 final long rxTimeMs = deltaInfo.getReceiveTimeMillis(rat, freq); 13108 final int[] txTimesMs = deltaInfo.getTransmitTimeMillis(rat, freq); 13109 13110 ratStats.incrementRxDuration(freq, rxTimeMs); 13111 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13112 // Accumulate the power cost of time spent receiving in a particular state. 13113 final double rxStatePowerConsumptionMah = 13114 mMobileRadioPowerCalculator.calcRxStatePowerMah(ratBucket, freq, 13115 rxTimeMs); 13116 rxConsumptionMah += rxStatePowerConsumptionMah; 13117 rxDurationMs += rxTimeMs; 13118 } 13119 13120 final int numTxLvl = txTimesMs.length; 13121 for (int lvl = 0; lvl < numTxLvl; lvl++) { 13122 final long txTimeMs = txTimesMs[lvl]; 13123 ratStats.incrementTxDuration(freq, lvl, txTimeMs); 13124 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13125 // Accumulate the power cost of time spent transmitting in a particular 13126 // state. 13127 final double txStatePowerConsumptionMah = 13128 mMobileRadioPowerCalculator.calcTxStatePowerMah(ratBucket, freq, 13129 lvl, txTimeMs); 13130 txConsumptionMah += txStatePowerConsumptionMah; 13131 txDurationMs += txTimeMs; 13132 } 13133 } 13134 } 13135 } 13136 13137 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13138 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13139 if (ratStats == null) continue; 13140 ratStats.setMark(elapsedRealtimeMs); 13141 } 13142 13143 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13144 return new RxTxConsumption(rxConsumptionMah, rxDurationMs, txConsumptionMah, 13145 txDurationMs); 13146 } else { 13147 return null; 13148 } 13149 } 13150 13151 /** 13152 * Smear modem Rx/Tx power consumption calculated from {@link ModemActivityInfo} using Rx/Tx 13153 * packets. 13154 * 13155 * @return the combine Rx/Tx smeared power consumption in milliamp-hours. 13156 */ smearModemActivityInfoRxTxConsumptionMah(RxTxConsumption rxTxConsumption, long rxPackets, long txPackets, long totalRxPackets, long totalTxPackets)13157 private double smearModemActivityInfoRxTxConsumptionMah(RxTxConsumption rxTxConsumption, 13158 long rxPackets, long txPackets, long totalRxPackets, long totalTxPackets) { 13159 // Distribute measured mobile radio charge consumption based on 13160 // rx/tx packets and estimated rx/tx charge consumption. 13161 double consumptionMah = 0.0; 13162 if (totalRxPackets != 0) { 13163 // Proportionally distribute receive battery consumption. 13164 consumptionMah += rxTxConsumption.rxConsumptionMah * rxPackets 13165 / totalRxPackets; 13166 } 13167 if (totalTxPackets != 0 || (totalRxPackets != 0 && rxTxConsumption.txToTotalRatio != 0.0)) { 13168 // ModemActivityInfo Tx time represents time spent both transmitting and receiving. 13169 // There is currently no way to distinguish how many Rx packets were received during 13170 // Rx time vs Tx time. 13171 // Assumption: The number of packets received while transmitting is proportional 13172 // to the time spent transmitting over total active time. 13173 final double totalPacketsDuringTxTime = 13174 totalTxPackets + rxTxConsumption.txToTotalRatio * totalRxPackets; 13175 final double packetsDuringTxTime = 13176 txPackets + rxTxConsumption.txToTotalRatio * rxPackets; 13177 consumptionMah += rxTxConsumption.txConsumptionMah * packetsDuringTxTime 13178 / totalPacketsDuringTxTime; 13179 } 13180 return consumptionMah; 13181 } 13182 13183 /** 13184 * Add modem tx power to history 13185 * Device is said to be in high cellular transmit power when it has spent most of the transmit 13186 * time at the highest power level. 13187 * @param activityInfo 13188 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo, long elapsedRealtimeMs, long uptimeMs)13189 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo, 13190 long elapsedRealtimeMs, long uptimeMs) { 13191 if (activityInfo == null) { 13192 return; 13193 } 13194 int levelMaxTimeSpent = 0; 13195 for (int i = 1; i < MODEM_TX_POWER_LEVEL_COUNT; i++) { 13196 if (activityInfo.getTransmitDurationMillisAtPowerLevel(i) 13197 > activityInfo.getTransmitDurationMillisAtPowerLevel(levelMaxTimeSpent)) { 13198 levelMaxTimeSpent = i; 13199 } 13200 } 13201 if (levelMaxTimeSpent == MODEM_TX_POWER_LEVEL_COUNT - 1) { 13202 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 13203 HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG); 13204 } 13205 } 13206 13207 private final class BluetoothActivityInfoCache { 13208 long idleTimeMs; 13209 long rxTimeMs; 13210 long txTimeMs; 13211 long energy; 13212 13213 SparseLongArray uidRxBytes = new SparseLongArray(); 13214 SparseLongArray uidTxBytes = new SparseLongArray(); 13215 set(BluetoothActivityEnergyInfo info)13216 void set(BluetoothActivityEnergyInfo info) { 13217 idleTimeMs = info.getControllerIdleTimeMillis(); 13218 rxTimeMs = info.getControllerRxTimeMillis(); 13219 txTimeMs = info.getControllerTxTimeMillis(); 13220 energy = info.getControllerEnergyUsed(); 13221 if (!info.getUidTraffic().isEmpty()) { 13222 for (UidTraffic traffic : info.getUidTraffic()) { 13223 uidRxBytes.put(traffic.getUid(), traffic.getRxBytes()); 13224 uidTxBytes.put(traffic.getUid(), traffic.getTxBytes()); 13225 } 13226 } 13227 } 13228 reset()13229 void reset() { 13230 idleTimeMs = 0; 13231 rxTimeMs = 0; 13232 txTimeMs = 0; 13233 energy = 0; 13234 uidRxBytes.clear(); 13235 uidTxBytes.clear(); 13236 } 13237 } 13238 13239 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 13240 = new BluetoothActivityInfoCache(); 13241 13242 /** 13243 * Distribute Bluetooth energy info and network traffic to apps. 13244 * 13245 * @param info The accumulated energy information from the bluetooth controller. 13246 */ 13247 @GuardedBy("this") updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)13248 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info, 13249 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 13250 if (mBluetoothPowerStatsCollector.isEnabled()) { 13251 return; 13252 } 13253 13254 if (DEBUG_ENERGY) { 13255 Slog.d(TAG, "Updating bluetooth stats: " + info); 13256 } 13257 13258 if (info == null) { 13259 return; 13260 } 13261 13262 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 13263 mLastBluetoothActivityInfo.set(info); 13264 return; 13265 } 13266 13267 mHasBluetoothReporting = true; 13268 13269 if (info.getControllerRxTimeMillis() < mLastBluetoothActivityInfo.rxTimeMs 13270 || info.getControllerTxTimeMillis() < mLastBluetoothActivityInfo.txTimeMs 13271 || info.getControllerIdleTimeMillis() < mLastBluetoothActivityInfo.idleTimeMs 13272 || info.getControllerEnergyUsed() < mLastBluetoothActivityInfo.energy) { 13273 // A drop in accumulated Bluetooth stats is a sign of a Bluetooth crash. 13274 // Reset the preserved previous snapshot in order to restart accumulating deltas. 13275 mLastBluetoothActivityInfo.reset(); 13276 } 13277 13278 final long rxTimeMs = 13279 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 13280 final long txTimeMs = 13281 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 13282 final long idleTimeMs = 13283 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 13284 13285 if (DEBUG_ENERGY) { 13286 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 13287 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 13288 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 13289 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 13290 } 13291 13292 final SparseDoubleArray uidEstimatedConsumptionMah = 13293 (mGlobalEnergyConsumerStats != null 13294 && mBluetoothPowerCalculator != null && consumedChargeUC > 0) ? 13295 new SparseDoubleArray() : null; 13296 long totalScanTimeMs = 0; 13297 13298 final int uidCount = mUidStats.size(); 13299 for (int i = 0; i < uidCount; i++) { 13300 final Uid u = mUidStats.valueAt(i); 13301 if (u.mBluetoothScanTimer == null) { 13302 continue; 13303 } 13304 13305 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 13306 elapsedRealtimeMs * 1000) / 1000; 13307 } 13308 13309 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 13310 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 13311 13312 if (DEBUG_ENERGY) { 13313 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 13314 + " TX=" + normalizeScanTxTime); 13315 } 13316 13317 long leftOverRxTimeMs = rxTimeMs; 13318 long leftOverTxTimeMs = txTimeMs; 13319 13320 final SparseLongArray rxTimesMs = new SparseLongArray(uidCount); 13321 final SparseLongArray txTimesMs = new SparseLongArray(uidCount); 13322 13323 for (int i = 0; i < uidCount; i++) { 13324 final Uid u = mUidStats.valueAt(i); 13325 if (u.mBluetoothScanTimer == null) { 13326 continue; 13327 } 13328 13329 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 13330 elapsedRealtimeMs * 1000) / 1000; 13331 if (scanTimeSinceMarkMs > 0) { 13332 // Set the new mark so that next time we get new data since this point. 13333 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 13334 13335 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 13336 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 13337 13338 if (normalizeScanRxTime) { 13339 // Scan time is longer than the total rx time in the controller, 13340 // so distribute the scan time proportionately. This means regular traffic 13341 // will not blamed, but scans are more expensive anyways. 13342 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 13343 } 13344 13345 if (normalizeScanTxTime) { 13346 // Scan time is longer than the total tx time in the controller, 13347 // so distribute the scan time proportionately. This means regular traffic 13348 // will not blamed, but scans are more expensive anyways. 13349 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 13350 } 13351 13352 rxTimesMs.incrementValue(u.getUid(), scanTimeRxSinceMarkMs); 13353 txTimesMs.incrementValue(u.getUid(), scanTimeTxSinceMarkMs); 13354 13355 if (uidEstimatedConsumptionMah != null) { 13356 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 13357 mBluetoothPowerCalculator.calculatePowerMah( 13358 scanTimeRxSinceMarkMs, scanTimeTxSinceMarkMs, 0)); 13359 } 13360 13361 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 13362 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 13363 } 13364 } 13365 13366 if (DEBUG_ENERGY) { 13367 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 13368 + leftOverTxTimeMs); 13369 } 13370 13371 // 13372 // Now distribute blame to apps that did bluetooth traffic. 13373 // 13374 13375 long totalTxBytes = 0; 13376 long totalRxBytes = 0; 13377 13378 final List<UidTraffic> uidTraffic = info.getUidTraffic(); 13379 final int numUids = uidTraffic.size(); 13380 for (int i = 0; i < numUids; i++) { 13381 final UidTraffic traffic = uidTraffic.get(i); 13382 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 13383 traffic.getUid()); 13384 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 13385 traffic.getUid()); 13386 13387 // Add to the global counters. 13388 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 13389 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 13390 13391 // Add to the UID counters. 13392 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()), elapsedRealtimeMs, uptimeMs); 13393 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 13394 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 13395 13396 // Calculate the total traffic. 13397 totalRxBytes += rxBytes; 13398 totalTxBytes += txBytes; 13399 } 13400 13401 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 13402 || leftOverTxTimeMs != 0)) { 13403 for (int i = 0; i < numUids; i++) { 13404 final UidTraffic traffic = uidTraffic.get(i); 13405 final int uid = traffic.getUid(); 13406 final long rxBytes = 13407 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 13408 final long txBytes = 13409 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 13410 13411 final Uid u = getUidStatsLocked(mapUid(uid), elapsedRealtimeMs, uptimeMs); 13412 final ControllerActivityCounterImpl counter = 13413 u.getOrCreateBluetoothControllerActivityLocked(); 13414 13415 if (totalRxBytes > 0 && rxBytes > 0) { 13416 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 13417 rxTimesMs.incrementValue(uid, timeRxMs); 13418 } 13419 13420 if (totalTxBytes > 0 && txBytes > 0) { 13421 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 13422 txTimesMs.incrementValue(uid, timeTxMs); 13423 } 13424 } 13425 13426 for (int i = 0; i < txTimesMs.size(); i++) { 13427 final int uid = txTimesMs.keyAt(i); 13428 final long myTxTimeMs = txTimesMs.valueAt(i); 13429 if (DEBUG_ENERGY) { 13430 Slog.d(TAG, " TxTime for UID " + uid + ": " + myTxTimeMs + " ms"); 13431 } 13432 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 13433 .getOrCreateBluetoothControllerActivityLocked() 13434 .getOrCreateTxTimeCounters()[0] 13435 .increment(myTxTimeMs, elapsedRealtimeMs); 13436 if (uidEstimatedConsumptionMah != null) { 13437 uidEstimatedConsumptionMah.incrementValue(uid, 13438 mBluetoothPowerCalculator.calculatePowerMah(0, myTxTimeMs, 0)); 13439 } 13440 } 13441 13442 for (int i = 0; i < rxTimesMs.size(); i++) { 13443 final int uid = rxTimesMs.keyAt(i); 13444 final long myRxTimeMs = rxTimesMs.valueAt(i); 13445 if (DEBUG_ENERGY) { 13446 Slog.d(TAG, " RxTime for UID " + uid + ": " + myRxTimeMs + " ms"); 13447 } 13448 13449 getUidStatsLocked(rxTimesMs.keyAt(i), elapsedRealtimeMs, uptimeMs) 13450 .getOrCreateBluetoothControllerActivityLocked() 13451 .getOrCreateRxTimeCounter() 13452 .increment(myRxTimeMs, elapsedRealtimeMs); 13453 if (uidEstimatedConsumptionMah != null) { 13454 uidEstimatedConsumptionMah.incrementValue(uid, 13455 mBluetoothPowerCalculator.calculatePowerMah(myRxTimeMs, 0, 0)); 13456 } 13457 } 13458 } 13459 13460 mBluetoothActivity.getOrCreateRxTimeCounter().increment(rxTimeMs, elapsedRealtimeMs); 13461 mBluetoothActivity.getOrCreateTxTimeCounters()[0].increment(txTimeMs, elapsedRealtimeMs); 13462 mBluetoothActivity.getOrCreateIdleTimeCounter().increment(idleTimeMs, elapsedRealtimeMs); 13463 13464 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 13465 final double opVolt = mPowerProfile.getAveragePower( 13466 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 13467 double controllerMaMs = 0; 13468 if (opVolt != 0) { 13469 controllerMaMs = (info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 13470 / opVolt; 13471 // We store the power drain as mAms. 13472 mBluetoothActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 13473 } 13474 13475 // Update the EnergyConsumerStats information. 13476 if (uidEstimatedConsumptionMah != null) { 13477 mGlobalEnergyConsumerStats.updateStandardBucket( 13478 EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, consumedChargeUC); 13479 13480 double totalEstimatedMah 13481 = mBluetoothPowerCalculator.calculatePowerMah(rxTimeMs, txTimeMs, idleTimeMs); 13482 totalEstimatedMah = Math.max(totalEstimatedMah, controllerMaMs / MILLISECONDS_IN_HOUR); 13483 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 13484 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedMah, 13485 elapsedRealtimeMs); 13486 } 13487 13488 mLastBluetoothActivityInfo.set(info); 13489 } 13490 /** 13491 * Read Resource Power Manager (RPM) state and voter times. 13492 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 13493 * instead of fetching it anew. 13494 * 13495 * Note: This should be called without synchronizing this BatteryStatsImpl object 13496 */ fillLowPowerStats()13497 public void fillLowPowerStats() { 13498 if (mPlatformIdleStateCallback == null) return; 13499 13500 RpmStats rpmStats = new RpmStats(); 13501 long now = SystemClock.elapsedRealtime(); 13502 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 13503 mPlatformIdleStateCallback.fillLowPowerStats(rpmStats); 13504 synchronized (this) { 13505 mTmpRpmStats = rpmStats; 13506 mLastRpmStatsUpdateTimeMs = now; 13507 } 13508 } 13509 } 13510 13511 /** 13512 * Record Resource Power Manager (RPM) state and voter times. 13513 * TODO(b/185252376): Remove this logging. PowerStatsService logs the same data more 13514 * efficiently. 13515 */ updateRpmStatsLocked(long elapsedRealtimeUs)13516 public void updateRpmStatsLocked(long elapsedRealtimeUs) { 13517 if (mTmpRpmStats == null) return; 13518 13519 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 13520 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 13521 13522 // Update values for this platform state. 13523 final String pName = pstate.getKey(); 13524 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 13525 final int pCount = pstate.getValue().mCount; 13526 getRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 13527 if (SCREEN_OFF_RPM_STATS_ENABLED) { 13528 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 13529 } 13530 13531 // Update values for each voter of this platform state. 13532 for (Map.Entry<String, RpmStats.PowerStateElement> voter 13533 : pstate.getValue().mVoters.entrySet()) { 13534 final String vName = pName + "." + voter.getKey(); 13535 final long vTimeUs = voter.getValue().mTimeMs * 1000; 13536 final int vCount = voter.getValue().mCount; 13537 getRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 13538 if (SCREEN_OFF_RPM_STATS_ENABLED) { 13539 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 13540 } 13541 } 13542 } 13543 13544 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 13545 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 13546 13547 final String subsysName = subsys.getKey(); 13548 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 13549 : subsys.getValue().mStates.entrySet()) { 13550 final String name = subsysName + "." + sstate.getKey(); 13551 final long timeUs = sstate.getValue().mTimeMs * 1000; 13552 final int count = sstate.getValue().mCount; 13553 getRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 13554 if (SCREEN_OFF_RPM_STATS_ENABLED) { 13555 getScreenOffRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 13556 } 13557 } 13558 } 13559 } 13560 13561 /** 13562 * Accumulate Cpu charge consumption and distribute it to the correct state and the apps. 13563 * Only call if device is on battery. 13564 * 13565 * @param clusterChargeUC amount of charge (microcoulombs) consumed by each Cpu Cluster 13566 * @param accumulator collection of calculated uid cpu power consumption to smear 13567 * clusterChargeUC against. 13568 */ 13569 @GuardedBy("this") 13570 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToStandardBucketLocked updateCpuEnergyConsumerStatsLocked(@onNull long[] clusterChargeUC, @NonNull CpuDeltaPowerAccumulator accumulator)13571 private void updateCpuEnergyConsumerStatsLocked(@NonNull long[] clusterChargeUC, 13572 @NonNull CpuDeltaPowerAccumulator accumulator) { 13573 if (DEBUG_ENERGY) { 13574 Slog.d(TAG, "Updating cpu cluster stats: " + Arrays.toString(clusterChargeUC)); 13575 } 13576 if (mGlobalEnergyConsumerStats == null) { 13577 return; 13578 } 13579 13580 final int numClusters = clusterChargeUC.length; 13581 long totalCpuChargeUC = 0; 13582 for (int i = 0; i < numClusters; i++) { 13583 totalCpuChargeUC += clusterChargeUC[i]; 13584 } 13585 if (totalCpuChargeUC <= 0) return; 13586 13587 final long timestampMs = mClock.elapsedRealtime(); 13588 13589 mGlobalEnergyConsumerStats.updateStandardBucket(EnergyConsumerStats.POWER_BUCKET_CPU, 13590 totalCpuChargeUC, timestampMs); 13591 13592 // Calculate the microcoulombs/milliamp-hour charge ratio for each 13593 // cluster to normalize each uid's estimated power usage against actual power usage for 13594 // a given cluster. 13595 final double[] clusterChargeRatio = new double[numClusters]; 13596 for (int cluster = 0; cluster < numClusters; cluster++) { 13597 13598 final double totalClusterChargeMah = accumulator.totalClusterChargesMah[cluster]; 13599 if (totalClusterChargeMah <= 0.0) { 13600 // This cluster did not have any work on it, since last update. 13601 // Avoid dividing by zero. 13602 clusterChargeRatio[cluster] = 0.0; 13603 } else { 13604 clusterChargeRatio[cluster] = 13605 clusterChargeUC[cluster] / accumulator.totalClusterChargesMah[cluster]; 13606 } 13607 } 13608 13609 // Assign and distribute power usage to apps based on their calculated cpu cluster charge. 13610 final long uidChargeArraySize = accumulator.perUidCpuClusterChargesMah.size(); 13611 for (int i = 0; i < uidChargeArraySize; i++) { 13612 final Uid uid = accumulator.perUidCpuClusterChargesMah.keyAt(i); 13613 final double[] uidClusterChargesMah = accumulator.perUidCpuClusterChargesMah.valueAt(i); 13614 13615 // Iterate each cpu cluster and sum the proportional cpu cluster charge to 13616 // get the total cpu charge consumed by a uid. 13617 long uidCpuChargeUC = 0; 13618 for (int cluster = 0; cluster < numClusters; cluster++) { 13619 final double uidClusterChargeMah = uidClusterChargesMah[cluster]; 13620 13621 // Proportionally allocate the cpu cluster charge to a uid using the 13622 // cluster charge/charge ratio. Add 0.5 to round the proportional 13623 // charge double to the nearest long value. 13624 final long uidClusterChargeUC = 13625 (long) (uidClusterChargeMah * clusterChargeRatio[cluster] 13626 + 0.5); 13627 13628 uidCpuChargeUC += uidClusterChargeUC; 13629 } 13630 13631 if (uidCpuChargeUC < 0) { 13632 Slog.wtf(TAG, "Unexpected proportional EnergyConsumer charge " 13633 + "(" + uidCpuChargeUC + ") for uid " + uid.mUid); 13634 continue; 13635 } 13636 13637 uid.addChargeToStandardBucketLocked(uidCpuChargeUC, 13638 EnergyConsumerStats.POWER_BUCKET_CPU, timestampMs); 13639 } 13640 } 13641 13642 /** 13643 * Accumulate Display charge consumption and distribute it to the correct state and the apps. 13644 * 13645 * NOTE: The algorithm used makes the strong assumption that app foreground activity time 13646 * is always 0 when the screen is not "ON" and whenever the rail energy is 0 (if supported). 13647 * To the extent that those assumptions are violated, the algorithm will err. 13648 * 13649 * @param chargesUC amount of charge (microcoulombs) used by each Display since this was last 13650 * called. 13651 * @param screenStates each screen state at the time this data collection was scheduled 13652 */ 13653 @GuardedBy("this") updateDisplayEnergyConsumerStatsLocked(long[] chargesUC, int[] screenStates, long elapsedRealtimeMs)13654 public void updateDisplayEnergyConsumerStatsLocked(long[] chargesUC, int[] screenStates, 13655 long elapsedRealtimeMs) { 13656 if (DEBUG_ENERGY) Slog.d(TAG, "Updating display stats: " + Arrays.toString(chargesUC)); 13657 if (mGlobalEnergyConsumerStats == null) { 13658 return; 13659 } 13660 13661 final int numDisplays; 13662 if (mPerDisplayBatteryStats.length == screenStates.length) { 13663 numDisplays = screenStates.length; 13664 } else { 13665 // if this point is reached, it will be reached every display state change. 13666 // Rate limit the wtf logging to once every 100 display updates. 13667 if (mDisplayMismatchWtfCount++ % 100 == 0) { 13668 Slog.wtf(TAG, "Mismatch between PowerProfile reported display count (" 13669 + mPerDisplayBatteryStats.length 13670 + ") and PowerStatsHal reported display count (" + screenStates.length 13671 + ")"); 13672 } 13673 // Keep the show going, use the shorter of the two. 13674 numDisplays = mPerDisplayBatteryStats.length < screenStates.length 13675 ? mPerDisplayBatteryStats.length : screenStates.length; 13676 } 13677 13678 final int[] oldScreenStates = new int[numDisplays]; 13679 for (int i = 0; i < numDisplays; i++) { 13680 final int screenState = screenStates[i]; 13681 oldScreenStates[i] = mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement; 13682 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 13683 } 13684 13685 if (!mOnBatteryInternal) { 13686 // There's nothing further to update. 13687 return; 13688 } 13689 if (mIgnoreNextExternalStats) { 13690 // Although under ordinary resets we won't get here, and typically a new sync will 13691 // happen right after the reset, strictly speaking we need to set all mark times to now. 13692 final int uidStatsSize = mUidStats.size(); 13693 for (int i = 0; i < uidStatsSize; i++) { 13694 final Uid uid = mUidStats.valueAt(i); 13695 uid.markProcessForegroundTimeUs(elapsedRealtimeMs, false); 13696 } 13697 return; 13698 } 13699 13700 long totalScreenOnChargeUC = 0; 13701 for (int i = 0; i < numDisplays; i++) { 13702 final long chargeUC = chargesUC[i]; 13703 if (chargeUC <= 0) { 13704 // There's nothing further to update. 13705 continue; 13706 } 13707 13708 final @StandardPowerBucket int powerBucket = 13709 EnergyConsumerStats.getDisplayPowerBucket(oldScreenStates[i]); 13710 mGlobalEnergyConsumerStats.updateStandardBucket(powerBucket, chargeUC); 13711 if (powerBucket == EnergyConsumerStats.POWER_BUCKET_SCREEN_ON) { 13712 totalScreenOnChargeUC += chargeUC; 13713 } 13714 } 13715 13716 // Now we blame individual apps, but only if the display was ON. 13717 if (totalScreenOnChargeUC <= 0) { 13718 return; 13719 } 13720 // TODO(b/175726779): Consider unifying the code with the non-rail display power blaming. 13721 13722 // NOTE: fg time is NOT pooled. If two uids are both somehow in fg, then that time is 13723 // 'double counted' and will simply exceed the realtime that elapsed. 13724 // TODO(b/175726779): collect per display uid visibility for display power attribution. 13725 13726 // Collect total time since mark so that we can normalize power. 13727 final SparseDoubleArray fgTimeUsArray = new SparseDoubleArray(); 13728 final long elapsedRealtimeUs = elapsedRealtimeMs * 1000; 13729 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 13730 final int uidStatsSize = mUidStats.size(); 13731 for (int i = 0; i < uidStatsSize; i++) { 13732 final Uid uid = mUidStats.valueAt(i); 13733 final long fgTimeUs = uid.markProcessForegroundTimeUs(elapsedRealtimeMs, true); 13734 if (fgTimeUs == 0) continue; 13735 fgTimeUsArray.put(uid.getUid(), (double) fgTimeUs); 13736 } 13737 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON, 13738 totalScreenOnChargeUC, fgTimeUsArray, 0, elapsedRealtimeMs); 13739 } 13740 13741 /** 13742 * Accumulate GNSS charge consumption and distribute it to the correct state and the apps. 13743 * 13744 * @param chargeUC amount of charge (microcoulombs) used by GNSS since this was last called. 13745 */ 13746 @GuardedBy("this") 13747 public void updateGnssEnergyConsumerStatsLocked(long chargeUC, long elapsedRealtimeMs) { 13748 if (DEBUG_ENERGY) Slog.d(TAG, "Updating gnss stats: " + chargeUC); 13749 if (mGlobalEnergyConsumerStats == null) { 13750 return; 13751 } 13752 13753 if (!mOnBatteryInternal || chargeUC <= 0) { 13754 // There's nothing further to update. 13755 return; 13756 } 13757 if (mIgnoreNextExternalStats) { 13758 // Although under ordinary resets we won't get here, and typically a new sync will 13759 // happen right after the reset, strictly speaking we need to set all mark times to now. 13760 final int uidStatsSize = mUidStats.size(); 13761 for (int i = 0; i < uidStatsSize; i++) { 13762 final Uid uid = mUidStats.valueAt(i); 13763 uid.markGnssTimeUs(elapsedRealtimeMs); 13764 } 13765 return; 13766 } 13767 13768 mGlobalEnergyConsumerStats.updateStandardBucket(EnergyConsumerStats.POWER_BUCKET_GNSS, 13769 chargeUC); 13770 13771 // Collect the per uid time since mark so that we can normalize power. 13772 final SparseDoubleArray gnssTimeUsArray = new SparseDoubleArray(); 13773 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 13774 final int uidStatsSize = mUidStats.size(); 13775 for (int i = 0; i < uidStatsSize; i++) { 13776 final Uid uid = mUidStats.valueAt(i); 13777 final long gnssTimeUs = uid.markGnssTimeUs(elapsedRealtimeMs); 13778 if (gnssTimeUs == 0) continue; 13779 gnssTimeUsArray.put(uid.getUid(), (double) gnssTimeUs); 13780 } 13781 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_GNSS, chargeUC, 13782 gnssTimeUsArray, 0, elapsedRealtimeMs); 13783 } 13784 13785 /** 13786 * Accumulate camera charge consumption and distribute it to the correct state and the apps. 13787 * 13788 * @param chargeUC amount of charge (microcoulombs) used by the camera since this was last 13789 * called. 13790 */ 13791 @GuardedBy("this") 13792 public void updateCameraEnergyConsumerStatsLocked(long chargeUC, long elapsedRealtimeMs) { 13793 if (DEBUG_ENERGY) Slog.d(TAG, "Updating camera stats: " + chargeUC); 13794 if (mGlobalEnergyConsumerStats == null) { 13795 return; 13796 } 13797 13798 if (!mOnBatteryInternal || chargeUC <= 0) { 13799 // There's nothing further to update. 13800 return; 13801 } 13802 13803 if (mIgnoreNextExternalStats) { 13804 // Although under ordinary resets we won't get here, and typically a new sync will 13805 // happen right after the reset, strictly speaking we need to set all mark times to now. 13806 final int uidStatsSize = mUidStats.size(); 13807 for (int i = 0; i < uidStatsSize; i++) { 13808 final Uid uid = mUidStats.valueAt(i); 13809 uid.markCameraTimeUs(elapsedRealtimeMs); 13810 } 13811 return; 13812 } 13813 13814 mGlobalEnergyConsumerStats.updateStandardBucket( 13815 EnergyConsumerStats.POWER_BUCKET_CAMERA, chargeUC); 13816 13817 // Collect the per uid time since mark so that we can normalize power. 13818 final SparseDoubleArray cameraTimeUsArray = new SparseDoubleArray(); 13819 13820 // Note: Iterating over all UIDs may be suboptimal. 13821 final int uidStatsSize = mUidStats.size(); 13822 for (int i = 0; i < uidStatsSize; i++) { 13823 final Uid uid = mUidStats.valueAt(i); 13824 final long cameraTimeUs = uid.markCameraTimeUs(elapsedRealtimeMs); 13825 if (cameraTimeUs == 0) continue; 13826 cameraTimeUsArray.put(uid.getUid(), (double) cameraTimeUs); 13827 } 13828 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_CAMERA, chargeUC, 13829 cameraTimeUsArray, 0, elapsedRealtimeMs); 13830 } 13831 13832 /** 13833 * Accumulate Custom power bucket charge, globally and for each app. 13834 * 13835 * @param totalChargeUC charge (microcoulombs) used for this bucket since this was last called. 13836 * @param uidCharges map of uid->charge (microcoulombs) for this bucket since last called. 13837 * Data inside uidCharges will not be modified (treated immutable). 13838 * Uids not already known to BatteryStats will be ignored. 13839 */ 13840 @GuardedBy("this") 13841 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToCustomBucketLocked 13842 public void updateCustomEnergyConsumerStatsLocked(int customPowerBucket, 13843 long totalChargeUC, @Nullable SparseLongArray uidCharges) { 13844 if (DEBUG_ENERGY) { 13845 Slog.d(TAG, "Updating attributed EnergyConsumer stats for custom bucket " 13846 + customPowerBucket 13847 + " with total charge " + totalChargeUC 13848 + " and uid charges " + uidCharges); 13849 } 13850 if (mGlobalEnergyConsumerStats == null) return; 13851 if (!mOnBatteryInternal || mIgnoreNextExternalStats || totalChargeUC <= 0) return; 13852 13853 mGlobalEnergyConsumerStats.updateCustomBucket(customPowerBucket, totalChargeUC, 13854 mClock.elapsedRealtime()); 13855 13856 if (uidCharges == null) return; 13857 final int numUids = uidCharges.size(); 13858 for (int i = 0; i < numUids; i++) { 13859 final int uidInt = mapUid(uidCharges.keyAt(i)); 13860 final long uidChargeUC = uidCharges.valueAt(i); 13861 if (uidChargeUC == 0) continue; 13862 13863 final Uid uidObj = getAvailableUidStatsLocked(uidInt); 13864 if (uidObj != null) { 13865 uidObj.addChargeToCustomBucketLocked(uidChargeUC, customPowerBucket); 13866 } else { 13867 // Ignore any uid not already known to BatteryStats, rather than creating a new Uid. 13868 // Otherwise we could end up reviving dead Uids. Note that the CPU data is updated 13869 // first, so any uid that has used any CPU should already be known to BatteryStats. 13870 // Recently removed uids (especially common for isolated uids) can reach this path 13871 // and are ignored. 13872 if (!Process.isIsolated(uidInt)) { 13873 Slog.w(TAG, "Received EnergyConsumer charge " + totalChargeUC 13874 + " for custom bucket " + customPowerBucket + " for non-existent uid " 13875 + uidInt); 13876 } 13877 } 13878 } 13879 } 13880 13881 /** 13882 * Attributes energy (for the given bucket) to each uid according to the following formula: 13883 * blamedEnergy[uid] = totalEnergy * ratioNumerators[uid] / ratioDenominator; 13884 * <p>Does nothing if ratioDenominator is 0. 13885 * 13886 * <p>Here, ratioDenominator = max(sumOfAllRatioNumerators, minRatioDenominator), 13887 * so if given minRatioDenominator <= 0, then sumOfAllRatioNumerators will be used implicitly. 13888 * 13889 * <p>Note that ratioNumerators and minRatioDenominator must use the same units, but need not 13890 * use the same units as totalConsumedChargeUC (which must be in microcoulombs). 13891 * 13892 * <p>A consequence of minRatioDenominator is that the sum over all uids might be less than 13893 * totalConsumedChargeUC. This is intentional; the remainder is purposefully unnaccounted rather 13894 * than incorrectly blamed on uids, and implies unknown (non-uid) sources of drain. 13895 * 13896 * <p>All uids in ratioNumerators must exist in mUidStats already. 13897 */ 13898 @GuardedBy("this") 13899 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToStandardBucketLocked 13900 private void distributeEnergyToUidsLocked(@StandardPowerBucket int bucket, 13901 long totalConsumedChargeUC, SparseDoubleArray ratioNumerators, 13902 double minRatioDenominator, long timestampMs) { 13903 13904 // If the sum of all app usage was greater than the total, use that instead: 13905 double sumRatioNumerators = 0; 13906 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 13907 sumRatioNumerators += ratioNumerators.valueAt(i); 13908 } 13909 final double ratioDenominator = Math.max(sumRatioNumerators, minRatioDenominator); 13910 if (ratioDenominator <= 0) return; 13911 13912 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 13913 final Uid uid = getAvailableUidStatsLocked(ratioNumerators.keyAt(i)); 13914 final double ratioNumerator = ratioNumerators.valueAt(i); 13915 final long uidActualUC 13916 = (long) (totalConsumedChargeUC * ratioNumerator / ratioDenominator + 0.5); 13917 uid.addChargeToStandardBucketLocked(uidActualUC, bucket, timestampMs); 13918 } 13919 } 13920 13921 /** 13922 * Read and record Rail Energy data. 13923 */ 13924 public void updateRailStatsLocked() { 13925 if (mEnergyConsumerRetriever == null || !mTmpRailStats.isRailStatsAvailable()) { 13926 return; 13927 } 13928 mEnergyConsumerRetriever.fillRailDataStats(mTmpRailStats); 13929 } 13930 13931 /** Informs that external stats data has been completely flushed. */ 13932 public void informThatAllExternalStatsAreFlushed() { 13933 synchronized (this) { 13934 // Any data from the pre-reset era is flushed, so we can henceforth process future data. 13935 mIgnoreNextExternalStats = false; 13936 } 13937 } 13938 13939 /** 13940 * Read and distribute kernel wake lock use across apps. 13941 */ 13942 public void updateKernelWakelocksLocked(long elapsedRealtimeUs) { 13943 if (mKernelWakelockReader == null) { 13944 return; 13945 } 13946 13947 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 13948 mTmpWakelockStats); 13949 if (wakelockStats == null) { 13950 // Not crashing might make board bringup easier. 13951 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 13952 return; 13953 } 13954 13955 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 13956 String name = ent.getKey(); 13957 KernelWakelockStats.Entry kws = ent.getValue(); 13958 13959 SamplingTimer kwlt = mKernelWakelockStats.get(name); 13960 if (kwlt == null) { 13961 kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 13962 mKernelWakelockStats.put(name, kwlt); 13963 } 13964 13965 kwlt.update(kws.totalTimeUs, kws.activeTimeUs, kws.count, elapsedRealtimeUs); 13966 kwlt.setUpdateVersion(kws.version); 13967 } 13968 13969 int numWakelocksSetStale = 0; 13970 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 13971 // this time. 13972 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 13973 SamplingTimer st = ent.getValue(); 13974 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 13975 st.endSample(elapsedRealtimeUs); 13976 numWakelocksSetStale++; 13977 } 13978 } 13979 13980 if (DEBUG) { 13981 // Record whether we've seen a non-zero time (for debugging b/22716723). 13982 if (wakelockStats.isEmpty()) { 13983 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 13984 } 13985 13986 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 13987 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" 13988 + wakelockStats.kernelWakelockVersion); 13989 } 13990 } 13991 } 13992 13993 // We use an anonymous class to access these variables, 13994 // so they can't live on the stack or they'd have to be 13995 // final MutableLong objects (more allocations). 13996 // Used in updateCpuTimeLocked(). 13997 long mTempTotalCpuUserTimeUs; 13998 long mTempTotalCpuSystemTimeUs; 13999 long[][] mWakeLockAllocationsUs; 14000 14001 /** 14002 * Reads the newest memory stats from the kernel. 14003 */ 14004 public void updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs) { 14005 mKernelMemoryBandwidthStats.updateStats(); 14006 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 14007 final int bandwidthEntryCount = bandwidthEntries.size(); 14008 int index; 14009 for (int i = 0; i < bandwidthEntryCount; i++) { 14010 SamplingTimer timer; 14011 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 14012 timer = mKernelMemoryStats.valueAt(index); 14013 } else { 14014 timer = new SamplingTimer(mClock, mOnBatteryTimeBase); 14015 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 14016 } 14017 timer.update(bandwidthEntries.valueAt(i), 1, elapsedRealtimeUs); 14018 if (DEBUG_MEMORY) { 14019 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 14020 + "mUnpluggedReportedTotalTimeUs %d size %d", bandwidthEntries.keyAt(i), 14021 mKernelMemoryStats.get( 14022 bandwidthEntries.keyAt(i)).mBaseReportedTotalTimeUs, 14023 mKernelMemoryStats.size())); 14024 } 14025 } 14026 } 14027 14028 public boolean isOnBatteryLocked() { 14029 return mOnBatteryTimeBase.isRunning(); 14030 } 14031 14032 public boolean isOnBatteryScreenOffLocked() { 14033 return mOnBatteryScreenOffTimeBase.isRunning(); 14034 } 14035 14036 /** 14037 * Object for calculating and accumulating the estimated cpu power used while reading the 14038 * various cpu kernel files. 14039 */ 14040 @VisibleForTesting 14041 public static class CpuDeltaPowerAccumulator { 14042 // Keeps track of total charge used per cluster. 14043 public final double[] totalClusterChargesMah; 14044 // Keeps track of charge used per cluster per uid. 14045 public final ArrayMap<Uid, double[]> perUidCpuClusterChargesMah; 14046 14047 private final CpuPowerCalculator mCalculator; 14048 private Uid mCachedUid = null; 14049 private double[] mUidClusterCache = null; 14050 14051 CpuDeltaPowerAccumulator(CpuPowerCalculator calculator, int nClusters) { 14052 mCalculator = calculator; 14053 totalClusterChargesMah = new double[nClusters]; 14054 perUidCpuClusterChargesMah = new ArrayMap<>(); 14055 } 14056 14057 /** Add per cpu cluster durations to the currently cached uid. */ 14058 public void addCpuClusterDurationsMs(Uid uid, long[] durationsMs) { 14059 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 14060 for (int cluster = 0; cluster < durationsMs.length; cluster++) { 14061 final double estimatedDeltaMah = mCalculator.calculatePerCpuClusterPowerMah(cluster, 14062 durationsMs[cluster]); 14063 uidChargesMah[cluster] += estimatedDeltaMah; 14064 totalClusterChargesMah[cluster] += estimatedDeltaMah; 14065 } 14066 } 14067 14068 /** Add per speed per cpu cluster durations to the currently cached uid. */ 14069 public void addCpuClusterSpeedDurationsMs(Uid uid, int cluster, int speed, 14070 long durationsMs) { 14071 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 14072 final double estimatedDeltaMah = mCalculator.calculatePerCpuFreqPowerMah(cluster, speed, 14073 durationsMs); 14074 uidChargesMah[cluster] += estimatedDeltaMah; 14075 totalClusterChargesMah[cluster] += estimatedDeltaMah; 14076 } 14077 14078 private double[] getOrCreateUidCpuClusterCharges(Uid uid) { 14079 // Repeated additions on the same uid is very likely. 14080 // Skip a lookup if getting the same uid as the last get. 14081 if (uid == mCachedUid) return mUidClusterCache; 14082 14083 double[] uidChargesMah = perUidCpuClusterChargesMah.get(uid); 14084 if (uidChargesMah == null) { 14085 uidChargesMah = new double[totalClusterChargesMah.length]; 14086 perUidCpuClusterChargesMah.put(uid, uidChargesMah); 14087 } 14088 mCachedUid = uid; 14089 mUidClusterCache = uidChargesMah; 14090 return uidChargesMah; 14091 } 14092 } 14093 14094 /** 14095 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 14096 * and we are on battery with screen off, we give more of the cpu time to those apps holding 14097 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 14098 * It's possible this will be invoked after the internal battery/screen states are updated, so 14099 * passing the appropriate battery/screen states to try attribute the cpu times to correct 14100 * buckets. 14101 */ 14102 @GuardedBy("this") 14103 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff, 14104 long[] cpuClusterChargeUC) { 14105 if (DEBUG_ENERGY_CPU) { 14106 Slog.d(TAG, "!Cpu updating!"); 14107 } 14108 14109 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 14110 // usually holding the wakelock on behalf of an app. 14111 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 14112 ArrayList<StopwatchTimer> partialTimersToConsider = null; 14113 if (onBatteryScreenOff) { 14114 partialTimersToConsider = new ArrayList<>(); 14115 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 14116 final StopwatchTimer timer = mPartialTimers.get(i); 14117 // Since the collection and blaming of wakelocks can be scheduled to run after 14118 // some delay, the mPartialTimers list may have new entries. We can't blame 14119 // the newly added timer for past cpu time, so we only consider timers that 14120 // were present for one round of collection. Once a timer has gone through 14121 // a round of collection, its mInList field is set to true. 14122 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 14123 partialTimersToConsider.add(timer); 14124 } 14125 } 14126 } 14127 markPartialTimersAsEligible(); 14128 14129 // When the battery is not on, we don't attribute the cpu times to any timers but we still 14130 // need to take the snapshots. 14131 if (!onBattery) { 14132 mCpuUidUserSysTimeReader.readDelta(false, null); 14133 mCpuUidFreqTimeReader.readDelta(false, null); 14134 mNumAllUidCpuTimeReads += 2; 14135 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 14136 mCpuUidActiveTimeReader.readDelta(false, null); 14137 mCpuUidClusterTimeReader.readDelta(false, null); 14138 mNumAllUidCpuTimeReads += 2; 14139 } 14140 for (int i = mKernelCpuSpeedReaders.length - 1; i >= 0; --i) { 14141 if (mKernelCpuSpeedReaders[i] != null) { 14142 mKernelCpuSpeedReaders[i].readDelta(); 14143 } 14144 } 14145 if (!Flags.disableSystemServicePowerAttr()) { 14146 mSystemServerCpuThreadReader.readDelta(); 14147 } 14148 return; 14149 } 14150 14151 mUserInfoProvider.refreshUserIds(); 14152 final SparseLongArray updatedUids = mCpuUidFreqTimeReader.allUidTimesAvailable() 14153 ? null : new SparseLongArray(); 14154 14155 final CpuDeltaPowerAccumulator powerAccumulator; 14156 if (mGlobalEnergyConsumerStats != null 14157 && mGlobalEnergyConsumerStats.isStandardBucketSupported( 14158 EnergyConsumerStats.POWER_BUCKET_CPU)) { 14159 if (cpuClusterChargeUC == null) { 14160 Slog.wtf(TAG, 14161 "POWER_BUCKET_CPU supported but no EnergyConsumer Cpu Cluster charge " 14162 + "reported on updateCpuTimeLocked!"); 14163 powerAccumulator = null; 14164 } else { 14165 if (mCpuPowerCalculator == null) { 14166 mCpuPowerCalculator = new CpuPowerCalculator(mCpuScalingPolicies, 14167 mPowerProfile); 14168 } 14169 // Cpu EnergyConsumer is supported, create an object to accumulate the estimated 14170 // charge consumption since the last cpu update 14171 powerAccumulator = new CpuDeltaPowerAccumulator(mCpuPowerCalculator, 14172 mCpuScalingPolicies.getPolicies().length); 14173 } 14174 } else { 14175 powerAccumulator = null; 14176 } 14177 14178 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 14179 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 14180 // freqs, so no need to approximate these values. 14181 if (updatedUids != null) { 14182 updateClusterSpeedTimes(updatedUids, onBattery, powerAccumulator); 14183 } 14184 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff, 14185 powerAccumulator); 14186 mNumAllUidCpuTimeReads += 2; 14187 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 14188 // Cpu Active times do not get any info ony how to attribute Cpu Cluster 14189 // charge, so not need to provide the powerAccumulator 14190 readKernelUidCpuActiveTimesLocked(onBattery); 14191 readKernelUidCpuClusterTimesLocked(onBattery, powerAccumulator); 14192 mNumAllUidCpuTimeReads += 2; 14193 } 14194 14195 if (!Flags.disableSystemServicePowerAttr()) { 14196 updateSystemServerThreadStats(); 14197 } 14198 14199 if (powerAccumulator != null) { 14200 updateCpuEnergyConsumerStatsLocked(cpuClusterChargeUC, powerAccumulator); 14201 } 14202 } 14203 14204 /** 14205 * Estimates the proportion of the System Server CPU activity (per cluster per speed) 14206 * spent on handling incoming binder calls. 14207 */ 14208 @VisibleForTesting 14209 public void updateSystemServerThreadStats() { 14210 // There are some simplifying assumptions made in this algorithm 14211 // 1) We assume that if a thread handles incoming binder calls, all of its activity 14212 // is spent doing that. Most incoming calls are handled by threads allocated 14213 // by the native layer in the binder thread pool, so this assumption is reasonable. 14214 // 2) We use the aggregate CPU time spent in different threads as a proxy for the CPU 14215 // cost. In reality, in multi-core CPUs, the CPU cost may not be linearly 14216 // affected by additional threads. 14217 14218 SystemServerCpuThreadReader.SystemServiceCpuThreadTimes systemServiceCpuThreadTimes = 14219 mSystemServerCpuThreadReader.readDelta(); 14220 if (systemServiceCpuThreadTimes == null) { 14221 return; 14222 } 14223 14224 if (mBinderThreadCpuTimesUs == null) { 14225 mBinderThreadCpuTimesUs = new LongSamplingCounterArray(mOnBatteryTimeBase); 14226 } 14227 mBinderThreadCpuTimesUs.addCountLocked(systemServiceCpuThreadTimes.binderThreadCpuTimesUs); 14228 14229 if (DEBUG_BINDER_STATS) { 14230 Slog.d(TAG, "System server threads per CPU cluster (incoming binder threads)"); 14231 long binderThreadTimeMs = 0; 14232 final long[] binderThreadCpuTimesUs = mBinderThreadCpuTimesUs.getCountsLocked( 14233 BatteryStats.STATS_SINCE_CHARGED); 14234 int index = 0; 14235 int[] policies = mCpuScalingPolicies.getPolicies(); 14236 for (int policy : policies) { 14237 StringBuilder sb = new StringBuilder(); 14238 sb.append("policy").append(policy).append(": ["); 14239 int numSpeeds = mCpuScalingPolicies.getFrequencies(policy).length; 14240 for (int speed = 0; speed < numSpeeds; speed++) { 14241 if (speed != 0) { 14242 sb.append(", "); 14243 } 14244 long binderCountMs = binderThreadCpuTimesUs[index] / 1000; 14245 sb.append(TextUtils.formatSimple("%10d", binderCountMs)); 14246 14247 binderThreadTimeMs += binderCountMs; 14248 index++; 14249 } 14250 Slog.d(TAG, sb.toString()); 14251 } 14252 } 14253 } 14254 14255 /** 14256 * Mark the current partial timers as gone through a collection so that they will be 14257 * considered in the next cpu times distribution to wakelock holders. 14258 */ 14259 @VisibleForTesting 14260 public void markPartialTimersAsEligible() { 14261 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 14262 // No difference, so each timer is now considered for the next collection. 14263 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 14264 mPartialTimers.get(i).mInList = true; 14265 } 14266 } else { 14267 // The lists are different, meaning we added (or removed a timer) since the last 14268 // collection. 14269 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 14270 mLastPartialTimers.get(i).mInList = false; 14271 } 14272 mLastPartialTimers.clear(); 14273 14274 // Mark the current timers as gone through a collection. 14275 final int numPartialTimers = mPartialTimers.size(); 14276 for (int i = 0; i < numPartialTimers; ++i) { 14277 final StopwatchTimer timer = mPartialTimers.get(i); 14278 timer.mInList = true; 14279 mLastPartialTimers.add(timer); 14280 } 14281 } 14282 } 14283 14284 /** 14285 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 14286 * calculate cpu times spent by each uid at different frequencies. Will also add estimated 14287 * power consumptions, if powerAccumulator data structure is provided. 14288 * 14289 * @param updatedUids The uids for which times spent at different frequencies are calculated. 14290 * @param onBattery whether or not this is onBattery 14291 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 14292 */ 14293 @VisibleForTesting 14294 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery, 14295 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 14296 long totalCpuClustersTimeMs = 0; 14297 // Read the time spent for each cluster at various cpu frequencies. 14298 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 14299 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 14300 if (mKernelCpuSpeedReaders[cluster] != null) { 14301 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 14302 if (clusterSpeedTimesMs[cluster] != null) { 14303 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 14304 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 14305 } 14306 } 14307 } 14308 } 14309 if (totalCpuClustersTimeMs != 0) { 14310 // We have cpu times per freq aggregated over all uids but we need the times per uid. 14311 // So, we distribute total time spent by an uid to different cpu freqs based on the 14312 // amount of time cpu was running at that freq. 14313 final int updatedUidsCount = updatedUids.size(); 14314 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14315 final long uptimeMs = mClock.uptimeMillis(); 14316 for (int i = 0; i < updatedUidsCount; ++i) { 14317 final Uid u = getUidStatsLocked(updatedUids.keyAt(i), elapsedRealtimeMs, uptimeMs); 14318 final long appCpuTimeUs = updatedUids.valueAt(i); 14319 // Add the cpu speeds to this UID. 14320 int[] policies = mCpuScalingPolicies.getPolicies(); 14321 if (u.mCpuClusterSpeedTimesUs == null || 14322 u.mCpuClusterSpeedTimesUs.length != policies.length) { 14323 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[policies.length][]; 14324 } 14325 14326 for (int cluster = 0; cluster < policies.length; cluster++) { 14327 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 14328 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 14329 u.mCpuClusterSpeedTimesUs[cluster].length) { 14330 u.mCpuClusterSpeedTimesUs[cluster] 14331 = new LongSamplingCounter[speedsInCluster]; 14332 } 14333 14334 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 14335 for (int speed = 0; speed < speedsInCluster; speed++) { 14336 if (cpuSpeeds[speed] == null) { 14337 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 14338 } 14339 final long deltaSpeedCount = appCpuTimeUs 14340 * clusterSpeedTimesMs[cluster][speed] 14341 / totalCpuClustersTimeMs; 14342 cpuSpeeds[speed].addCountLocked(deltaSpeedCount, onBattery); 14343 14344 if (powerAccumulator != null) { 14345 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14346 speed, deltaSpeedCount); 14347 } 14348 } 14349 } 14350 } 14351 } 14352 } 14353 14354 /** 14355 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 14356 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 14357 * wakelock holders. 14358 * 14359 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 14360 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 14361 */ 14362 @VisibleForTesting 14363 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 14364 @Nullable SparseLongArray updatedUids, boolean onBattery) { 14365 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 14366 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 14367 final long startTimeMs = mClock.uptimeMillis(); 14368 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14369 14370 mCpuUidUserSysTimeReader.readDelta(false, (uid, timesUs) -> { 14371 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 14372 14373 uid = mapUid(uid); 14374 if (Process.isIsolated(uid)) { 14375 // This could happen if the isolated uid mapping was removed before that process 14376 // was actually killed. 14377 if (DEBUG) Slog.d(TAG, "Got readings for an isolated uid: " + uid); 14378 return; 14379 } 14380 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14381 if (DEBUG) Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 14382 return; 14383 } 14384 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 14385 14386 // Accumulate the total system and user time. 14387 mTempTotalCpuUserTimeUs += userTimeUs; 14388 mTempTotalCpuSystemTimeUs += systemTimeUs; 14389 14390 StringBuilder sb = null; 14391 if (DEBUG_ENERGY_CPU) { 14392 sb = new StringBuilder(); 14393 sb.append(" got time for uid=").append(u.mUid).append(": u="); 14394 TimeUtils.formatDuration(userTimeUs / 1000, sb); 14395 sb.append(" s="); 14396 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 14397 sb.append("\n"); 14398 } 14399 14400 if (numWakelocks > 0) { 14401 // We have wakelocks being held, so only give a portion of the 14402 // time to the process. The rest will be distributed among wakelock 14403 // holders. 14404 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 14405 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 14406 } 14407 14408 if (sb != null) { 14409 sb.append(" adding to uid=").append(u.mUid).append(": u="); 14410 TimeUtils.formatDuration(userTimeUs / 1000, sb); 14411 sb.append(" s="); 14412 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 14413 Slog.d(TAG, sb.toString()); 14414 } 14415 14416 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 14417 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 14418 if (updatedUids != null) { 14419 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 14420 } 14421 }); 14422 14423 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14424 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14425 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 14426 } 14427 14428 if (numWakelocks > 0) { 14429 // Distribute a portion of the total cpu time to wakelock holders. 14430 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 14431 mTempTotalCpuSystemTimeUs = 14432 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 14433 14434 for (int i = 0; i < numWakelocks; ++i) { 14435 final StopwatchTimer timer = partialTimers.get(i); 14436 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 14437 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 14438 14439 if (DEBUG_ENERGY_CPU) { 14440 final StringBuilder sb = new StringBuilder(); 14441 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 14442 .append(": u="); 14443 TimeUtils.formatDuration(userTimeUs / 1000, sb); 14444 sb.append(" s="); 14445 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 14446 Slog.d(TAG, sb.toString()); 14447 } 14448 14449 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 14450 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 14451 if (updatedUids != null) { 14452 final int uid = timer.mUid.getUid(); 14453 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 14454 } 14455 14456 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 14457 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 14458 14459 mTempTotalCpuUserTimeUs -= userTimeUs; 14460 mTempTotalCpuSystemTimeUs -= systemTimeUs; 14461 } 14462 } 14463 } 14464 14465 /** 14466 * Take a snapshot of the cpu times spent by each uid in each freq and update the 14467 * corresponding counters. Will also add estimated power consumptions, if powerAccumulator 14468 * data structure is provided. 14469 * 14470 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 14471 * @param onBattery whether or not this is onBattery 14472 * @param onBatteryScreenOff whether or not this is onBattery with the screen off. 14473 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 14474 */ 14475 @VisibleForTesting 14476 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 14477 boolean onBattery, boolean onBatteryScreenOff, 14478 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 14479 final boolean perClusterTimesAvailable = 14480 mCpuUidFreqTimeReader.perClusterTimesAvailable(); 14481 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 14482 final int[] policies = mCpuScalingPolicies.getPolicies(); 14483 final int numClusters = policies.length; 14484 mWakeLockAllocationsUs = null; 14485 final long startTimeMs = mClock.uptimeMillis(); 14486 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14487 // If power is being accumulated for attribution, data needs to be read immediately. 14488 final boolean forceRead = powerAccumulator != null; 14489 mCpuUidFreqTimeReader.readDelta(forceRead, (uid, cpuFreqTimeMs) -> { 14490 uid = mapUid(uid); 14491 if (Process.isIsolated(uid)) { 14492 if (DEBUG) Slog.d(TAG, "Got freq readings for an isolated uid: " + uid); 14493 return; 14494 } 14495 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14496 if (DEBUG) Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 14497 return; 14498 } 14499 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 14500 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 14501 detachIfNotNull(u.mCpuFreqTimeMs); 14502 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 14503 } 14504 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 14505 if (u.mScreenOffCpuFreqTimeMs == null || 14506 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 14507 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 14508 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 14509 mOnBatteryScreenOffTimeBase); 14510 } 14511 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 14512 14513 if (perClusterTimesAvailable) { 14514 if (u.mCpuClusterSpeedTimesUs == null || 14515 u.mCpuClusterSpeedTimesUs.length != numClusters) { 14516 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 14517 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 14518 } 14519 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 14520 mWakeLockAllocationsUs = new long[numClusters][]; 14521 } 14522 14523 int freqIndex = 0; 14524 for (int cluster = 0; cluster < numClusters; cluster++) { 14525 final int[] freqs = mCpuScalingPolicies.getFrequencies(policies[cluster]); 14526 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 14527 u.mCpuClusterSpeedTimesUs[cluster].length != freqs.length) { 14528 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 14529 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[freqs.length]; 14530 } 14531 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 14532 mWakeLockAllocationsUs[cluster] = new long[freqs.length]; 14533 } 14534 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 14535 for (int speed = 0; speed < freqs.length; ++speed) { 14536 if (cpuTimesUs[speed] == null) { 14537 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 14538 } 14539 final long appAllocationUs; 14540 if (mWakeLockAllocationsUs != null) { 14541 appAllocationUs = 14542 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 14543 mWakeLockAllocationsUs[cluster][speed] += 14544 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 14545 } else { 14546 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 14547 } 14548 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 14549 14550 if (powerAccumulator != null) { 14551 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14552 speed, appAllocationUs / 1000); 14553 } 14554 freqIndex++; 14555 } 14556 } 14557 } 14558 }); 14559 14560 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14561 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14562 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 14563 } 14564 14565 if (mWakeLockAllocationsUs != null) { 14566 for (int i = 0; i < numWakelocks; ++i) { 14567 final Uid u = partialTimers.get(i).mUid; 14568 if (u.mCpuClusterSpeedTimesUs == null || 14569 u.mCpuClusterSpeedTimesUs.length != numClusters) { 14570 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 14571 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 14572 } 14573 14574 for (int cluster = 0; cluster < numClusters; ++cluster) { 14575 final int speedsInCluster = 14576 mCpuScalingPolicies.getFrequencies(policies[cluster]).length; 14577 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 14578 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 14579 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 14580 u.mCpuClusterSpeedTimesUs[cluster] 14581 = new LongSamplingCounter[speedsInCluster]; 14582 } 14583 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 14584 for (int speed = 0; speed < speedsInCluster; ++speed) { 14585 if (cpuTimeUs[speed] == null) { 14586 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 14587 } 14588 final long allocationUs = 14589 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 14590 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 14591 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 14592 14593 if (powerAccumulator != null) { 14594 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14595 speed, allocationUs / 1000); 14596 } 14597 } 14598 } 14599 } 14600 } 14601 } 14602 14603 /** 14604 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 14605 * counters. 14606 */ 14607 @VisibleForTesting 14608 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 14609 final long startTimeMs = mClock.uptimeMillis(); 14610 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14611 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { 14612 final int parentUid = mapUid(uid); 14613 if (Process.isIsolated(parentUid)) { 14614 if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); 14615 return; 14616 } 14617 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14618 if (DEBUG) Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 14619 return; 14620 } 14621 final Uid u = getUidStatsLocked(parentUid, elapsedRealtimeMs, startTimeMs); 14622 if (parentUid == uid) { 14623 u.getCpuActiveTimeCounter().update(cpuActiveTimesMs, elapsedRealtimeMs); 14624 } else { 14625 final SparseArray<Uid.ChildUid> childUids = u.mChildUids; 14626 if (childUids == null) { 14627 return; 14628 } 14629 14630 Uid.ChildUid childUid = childUids.get(uid); 14631 if (childUid != null) { 14632 final long delta = 14633 childUid.cpuActiveCounter.update(cpuActiveTimesMs, elapsedRealtimeMs); 14634 u.getCpuActiveTimeCounter().increment(delta, elapsedRealtimeMs); 14635 } 14636 } 14637 }); 14638 14639 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14640 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14641 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 14642 } 14643 } 14644 14645 /** 14646 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 14647 * counters. Will also add estimated power consumptions, if powerAccumulator data structure 14648 * is provided. 14649 * 14650 * @param onBattery whether or not this is onBattery 14651 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 14652 */ 14653 @VisibleForTesting 14654 public void readKernelUidCpuClusterTimesLocked(boolean onBattery, 14655 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 14656 final long startTimeMs = mClock.uptimeMillis(); 14657 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14658 // If power is being accumulated for attribution, data needs to be read immediately. 14659 final boolean forceRead = powerAccumulator != null; 14660 mCpuUidClusterTimeReader.readDelta(forceRead, (uid, cpuClusterTimesMs) -> { 14661 uid = mapUid(uid); 14662 if (Process.isIsolated(uid)) { 14663 if (DEBUG) Slog.w(TAG, "Got cluster times for an isolated uid: " + uid); 14664 return; 14665 } 14666 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14667 if (DEBUG) Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 14668 return; 14669 } 14670 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 14671 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 14672 14673 if (powerAccumulator != null) { 14674 powerAccumulator.addCpuClusterDurationsMs(u, cpuClusterTimesMs); 14675 } 14676 }); 14677 14678 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14679 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14680 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 14681 } 14682 } 14683 14684 boolean setChargingLocked(boolean charging) { 14685 // if the device is no longer charging, remove the callback 14686 // if the device is now charging, it means that this is either called 14687 // 1. directly when level >= 90 14688 // 2. or from within the runnable that we deferred 14689 // For 1. if we have an existing callback, remove it, since we will immediately send a 14690 // ACTION_CHARGING 14691 // For 2. we remove existing callback so we don't send multiple ACTION_CHARGING 14692 mHandler.removeCallbacks(mDeferSetCharging); 14693 if (mCharging != charging) { 14694 mCharging = charging; 14695 mHistory.setChargingState(charging); 14696 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 14697 return true; 14698 } 14699 return false; 14700 } 14701 14702 /** 14703 * Notifies BatteryStatsImpl that the system server is ready. 14704 */ 14705 public void onSystemReady(Context context) { 14706 if (mCpuUidFreqTimeReader != null) { 14707 mCpuUidFreqTimeReader.onSystemReady(); 14708 } 14709 14710 mPowerStatsCollectorInjector.setContext(context); 14711 14712 mCpuPowerStatsCollector.setEnabled( 14713 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)); 14714 mCpuPowerStatsCollector.schedule(); 14715 14716 mMobileRadioPowerStatsCollector.setEnabled( 14717 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)); 14718 mMobileRadioPowerStatsCollector.schedule(); 14719 14720 mWifiPowerStatsCollector.setEnabled( 14721 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_WIFI)); 14722 mWifiPowerStatsCollector.schedule(); 14723 14724 mBluetoothPowerStatsCollector.setEnabled( 14725 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_BLUETOOTH)); 14726 mBluetoothPowerStatsCollector.schedule(); 14727 14728 mCameraPowerStatsCollector.setEnabled( 14729 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CAMERA)); 14730 mCameraPowerStatsCollector.schedule(); 14731 14732 mGnssPowerStatsCollector.setEnabled( 14733 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS)); 14734 mGnssPowerStatsCollector.schedule(); 14735 14736 mSystemReady = true; 14737 } 14738 14739 /** 14740 * Returns a PowerStatsCollector for the specified power component or null if unavailable. 14741 */ 14742 @Nullable 14743 PowerStatsCollector getPowerStatsCollector( 14744 @BatteryConsumer.PowerComponent int powerComponent) { 14745 switch (powerComponent) { 14746 case BatteryConsumer.POWER_COMPONENT_CPU: 14747 return mCpuPowerStatsCollector; 14748 case BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO: 14749 return mMobileRadioPowerStatsCollector; 14750 case BatteryConsumer.POWER_COMPONENT_WIFI: 14751 return mWifiPowerStatsCollector; 14752 case BatteryConsumer.POWER_COMPONENT_BLUETOOTH: 14753 return mBluetoothPowerStatsCollector; 14754 case BatteryConsumer.POWER_COMPONENT_CAMERA: 14755 return mCameraPowerStatsCollector; 14756 case BatteryConsumer.POWER_COMPONENT_GNSS: 14757 return mGnssPowerStatsCollector; 14758 } 14759 return null; 14760 } 14761 14762 14763 /** 14764 * Force recording of all history events regardless of the "charging" state. 14765 */ 14766 @VisibleForTesting 14767 public void forceRecordAllHistory() { 14768 mHistory.forceRecordAllHistory(); 14769 mRecordAllHistory = true; 14770 } 14771 14772 /** 14773 * Might reset battery stats if conditions are met. Assumed the device is currently plugged in. 14774 */ 14775 @VisibleForTesting 14776 @GuardedBy("this") 14777 public void maybeResetWhilePluggedInLocked() { 14778 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14779 if (shouldResetWhilePluggedInLocked(elapsedRealtimeMs)) { 14780 Slog.i(TAG, 14781 "Resetting due to long plug in duration. elapsed time = " + elapsedRealtimeMs 14782 + " ms, last plug in time = " + mBatteryPluggedInRealTimeMs 14783 + " ms, last reset time = " + mRealtimeStartUs / 1000); 14784 resetAllStatsAndHistoryLocked(RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION); 14785 } 14786 14787 scheduleNextResetWhilePluggedInCheck(); 14788 } 14789 14790 @GuardedBy("this") 14791 private void scheduleNextResetWhilePluggedInCheck() { 14792 if (mAlarmManager == null) return; 14793 final long timeoutMs = mClock.currentTimeMillis() 14794 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14795 * DateUtils.HOUR_IN_MILLIS; 14796 Calendar nextAlarm = Calendar.getInstance(); 14797 nextAlarm.setTimeInMillis(timeoutMs); 14798 14799 // Find the 2 AM the same day as the end of the minimum duration. 14800 // This logic does not handle a Daylight Savings transition, or a timezone change 14801 // while the alarm has been set. The need to reset after a long period while plugged 14802 // in is not strict enough to warrant a well architected out solution. 14803 nextAlarm.set(Calendar.MILLISECOND, 0); 14804 nextAlarm.set(Calendar.SECOND, 0); 14805 nextAlarm.set(Calendar.MINUTE, 0); 14806 nextAlarm.set(Calendar.HOUR_OF_DAY, 2); 14807 long possibleNextTimeMs = nextAlarm.getTimeInMillis(); 14808 if (possibleNextTimeMs < timeoutMs) { 14809 // The 2AM on the day of the timeout, move on the next day. 14810 possibleNextTimeMs += DateUtils.DAY_IN_MILLIS; 14811 } 14812 final long nextTimeMs = possibleNextTimeMs; 14813 final AlarmManager am = mAlarmManager; 14814 mHandler.post(() -> am.setWindow(AlarmManager.RTC, nextTimeMs, 14815 DateUtils.HOUR_IN_MILLIS, 14816 TAG, mLongPlugInAlarmHandler, mHandler)); 14817 } 14818 14819 14820 @GuardedBy("this") 14821 private boolean shouldResetWhilePluggedInLocked(long elapsedRealtimeMs) { 14822 if (mNoAutoReset) return false; 14823 if (!mSystemReady) return false; 14824 if (!mHistory.isResetEnabled()) return false; 14825 14826 final long pluggedInThresholdMs = mBatteryPluggedInRealTimeMs 14827 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14828 * DateUtils.HOUR_IN_MILLIS; 14829 if (elapsedRealtimeMs >= pluggedInThresholdMs) { 14830 // The device has been plugged in for a long time. 14831 final long resetThresholdMs = mRealtimeStartUs / 1000 14832 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14833 * DateUtils.HOUR_IN_MILLIS; 14834 if (elapsedRealtimeMs >= resetThresholdMs) { 14835 // And it has been a long time since the last reset. 14836 return true; 14837 } 14838 } 14839 14840 return false; 14841 } 14842 14843 @GuardedBy("this") 14844 private boolean shouldResetOnUnplugLocked(int batteryStatus, int batteryLevel) { 14845 if (mNoAutoReset) return false; 14846 if (!mSystemReady) return false; 14847 if (!mHistory.isResetEnabled()) return false; 14848 if (mBatteryStatsConfig.shouldResetOnUnplugHighBatteryLevel()) { 14849 // Allow resetting due to currently being at high battery level 14850 if (batteryStatus == BatteryManager.BATTERY_STATUS_FULL) return true; 14851 if (batteryLevel >= 90) return true; 14852 } 14853 if (mBatteryStatsConfig.shouldResetOnUnplugAfterSignificantCharge()) { 14854 // Allow resetting after a significant charge (from a very low level to a now very 14855 // high level). 14856 if (mDischargePlugLevel < 20 && batteryLevel >= 80) return true; 14857 } 14858 if (getHighDischargeAmountSinceCharge() >= 200) { 14859 // Reset the stats if battery got partially charged and discharged repeatedly without 14860 // ever reaching the full charge. 14861 // This reset is done in order to prevent stats sessions from going on forever. 14862 // Exceedingly long battery sessions would lead to an overflow of 14863 // data structures such as mWakeupReasonStats. 14864 return true; 14865 } 14866 14867 return false; 14868 } 14869 14870 @GuardedBy("this") 14871 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 14872 final boolean onBattery, final int oldStatus, final int level, final int chargeUah) { 14873 boolean doWrite = false; 14874 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 14875 m.arg1 = onBattery ? 1 : 0; 14876 mHandler.sendMessage(m); 14877 14878 final long uptimeUs = mSecUptime * 1000; 14879 final long realtimeUs = mSecRealtime * 1000; 14880 final int screenState = mScreenState; 14881 if (onBattery) { 14882 boolean reset = false; 14883 if (shouldResetOnUnplugLocked(oldStatus, level)) { 14884 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 14885 + " dischargeLevel=" + mDischargePlugLevel 14886 + " lowAmount=" + getLowDischargeAmountSinceCharge() 14887 + " highAmount=" + getHighDischargeAmountSinceCharge()); 14888 // Before we write, collect a snapshot of the final aggregated 14889 // stats to be reported in the next checkin. Only do this if we have 14890 // a sufficient amount of data to make it interesting. 14891 if (getLowDischargeAmountSinceCharge() >= 20) { 14892 final long startTimeMs = SystemClock.uptimeMillis(); 14893 final Parcel parcel = Parcel.obtain(); 14894 writeSummaryToParcel(parcel, true); 14895 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 14896 BackgroundThread.getHandler().post(new Runnable() { 14897 @Override public void run() { 14898 synchronized (mCheckinFile) { 14899 final long startTimeMs2 = SystemClock.uptimeMillis(); 14900 FileOutputStream stream = null; 14901 try { 14902 stream = mCheckinFile.startWrite(); 14903 stream.write(parcel.marshall()); 14904 stream.flush(); 14905 mCheckinFile.finishWrite(stream); 14906 mFrameworkStatsLogger.writeCommitSysConfigFile( 14907 "batterystats-checkin", 14908 initialTimeMs + SystemClock.uptimeMillis() 14909 - startTimeMs2); 14910 } catch (IOException e) { 14911 Slog.w("BatteryStats", 14912 "Error writing checkin battery statistics", e); 14913 mCheckinFile.failWrite(stream); 14914 } finally { 14915 parcel.recycle(); 14916 } 14917 } 14918 } 14919 }); 14920 } 14921 doWrite = true; 14922 resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_FULL_CHARGE); 14923 if (chargeUah > 0 && level > 0) { 14924 // Only use the reported coulomb charge value if it is supported and reported. 14925 mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0)); 14926 } 14927 reset = true; 14928 mDischargeStepTracker.init(); 14929 } 14930 if (mCharging) { 14931 setChargingLocked(false); 14932 } 14933 mOnBattery = mOnBatteryInternal = true; 14934 mLastDischargeStepLevel = level; 14935 mMinDischargeStepLevel = level; 14936 mDischargeStepTracker.clearTime(); 14937 mDailyDischargeStepTracker.clearTime(); 14938 mInitStepMode = mCurStepMode; 14939 mModStepMode = 0; 14940 pullPendingStateUpdatesLocked(); 14941 if (reset) { 14942 mHistory.startRecordingHistory(mSecRealtime, mSecUptime, reset); 14943 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 14944 } 14945 mBatteryPluggedIn = false; 14946 if (mAlarmManager != null) { 14947 final AlarmManager am = mAlarmManager; 14948 mHandler.post(() -> { 14949 // No longer plugged in. Cancel the long plug in alarm. 14950 am.cancel(mLongPlugInAlarmHandler); 14951 }); 14952 } 14953 mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn); 14954 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 14955 if (Display.isOnState(screenState)) { 14956 mDischargeScreenOnUnplugLevel = level; 14957 mDischargeScreenDozeUnplugLevel = 0; 14958 mDischargeScreenOffUnplugLevel = 0; 14959 } else if (Display.isDozeState(screenState)) { 14960 mDischargeScreenOnUnplugLevel = 0; 14961 mDischargeScreenDozeUnplugLevel = level; 14962 mDischargeScreenOffUnplugLevel = 0; 14963 } else { 14964 mDischargeScreenOnUnplugLevel = 0; 14965 mDischargeScreenDozeUnplugLevel = 0; 14966 mDischargeScreenOffUnplugLevel = level; 14967 } 14968 mDischargeAmountScreenOn = 0; 14969 mDischargeAmountScreenDoze = 0; 14970 mDischargeAmountScreenOff = 0; 14971 updateTimeBasesLocked(true, screenState, uptimeUs, realtimeUs); 14972 } else { 14973 mOnBattery = mOnBatteryInternal = false; 14974 pullPendingStateUpdatesLocked(); 14975 mBatteryPluggedIn = true; 14976 mBatteryPluggedInRealTimeMs = mSecRealtime; 14977 mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn); 14978 mDischargeCurrentLevel = mDischargePlugLevel = level; 14979 if (level < mDischargeUnplugLevel) { 14980 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 14981 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 14982 } 14983 updateDischargeScreenLevelsLocked(screenState, screenState); 14984 updateTimeBasesLocked(false, screenState, uptimeUs, realtimeUs); 14985 mChargeStepTracker.init(); 14986 mLastChargeStepLevel = level; 14987 mMaxChargeStepLevel = level; 14988 mInitStepMode = mCurStepMode; 14989 mModStepMode = 0; 14990 scheduleNextResetWhilePluggedInCheck(); 14991 } 14992 if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) { 14993 if (mStatsFile != null && !mHistory.isReadOnly()) { 14994 writeAsyncLocked(); 14995 } 14996 } 14997 } 14998 14999 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 15000 if (mExternalSync != null) { 15001 mExternalSync.scheduleSync(reason, updateFlags); 15002 } 15003 } 15004 15005 // This should probably be exposed in the API, though it's not critical 15006 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 15007 15008 @GuardedBy("this") 15009 public void setBatteryStateLocked(final int status, final int health, final int plugType, 15010 final int level, /* not final */ int temp, final int voltageMv, final int chargeUah, 15011 final int chargeFullUah, final long chargeTimeToFullSeconds, 15012 final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs) { 15013 15014 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 15015 temp = Math.max(0, temp); 15016 15017 reportChangesToStatsLog(status, plugType, level); 15018 15019 final boolean onBattery = isOnBattery(plugType, status); 15020 if (!mHaveBatteryLevel) { 15021 mHaveBatteryLevel = true; 15022 // We start out assuming that the device is plugged in (not 15023 // on battery). If our first report is now that we are indeed 15024 // plugged in, then twiddle our state to correctly reflect that 15025 // since we won't be going through the full setOnBattery(). 15026 if (onBattery == mOnBattery) { 15027 mHistory.setPluggedInState(!onBattery); 15028 } 15029 mBatteryStatus = status; 15030 mBatteryLevel = level; 15031 mBatteryChargeUah = chargeUah; 15032 15033 // Always start out assuming charging, that will be updated later. 15034 mHistory.setBatteryState(true /* charging */, status, level, chargeUah); 15035 15036 mMaxChargeStepLevel = mMinDischargeStepLevel = 15037 mLastChargeStepLevel = mLastDischargeStepLevel = level; 15038 } else if (mBatteryLevel != level || mOnBattery != onBattery) { 15039 recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs); 15040 } 15041 int oldStatus = mBatteryStatus; 15042 if (onBattery) { 15043 mDischargeCurrentLevel = level; 15044 if (!mHistory.isRecordingHistory()) { 15045 mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 15046 } 15047 } else if (level < 96 && 15048 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 15049 if (!mHistory.isRecordingHistory()) { 15050 mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 15051 } 15052 } 15053 if (mDischargePlugLevel < 0) { 15054 mDischargePlugLevel = level; 15055 } 15056 15057 if (onBattery != mOnBattery) { 15058 mBatteryLevel = level; 15059 mBatteryStatus = status; 15060 mBatteryHealth = health; 15061 mBatteryPlugType = plugType; 15062 mBatteryTemperature = temp; 15063 mBatteryVoltageMv = voltageMv; 15064 mHistory.setBatteryState(status, level, health, plugType, temp, voltageMv, chargeUah); 15065 if (chargeUah < mBatteryChargeUah) { 15066 // Only record discharges 15067 final long chargeDiff = (long) mBatteryChargeUah - chargeUah; 15068 mDischargeCounter.addCountLocked(chargeDiff); 15069 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 15070 if (Display.isDozeState(mScreenState)) { 15071 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 15072 } 15073 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 15074 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 15075 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 15076 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 15077 } 15078 } 15079 mBatteryChargeUah = chargeUah; 15080 setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUah); 15081 } else { 15082 boolean changed = false; 15083 if (mBatteryLevel != level) { 15084 mBatteryLevel = level; 15085 changed = true; 15086 15087 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 15088 // which will pull external stats. 15089 mExternalSync.scheduleSyncDueToBatteryLevelChange( 15090 mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); 15091 } 15092 if (mBatteryStatus != status) { 15093 mBatteryStatus = status; 15094 changed = true; 15095 } 15096 if (mBatteryHealth != health) { 15097 mBatteryHealth = health; 15098 changed = true; 15099 } 15100 if (mBatteryPlugType != plugType) { 15101 mBatteryPlugType = plugType; 15102 changed = true; 15103 } 15104 if (temp >= (mBatteryTemperature + 10) 15105 || temp <= (mBatteryTemperature - 10)) { 15106 mBatteryTemperature = temp; 15107 changed = true; 15108 } 15109 if (voltageMv > (mBatteryVoltageMv + 20) 15110 || voltageMv < (mBatteryVoltageMv - 20)) { 15111 mBatteryVoltageMv = voltageMv; 15112 changed = true; 15113 } 15114 if (chargeUah >= (mBatteryChargeUah + 10) 15115 || chargeUah <= (mBatteryChargeUah - 10)) { 15116 if (chargeUah < mBatteryChargeUah) { 15117 // Only record discharges 15118 final long chargeDiff = (long) mBatteryChargeUah - chargeUah; 15119 mDischargeCounter.addCountLocked(chargeDiff); 15120 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 15121 if (Display.isDozeState(mScreenState)) { 15122 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 15123 } 15124 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 15125 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 15126 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 15127 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 15128 } 15129 } 15130 mBatteryChargeUah = chargeUah; 15131 changed = true; 15132 } 15133 15134 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 15135 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 15136 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 15137 if (onBattery) { 15138 changed |= setChargingLocked(false); 15139 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 15140 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 15141 modeBits, elapsedRealtimeMs); 15142 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 15143 modeBits, elapsedRealtimeMs); 15144 mLastDischargeStepLevel = level; 15145 mMinDischargeStepLevel = level; 15146 mInitStepMode = mCurStepMode; 15147 mModStepMode = 0; 15148 } 15149 } else { 15150 if (level >= mConstants.BATTERY_CHARGING_ENFORCE_LEVEL) { 15151 // If the battery level is at least Constants.BATTERY_CHARGING_ENFORCE_LEVEL, 15152 // always consider the device to be charging even if it happens to go down a 15153 // level. 15154 changed |= setChargingLocked(true); 15155 } else if (!mCharging) { 15156 if (mLastChargeStepLevel < level) { 15157 // We have not reported that we are charging, but the level has gone up, 15158 // but we would like to not have tons of activity from charging-constraint 15159 // jobs, so instead of reporting ACTION_CHARGING immediately, we defer it. 15160 if (!mHandler.hasCallbacks(mDeferSetCharging)) { 15161 mHandler.postDelayed( 15162 mDeferSetCharging, 15163 mConstants.BATTERY_CHARGED_DELAY_MS); 15164 } 15165 } else if (mLastChargeStepLevel > level) { 15166 // if we had deferred a runnable due to charge level increasing, but then 15167 // later the charge level drops (could be due to thermal issues), we don't 15168 // want to trigger the deferred runnable, so remove it here 15169 mHandler.removeCallbacks(mDeferSetCharging); 15170 } 15171 } else { 15172 if (mLastChargeStepLevel > level) { 15173 // We had reported that the device was charging, but here we are with 15174 // power connected and the level going down. Looks like the current 15175 // power supplied isn't enough, so consider the device to now be 15176 // discharging. 15177 changed |= setChargingLocked(false); 15178 } 15179 } 15180 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 15181 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 15182 modeBits, elapsedRealtimeMs); 15183 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 15184 modeBits, elapsedRealtimeMs); 15185 mMaxChargeStepLevel = level; 15186 mInitStepMode = mCurStepMode; 15187 mModStepMode = 0; 15188 } 15189 mLastChargeStepLevel = level; 15190 } 15191 if (changed) { 15192 mHistory.setBatteryState(mBatteryStatus, mBatteryLevel, mBatteryHealth, 15193 mBatteryPlugType, mBatteryTemperature, mBatteryVoltageMv, 15194 mBatteryChargeUah); 15195 mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs); 15196 } 15197 } 15198 if (!onBattery && 15199 (status == BatteryManager.BATTERY_STATUS_FULL || 15200 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) { 15201 // We don't record history while we are plugged in and fully charged 15202 // (or when battery is not present). The next time we are 15203 // unplugged, history will be cleared. 15204 mHistory.setHistoryRecordingEnabled(DEBUG); 15205 } 15206 15207 mLastLearnedBatteryCapacityUah = chargeFullUah; 15208 if (mMinLearnedBatteryCapacityUah == -1) { 15209 mMinLearnedBatteryCapacityUah = chargeFullUah; 15210 } else { 15211 mMinLearnedBatteryCapacityUah = Math.min(mMinLearnedBatteryCapacityUah, chargeFullUah); 15212 } 15213 mMaxLearnedBatteryCapacityUah = Math.max(mMaxLearnedBatteryCapacityUah, chargeFullUah); 15214 15215 mBatteryTimeToFullSeconds = chargeTimeToFullSeconds; 15216 } 15217 15218 public static boolean isOnBattery(int plugType, int status) { 15219 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 15220 } 15221 15222 // Inform StatsLog of setBatteryState changes. 15223 private void reportChangesToStatsLog(final int status, final int plugType, final int level) { 15224 if (!mHaveBatteryLevel || mBatteryStatus != status) { 15225 mFrameworkStatsLogger.chargingStateChanged(status); 15226 } 15227 if (!mHaveBatteryLevel || mBatteryPlugType != plugType) { 15228 mFrameworkStatsLogger.pluggedStateChanged(plugType); 15229 } 15230 if (!mHaveBatteryLevel || mBatteryLevel != level) { 15231 mFrameworkStatsLogger.batteryLevelChanged(level); 15232 } 15233 } 15234 15235 public long getAwakeTimeBattery() { 15236 // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); 15237 // for over a decade, but surely that was a mistake. 15238 return getBatteryUptimeLocked(mClock.uptimeMillis()); 15239 } 15240 15241 public long getAwakeTimePlugged() { 15242 return (mClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 15243 } 15244 15245 @Override 15246 public long computeUptime(long curTimeUs, int which) { 15247 return mUptimeUs + (curTimeUs - mUptimeStartUs); 15248 } 15249 15250 @Override 15251 public long computeRealtime(long curTimeUs, int which) { 15252 return mRealtimeUs + (curTimeUs - mRealtimeStartUs); 15253 } 15254 15255 @Override 15256 public long computeBatteryUptime(long curTimeUs, int which) { 15257 return mOnBatteryTimeBase.computeUptime(curTimeUs, which); 15258 } 15259 15260 @Override 15261 public long computeBatteryRealtime(long curTimeUs, int which) { 15262 return mOnBatteryTimeBase.computeRealtime(curTimeUs, which); 15263 } 15264 15265 @Override 15266 public long computeBatteryScreenOffUptime(long curTimeUs, int which) { 15267 return mOnBatteryScreenOffTimeBase.computeUptime(curTimeUs, which); 15268 } 15269 15270 @Override 15271 public long computeBatteryScreenOffRealtime(long curTimeUs, int which) { 15272 return mOnBatteryScreenOffTimeBase.computeRealtime(curTimeUs, which); 15273 } 15274 15275 @Override 15276 public long computeBatteryTimeRemaining(long curTime) { 15277 if (!mOnBattery) { 15278 return -1; 15279 } 15280 /* Simple implementation just looks at the average discharge per level across the 15281 entire sample period. 15282 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 15283 if (discharge < 2) { 15284 return -1; 15285 } 15286 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 15287 if (duration < 1000*1000) { 15288 return -1; 15289 } 15290 long usPerLevel = duration/discharge; 15291 return usPerLevel * mCurrentBatteryLevel; 15292 */ 15293 if (mDischargeStepTracker.mNumStepDurations < 1) { 15294 return -1; 15295 } 15296 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 15297 if (msPerLevel <= 0) { 15298 return -1; 15299 } 15300 return (msPerLevel * mBatteryLevel) * 1000; 15301 } 15302 15303 @Override 15304 public LevelStepTracker getDischargeLevelStepTracker() { 15305 return mDischargeStepTracker; 15306 } 15307 15308 @Override 15309 public LevelStepTracker getDailyDischargeLevelStepTracker() { 15310 return mDailyDischargeStepTracker; 15311 } 15312 15313 @Override 15314 public long computeChargeTimeRemaining(long curTime) { 15315 if (mOnBattery) { 15316 // Not yet working. 15317 return -1; 15318 } 15319 if (mBatteryTimeToFullSeconds >= 0) { 15320 return mBatteryTimeToFullSeconds * (1000 * 1000); // s to us 15321 } 15322 // Else use algorithmic approach 15323 if (mChargeStepTracker.mNumStepDurations < 1) { 15324 return -1; 15325 } 15326 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 15327 if (msPerLevel <= 0) { 15328 return -1; 15329 } 15330 return (msPerLevel * (100 - mBatteryLevel)) * 1000; 15331 } 15332 15333 /*@hide */ 15334 public CellularBatteryStats getCellularBatteryStats() { 15335 final int which = STATS_SINCE_CHARGED; 15336 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 15337 final ControllerActivityCounter counter = getModemControllerActivity(); 15338 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 15339 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 15340 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 15341 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 15342 final long monitoredRailChargeConsumedMaMs = 15343 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 15344 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 15345 for (int i = 0; i < timeInRatMs.length; i++) { 15346 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTimeUs, which) / 1000; 15347 } 15348 long[] timeInRxSignalStrengthLevelMs = 15349 new long[CELL_SIGNAL_STRENGTH_LEVEL_COUNT]; 15350 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { 15351 timeInRxSignalStrengthLevelMs[i] = 15352 getPhoneSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 15353 } 15354 long[] txTimeMs = new long[Math.min(MODEM_TX_POWER_LEVEL_COUNT, 15355 counter.getTxTimeCounters().length)]; 15356 long totalTxTimeMs = 0; 15357 for (int i = 0; i < txTimeMs.length; i++) { 15358 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which); 15359 totalTxTimeMs += txTimeMs[i]; 15360 } 15361 15362 return new CellularBatteryStats(computeBatteryRealtime(rawRealTimeUs, which) / 1000, 15363 getMobileRadioActiveTime(rawRealTimeUs, which) / 1000, 15364 getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which), 15365 getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which), 15366 getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which), 15367 getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which), 15368 sleepTimeMs, idleTimeMs, rxTimeMs, energyConsumedMaMs, timeInRatMs, 15369 timeInRxSignalStrengthLevelMs, txTimeMs, 15370 monitoredRailChargeConsumedMaMs); 15371 } 15372 15373 /*@hide */ 15374 public WifiBatteryStats getWifiBatteryStats() { 15375 final int which = STATS_SINCE_CHARGED; 15376 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 15377 final ControllerActivityCounter counter = getWifiControllerActivity(); 15378 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 15379 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); 15380 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 15381 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); 15382 final long totalControllerActivityTimeMs 15383 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000; 15384 final long sleepTimeMs 15385 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs); 15386 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 15387 final long monitoredRailChargeConsumedMaMs = 15388 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 15389 long numAppScanRequest = 0; 15390 for (int i = 0; i < mUidStats.size(); i++) { 15391 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); 15392 } 15393 long[] timeInStateMs = new long[NUM_WIFI_STATES]; 15394 for (int i=0; i<NUM_WIFI_STATES; i++) { 15395 timeInStateMs[i] = getWifiStateTime(i, rawRealTimeUs, which) / 1000; 15396 } 15397 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; 15398 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15399 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTimeUs, which) / 1000; 15400 } 15401 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 15402 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15403 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 15404 } 15405 return new WifiBatteryStats( 15406 computeBatteryRealtime(rawRealTimeUs, which) / 1000, 15407 getWifiActiveTime(rawRealTimeUs, which) / 1000, 15408 getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which), 15409 getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which), 15410 getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which), 15411 getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which), 15412 sleepTimeMs, scanTimeMs, idleTimeMs, rxTimeMs, txTimeMs, energyConsumedMaMs, 15413 numAppScanRequest, timeInStateMs, timeSignalStrengthTimeMs, timeInSupplStateMs, 15414 monitoredRailChargeConsumedMaMs); 15415 } 15416 15417 /*@hide */ 15418 public GpsBatteryStats getGpsBatteryStats() { 15419 GpsBatteryStats s = new GpsBatteryStats(); 15420 final int which = STATS_SINCE_CHARGED; 15421 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 15422 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTimeUs, which) / 1000); 15423 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); 15424 long[] time = new long[mGpsSignalQualityTimer.length]; 15425 for (int i=0; i<time.length; i++) { 15426 time[i] = getGpsSignalQualityTime(i, rawRealTimeUs, which) / 1000; 15427 } 15428 s.setTimeInGpsSignalQualityLevel(time); 15429 return s; 15430 } 15431 15432 @Override 15433 public LevelStepTracker getChargeLevelStepTracker() { 15434 return mChargeStepTracker; 15435 } 15436 15437 @Override 15438 public LevelStepTracker getDailyChargeLevelStepTracker() { 15439 return mDailyChargeStepTracker; 15440 } 15441 15442 @Override 15443 public ArrayList<PackageChange> getDailyPackageChanges() { 15444 return mDailyPackageChanges; 15445 } 15446 15447 /** 15448 * @return battery uptime in microseconds 15449 */ 15450 protected long getBatteryUptimeLocked(long uptimeMs) { 15451 return mOnBatteryTimeBase.getUptime(uptimeMs * 1000); 15452 } 15453 15454 @Override 15455 public long getBatteryUptime(long curTimeUs) { 15456 return mOnBatteryTimeBase.getUptime(curTimeUs); 15457 } 15458 15459 @Override 15460 public long getBatteryRealtime(long curTimeUs) { 15461 return mOnBatteryTimeBase.getRealtime(curTimeUs); 15462 } 15463 15464 @Override 15465 public int getDischargeStartLevel() { 15466 synchronized(this) { 15467 return getDischargeStartLevelLocked(); 15468 } 15469 } 15470 15471 public int getDischargeStartLevelLocked() { 15472 return mDischargeUnplugLevel; 15473 } 15474 15475 @Override 15476 public int getDischargeCurrentLevel() { 15477 synchronized(this) { 15478 return getDischargeCurrentLevelLocked(); 15479 } 15480 } 15481 15482 public int getDischargeCurrentLevelLocked() { 15483 return mDischargeCurrentLevel; 15484 } 15485 15486 @Override 15487 public int getLowDischargeAmountSinceCharge() { 15488 synchronized(this) { 15489 int val = mLowDischargeAmountSinceCharge; 15490 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 15491 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 15492 } 15493 return val; 15494 } 15495 } 15496 15497 @Override 15498 public int getHighDischargeAmountSinceCharge() { 15499 synchronized(this) { 15500 int val = mHighDischargeAmountSinceCharge; 15501 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 15502 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 15503 } 15504 return val; 15505 } 15506 } 15507 15508 @Override 15509 public int getDischargeAmount(int which) { 15510 int dischargeAmount = which == STATS_SINCE_CHARGED 15511 ? getHighDischargeAmountSinceCharge() 15512 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 15513 if (dischargeAmount < 0) { 15514 dischargeAmount = 0; 15515 } 15516 return dischargeAmount; 15517 } 15518 15519 @Override 15520 public int getDischargeAmountScreenOn() { 15521 synchronized(this) { 15522 int val = mDischargeAmountScreenOn; 15523 if (mOnBattery && Display.isOnState(mScreenState) 15524 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 15525 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 15526 } 15527 return val; 15528 } 15529 } 15530 15531 @Override 15532 public int getDischargeAmountScreenOnSinceCharge() { 15533 synchronized(this) { 15534 int val = mDischargeAmountScreenOnSinceCharge; 15535 if (mOnBattery && Display.isOnState(mScreenState) 15536 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 15537 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 15538 } 15539 return val; 15540 } 15541 } 15542 15543 @Override 15544 public int getDischargeAmountScreenOff() { 15545 synchronized(this) { 15546 int val = mDischargeAmountScreenOff; 15547 if (mOnBattery && Display.isOffState(mScreenState) 15548 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 15549 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 15550 } 15551 // For backward compatibility, doze discharge is counted into screen off. 15552 return val + getDischargeAmountScreenDoze(); 15553 } 15554 } 15555 15556 @Override 15557 public int getDischargeAmountScreenOffSinceCharge() { 15558 synchronized(this) { 15559 int val = mDischargeAmountScreenOffSinceCharge; 15560 if (mOnBattery && Display.isOffState(mScreenState) 15561 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 15562 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 15563 } 15564 // For backward compatibility, doze discharge is counted into screen off. 15565 return val + getDischargeAmountScreenDozeSinceCharge(); 15566 } 15567 } 15568 15569 @Override 15570 public int getDischargeAmountScreenDoze() { 15571 synchronized(this) { 15572 int val = mDischargeAmountScreenDoze; 15573 if (mOnBattery && Display.isDozeState(mScreenState) 15574 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 15575 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 15576 } 15577 return val; 15578 } 15579 } 15580 15581 @Override 15582 public int getDischargeAmountScreenDozeSinceCharge() { 15583 synchronized(this) { 15584 int val = mDischargeAmountScreenDozeSinceCharge; 15585 if (mOnBattery && Display.isDozeState(mScreenState) 15586 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 15587 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 15588 } 15589 return val; 15590 } 15591 } 15592 15593 15594 /** 15595 * Estimates the time spent by the system server handling incoming binder requests. 15596 */ 15597 @Override 15598 public long[] getSystemServiceTimeAtCpuSpeeds() { 15599 if (mBinderThreadCpuTimesUs == null) { 15600 return null; 15601 } 15602 15603 return mBinderThreadCpuTimesUs.getCountsLocked(BatteryStats.STATS_SINCE_CHARGED); 15604 } 15605 15606 /** 15607 * Retrieve the statistics object for a particular uid, creating if needed. 15608 */ 15609 public Uid getUidStatsLocked(int uid) { 15610 return getUidStatsLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 15611 } 15612 15613 public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 15614 Uid u = mUidStats.get(uid); 15615 if (u == null) { 15616 if (Process.isSdkSandboxUid(uid)) { 15617 Log.wtf(TAG, "Tracking an SDK Sandbox UID"); 15618 } 15619 u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 15620 mUidStats.put(uid, u); 15621 } 15622 return u; 15623 } 15624 15625 /** 15626 * Retrieve the statistics object for a particular uid. Returns null if the object is not 15627 * available. 15628 */ 15629 public Uid getAvailableUidStatsLocked(int uid) { 15630 Uid u = mUidStats.get(uid); 15631 return u; 15632 } 15633 15634 @GuardedBy("this") 15635 public void onCleanupUserLocked(int userId, long elapsedRealtimeMs) { 15636 final int firstUidForUser = UserHandle.getUid(userId, 0); 15637 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 15638 mPendingRemovedUids.add( 15639 new UidToRemove(firstUidForUser, lastUidForUser, elapsedRealtimeMs)); 15640 } 15641 15642 @GuardedBy("this") 15643 public void onUserRemovedLocked(int userId) { 15644 if (mExternalSync != null) { 15645 // Clear out the removed user's UIDs after a short delay. The delay is needed 15646 // because at the point that this method is called, some activities are still 15647 // being wrapped up by those UIDs 15648 mExternalSync.scheduleCleanupDueToRemovedUser(userId); 15649 } 15650 } 15651 15652 /** 15653 * Removes battery stats for UIDs corresponding to a removed user. 15654 */ 15655 @GuardedBy("this") 15656 public void clearRemovedUserUidsLocked(int userId) { 15657 final int firstUidForUser = UserHandle.getUid(userId, 0); 15658 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 15659 mUidStats.put(firstUidForUser, null); 15660 mUidStats.put(lastUidForUser, null); 15661 final int firstIndex = mUidStats.indexOfKey(firstUidForUser); 15662 final int lastIndex = mUidStats.indexOfKey(lastUidForUser); 15663 for (int i = firstIndex; i <= lastIndex; i++) { 15664 final Uid uid = mUidStats.valueAt(i); 15665 if (uid != null) { 15666 uid.detachFromTimeBase(); 15667 } 15668 } 15669 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1); 15670 removeCpuStatsForUidRangeLocked(firstUidForUser, lastUidForUser); 15671 } 15672 15673 /** 15674 * @see #removeUidStatsLocked(int) 15675 */ 15676 @GuardedBy("this") 15677 public void removeUidStatsLocked(int uid, long elapsedRealtimeMs) { 15678 final Uid u = mUidStats.get(uid); 15679 if (u != null) { 15680 u.detachFromTimeBase(); 15681 } 15682 mUidStats.remove(uid); 15683 mPendingRemovedUids.add(new UidToRemove(uid, elapsedRealtimeMs)); 15684 } 15685 15686 /** 15687 * Removes the data for the deleted UIDs from the underlying kernel eBPF tables. 15688 */ 15689 @GuardedBy("this") 15690 private void removeCpuStatsForUidRangeLocked(int startUid, int endUid) { 15691 if (startUid == endUid) { 15692 mCpuUidUserSysTimeReader.removeUid(startUid); 15693 mCpuUidFreqTimeReader.removeUid(startUid); 15694 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 15695 mCpuUidActiveTimeReader.removeUid(startUid); 15696 mCpuUidClusterTimeReader.removeUid(startUid); 15697 } 15698 if (mKernelSingleUidTimeReader != null) { 15699 mKernelSingleUidTimeReader.removeUid(startUid); 15700 } 15701 mNumUidsRemoved++; 15702 } else if (startUid < endUid) { 15703 mCpuUidFreqTimeReader.removeUidsInRange(startUid, endUid); 15704 mCpuUidUserSysTimeReader.removeUidsInRange(startUid, endUid); 15705 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 15706 mCpuUidActiveTimeReader.removeUidsInRange(startUid, endUid); 15707 mCpuUidClusterTimeReader.removeUidsInRange(startUid, endUid); 15708 } 15709 if (mKernelSingleUidTimeReader != null) { 15710 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid); 15711 } 15712 mPowerStatsUidResolver.releaseUidsInRange(startUid, endUid); 15713 // Treat as one. We don't know how many uids there are in between. 15714 mNumUidsRemoved++; 15715 } else { 15716 Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid); 15717 } 15718 } 15719 15720 /** 15721 * Retrieve the statistics object for a particular process, creating 15722 * if needed. 15723 */ 15724 public Uid.Proc getProcessStatsLocked(int uid, String name, 15725 long elapsedRealtimeMs, long uptimeMs) { 15726 uid = mapUid(uid); 15727 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15728 return u.getProcessStatsLocked(name); 15729 } 15730 15731 /** 15732 * Retrieve the statistics object for a particular process, creating 15733 * if needed. 15734 */ 15735 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 15736 return getPackageStatsLocked(uid, pkg, mClock.elapsedRealtime(), mClock.uptimeMillis()); 15737 } 15738 15739 /** 15740 * @see getPackageStatsLocked(int, String) 15741 */ 15742 public Uid.Pkg getPackageStatsLocked(int uid, String pkg, 15743 long elapsedRealtimeMs, long uptimeMs) { 15744 uid = mapUid(uid); 15745 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15746 return u.getPackageStatsLocked(pkg); 15747 } 15748 15749 /** 15750 * Retrieve the statistics object for a particular service, creating 15751 * if needed. 15752 */ 15753 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name, 15754 long elapsedRealtimeMs, long uptimeMs) { 15755 uid = mapUid(uid); 15756 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15757 return u.getServiceStatsLocked(pkg, name); 15758 } 15759 15760 @GuardedBy("this") 15761 public void shutdownLocked() { 15762 mHistory.recordShutdownEvent(mClock.elapsedRealtime(), mClock.uptimeMillis(), 15763 mClock.currentTimeMillis()); 15764 writeSyncLocked(); 15765 mShuttingDown = true; 15766 } 15767 15768 @Override 15769 public boolean isProcessStateDataAvailable() { 15770 synchronized (this) { 15771 return trackPerProcStateCpuTimes(); 15772 } 15773 } 15774 15775 @GuardedBy("this") 15776 private boolean trackPerProcStateCpuTimes() { 15777 return mCpuUidFreqTimeReader.isFastCpuTimesReader(); 15778 } 15779 15780 /** 15781 * Enables or disables the PowerStatsCollector mode. 15782 */ 15783 public void setPowerStatsCollectorEnabled(@BatteryConsumer.PowerComponent int powerComponent, 15784 boolean enabled) { 15785 synchronized (this) { 15786 mPowerStatsCollectorEnabled.put(powerComponent, enabled); 15787 } 15788 } 15789 15790 @GuardedBy("this") 15791 public void systemServicesReady(Context context) { 15792 mConstants.startObserving(context.getContentResolver()); 15793 registerUsbStateReceiver(context); 15794 15795 synchronized (this) { 15796 mAlarmManager = context.getSystemService(AlarmManager.class); 15797 if (mBatteryPluggedIn) { 15798 // Already plugged in. Schedule the long plug in alarm. 15799 scheduleNextResetWhilePluggedInCheck(); 15800 } 15801 } 15802 } 15803 15804 /** 15805 * Initialize the EnergyConsumer stats data structures. 15806 * 15807 * @param supportedStandardBuckets boolean array indicating which {@link StandardPowerBucket}s 15808 * are currently supported. If null, none are supported 15809 * (regardless of customBucketNames). 15810 * @param customBucketNames names of custom (OTHER) EnergyConsumers on this device 15811 */ 15812 @GuardedBy("this") 15813 public void initEnergyConsumerStatsLocked(@Nullable boolean[] supportedStandardBuckets, 15814 String[] customBucketNames) { 15815 final int numDisplays = mPerDisplayBatteryStats.length; 15816 for (int i = 0; i < numDisplays; i++) { 15817 final int screenState = mPerDisplayBatteryStats[i].screenState; 15818 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 15819 } 15820 15821 if (supportedStandardBuckets != null) { 15822 final EnergyConsumerStats.Config config = new EnergyConsumerStats.Config( 15823 supportedStandardBuckets, customBucketNames, 15824 SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS, 15825 getBatteryConsumerProcessStateNames()); 15826 15827 if (mEnergyConsumerStatsConfig != null 15828 && !mEnergyConsumerStatsConfig.isCompatible(config)) { 15829 // Supported power buckets changed since last boot. 15830 // Existing data is no longer reliable. 15831 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 15832 RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE); 15833 } 15834 15835 mEnergyConsumerStatsConfig = config; 15836 mGlobalEnergyConsumerStats = new EnergyConsumerStats(config); 15837 15838 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_BLUETOOTH]) { 15839 mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile); 15840 } 15841 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO]) { 15842 mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile); 15843 } 15844 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_WIFI]) { 15845 mWifiPowerCalculator = new WifiPowerCalculator(mPowerProfile); 15846 } 15847 } else { 15848 if (mEnergyConsumerStatsConfig != null) { 15849 // EnergyConsumer no longer supported, wipe out the existing data. 15850 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 15851 RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE); 15852 } 15853 mEnergyConsumerStatsConfig = null; 15854 mGlobalEnergyConsumerStats = null; 15855 } 15856 } 15857 15858 @GuardedBy("this") 15859 private boolean isMobileRadioEnergyConsumerSupportedLocked() { 15860 if (mGlobalEnergyConsumerStats == null) return false; 15861 return mGlobalEnergyConsumerStats.isStandardBucketSupported( 15862 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 15863 } 15864 15865 @NonNull 15866 private static String[] getBatteryConsumerProcessStateNames() { 15867 String[] procStateNames = new String[BatteryConsumer.PROCESS_STATE_COUNT]; 15868 for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { 15869 procStateNames[procState] = BatteryConsumer.processStateToString(procState); 15870 } 15871 return procStateNames; 15872 } 15873 15874 /** Get the last known Battery voltage (in millivolts), returns -1 if unknown */ 15875 @GuardedBy("this") 15876 public int getBatteryVoltageMvLocked() { 15877 return mBatteryVoltageMv; 15878 } 15879 15880 @VisibleForTesting 15881 public final class Constants extends ContentObserver { 15882 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME 15883 = "track_cpu_active_cluster_time"; 15884 public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME 15885 = "kernel_uid_readers_throttle_time"; 15886 public static final String KEY_UID_REMOVE_DELAY_MS 15887 = "uid_remove_delay_ms"; 15888 public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 15889 = "external_stats_collection_rate_limit_ms"; 15890 public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS 15891 = "battery_level_collection_delay_ms"; 15892 public static final String KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 15893 "procstate_change_collection_delay_ms"; 15894 public static final String KEY_MAX_HISTORY_FILES = "max_history_files"; 15895 public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb"; 15896 public static final String KEY_BATTERY_CHARGED_DELAY_MS = 15897 "battery_charged_delay_ms"; 15898 public static final String KEY_BATTERY_CHARGING_ENFORCE_LEVEL = 15899 "battery_charging_enforce_level"; 15900 public static final String KEY_PER_UID_MODEM_POWER_MODEL = 15901 "per_uid_modem_power_model"; 15902 public static final String KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION = 15903 "phone_on_external_stats_collection"; 15904 public static final String KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 15905 "reset_while_plugged_in_minimum_duration_hours"; 15906 15907 public static final String PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME = 15908 "mobile_radio_active_time"; 15909 public static final String PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME = 15910 "modem_activity_info_rx_tx"; 15911 15912 /** Convert {@link PerUidModemPowerModel} to string */ 15913 public String getPerUidModemModelName(@PerUidModemPowerModel int model) { 15914 switch(model) { 15915 case PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME: 15916 return PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME; 15917 case PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX: 15918 return PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME; 15919 default: 15920 Slog.w(TAG, "Unexpected per uid modem model (" + model + ")"); 15921 return "unknown_" + model; 15922 } 15923 } 15924 15925 /** Convert string to {@link PerUidModemPowerModel} */ 15926 @PerUidModemPowerModel 15927 public int getPerUidModemModel(String name) { 15928 switch(name) { 15929 case PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME: 15930 return PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME; 15931 case PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME: 15932 return PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX; 15933 default: 15934 Slog.w(TAG, "Unexpected per uid modem model name (" + name + ")"); 15935 return DEFAULT_PER_UID_MODEM_MODEL; 15936 } 15937 } 15938 15939 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; 15940 private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000; 15941 private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; 15942 private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; 15943 private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; 15944 private static final long DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 60_000; 15945 private static final int DEFAULT_MAX_HISTORY_FILES = 32; 15946 private static final int DEFAULT_MAX_HISTORY_BUFFER_KB = 128; /*Kilo Bytes*/ 15947 private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64; 15948 private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/ 15949 private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */ 15950 private static final int DEFAULT_BATTERY_CHARGING_ENFORCE_LEVEL = 90; 15951 @PerUidModemPowerModel 15952 private static final int DEFAULT_PER_UID_MODEM_MODEL = 15953 PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX; 15954 private static final boolean DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION = true; 15955 // Little less than 2 days 15956 private static final int DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 47; 15957 15958 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; 15959 /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an 15960 * update when startObserving. */ 15961 public long KERNEL_UID_READERS_THROTTLE_TIME; 15962 public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; 15963 public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 15964 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 15965 public long BATTERY_LEVEL_COLLECTION_DELAY_MS 15966 = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; 15967 public long PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 15968 DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS; 15969 public int MAX_HISTORY_FILES; 15970 public int MAX_HISTORY_BUFFER; /*Bytes*/ 15971 public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS; 15972 public int BATTERY_CHARGING_ENFORCE_LEVEL = DEFAULT_BATTERY_CHARGING_ENFORCE_LEVEL; 15973 public int PER_UID_MODEM_MODEL = DEFAULT_PER_UID_MODEM_MODEL; 15974 public boolean PHONE_ON_EXTERNAL_STATS_COLLECTION = 15975 DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION; 15976 public int RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 15977 DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS; 15978 15979 private ContentResolver mResolver; 15980 private final KeyValueListParser mParser = new KeyValueListParser(','); 15981 15982 public Constants(Handler handler) { 15983 super(handler); 15984 if (isLowRamDevice()) { 15985 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE; 15986 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB * 1024; 15987 } else { 15988 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES; 15989 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_KB * 1024; 15990 } 15991 } 15992 15993 public void startObserving(ContentResolver resolver) { 15994 mResolver = resolver; 15995 mResolver.registerContentObserver( 15996 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS), 15997 false /* notifyForDescendants */, this); 15998 mResolver.registerContentObserver( 15999 Settings.Global.getUriFor(Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY), 16000 false /* notifyForDescendants */, this); 16001 mResolver.registerContentObserver(Settings.Global.getUriFor( 16002 Settings.Global.BATTERY_CHARGING_STATE_ENFORCE_LEVEL), 16003 false /* notifyForDescendants */, this); 16004 updateConstants(); 16005 } 16006 16007 @Override 16008 public void onChange(boolean selfChange, Uri uri) { 16009 if (uri.equals( 16010 Settings.Global.getUriFor( 16011 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY))) { 16012 synchronized (BatteryStatsImpl.this) { 16013 updateBatteryChargedDelayMsLocked(); 16014 } 16015 return; 16016 } else if (uri.equals(Settings.Global.getUriFor( 16017 Settings.Global.BATTERY_CHARGING_STATE_ENFORCE_LEVEL))) { 16018 synchronized (BatteryStatsImpl.this) { 16019 updateBatteryChargingEnforceLevelLocked(); 16020 } 16021 return; 16022 } 16023 updateConstants(); 16024 } 16025 16026 private void updateConstants() { 16027 synchronized (BatteryStatsImpl.this) { 16028 try { 16029 mParser.setString(Settings.Global.getString(mResolver, 16030 Settings.Global.BATTERY_STATS_CONSTANTS)); 16031 } catch (IllegalArgumentException e) { 16032 // Failed to parse the settings string, log this and move on 16033 // with defaults. 16034 Slog.e(TAG, "Bad batterystats settings", e); 16035 } 16036 16037 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( 16038 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); 16039 updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME, 16040 mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME, 16041 DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME)); 16042 updateUidRemoveDelay( 16043 mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS)); 16044 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( 16045 KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, 16046 DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 16047 BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( 16048 KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, 16049 DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); 16050 PROC_STATE_CHANGE_COLLECTION_DELAY_MS = mParser.getLong( 16051 KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS, 16052 DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 16053 MAX_HISTORY_FILES = mParser.getInt(KEY_MAX_HISTORY_FILES, 16054 isLowRamDevice() ? DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE 16055 : DEFAULT_MAX_HISTORY_FILES); 16056 MAX_HISTORY_BUFFER = mParser.getInt(KEY_MAX_HISTORY_BUFFER_KB, 16057 isLowRamDevice() ? DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB 16058 : DEFAULT_MAX_HISTORY_BUFFER_KB) 16059 * 1024; 16060 final String perUidModemModel = mParser.getString(KEY_PER_UID_MODEM_POWER_MODEL, 16061 ""); 16062 PER_UID_MODEM_MODEL = getPerUidModemModel(perUidModemModel); 16063 16064 PHONE_ON_EXTERNAL_STATS_COLLECTION = mParser.getBoolean( 16065 KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION, 16066 DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION); 16067 16068 RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = mParser.getInt( 16069 KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS, 16070 DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); 16071 16072 updateBatteryChargedDelayMsLocked(); 16073 updateBatteryChargingEnforceLevelLocked(); 16074 16075 onChange(); 16076 } 16077 } 16078 16079 /** 16080 * Propagates changes in constant values. 16081 */ 16082 @VisibleForTesting 16083 public void onChange() { 16084 mHistory.setMaxHistoryFiles(MAX_HISTORY_FILES); 16085 mHistory.setMaxHistoryBufferSize(MAX_HISTORY_BUFFER); 16086 } 16087 16088 private void updateBatteryChargedDelayMsLocked() { 16089 // a negative value indicates that we should ignore this override 16090 final int delay = Settings.Global.getInt(mResolver, 16091 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 16092 -1); 16093 16094 BATTERY_CHARGED_DELAY_MS = delay >= 0 ? delay : mParser.getInt( 16095 KEY_BATTERY_CHARGED_DELAY_MS, 16096 DEFAULT_BATTERY_CHARGED_DELAY_MS); 16097 16098 if (mHandler.hasCallbacks(mDeferSetCharging)) { 16099 mHandler.removeCallbacks(mDeferSetCharging); 16100 mHandler.postDelayed(mDeferSetCharging, BATTERY_CHARGED_DELAY_MS); 16101 } 16102 } 16103 16104 private void updateBatteryChargingEnforceLevelLocked() { 16105 int lastChargingEnforceLevel = BATTERY_CHARGING_ENFORCE_LEVEL; 16106 final int level = Settings.Global.getInt(mResolver, 16107 Settings.Global.BATTERY_CHARGING_STATE_ENFORCE_LEVEL, 16108 -1); 16109 16110 BATTERY_CHARGING_ENFORCE_LEVEL = level >= 0 ? level : mParser.getInt( 16111 KEY_BATTERY_CHARGING_ENFORCE_LEVEL, DEFAULT_BATTERY_CHARGING_ENFORCE_LEVEL); 16112 16113 if (BATTERY_CHARGING_ENFORCE_LEVEL <= mLastChargeStepLevel 16114 && mLastChargeStepLevel < lastChargingEnforceLevel) { 16115 setChargingLocked(true); 16116 } 16117 } 16118 16119 private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) { 16120 KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs; 16121 if (oldTimeMs != newTimeMs) { 16122 mCpuUidUserSysTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16123 mCpuUidFreqTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16124 mCpuUidActiveTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16125 mCpuUidClusterTimeReader 16126 .setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16127 } 16128 } 16129 16130 @GuardedBy("BatteryStatsImpl.this") 16131 private void updateUidRemoveDelay(long newTimeMs) { 16132 UID_REMOVE_DELAY_MS = newTimeMs; 16133 clearPendingRemovedUidsLocked(); 16134 } 16135 16136 public void dumpLocked(PrintWriter pw) { 16137 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); 16138 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); 16139 pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("="); 16140 pw.println(KERNEL_UID_READERS_THROTTLE_TIME); 16141 pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); 16142 pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 16143 pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); 16144 pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); 16145 pw.print(KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS); pw.print("="); 16146 pw.println(PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 16147 pw.print(KEY_MAX_HISTORY_FILES); pw.print("="); 16148 pw.println(MAX_HISTORY_FILES); 16149 pw.print(KEY_MAX_HISTORY_BUFFER_KB); pw.print("="); 16150 pw.println(MAX_HISTORY_BUFFER/1024); 16151 pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("="); 16152 pw.println(BATTERY_CHARGED_DELAY_MS); 16153 pw.print(KEY_BATTERY_CHARGING_ENFORCE_LEVEL); pw.print("="); 16154 pw.println(BATTERY_CHARGING_ENFORCE_LEVEL); 16155 pw.print(KEY_PER_UID_MODEM_POWER_MODEL); pw.print("="); 16156 pw.println(getPerUidModemModelName(PER_UID_MODEM_MODEL)); 16157 pw.print(KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION); pw.print("="); 16158 pw.println(PHONE_ON_EXTERNAL_STATS_COLLECTION); 16159 pw.print(KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); pw.print("="); 16160 pw.println(RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); 16161 } 16162 } 16163 16164 public long getExternalStatsCollectionRateLimitMs() { 16165 synchronized (this) { 16166 return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 16167 } 16168 } 16169 16170 @GuardedBy("this") 16171 public void dumpConstantsLocked(PrintWriter pw) { 16172 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16173 iPw.println("BatteryStats constants:"); 16174 iPw.increaseIndent(); 16175 mConstants.dumpLocked(iPw); 16176 iPw.decreaseIndent(); 16177 } 16178 16179 @GuardedBy("this") 16180 public void dumpCpuStatsLocked(PrintWriter pw) { 16181 int size = mUidStats.size(); 16182 pw.println("Per UID CPU user & system time in ms:"); 16183 for (int i = 0; i < size; i++) { 16184 int u = mUidStats.keyAt(i); 16185 Uid uid = mUidStats.get(u); 16186 pw.print(" "); pw.print(u); pw.print(": "); 16187 pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" "); 16188 pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000); 16189 } 16190 16191 pw.println("Per UID CPU active time in ms:"); 16192 for (int i = 0; i < size; i++) { 16193 int u = mUidStats.keyAt(i); 16194 Uid uid = mUidStats.get(u); 16195 if (uid.getCpuActiveTime() > 0) { 16196 pw.print(" "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime()); 16197 } 16198 } 16199 pw.println("Per UID CPU cluster time in ms:"); 16200 for (int i = 0; i < size; i++) { 16201 int u = mUidStats.keyAt(i); 16202 long[] times = mUidStats.get(u).getCpuClusterTimes(); 16203 if (times != null) { 16204 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 16205 } 16206 } 16207 pw.println("Per UID CPU frequency time in ms:"); 16208 for (int i = 0; i < size; i++) { 16209 int u = mUidStats.keyAt(i); 16210 long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED); 16211 if (times != null) { 16212 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 16213 } 16214 } 16215 16216 if (!Flags.disableSystemServicePowerAttr()) { 16217 updateSystemServiceCallStats(); 16218 if (mBinderThreadCpuTimesUs != null) { 16219 pw.println("Per UID System server binder time in ms:"); 16220 long[] systemServiceTimeAtCpuSpeeds = getSystemServiceTimeAtCpuSpeeds(); 16221 for (int i = 0; i < size; i++) { 16222 int u = mUidStats.keyAt(i); 16223 Uid uid = mUidStats.get(u); 16224 double proportionalSystemServiceUsage = uid.getProportionalSystemServiceUsage(); 16225 long timeUs = 0; 16226 for (int j = systemServiceTimeAtCpuSpeeds.length - 1; j >= 0; j--) { 16227 timeUs += systemServiceTimeAtCpuSpeeds[j] * proportionalSystemServiceUsage; 16228 } 16229 16230 pw.print(" "); 16231 pw.print(u); 16232 pw.print(": "); 16233 pw.println(timeUs / 1000); 16234 } 16235 } 16236 } 16237 } 16238 16239 /** 16240 * Dump EnergyConsumer stats 16241 */ 16242 @GuardedBy("this") 16243 public void dumpEnergyConsumerStatsLocked(PrintWriter pw) { 16244 pw.printf("On-battery energy consumer stats (microcoulombs) \n"); 16245 if (mGlobalEnergyConsumerStats == null) { 16246 pw.printf(" Not supported on this device.\n"); 16247 return; 16248 } 16249 16250 dumpEnergyConsumerStatsLocked(pw, "global usage", mGlobalEnergyConsumerStats); 16251 16252 int size = mUidStats.size(); 16253 for (int i = 0; i < size; i++) { 16254 final int u = mUidStats.keyAt(i); 16255 final Uid uid = mUidStats.get(u); 16256 final String name = "uid " + uid.mUid; 16257 dumpEnergyConsumerStatsLocked(pw, name, uid.mUidEnergyConsumerStats); 16258 } 16259 } 16260 16261 /** Dump EnergyConsumer stats for the given uid */ 16262 @GuardedBy("this") 16263 private void dumpEnergyConsumerStatsLocked(PrintWriter pw, String name, 16264 EnergyConsumerStats stats) { 16265 if (stats == null) return; 16266 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16267 iPw.increaseIndent(); 16268 iPw.printf("%s:\n", name); 16269 iPw.increaseIndent(); 16270 stats.dump(iPw); 16271 iPw.decreaseIndent(); 16272 } 16273 16274 /** 16275 * Dump Power Profile 16276 */ 16277 @GuardedBy("this") 16278 public void dumpPowerProfileLocked(PrintWriter pw) { 16279 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16280 iPw.printf("Power Profile: \n"); 16281 iPw.increaseIndent(); 16282 mPowerProfile.dump(iPw); 16283 iPw.decreaseIndent(); 16284 } 16285 16286 /** 16287 * Schedules an immediate (but asynchronous) collection of PowerStats samples. 16288 * Callers will need to wait for the collection to complete on the handler thread. 16289 */ 16290 public void schedulePowerStatsSampleCollection() { 16291 mCpuPowerStatsCollector.forceSchedule(); 16292 mMobileRadioPowerStatsCollector.forceSchedule(); 16293 mWifiPowerStatsCollector.forceSchedule(); 16294 mBluetoothPowerStatsCollector.forceSchedule(); 16295 mCameraPowerStatsCollector.forceSchedule(); 16296 mGnssPowerStatsCollector.forceSchedule(); 16297 } 16298 16299 /** 16300 * Schedules an immediate collection of PowerStats samples and awaits the result. 16301 */ 16302 public void collectPowerStatsSamples() { 16303 schedulePowerStatsSampleCollection(); 16304 ConditionVariable done = new ConditionVariable(); 16305 mHandler.post(done::open); 16306 done.block(); 16307 } 16308 16309 /** 16310 * Grabs one sample of PowerStats and prints it. 16311 */ 16312 public void dumpStatsSample(PrintWriter pw) { 16313 mCpuPowerStatsCollector.collectAndDump(pw); 16314 mMobileRadioPowerStatsCollector.collectAndDump(pw); 16315 mWifiPowerStatsCollector.collectAndDump(pw); 16316 mBluetoothPowerStatsCollector.collectAndDump(pw); 16317 mCameraPowerStatsCollector.collectAndDump(pw); 16318 mGnssPowerStatsCollector.collectAndDump(pw); 16319 } 16320 16321 private final Runnable mWriteAsyncRunnable = () -> { 16322 synchronized (BatteryStatsImpl.this) { 16323 writeSyncLocked(); 16324 } 16325 }; 16326 16327 @GuardedBy("this") 16328 public void writeAsyncLocked() { 16329 BackgroundThread.getHandler().removeCallbacks(mWriteAsyncRunnable); 16330 BackgroundThread.getHandler().post(mWriteAsyncRunnable); 16331 } 16332 16333 @GuardedBy("this") 16334 public void writeSyncLocked() { 16335 BackgroundThread.getHandler().removeCallbacks(mWriteAsyncRunnable); 16336 writeStatsLocked(); 16337 writeHistoryLocked(); 16338 } 16339 16340 @GuardedBy("this") 16341 private void writeStatsLocked() { 16342 if (mStatsFile == null) { 16343 Slog.w(TAG, 16344 "writeStatsLocked: no file associated with this instance"); 16345 return; 16346 } 16347 16348 if (mShuttingDown) { 16349 return; 16350 } 16351 16352 final Parcel p = Parcel.obtain(); 16353 try { 16354 final long start = SystemClock.uptimeMillis(); 16355 writeSummaryToParcel(p, false/*history is in separate file*/); 16356 if (DEBUG) { 16357 Slog.d(TAG, "writeSummaryToParcel duration ms:" 16358 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 16359 } 16360 mLastWriteTimeMs = mClock.elapsedRealtime(); 16361 writeParcelToFileLocked(p, mStatsFile); 16362 } finally { 16363 p.recycle(); 16364 } 16365 } 16366 16367 private void writeHistoryLocked() { 16368 if (mShuttingDown) { 16369 return; 16370 } 16371 16372 mHistory.writeHistory(); 16373 } 16374 16375 private final ReentrantLock mWriteLock = new ReentrantLock(); 16376 private void writeParcelToFileLocked(Parcel p, AtomicFile file) { 16377 mWriteLock.lock(); 16378 FileOutputStream fos = null; 16379 try { 16380 final long startTimeMs = SystemClock.uptimeMillis(); 16381 fos = file.startWrite(); 16382 fos.write(p.marshall()); 16383 fos.flush(); 16384 file.finishWrite(fos); 16385 if (DEBUG) { 16386 Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath() 16387 + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs) 16388 + " bytes:" + p.dataSize()); 16389 } 16390 mFrameworkStatsLogger.writeCommitSysConfigFile( 16391 "batterystats", SystemClock.uptimeMillis() - startTimeMs); 16392 } catch (IOException e) { 16393 Slog.w(TAG, "Error writing battery statistics", e); 16394 file.failWrite(fos); 16395 } finally { 16396 mWriteLock.unlock(); 16397 } 16398 } 16399 16400 @GuardedBy("this") 16401 public void readLocked() { 16402 if (mDailyFile != null) { 16403 readDailyStatsLocked(); 16404 } 16405 16406 if (mStatsFile == null) { 16407 Slog.w(TAG, "readLocked: no file associated with this instance"); 16408 return; 16409 } 16410 16411 mUidStats.clear(); 16412 16413 Parcel stats = Parcel.obtain(); 16414 try { 16415 final long start = SystemClock.uptimeMillis(); 16416 if (mStatsFile.exists()) { 16417 byte[] raw = mStatsFile.readFully(); 16418 stats.unmarshall(raw, 0, raw.length); 16419 stats.setDataPosition(0); 16420 readSummaryFromParcel(stats); 16421 if (DEBUG) { 16422 Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath() 16423 + " bytes:" + raw.length + " took ms:" + (SystemClock.uptimeMillis() 16424 - start)); 16425 } 16426 } 16427 } catch (Exception e) { 16428 Slog.e(TAG, "Error reading battery statistics", e); 16429 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 16430 RESET_REASON_CORRUPT_FILE); 16431 } finally { 16432 stats.recycle(); 16433 } 16434 16435 if (!mHistory.readSummary()) { 16436 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 16437 RESET_REASON_CORRUPT_FILE); 16438 } 16439 16440 mEndPlatformVersion = Build.ID; 16441 16442 mMonotonicEndTime = MonotonicClock.UNDEFINED; 16443 mHistory.continueRecordingHistory(); 16444 16445 recordDailyStatsIfNeededLocked(false, mClock.currentTimeMillis()); 16446 } 16447 16448 @GuardedBy("this") 16449 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 16450 final int version = in.readInt(); 16451 16452 if (version != VERSION) { 16453 Slog.w("BatteryStats", "readFromParcel: version got " + version 16454 + ", expected " + VERSION + "; erasing old stats"); 16455 return; 16456 } 16457 16458 mHistory.readSummaryFromParcel(in); 16459 16460 mStartCount = in.readInt(); 16461 mUptimeUs = in.readLong(); 16462 mRealtimeUs = in.readLong(); 16463 mStartClockTimeMs = in.readLong(); 16464 mMonotonicStartTime = in.readLong(); 16465 mMonotonicEndTime = in.readLong(); 16466 mStartPlatformVersion = in.readString(); 16467 mEndPlatformVersion = in.readString(); 16468 mOnBatteryTimeBase.readSummaryFromParcel(in); 16469 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 16470 mDischargeUnplugLevel = in.readInt(); 16471 mDischargePlugLevel = in.readInt(); 16472 mDischargeCurrentLevel = in.readInt(); 16473 mBatteryLevel = in.readInt(); 16474 mEstimatedBatteryCapacityMah = in.readInt(); 16475 mLastLearnedBatteryCapacityUah = in.readInt(); 16476 mMinLearnedBatteryCapacityUah = in.readInt(); 16477 mMaxLearnedBatteryCapacityUah = in.readInt(); 16478 mLowDischargeAmountSinceCharge = in.readInt(); 16479 mHighDischargeAmountSinceCharge = in.readInt(); 16480 mDischargeAmountScreenOnSinceCharge = in.readInt(); 16481 mDischargeAmountScreenOffSinceCharge = in.readInt(); 16482 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 16483 mDischargeStepTracker.readFromParcel(in); 16484 mChargeStepTracker.readFromParcel(in); 16485 mDailyDischargeStepTracker.readFromParcel(in); 16486 mDailyChargeStepTracker.readFromParcel(in); 16487 mDischargeCounter.readSummaryFromParcelLocked(in); 16488 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 16489 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in); 16490 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in); 16491 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in); 16492 int NPKG = in.readInt(); 16493 if (NPKG > 0) { 16494 mDailyPackageChanges = new ArrayList<>(NPKG); 16495 while (NPKG > 0) { 16496 NPKG--; 16497 PackageChange pc = new PackageChange(); 16498 pc.mPackageName = in.readString(); 16499 pc.mUpdate = in.readInt() != 0; 16500 pc.mVersionCode = in.readLong(); 16501 mDailyPackageChanges.add(pc); 16502 } 16503 } else { 16504 mDailyPackageChanges = null; 16505 } 16506 mDailyStartTimeMs = in.readLong(); 16507 mNextMinDailyDeadlineMs = in.readLong(); 16508 mNextMaxDailyDeadlineMs = in.readLong(); 16509 mBatteryTimeToFullSeconds = in.readLong(); 16510 16511 final EnergyConsumerStats.Config config = EnergyConsumerStats.Config.createFromParcel(in); 16512 final EnergyConsumerStats energyConsumerStats = 16513 EnergyConsumerStats.createAndReadSummaryFromParcel(mEnergyConsumerStatsConfig, in); 16514 if (config != null && Arrays.equals(config.getStateNames(), 16515 getBatteryConsumerProcessStateNames())) { 16516 /** 16517 * WARNING: Supported buckets may have changed across boots. Bucket mismatch is handled 16518 * later when {@link #initEnergyConsumerStatsLocked} is called. 16519 */ 16520 mEnergyConsumerStatsConfig = config; 16521 mGlobalEnergyConsumerStats = energyConsumerStats; 16522 } 16523 16524 mStartCount++; 16525 16526 mScreenState = Display.STATE_UNKNOWN; 16527 mScreenOnTimer.readSummaryFromParcelLocked(in); 16528 mScreenDozeTimer.readSummaryFromParcelLocked(in); 16529 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16530 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 16531 } 16532 final int numDisplays = in.readInt(); 16533 for (int i = 0; i < numDisplays; i++) { 16534 mPerDisplayBatteryStats[i].readSummaryFromParcel(in); 16535 } 16536 mInteractive = false; 16537 mInteractiveTimer.readSummaryFromParcelLocked(in); 16538 mPhoneOn = false; 16539 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 16540 mLongestLightIdleTimeMs = in.readLong(); 16541 mLongestFullIdleTimeMs = in.readLong(); 16542 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 16543 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 16544 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 16545 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 16546 mPhoneOnTimer.readSummaryFromParcelLocked(in); 16547 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 16548 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 16549 } 16550 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 16551 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 16552 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 16553 } 16554 mNrNsaTimer.readSummaryFromParcelLocked(in); 16555 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16556 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 16557 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 16558 } 16559 16560 final int numRat = in.readInt(); 16561 for (int i = 0; i < numRat; i++) { 16562 if (in.readInt() == 0) continue; 16563 getRatBatteryStatsLocked(i).readSummaryFromParcel(in); 16564 } 16565 16566 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 16567 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 16568 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 16569 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 16570 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 16571 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 16572 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in); 16573 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 16574 mWifiOn = false; 16575 mWifiOnTimer.readSummaryFromParcelLocked(in); 16576 mGlobalWifiRunning = false; 16577 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 16578 for (int i=0; i<NUM_WIFI_STATES; i++) { 16579 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 16580 } 16581 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 16582 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 16583 } 16584 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16585 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 16586 } 16587 mWifiActiveTimer.readSummaryFromParcelLocked(in); 16588 mWifiActivity.readSummaryFromParcel(in); 16589 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 16590 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); 16591 } 16592 mBluetoothActivity.readSummaryFromParcel(in); 16593 mModemActivity.readSummaryFromParcel(in); 16594 mHasWifiReporting = in.readInt() != 0; 16595 mHasBluetoothReporting = in.readInt() != 0; 16596 mHasModemReporting = in.readInt() != 0; 16597 16598 mNumConnectivityChange = in.readInt(); 16599 mFlashlightOnNesting = 0; 16600 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 16601 mCameraOnNesting = 0; 16602 mCameraOnTimer.readSummaryFromParcelLocked(in); 16603 mBluetoothScanNesting = 0; 16604 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 16605 16606 int NRPMS = in.readInt(); 16607 if (NRPMS > 10000) { 16608 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 16609 } 16610 for (int irpm = 0; irpm < NRPMS; irpm++) { 16611 if (in.readInt() != 0) { 16612 String rpmName = in.readString(); 16613 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 16614 } 16615 } 16616 int NSORPMS = in.readInt(); 16617 if (NSORPMS > 10000) { 16618 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS); 16619 } 16620 for (int irpm = 0; irpm < NSORPMS; irpm++) { 16621 if (in.readInt() != 0) { 16622 String rpmName = in.readString(); 16623 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 16624 } 16625 } 16626 int NKW = in.readInt(); 16627 if (NKW > 10000) { 16628 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 16629 } 16630 for (int ikw = 0; ikw < NKW; ikw++) { 16631 if (in.readInt() != 0) { 16632 String kwltName = in.readString(); 16633 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 16634 } 16635 } 16636 16637 int NWR = in.readInt(); 16638 if (NWR > 10000) { 16639 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 16640 } 16641 for (int iwr = 0; iwr < NWR; iwr++) { 16642 if (in.readInt() != 0) { 16643 String reasonName = in.readString(); 16644 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 16645 } 16646 } 16647 16648 int NMS = in.readInt(); 16649 for (int ims = 0; ims < NMS; ims++) { 16650 if (in.readInt() != 0) { 16651 long kmstName = in.readLong(); 16652 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 16653 } 16654 } 16655 16656 final int NU = in.readInt(); 16657 if (NU > 10000) { 16658 throw new ParcelFormatException("File corrupt: too many uids " + NU); 16659 } 16660 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 16661 final long uptimeMs = mClock.uptimeMillis(); 16662 for (int iu = 0; iu < NU; iu++) { 16663 int uid = in.readInt(); 16664 Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 16665 mUidStats.put(uid, u); 16666 16667 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 16668 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 16669 16670 u.mWifiRunning = false; 16671 if (in.readInt() != 0) { 16672 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 16673 } 16674 u.mFullWifiLockOut = false; 16675 if (in.readInt() != 0) { 16676 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 16677 } 16678 u.mWifiScanStarted = false; 16679 if (in.readInt() != 0) { 16680 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 16681 } 16682 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 16683 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 16684 if (in.readInt() != 0) { 16685 u.makeWifiBatchedScanBin(i, null); 16686 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 16687 } 16688 } 16689 u.mWifiMulticastWakelockCount = 0; 16690 if (in.readInt() != 0) { 16691 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 16692 } 16693 if (in.readInt() != 0) { 16694 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16695 } 16696 if (in.readInt() != 0) { 16697 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16698 } 16699 if (in.readInt() != 0) { 16700 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16701 } 16702 if (in.readInt() != 0) { 16703 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16704 } 16705 if (in.readInt() != 0) { 16706 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 16707 } 16708 if (in.readInt() != 0) { 16709 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 16710 } 16711 if (in.readInt() != 0) { 16712 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 16713 } 16714 if (in.readInt() != 0) { 16715 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 16716 } 16717 if (in.readInt() != 0) { 16718 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 16719 } 16720 if (in.readInt() != 0) { 16721 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 16722 } 16723 if (in.readInt() != 0) { 16724 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 16725 } 16726 u.mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 16727 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 16728 if (in.readInt() != 0) { 16729 u.makeProcessState(i, null); 16730 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 16731 } 16732 } 16733 if (in.readInt() != 0) { 16734 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 16735 } 16736 16737 if (in.readInt() != 0) { 16738 if (u.mUserActivityCounters == null) { 16739 u.initUserActivityLocked(); 16740 } 16741 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 16742 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 16743 } 16744 } 16745 16746 if (in.readInt() != 0) { 16747 u.ensureNetworkActivityLocked(); 16748 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16749 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 16750 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 16751 } 16752 if (in.readBoolean()) { 16753 u.mMobileRadioActiveTime = TimeMultiStateCounter.readFromParcel(in, 16754 mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 16755 elapsedRealtimeMs); 16756 } 16757 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 16758 } 16759 16760 u.mUserCpuTime.readSummaryFromParcelLocked(in); 16761 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 16762 16763 if (in.readInt() != 0) { 16764 final int numClusters = in.readInt(); 16765 int[] policies = 16766 mCpuScalingPolicies != null ? mCpuScalingPolicies.getPolicies() : null; 16767 if (policies != null && policies.length != numClusters) { 16768 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 16769 } 16770 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 16771 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 16772 for (int cluster = 0; cluster < numClusters; cluster++) { 16773 if (in.readInt() != 0) { 16774 final int NSB = in.readInt(); 16775 if (policies != null 16776 && mCpuScalingPolicies.getFrequencies(policies[cluster]).length 16777 != NSB) { 16778 throw new ParcelFormatException("File corrupt: too many speed bins " + 16779 NSB); 16780 } 16781 16782 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 16783 for (int speed = 0; speed < NSB; speed++) { 16784 if (in.readInt() != 0) { 16785 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 16786 mOnBatteryTimeBase); 16787 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 16788 } 16789 } 16790 } else { 16791 u.mCpuClusterSpeedTimesUs[cluster] = null; 16792 } 16793 } 16794 } else { 16795 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 16796 u.mCpuClusterSpeedTimesUs = null; 16797 } 16798 16799 detachIfNotNull(u.mCpuFreqTimeMs); 16800 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 16801 in, mOnBatteryTimeBase); 16802 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 16803 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 16804 in, mOnBatteryScreenOffTimeBase); 16805 16806 int stateCount = in.readInt(); 16807 if (stateCount != 0) { 16808 u.mCpuActiveTimeMs = TimeMultiStateCounter.readFromParcel(in, 16809 mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 16810 mClock.elapsedRealtime()); 16811 } 16812 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 16813 16814 detachIfNotNull(u.mProcStateTimeMs); 16815 u.mProcStateTimeMs = null; 16816 16817 stateCount = in.readInt(); 16818 if (stateCount != 0) { 16819 detachIfNotNull(u.mProcStateTimeMs); 16820 u.mProcStateTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 16821 mOnBatteryTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 16822 mCpuScalingPolicies.getScalingStepCount(), mClock.elapsedRealtime()); 16823 } 16824 16825 detachIfNotNull(u.mProcStateScreenOffTimeMs); 16826 u.mProcStateScreenOffTimeMs = null; 16827 16828 stateCount = in.readInt(); 16829 if (stateCount != 0) { 16830 detachIfNotNull(u.mProcStateScreenOffTimeMs); 16831 u.mProcStateScreenOffTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 16832 mOnBatteryScreenOffTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 16833 mCpuScalingPolicies.getScalingStepCount(), mClock.elapsedRealtime()); 16834 } 16835 16836 if (in.readInt() != 0) { 16837 detachIfNotNull(u.mMobileRadioApWakeupCount); 16838 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 16839 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 16840 } else { 16841 detachIfNotNull(u.mMobileRadioApWakeupCount); 16842 u.mMobileRadioApWakeupCount = null; 16843 } 16844 16845 if (in.readInt() != 0) { 16846 detachIfNotNull(u.mWifiRadioApWakeupCount); 16847 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 16848 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 16849 } else { 16850 detachIfNotNull(u.mWifiRadioApWakeupCount); 16851 u.mWifiRadioApWakeupCount = null; 16852 } 16853 16854 u.mUidEnergyConsumerStats = EnergyConsumerStats.createAndReadSummaryFromParcel( 16855 mEnergyConsumerStatsConfig, in); 16856 16857 int NW = in.readInt(); 16858 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 16859 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 16860 } 16861 for (int iw = 0; iw < NW; iw++) { 16862 String wlName = in.readString(); 16863 u.readWakeSummaryFromParcelLocked(wlName, in); 16864 } 16865 16866 int NS = in.readInt(); 16867 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 16868 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 16869 } 16870 for (int is = 0; is < NS; is++) { 16871 String name = in.readString(); 16872 u.readSyncSummaryFromParcelLocked(name, in); 16873 } 16874 16875 int NJ = in.readInt(); 16876 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 16877 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 16878 } 16879 for (int ij = 0; ij < NJ; ij++) { 16880 String name = in.readString(); 16881 u.readJobSummaryFromParcelLocked(name, in); 16882 } 16883 16884 u.readJobCompletionsFromParcelLocked(in); 16885 16886 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 16887 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 16888 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 16889 detachIfNotNull(u.mJobsFreshnessBuckets); 16890 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 16891 if (in.readInt() != 0) { 16892 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 16893 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 16894 } 16895 } 16896 16897 int NP = in.readInt(); 16898 if (NP > 1000) { 16899 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 16900 } 16901 for (int is = 0; is < NP; is++) { 16902 int seNumber = in.readInt(); 16903 if (in.readInt() != 0) { 16904 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 16905 } 16906 } 16907 16908 NP = in.readInt(); 16909 if (NP > 10000) { 16910 throw new ParcelFormatException("File corrupt: too many processes " + NP); 16911 } 16912 for (int ip = 0; ip < NP; ip++) { 16913 String procName = in.readString(); 16914 Uid.Proc p = u.getProcessStatsLocked(procName); 16915 p.mUserTimeMs = in.readLong(); 16916 p.mSystemTimeMs = in.readLong(); 16917 p.mForegroundTimeMs = in.readLong(); 16918 p.mStarts = in.readInt(); 16919 p.mNumCrashes = in.readInt(); 16920 p.mNumAnrs = in.readInt(); 16921 p.readExcessivePowerFromParcelLocked(in); 16922 } 16923 16924 NP = in.readInt(); 16925 if (NP > 10000) { 16926 throw new ParcelFormatException("File corrupt: too many packages " + NP); 16927 } 16928 for (int ip = 0; ip < NP; ip++) { 16929 String pkgName = in.readString(); 16930 detachIfNotNull(u.mPackageStats.get(pkgName)); 16931 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 16932 final int NWA = in.readInt(); 16933 if (NWA > 10000) { 16934 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 16935 } 16936 p.mWakeupAlarms.clear(); 16937 for (int iwa = 0; iwa < NWA; iwa++) { 16938 String tag = in.readString(); 16939 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 16940 c.readSummaryFromParcelLocked(in); 16941 p.mWakeupAlarms.put(tag, c); 16942 } 16943 NS = in.readInt(); 16944 if (NS > 10000) { 16945 throw new ParcelFormatException("File corrupt: too many services " + NS); 16946 } 16947 for (int is = 0; is < NS; is++) { 16948 String servName = in.readString(); 16949 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 16950 s.mStartTimeMs = in.readLong(); 16951 s.mStarts = in.readInt(); 16952 s.mLaunches = in.readInt(); 16953 } 16954 } 16955 } 16956 16957 if (!Flags.disableSystemServicePowerAttr()) { 16958 mBinderThreadCpuTimesUs = 16959 LongSamplingCounterArray.readSummaryFromParcelLocked(in, mOnBatteryTimeBase); 16960 } 16961 } 16962 16963 /** 16964 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 16965 * disk. This format does not allow a lossless round-trip. 16966 * 16967 * @param out the Parcel to be written to. 16968 */ 16969 @GuardedBy("this") 16970 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 16971 pullPendingStateUpdatesLocked(); 16972 16973 // Pull the clock time. This may update the time and make a new history entry 16974 // if we had originally pulled a time before the RTC was set. 16975 getStartClockTime(); 16976 16977 final long nowUptime = mClock.uptimeMillis() * 1000; 16978 final long nowRealtime = mClock.elapsedRealtime() * 1000; 16979 16980 out.writeInt(VERSION); 16981 16982 mHistory.writeSummaryToParcel(out, inclHistory); 16983 16984 out.writeInt(mStartCount); 16985 out.writeLong(computeUptime(nowUptime, STATS_SINCE_CHARGED)); 16986 out.writeLong(computeRealtime(nowRealtime, STATS_SINCE_CHARGED)); 16987 out.writeLong(mStartClockTimeMs); 16988 out.writeLong(mMonotonicStartTime); 16989 out.writeLong(mMonotonicClock.monotonicTime()); 16990 out.writeString(mStartPlatformVersion); 16991 out.writeString(mEndPlatformVersion); 16992 mOnBatteryTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 16993 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 16994 out.writeInt(mDischargeUnplugLevel); 16995 out.writeInt(mDischargePlugLevel); 16996 out.writeInt(mDischargeCurrentLevel); 16997 out.writeInt(mBatteryLevel); 16998 out.writeInt(mEstimatedBatteryCapacityMah); 16999 out.writeInt(mLastLearnedBatteryCapacityUah); 17000 out.writeInt(mMinLearnedBatteryCapacityUah); 17001 out.writeInt(mMaxLearnedBatteryCapacityUah); 17002 out.writeInt(getLowDischargeAmountSinceCharge()); 17003 out.writeInt(getHighDischargeAmountSinceCharge()); 17004 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 17005 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 17006 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 17007 mDischargeStepTracker.writeToParcel(out); 17008 mChargeStepTracker.writeToParcel(out); 17009 mDailyDischargeStepTracker.writeToParcel(out); 17010 mDailyChargeStepTracker.writeToParcel(out); 17011 mDischargeCounter.writeSummaryFromParcelLocked(out); 17012 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 17013 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 17014 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 17015 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 17016 if (mDailyPackageChanges != null) { 17017 final int NPKG = mDailyPackageChanges.size(); 17018 out.writeInt(NPKG); 17019 for (int i=0; i<NPKG; i++) { 17020 PackageChange pc = mDailyPackageChanges.get(i); 17021 out.writeString(pc.mPackageName); 17022 out.writeInt(pc.mUpdate ? 1 : 0); 17023 out.writeLong(pc.mVersionCode); 17024 } 17025 } else { 17026 out.writeInt(0); 17027 } 17028 out.writeLong(mDailyStartTimeMs); 17029 out.writeLong(mNextMinDailyDeadlineMs); 17030 out.writeLong(mNextMaxDailyDeadlineMs); 17031 out.writeLong(mBatteryTimeToFullSeconds); 17032 17033 EnergyConsumerStats.Config.writeToParcel(mEnergyConsumerStatsConfig, out); 17034 EnergyConsumerStats.writeSummaryToParcel(mGlobalEnergyConsumerStats, out); 17035 17036 mScreenOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17037 mScreenDozeTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17038 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 17039 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17040 } 17041 final int numDisplays = mPerDisplayBatteryStats.length; 17042 out.writeInt(numDisplays); 17043 for (int i = 0; i < numDisplays; i++) { 17044 mPerDisplayBatteryStats[i].writeSummaryToParcel(out, nowRealtime); 17045 } 17046 mInteractiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17047 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17048 out.writeLong(mLongestLightIdleTimeMs); 17049 out.writeLong(mLongestFullIdleTimeMs); 17050 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17051 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17052 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17053 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17054 mPhoneOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17055 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 17056 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17057 } 17058 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17059 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 17060 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17061 } 17062 mNrNsaTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17063 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 17064 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 17065 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 17066 } 17067 final int numRat = mPerRatBatteryStats.length; 17068 out.writeInt(numRat); 17069 for (int i = 0; i < numRat; i++) { 17070 final RadioAccessTechnologyBatteryStats ratStat = mPerRatBatteryStats[i]; 17071 if (ratStat == null) { 17072 out.writeInt(0); 17073 continue; 17074 } 17075 out.writeInt(1); 17076 ratStat.writeSummaryToParcel(out, nowRealtime); 17077 } 17078 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17079 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17080 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 17081 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 17082 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 17083 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17084 mWifiOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17085 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17086 for (int i=0; i<NUM_WIFI_STATES; i++) { 17087 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17088 } 17089 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 17090 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17091 } 17092 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 17093 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17094 } 17095 mWifiActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17096 mWifiActivity.writeSummaryToParcel(out); 17097 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 17098 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17099 } 17100 mBluetoothActivity.writeSummaryToParcel(out); 17101 mModemActivity.writeSummaryToParcel(out); 17102 out.writeInt(mHasWifiReporting ? 1 : 0); 17103 out.writeInt(mHasBluetoothReporting ? 1 : 0); 17104 out.writeInt(mHasModemReporting ? 1 : 0); 17105 17106 out.writeInt(mNumConnectivityChange); 17107 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17108 mCameraOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17109 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17110 17111 out.writeInt(mRpmStats.size()); 17112 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 17113 Timer rpmt = ent.getValue(); 17114 if (rpmt != null) { 17115 out.writeInt(1); 17116 out.writeString(ent.getKey()); 17117 rpmt.writeSummaryFromParcelLocked(out, nowRealtime); 17118 } else { 17119 out.writeInt(0); 17120 } 17121 } 17122 out.writeInt(mScreenOffRpmStats.size()); 17123 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 17124 Timer rpmt = ent.getValue(); 17125 if (rpmt != null) { 17126 out.writeInt(1); 17127 out.writeString(ent.getKey()); 17128 rpmt.writeSummaryFromParcelLocked(out, nowRealtime); 17129 } else { 17130 out.writeInt(0); 17131 } 17132 } 17133 17134 out.writeInt(mKernelWakelockStats.size()); 17135 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 17136 Timer kwlt = ent.getValue(); 17137 if (kwlt != null) { 17138 out.writeInt(1); 17139 out.writeString(ent.getKey()); 17140 kwlt.writeSummaryFromParcelLocked(out, nowRealtime); 17141 } else { 17142 out.writeInt(0); 17143 } 17144 } 17145 17146 out.writeInt(mWakeupReasonStats.size()); 17147 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 17148 SamplingTimer timer = ent.getValue(); 17149 if (timer != null) { 17150 out.writeInt(1); 17151 out.writeString(ent.getKey()); 17152 timer.writeSummaryFromParcelLocked(out, nowRealtime); 17153 } else { 17154 out.writeInt(0); 17155 } 17156 } 17157 17158 out.writeInt(mKernelMemoryStats.size()); 17159 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 17160 Timer kmt = mKernelMemoryStats.valueAt(i); 17161 if (kmt != null) { 17162 out.writeInt(1); 17163 out.writeLong(mKernelMemoryStats.keyAt(i)); 17164 kmt.writeSummaryFromParcelLocked(out, nowRealtime); 17165 } else { 17166 out.writeInt(0); 17167 } 17168 } 17169 17170 final int NU = mUidStats.size(); 17171 out.writeInt(NU); 17172 for (int iu = 0; iu < NU; iu++) { 17173 out.writeInt(mUidStats.keyAt(iu)); 17174 Uid u = mUidStats.valueAt(iu); 17175 17176 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 17177 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, nowUptime, 17178 nowRealtime); 17179 17180 if (u.mWifiRunningTimer != null) { 17181 out.writeInt(1); 17182 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17183 } else { 17184 out.writeInt(0); 17185 } 17186 if (u.mFullWifiLockTimer != null) { 17187 out.writeInt(1); 17188 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17189 } else { 17190 out.writeInt(0); 17191 } 17192 if (u.mWifiScanTimer != null) { 17193 out.writeInt(1); 17194 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17195 } else { 17196 out.writeInt(0); 17197 } 17198 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 17199 if (u.mWifiBatchedScanTimer[i] != null) { 17200 out.writeInt(1); 17201 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17202 } else { 17203 out.writeInt(0); 17204 } 17205 } 17206 if (u.mWifiMulticastTimer != null) { 17207 out.writeInt(1); 17208 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17209 } else { 17210 out.writeInt(0); 17211 } 17212 if (u.mAudioTurnedOnTimer != null) { 17213 out.writeInt(1); 17214 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17215 } else { 17216 out.writeInt(0); 17217 } 17218 if (u.mVideoTurnedOnTimer != null) { 17219 out.writeInt(1); 17220 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17221 } else { 17222 out.writeInt(0); 17223 } 17224 if (u.mFlashlightTurnedOnTimer != null) { 17225 out.writeInt(1); 17226 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17227 } else { 17228 out.writeInt(0); 17229 } 17230 if (u.mCameraTurnedOnTimer != null) { 17231 out.writeInt(1); 17232 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17233 } else { 17234 out.writeInt(0); 17235 } 17236 if (u.mForegroundActivityTimer != null) { 17237 out.writeInt(1); 17238 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17239 } else { 17240 out.writeInt(0); 17241 } 17242 if (u.mForegroundServiceTimer != null) { 17243 out.writeInt(1); 17244 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17245 } else { 17246 out.writeInt(0); 17247 } 17248 if (u.mAggregatedPartialWakelockTimer != null) { 17249 out.writeInt(1); 17250 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17251 } else { 17252 out.writeInt(0); 17253 } 17254 if (u.mBluetoothScanTimer != null) { 17255 out.writeInt(1); 17256 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17257 } else { 17258 out.writeInt(0); 17259 } 17260 if (u.mBluetoothUnoptimizedScanTimer != null) { 17261 out.writeInt(1); 17262 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17263 } else { 17264 out.writeInt(0); 17265 } 17266 if (u.mBluetoothScanResultCounter != null) { 17267 out.writeInt(1); 17268 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 17269 } else { 17270 out.writeInt(0); 17271 } 17272 if (u.mBluetoothScanResultBgCounter != null) { 17273 out.writeInt(1); 17274 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 17275 } else { 17276 out.writeInt(0); 17277 } 17278 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 17279 if (u.mProcessStateTimer[i] != null) { 17280 out.writeInt(1); 17281 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17282 } else { 17283 out.writeInt(0); 17284 } 17285 } 17286 if (u.mVibratorOnTimer != null) { 17287 out.writeInt(1); 17288 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17289 } else { 17290 out.writeInt(0); 17291 } 17292 17293 if (u.mUserActivityCounters == null) { 17294 out.writeInt(0); 17295 } else { 17296 out.writeInt(1); 17297 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 17298 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 17299 } 17300 } 17301 17302 if (u.mNetworkByteActivityCounters == null) { 17303 out.writeInt(0); 17304 } else { 17305 out.writeInt(1); 17306 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 17307 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 17308 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 17309 } 17310 if (u.mMobileRadioActiveTime != null) { 17311 out.writeBoolean(true); 17312 u.mMobileRadioActiveTime.writeToParcel(out); 17313 } else { 17314 out.writeBoolean(false); 17315 } 17316 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 17317 } 17318 17319 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 17320 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 17321 17322 if (u.mCpuClusterSpeedTimesUs != null) { 17323 out.writeInt(1); 17324 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 17325 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 17326 if (cpuSpeeds != null) { 17327 out.writeInt(1); 17328 out.writeInt(cpuSpeeds.length); 17329 for (LongSamplingCounter c : cpuSpeeds) { 17330 if (c != null) { 17331 out.writeInt(1); 17332 c.writeSummaryFromParcelLocked(out); 17333 } else { 17334 out.writeInt(0); 17335 } 17336 } 17337 } else { 17338 out.writeInt(0); 17339 } 17340 } 17341 } else { 17342 out.writeInt(0); 17343 } 17344 17345 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 17346 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 17347 17348 if (u.mCpuActiveTimeMs != null) { 17349 out.writeInt(u.mCpuActiveTimeMs.getStateCount()); 17350 u.mCpuActiveTimeMs.writeToParcel(out); 17351 } else { 17352 out.writeInt(0); 17353 } 17354 17355 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 17356 17357 if (u.mProcStateTimeMs != null) { 17358 out.writeInt(u.mProcStateTimeMs.getStateCount()); 17359 u.mProcStateTimeMs.writeToParcel(out); 17360 } else { 17361 out.writeInt(0); 17362 } 17363 17364 if (u.mProcStateScreenOffTimeMs != null) { 17365 out.writeInt(u.mProcStateScreenOffTimeMs.getStateCount()); 17366 u.mProcStateScreenOffTimeMs.writeToParcel(out); 17367 } else { 17368 out.writeInt(0); 17369 } 17370 17371 if (u.mMobileRadioApWakeupCount != null) { 17372 out.writeInt(1); 17373 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 17374 } else { 17375 out.writeInt(0); 17376 } 17377 17378 if (u.mWifiRadioApWakeupCount != null) { 17379 out.writeInt(1); 17380 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 17381 } else { 17382 out.writeInt(0); 17383 } 17384 17385 EnergyConsumerStats.writeSummaryToParcel(u.mUidEnergyConsumerStats, out); 17386 17387 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 17388 int NW = wakeStats.size(); 17389 out.writeInt(NW); 17390 for (int iw=0; iw<NW; iw++) { 17391 out.writeString(wakeStats.keyAt(iw)); 17392 Uid.Wakelock wl = wakeStats.valueAt(iw); 17393 if (wl.mTimerFull != null) { 17394 out.writeInt(1); 17395 wl.mTimerFull.writeSummaryFromParcelLocked(out, nowRealtime); 17396 } else { 17397 out.writeInt(0); 17398 } 17399 if (wl.mTimerPartial != null) { 17400 out.writeInt(1); 17401 wl.mTimerPartial.writeSummaryFromParcelLocked(out, nowRealtime); 17402 } else { 17403 out.writeInt(0); 17404 } 17405 if (wl.mTimerWindow != null) { 17406 out.writeInt(1); 17407 wl.mTimerWindow.writeSummaryFromParcelLocked(out, nowRealtime); 17408 } else { 17409 out.writeInt(0); 17410 } 17411 if (wl.mTimerDraw != null) { 17412 out.writeInt(1); 17413 wl.mTimerDraw.writeSummaryFromParcelLocked(out, nowRealtime); 17414 } else { 17415 out.writeInt(0); 17416 } 17417 } 17418 17419 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 17420 int NS = syncStats.size(); 17421 out.writeInt(NS); 17422 for (int is=0; is<NS; is++) { 17423 out.writeString(syncStats.keyAt(is)); 17424 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, nowRealtime); 17425 } 17426 17427 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 17428 int NJ = jobStats.size(); 17429 out.writeInt(NJ); 17430 for (int ij=0; ij<NJ; ij++) { 17431 out.writeString(jobStats.keyAt(ij)); 17432 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, nowRealtime); 17433 } 17434 17435 u.writeJobCompletionsToParcelLocked(out); 17436 17437 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 17438 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 17439 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 17440 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 17441 if (u.mJobsFreshnessBuckets[i] != null) { 17442 out.writeInt(1); 17443 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 17444 } else { 17445 out.writeInt(0); 17446 } 17447 } 17448 17449 int NSE = u.mSensorStats.size(); 17450 out.writeInt(NSE); 17451 for (int ise=0; ise<NSE; ise++) { 17452 out.writeInt(u.mSensorStats.keyAt(ise)); 17453 Uid.Sensor se = u.mSensorStats.valueAt(ise); 17454 if (se.mTimer != null) { 17455 out.writeInt(1); 17456 se.mTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17457 } else { 17458 out.writeInt(0); 17459 } 17460 } 17461 17462 int NP = u.mProcessStats.size(); 17463 out.writeInt(NP); 17464 for (int ip=0; ip<NP; ip++) { 17465 out.writeString(u.mProcessStats.keyAt(ip)); 17466 Uid.Proc ps = u.mProcessStats.valueAt(ip); 17467 out.writeLong(ps.mUserTimeMs); 17468 out.writeLong(ps.mSystemTimeMs); 17469 out.writeLong(ps.mForegroundTimeMs); 17470 out.writeInt(ps.mStarts); 17471 out.writeInt(ps.mNumCrashes); 17472 out.writeInt(ps.mNumAnrs); 17473 ps.writeExcessivePowerToParcelLocked(out); 17474 } 17475 17476 NP = u.mPackageStats.size(); 17477 out.writeInt(NP); 17478 if (NP > 0) { 17479 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 17480 : u.mPackageStats.entrySet()) { 17481 out.writeString(ent.getKey()); 17482 Uid.Pkg ps = ent.getValue(); 17483 final int NWA = ps.mWakeupAlarms.size(); 17484 out.writeInt(NWA); 17485 for (int iwa=0; iwa<NWA; iwa++) { 17486 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 17487 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 17488 } 17489 NS = ps.mServiceStats.size(); 17490 out.writeInt(NS); 17491 for (int is=0; is<NS; is++) { 17492 out.writeString(ps.mServiceStats.keyAt(is)); 17493 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 17494 long time = ss.getStartTimeToNowLocked( 17495 mOnBatteryTimeBase.getUptime(nowUptime) / 1000); 17496 out.writeLong(time); 17497 out.writeInt(ss.mStarts); 17498 out.writeInt(ss.mLaunches); 17499 } 17500 } 17501 } 17502 } 17503 17504 if (!Flags.disableSystemServicePowerAttr()) { 17505 LongSamplingCounterArray.writeSummaryToParcelLocked(out, mBinderThreadCpuTimesUs); 17506 } 17507 } 17508 17509 @GuardedBy("this") 17510 public void prepareForDumpLocked() { 17511 // Need to retrieve current kernel wake lock stats before printing. 17512 pullPendingStateUpdatesLocked(); 17513 17514 // Pull the clock time. This may update the time and make a new history entry 17515 // if we had originally pulled a time before the RTC was set. 17516 getStartClockTime(); 17517 17518 if (!Flags.disableSystemServicePowerAttr()) { 17519 updateSystemServiceCallStats(); 17520 } 17521 } 17522 17523 @GuardedBy("this") 17524 public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart, 17525 BatteryStatsDumpHelper dumpHelper) { 17526 if (DEBUG) { 17527 pw.println("mOnBatteryTimeBase:"); 17528 mOnBatteryTimeBase.dump(pw, " "); 17529 pw.println("mOnBatteryScreenOffTimeBase:"); 17530 mOnBatteryScreenOffTimeBase.dump(pw, " "); 17531 Printer pr = new PrintWriterPrinter(pw); 17532 pr.println("*** Screen on timer:"); 17533 mScreenOnTimer.logState(pr, " "); 17534 pr.println("*** Screen doze timer:"); 17535 mScreenDozeTimer.logState(pr, " "); 17536 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 17537 pr.println("*** Screen brightness #" + i + ":"); 17538 mScreenBrightnessTimer[i].logState(pr, " "); 17539 } 17540 pr.println("*** Interactive timer:"); 17541 mInteractiveTimer.logState(pr, " "); 17542 pr.println("*** Power save mode timer:"); 17543 mPowerSaveModeEnabledTimer.logState(pr, " "); 17544 pr.println("*** Device idle mode light timer:"); 17545 mDeviceIdleModeLightTimer.logState(pr, " "); 17546 pr.println("*** Device idle mode full timer:"); 17547 mDeviceIdleModeFullTimer.logState(pr, " "); 17548 pr.println("*** Device light idling timer:"); 17549 mDeviceLightIdlingTimer.logState(pr, " "); 17550 pr.println("*** Device idling timer:"); 17551 mDeviceIdlingTimer.logState(pr, " "); 17552 pr.println("*** Phone timer:"); 17553 mPhoneOnTimer.logState(pr, " "); 17554 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 17555 pr.println("*** Phone signal strength #" + i + ":"); 17556 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 17557 } 17558 pr.println("*** Signal scanning :"); 17559 mPhoneSignalScanningTimer.logState(pr, " "); 17560 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 17561 pr.println("*** Data connection type #" + i + ":"); 17562 mPhoneDataConnectionsTimer[i].logState(pr, " "); 17563 } 17564 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 17565 pr.println("*** Mobile network active timer:"); 17566 mMobileRadioActiveTimer.logState(pr, " "); 17567 pr.println("*** Mobile network active adjusted timer:"); 17568 mMobileRadioActiveAdjustedTime.logState(pr, " "); 17569 pr.println("*** Wifi Multicast WakeLock Timer:"); 17570 mWifiMulticastWakelockTimer.logState(pr, " "); 17571 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 17572 pr.println("*** Wifi timer:"); 17573 mWifiOnTimer.logState(pr, " "); 17574 pr.println("*** WifiRunning timer:"); 17575 mGlobalWifiRunningTimer.logState(pr, " "); 17576 for (int i=0; i<NUM_WIFI_STATES; i++) { 17577 pr.println("*** Wifi state #" + i + ":"); 17578 mWifiStateTimer[i].logState(pr, " "); 17579 } 17580 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 17581 pr.println("*** Wifi suppl state #" + i + ":"); 17582 mWifiSupplStateTimer[i].logState(pr, " "); 17583 } 17584 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 17585 pr.println("*** Wifi signal strength #" + i + ":"); 17586 mWifiSignalStrengthsTimer[i].logState(pr, " "); 17587 } 17588 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 17589 pr.println("*** GPS signal quality #" + i + ":"); 17590 mGpsSignalQualityTimer[i].logState(pr, " "); 17591 } 17592 pr.println("*** Flashlight timer:"); 17593 mFlashlightOnTimer.logState(pr, " "); 17594 pr.println("*** Camera timer:"); 17595 mCameraOnTimer.logState(pr, " "); 17596 } 17597 super.dump(context, pw, flags, reqUid, histStart, dumpHelper); 17598 17599 synchronized (this) { 17600 pw.print("Per process state tracking available: "); 17601 pw.println(trackPerProcStateCpuTimes()); 17602 pw.print("Total cpu time reads: "); 17603 pw.println(mNumSingleUidCpuTimeReads); 17604 pw.print("Batching Duration (min): "); 17605 pw.println((mClock.uptimeMillis() - mCpuTimeReadsTrackingStartTimeMs) / (60 * 1000)); 17606 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 17607 pw.println(mNumAllUidCpuTimeReads); 17608 pw.print("UIDs removed since the later of device start or stats reset: "); 17609 pw.println(mNumUidsRemoved); 17610 17611 mPowerStatsUidResolver.dump(pw); 17612 17613 pw.println(); 17614 dumpConstantsLocked(pw); 17615 17616 pw.println(); 17617 mCpuPowerStatsCollector.dumpCpuPowerBracketsLocked(pw); 17618 17619 pw.println(); 17620 dumpEnergyConsumerStatsLocked(pw); 17621 } 17622 } 17623 } 17624