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 SparseBooleanArray mPowerStatsCollectorEnabled = new SparseBooleanArray(); 302 private final WifiPowerStatsCollector.WifiStatsRetriever mWifiStatsRetriever = 303 new WifiPowerStatsCollector.WifiStatsRetriever() { 304 @Override 305 public void retrieveWifiScanTimes(Callback callback) { 306 synchronized (BatteryStatsImpl.this) { 307 retrieveWifiScanTimesLocked(callback); 308 } 309 } 310 311 @Override 312 public long getWifiActiveDuration() { 313 synchronized (BatteryStatsImpl.this) { 314 return getGlobalWifiRunningTime(mClock.elapsedRealtime() * 1000, 315 STATS_SINCE_CHARGED) / 1000; 316 } 317 } 318 }; 319 320 private class BluetoothStatsRetrieverImpl implements 321 BluetoothPowerStatsCollector.BluetoothStatsRetriever { 322 private final BluetoothManager mBluetoothManager; 323 BluetoothStatsRetrieverImpl(BluetoothManager bluetoothManager)324 BluetoothStatsRetrieverImpl(BluetoothManager bluetoothManager) { 325 mBluetoothManager = bluetoothManager; 326 } 327 328 @Override retrieveBluetoothScanTimes(Callback callback)329 public void retrieveBluetoothScanTimes(Callback callback) { 330 synchronized (BatteryStatsImpl.this) { 331 retrieveBluetoothScanTimesLocked(callback); 332 } 333 } 334 335 @Override requestControllerActivityEnergyInfo(Executor executor, BluetoothAdapter.OnBluetoothActivityEnergyInfoCallback callback)336 public boolean requestControllerActivityEnergyInfo(Executor executor, 337 BluetoothAdapter.OnBluetoothActivityEnergyInfoCallback callback) { 338 if (mBluetoothManager == null) { 339 return false; 340 } 341 342 BluetoothAdapter adapter = mBluetoothManager.getAdapter(); 343 if (adapter == null) { 344 return false; 345 } 346 347 adapter.requestControllerActivityEnergyInfo(executor, callback); 348 return true; 349 } 350 } 351 getKernelMemoryStats()352 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 353 return mKernelMemoryStats; 354 } 355 356 private static final int[] SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS = { 357 EnergyConsumerStats.POWER_BUCKET_CPU, 358 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 359 EnergyConsumerStats.POWER_BUCKET_WIFI, 360 EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 361 }; 362 363 // TimeInState counters need NUM_PROCESS_STATE states in order to accommodate 364 // Uid.PROCESS_STATE_NONEXISTENT, which is outside the range of legitimate proc states. 365 private static final int PROC_STATE_TIME_COUNTER_STATE_COUNT = NUM_PROCESS_STATE + 1; 366 367 @GuardedBy("this") 368 public boolean mPerProcStateCpuTimesAvailable = true; 369 370 @GuardedBy("this") 371 private long mNumSingleUidCpuTimeReads; 372 @GuardedBy("this") 373 private long mCpuTimeReadsTrackingStartTimeMs = SystemClock.uptimeMillis(); 374 @GuardedBy("this") 375 private int mNumUidsRemoved; 376 @GuardedBy("this") 377 private int mNumAllUidCpuTimeReads; 378 379 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ 380 private RpmStats mTmpRpmStats = null; 381 /** The soonest the RPM stats can be updated after it was last updated. */ 382 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; 383 /** Last time that RPM stats were updated by updateRpmStatsLocked. */ 384 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS; 385 386 /** Container for Rail Energy Data stats. */ 387 private RailStats mTmpRailStats; 388 389 /** 390 * Estimate UID modem power usage based on their estimated mobile radio active time. 391 */ 392 public static final int PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME = 1; 393 /** 394 * Estimate UID modem power consumption by proportionally attributing estimated Rx and Tx 395 * power consumption individually. 396 * ModemActivityInfo must be available. 397 */ 398 public static final int PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX = 2; 399 400 @IntDef(flag = true, prefix = "PER_UID_MODEM_MODEL_", value = { 401 PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME, 402 PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX, 403 }) 404 @Retention(RetentionPolicy.SOURCE) 405 public @interface PerUidModemPowerModel { 406 } 407 408 /** 409 * Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader}, 410 * {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader}, 411 * {@link KernelCpuUidFreqTimeReader} and from the Kernel. 412 * 413 * Isolated and invalid UID info must be removed to conserve memory. However, STATSD and 414 * Batterystats both need to access UID cpu time. To resolve this race condition, only 415 * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is 416 * implemented so that STATSD can capture those UID times before they are deleted. 417 */ 418 @GuardedBy("this") 419 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 420 protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>(); 421 422 @NonNull getHistory()423 public BatteryStatsHistory getHistory() { 424 return mHistory; 425 } 426 427 @NonNull copyHistory()428 BatteryStatsHistory copyHistory() { 429 return mHistory.copy(); 430 } 431 432 @VisibleForTesting 433 public final class UidToRemove { 434 private final int mStartUid; 435 private final int mEndUid; 436 private final long mUidRemovalTimestamp; 437 438 /** Remove just one UID */ UidToRemove(int uid, long timestamp)439 public UidToRemove(int uid, long timestamp) { 440 this(uid, uid, timestamp); 441 } 442 443 /** Remove a range of UIDs, startUid must be smaller than endUid. */ UidToRemove(int startUid, int endUid, long timestamp)444 public UidToRemove(int startUid, int endUid, long timestamp) { 445 mStartUid = startUid; 446 mEndUid = endUid; 447 mUidRemovalTimestamp = timestamp; 448 } 449 getUidRemovalTimestamp()450 public long getUidRemovalTimestamp() { 451 return mUidRemovalTimestamp; 452 } 453 454 @GuardedBy("BatteryStatsImpl.this") removeLocked()455 void removeLocked() { 456 removeCpuStatsForUidRangeLocked(mStartUid, mEndUid); 457 } 458 } 459 460 private boolean mSaveBatteryUsageStatsOnReset; 461 private BatteryUsageStatsProvider mBatteryUsageStatsProvider; 462 private PowerStatsStore mPowerStatsStore; 463 464 public interface BatteryCallback { batteryNeedsCpuUpdate()465 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)466 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)467 public void batterySendBroadcast(Intent intent); batteryStatsReset()468 public void batteryStatsReset(); 469 } 470 471 public interface PlatformIdleStateCallback { fillLowPowerStats(RpmStats rpmStats)472 public void fillLowPowerStats(RpmStats rpmStats); getSubsystemLowPowerStats()473 public String getSubsystemLowPowerStats(); 474 } 475 476 /** interface to update rail information for power monitor */ 477 public interface EnergyStatsRetriever { 478 /** Function to fill the map for the rail data stats 479 * Used for power monitoring feature 480 * @param railStats 481 */ fillRailDataStats(RailStats railStats)482 void fillRailDataStats(RailStats railStats); 483 } 484 485 public static abstract class UserInfoProvider { 486 private int[] userIds; getUserIds()487 protected abstract @Nullable int[] getUserIds(); 488 @VisibleForTesting refreshUserIds()489 public final void refreshUserIds() { 490 userIds = getUserIds(); 491 } 492 @VisibleForTesting exists(int userId)493 public boolean exists(int userId) { 494 return userIds != null ? ArrayUtils.contains(userIds, userId) : true; 495 } 496 } 497 498 /** Provide BatteryStatsImpl configuration choices */ 499 public static class BatteryStatsConfig { 500 static final int RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG = 1 << 0; 501 static final int RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG = 1 << 1; 502 503 private final int mFlags; 504 private final Long mDefaultPowerStatsThrottlePeriod; 505 private final Map<String, Long> mPowerStatsThrottlePeriods; 506 507 @VisibleForTesting BatteryStatsConfig()508 public BatteryStatsConfig() { 509 mFlags = 0; 510 mDefaultPowerStatsThrottlePeriod = 0L; 511 mPowerStatsThrottlePeriods = Map.of(); 512 } 513 BatteryStatsConfig(Builder builder)514 private BatteryStatsConfig(Builder builder) { 515 int flags = 0; 516 if (builder.mResetOnUnplugHighBatteryLevel) { 517 flags |= RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG; 518 } 519 if (builder.mResetOnUnplugAfterSignificantCharge) { 520 flags |= RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG; 521 } 522 mFlags = flags; 523 mDefaultPowerStatsThrottlePeriod = builder.mDefaultPowerStatsThrottlePeriod; 524 mPowerStatsThrottlePeriods = builder.mPowerStatsThrottlePeriods; 525 } 526 527 /** 528 * Returns whether a BatteryStats reset should occur on unplug when the battery level is 529 * high. 530 */ shouldResetOnUnplugHighBatteryLevel()531 public boolean shouldResetOnUnplugHighBatteryLevel() { 532 return (mFlags & RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG) 533 == RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG; 534 } 535 536 /** 537 * Returns whether a BatteryStats reset should occur on unplug if the battery charge a 538 * significant amount since it has been plugged in. 539 */ shouldResetOnUnplugAfterSignificantCharge()540 public boolean shouldResetOnUnplugAfterSignificantCharge() { 541 return (mFlags & RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG) 542 == RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG; 543 } 544 545 /** 546 * Returns the minimum amount of time (in millis) to wait between passes 547 * of power stats collection for the specified power component. 548 */ getPowerStatsThrottlePeriod(String powerComponentName)549 public long getPowerStatsThrottlePeriod(String powerComponentName) { 550 return mPowerStatsThrottlePeriods.getOrDefault(powerComponentName, 551 mDefaultPowerStatsThrottlePeriod); 552 } 553 554 /** 555 * Builder for BatteryStatsConfig 556 */ 557 public static class Builder { 558 private boolean mResetOnUnplugHighBatteryLevel; 559 private boolean mResetOnUnplugAfterSignificantCharge; 560 public static final long DEFAULT_POWER_STATS_THROTTLE_PERIOD = 561 TimeUnit.HOURS.toMillis(1); 562 public static final long DEFAULT_POWER_STATS_THROTTLE_PERIOD_CPU = 563 TimeUnit.MINUTES.toMillis(1); 564 private long mDefaultPowerStatsThrottlePeriod = DEFAULT_POWER_STATS_THROTTLE_PERIOD; 565 private final Map<String, Long> mPowerStatsThrottlePeriods = new HashMap<>(); 566 Builder()567 public Builder() { 568 mResetOnUnplugHighBatteryLevel = true; 569 mResetOnUnplugAfterSignificantCharge = true; 570 setPowerStatsThrottlePeriodMillis(BatteryConsumer.powerComponentIdToString( 571 BatteryConsumer.POWER_COMPONENT_CPU), 572 DEFAULT_POWER_STATS_THROTTLE_PERIOD_CPU); 573 } 574 575 /** 576 * Build the BatteryStatsConfig. 577 */ build()578 public BatteryStatsConfig build() { 579 return new BatteryStatsConfig(this); 580 } 581 582 /** 583 * Set whether a BatteryStats reset should occur on unplug when the battery level is 584 * high. 585 */ setResetOnUnplugHighBatteryLevel(boolean reset)586 public Builder setResetOnUnplugHighBatteryLevel(boolean reset) { 587 mResetOnUnplugHighBatteryLevel = reset; 588 return this; 589 } 590 591 /** 592 * Set whether a BatteryStats reset should occur on unplug if the battery charge a 593 * significant amount since it has been plugged in. 594 */ setResetOnUnplugAfterSignificantCharge(boolean reset)595 public Builder setResetOnUnplugAfterSignificantCharge(boolean reset) { 596 mResetOnUnplugAfterSignificantCharge = reset; 597 return this; 598 } 599 600 /** 601 * Sets the minimum amount of time (in millis) to wait between passes 602 * of power stats collection for the specified power component. 603 */ setPowerStatsThrottlePeriodMillis(String powerComponentName, long periodMs)604 public Builder setPowerStatsThrottlePeriodMillis(String powerComponentName, 605 long periodMs) { 606 mPowerStatsThrottlePeriods.put(powerComponentName, periodMs); 607 return this; 608 } 609 610 /** 611 * Sets the minimum amount of time (in millis) to wait between passes 612 * of power stats collection for any components not configured explicitly. 613 */ setDefaultPowerStatsThrottlePeriodMillis(long periodMs)614 public Builder setDefaultPowerStatsThrottlePeriodMillis(long periodMs) { 615 mDefaultPowerStatsThrottlePeriod = periodMs; 616 return this; 617 } 618 } 619 } 620 621 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 622 623 private final Runnable mDeferSetCharging = new Runnable() { 624 @Override 625 public void run() { 626 synchronized (BatteryStatsImpl.this) { 627 if (mOnBattery) { 628 // if the device gets unplugged in the time between this runnable being 629 // executed and the lock being taken, we don't want to set charging state 630 return; 631 } 632 boolean changed = setChargingLocked(true); 633 if (changed) { 634 final long uptimeMs = mClock.uptimeMillis(); 635 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 636 mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs); 637 } 638 } 639 } 640 }; 641 642 public final EnergyStatsRetriever mEnergyConsumerRetriever; 643 644 /** 645 * This handler is running on {@link BackgroundThread}. 646 */ 647 final class MyHandler extends Handler { MyHandler(Looper looper)648 public MyHandler(Looper looper) { 649 super(looper, null, true); 650 } 651 652 @Override handleMessage(Message msg)653 public void handleMessage(Message msg) { 654 BatteryCallback cb = mCallback; 655 switch (msg.what) { 656 case MSG_REPORT_CPU_UPDATE_NEEDED: 657 if (cb != null) { 658 cb.batteryNeedsCpuUpdate(); 659 } 660 break; 661 case MSG_REPORT_POWER_CHANGE: 662 if (cb != null) { 663 cb.batteryPowerChanged(msg.arg1 != 0); 664 } 665 break; 666 case MSG_REPORT_CHARGING: 667 if (cb != null) { 668 final String action; 669 synchronized (BatteryStatsImpl.this) { 670 action = mCharging ? BatteryManager.ACTION_CHARGING 671 : BatteryManager.ACTION_DISCHARGING; 672 } 673 Intent intent = new Intent(action); 674 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 675 cb.batterySendBroadcast(intent); 676 } 677 break; 678 case MSG_REPORT_RESET_STATS: 679 if (cb != null) { 680 cb.batteryStatsReset(); 681 } 682 } 683 } 684 } 685 postBatteryNeedsCpuUpdateMsg()686 public void postBatteryNeedsCpuUpdateMsg() { 687 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); 688 } 689 690 /** 691 * Update per-freq cpu times for the supplied UID. 692 */ 693 @GuardedBy("this") 694 @SuppressWarnings("GuardedBy") // errorprone false positive on getProcStateTimeCounter 695 @VisibleForTesting updateProcStateCpuTimesLocked(int uid, long elapsedRealtimeMs, long uptimeMs)696 public void updateProcStateCpuTimesLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 697 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 698 return; 699 } 700 701 ensureKernelSingleUidTimeReaderLocked(); 702 703 final Uid u = getUidStatsLocked(uid); 704 705 mNumSingleUidCpuTimeReads++; 706 707 LongArrayMultiStateCounter onBatteryCounter = 708 u.getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 709 LongArrayMultiStateCounter onBatteryScreenOffCounter = 710 u.getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 711 712 713 mKernelSingleUidTimeReader.addDelta(uid, onBatteryCounter, elapsedRealtimeMs); 714 mKernelSingleUidTimeReader.addDelta(uid, onBatteryScreenOffCounter, elapsedRealtimeMs); 715 716 if (u.mChildUids != null) { 717 LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 718 getCpuTimeInFreqContainer(); 719 int childUidCount = u.mChildUids.size(); 720 for (int j = childUidCount - 1; j >= 0; --j) { 721 LongArrayMultiStateCounter cpuTimeInFreqCounter = 722 u.mChildUids.valueAt(j).cpuTimeInFreqCounter; 723 if (cpuTimeInFreqCounter != null) { 724 mKernelSingleUidTimeReader.addDelta(u.mChildUids.keyAt(j), 725 cpuTimeInFreqCounter, elapsedRealtimeMs, deltaContainer); 726 onBatteryCounter.addCounts(deltaContainer); 727 onBatteryScreenOffCounter.addCounts(deltaContainer); 728 } 729 } 730 } 731 } 732 733 /** 734 * Removes kernel CPU stats for removed UIDs, in the order they were added to the 735 * mPendingRemovedUids queue. 736 */ 737 @GuardedBy("this") 738 @SuppressWarnings("GuardedBy") // errorprone false positive on removeLocked clearPendingRemovedUidsLocked()739 public void clearPendingRemovedUidsLocked() { 740 long cutOffTimeMs = mClock.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; 741 while (!mPendingRemovedUids.isEmpty() 742 && mPendingRemovedUids.peek().getUidRemovalTimestamp() < cutOffTimeMs) { 743 mPendingRemovedUids.poll().removeLocked(); 744 } 745 } 746 747 /** 748 * When the battery/screen state changes, we don't attribute the cpu times to any process 749 * but we still need to take snapshots of all uids to get correct deltas later on. 750 */ 751 @SuppressWarnings("GuardedBy") // errorprone false positive on getProcStateTimeCounter updateCpuTimesForAllUids()752 public void updateCpuTimesForAllUids() { 753 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 754 mCpuPowerStatsCollector.schedule(); 755 return; 756 } 757 758 synchronized (BatteryStatsImpl.this) { 759 if (!trackPerProcStateCpuTimes()) { 760 return; 761 } 762 763 ensureKernelSingleUidTimeReaderLocked(); 764 765 // TODO(b/197162116): just get a list of UIDs 766 final SparseArray<long[]> allUidCpuFreqTimesMs = 767 mCpuUidFreqTimeReader.getAllUidCpuFreqTimeMs(); 768 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) { 769 final int uid = allUidCpuFreqTimesMs.keyAt(i); 770 final int parentUid = mapUid(uid); 771 final Uid u = getAvailableUidStatsLocked(parentUid); 772 if (u == null) { 773 continue; 774 } 775 776 final int procState = u.mProcessState; 777 if (procState == Uid.PROCESS_STATE_NONEXISTENT) { 778 continue; 779 } 780 781 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 782 final long uptimeMs = mClock.uptimeMillis(); 783 final LongArrayMultiStateCounter onBatteryCounter = 784 u.getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 785 final LongArrayMultiStateCounter onBatteryScreenOffCounter = 786 u.getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 787 788 if (uid == parentUid || Process.isSdkSandboxUid(uid)) { 789 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryCounter, 790 elapsedRealtimeMs); 791 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryScreenOffCounter, 792 elapsedRealtimeMs); 793 } else { 794 Uid.ChildUid childUid = u.getChildUid(uid); 795 if (childUid != null) { 796 final LongArrayMultiStateCounter counter = childUid.cpuTimeInFreqCounter; 797 if (counter != null) { 798 final LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 799 getCpuTimeInFreqContainer(); 800 mKernelSingleUidTimeReader.addDelta(uid, counter, elapsedRealtimeMs, 801 deltaContainer); 802 onBatteryCounter.addCounts(deltaContainer); 803 onBatteryScreenOffCounter.addCounts(deltaContainer); 804 } 805 } 806 } 807 } 808 } 809 } 810 811 @GuardedBy("this") ensureKernelSingleUidTimeReaderLocked()812 private void ensureKernelSingleUidTimeReaderLocked() { 813 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU) 814 || mKernelSingleUidTimeReader != null) { 815 return; 816 } 817 818 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader( 819 mCpuScalingPolicies.getScalingStepCount()); 820 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.perClusterTimesAvailable() 821 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable(); 822 } 823 824 public interface ExternalStatsSync { 825 int UPDATE_CPU = 0x01; 826 int UPDATE_WIFI = 0x02; 827 int UPDATE_RADIO = 0x04; 828 int UPDATE_BT = 0x08; 829 int UPDATE_RPM = 0x10; 830 int UPDATE_DISPLAY = 0x20; 831 int UPDATE_CAMERA = 0x40; 832 int RESET = 0x80; 833 834 int UPDATE_ALL = 835 UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM | UPDATE_DISPLAY 836 | UPDATE_CAMERA; 837 838 int UPDATE_ON_PROC_STATE_CHANGE = UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT; 839 840 int UPDATE_ON_RESET = UPDATE_ALL | RESET; 841 842 @IntDef(flag = true, prefix = "UPDATE_", value = { 843 UPDATE_CPU, 844 UPDATE_WIFI, 845 UPDATE_RADIO, 846 UPDATE_BT, 847 UPDATE_RPM, 848 UPDATE_DISPLAY, 849 UPDATE_CAMERA, 850 UPDATE_ALL, 851 }) 852 @Retention(RetentionPolicy.SOURCE) 853 public @interface ExternalUpdateFlag { 854 } 855 scheduleSync(String reason, int flags)856 Future<?> scheduleSync(String reason, int flags); scheduleCpuSyncDueToRemovedUid(int uid)857 Future<?> scheduleCpuSyncDueToRemovedUid(int uid); 858 859 /** 860 * Schedule a sync because of a screen state change. 861 */ scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates)862 Future<?> scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, 863 boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates); scheduleCpuSyncDueToWakelockChange(long delayMillis)864 Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); cancelCpuSyncDueToWakelockChange()865 void cancelCpuSyncDueToWakelockChange(); scheduleSyncDueToBatteryLevelChange(long delayMillis)866 Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); 867 /** Schedule removal of UIDs corresponding to a removed user */ scheduleCleanupDueToRemovedUser(int userId)868 Future<?> scheduleCleanupDueToRemovedUser(int userId); 869 /** Schedule a sync because of a process state change */ scheduleSyncDueToProcessStateChange(int flags, long delayMillis)870 void scheduleSyncDueToProcessStateChange(int flags, long delayMillis); 871 } 872 873 public Handler mHandler; 874 private ExternalStatsSync mExternalSync = null; 875 @VisibleForTesting 876 protected UserInfoProvider mUserInfoProvider = null; 877 878 private BatteryCallback mCallback; 879 880 /** 881 * Mapping child uids to their parent uid. 882 */ 883 @VisibleForTesting 884 protected final PowerStatsUidResolver mPowerStatsUidResolver; 885 886 /** 887 * The statistics we have collected organized by uids. 888 */ 889 private final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 890 891 // A set of pools of currently active timers. When a timer is queried, we will divide the 892 // elapsed time by the number of active timers to arrive at that timer's share of the time. 893 // In order to do this, we must refresh each timer whenever the number of active timers 894 // changes. 895 @VisibleForTesting 896 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 897 private final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 898 private final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 899 private final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 900 private final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 901 private final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 902 private final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 903 private final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 904 private final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 905 private final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = 906 new SparseArray<>(); 907 private final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 908 private final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 909 private final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 910 private final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 911 private final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 912 913 // Last partial timers we use for distributing CPU usage. 914 @VisibleForTesting 915 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 916 917 // These are the objects that will want to do something when the device 918 // is unplugged from power. 919 protected final TimeBase mOnBatteryTimeBase = new TimeBase(true); 920 921 // These are the objects that will want to do something when the device 922 // is unplugged from power *and* the screen is off or doze. 923 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true); 924 925 private boolean mSystemReady; 926 private boolean mShuttingDown; 927 928 private final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 929 private final HistoryStepDetailsCalculatorImpl mStepDetailsCalculator = 930 new HistoryStepDetailsCalculatorImpl(); 931 932 private boolean mHaveBatteryLevel = false; 933 private boolean mBatteryPluggedIn; 934 private long mBatteryPluggedInRealTimeMs = 0; 935 private int mBatteryStatus; 936 private int mBatteryLevel; 937 private int mBatteryPlugType; 938 private int mBatteryChargeUah; 939 private int mBatteryHealth; 940 private int mBatteryTemperature; 941 private int mBatteryVoltageMv; 942 943 @NonNull 944 private final BatteryStatsHistory mHistory; 945 946 int mStartCount; 947 948 /** 949 * Set to true when a reset occurs, informing us that the next time BatteryExternalStatsWorker 950 * gives us data, we mustn't process it since this data includes pre-reset-period data. 951 */ 952 @GuardedBy("this") 953 boolean mIgnoreNextExternalStats = false; 954 955 long mStartClockTimeMs; 956 String mStartPlatformVersion; 957 String mEndPlatformVersion; 958 959 long mUptimeUs; 960 long mUptimeStartUs; 961 long mRealtimeUs; 962 long mRealtimeStartUs; 963 long mMonotonicStartTime; 964 long mMonotonicEndTime = MonotonicClock.UNDEFINED; 965 966 int mWakeLockNesting; 967 boolean mWakeLockImportant; 968 public boolean mRecordAllHistory; 969 boolean mNoAutoReset; 970 971 /** 972 * Overall screen state. For multidisplay devices, this represents the current highest screen 973 * state of the displays. 974 */ 975 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 976 protected int mScreenState = Display.STATE_UNKNOWN; 977 /** 978 * Overall screen on timer. For multidisplay devices, this represents the time spent with at 979 * least one display in the screen on state. 980 */ 981 StopwatchTimer mScreenOnTimer; 982 /** 983 * Overall screen doze timer. For multidisplay devices, this represents the time spent with 984 * screen doze being the highest screen state. 985 */ 986 StopwatchTimer mScreenDozeTimer; 987 /** 988 * Overall screen brightness bin. For multidisplay devices, this represents the current 989 * brightest screen. 990 */ 991 int mScreenBrightnessBin = -1; 992 /** 993 * Overall screen brightness timers. For multidisplay devices, the {@link mScreenBrightnessBin} 994 * timer will be active at any given time 995 */ 996 final StopwatchTimer[] mScreenBrightnessTimer = 997 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 998 999 boolean mPretendScreenOff; 1000 1001 private static class DisplayBatteryStats { 1002 /** 1003 * Per display screen state. 1004 */ 1005 public int screenState = Display.STATE_UNKNOWN; 1006 /** 1007 * Per display screen on timers. 1008 */ 1009 public StopwatchTimer screenOnTimer; 1010 /** 1011 * Per display screen doze timers. 1012 */ 1013 public StopwatchTimer screenDozeTimer; 1014 /** 1015 * Per display screen brightness bins. 1016 */ 1017 public int screenBrightnessBin = -1; 1018 /** 1019 * Per display screen brightness timers. 1020 */ 1021 public StopwatchTimer[] screenBrightnessTimers = 1022 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 1023 /** 1024 * Per display screen state the last time {@link #updateDisplayEnergyConsumerStatsLocked} 1025 * was called. 1026 */ 1027 public int screenStateAtLastEnergyMeasurement = Display.STATE_UNKNOWN; 1028 DisplayBatteryStats(Clock clock, TimeBase timeBase)1029 DisplayBatteryStats(Clock clock, TimeBase timeBase) { 1030 screenOnTimer = new StopwatchTimer(clock, null, -1, null, 1031 timeBase); 1032 screenDozeTimer = new StopwatchTimer(clock, null, -1, null, 1033 timeBase); 1034 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1035 screenBrightnessTimers[i] = new StopwatchTimer(clock, null, -100 - i, null, 1036 timeBase); 1037 } 1038 } 1039 1040 /** 1041 * Reset display timers. 1042 */ reset(long elapsedRealtimeUs)1043 public void reset(long elapsedRealtimeUs) { 1044 screenOnTimer.reset(false, elapsedRealtimeUs); 1045 screenDozeTimer.reset(false, elapsedRealtimeUs); 1046 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1047 screenBrightnessTimers[i].reset(false, elapsedRealtimeUs); 1048 } 1049 } 1050 1051 /** 1052 * Write data to summary parcel 1053 */ writeSummaryToParcel(Parcel out, long elapsedRealtimeUs)1054 public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { 1055 screenOnTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1056 screenDozeTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1057 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1058 screenBrightnessTimers[i].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1059 } 1060 } 1061 1062 /** 1063 * Read data from summary parcel 1064 */ readSummaryFromParcel(Parcel in)1065 public void readSummaryFromParcel(Parcel in) { 1066 screenOnTimer.readSummaryFromParcelLocked(in); 1067 screenDozeTimer.readSummaryFromParcelLocked(in); 1068 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1069 screenBrightnessTimers[i].readSummaryFromParcelLocked(in); 1070 } 1071 } 1072 } 1073 1074 DisplayBatteryStats[] mPerDisplayBatteryStats; 1075 1076 private int mDisplayMismatchWtfCount = 0; 1077 1078 boolean mInteractive; 1079 StopwatchTimer mInteractiveTimer; 1080 1081 boolean mPowerSaveModeEnabled; 1082 StopwatchTimer mPowerSaveModeEnabledTimer; 1083 1084 boolean mDeviceIdling; 1085 StopwatchTimer mDeviceIdlingTimer; 1086 1087 boolean mDeviceLightIdling; 1088 StopwatchTimer mDeviceLightIdlingTimer; 1089 1090 int mDeviceIdleMode; 1091 long mLastIdleTimeStartMs; 1092 long mLongestLightIdleTimeMs; 1093 long mLongestFullIdleTimeMs; 1094 StopwatchTimer mDeviceIdleModeLightTimer; 1095 StopwatchTimer mDeviceIdleModeFullTimer; 1096 1097 boolean mPhoneOn; 1098 StopwatchTimer mPhoneOnTimer; 1099 1100 int mAudioOnNesting; 1101 StopwatchTimer mAudioOnTimer; 1102 1103 int mVideoOnNesting; 1104 StopwatchTimer mVideoOnTimer; 1105 1106 int mFlashlightOnNesting; 1107 StopwatchTimer mFlashlightOnTimer; 1108 1109 int mCameraOnNesting; 1110 StopwatchTimer mCameraOnTimer; 1111 1112 private static final int USB_DATA_UNKNOWN = 0; 1113 private static final int USB_DATA_DISCONNECTED = 1; 1114 private static final int USB_DATA_CONNECTED = 2; 1115 int mUsbDataState = USB_DATA_UNKNOWN; 1116 1117 private static final int GPS_SIGNAL_QUALITY_NONE = 2; 1118 int mGpsSignalQualityBin = -1; 1119 final StopwatchTimer[] mGpsSignalQualityTimer = 1120 new StopwatchTimer[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS]; 1121 1122 int mPhoneSignalStrengthBin = -1; 1123 int mPhoneSignalStrengthBinRaw = -1; 1124 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 1125 new StopwatchTimer[CELL_SIGNAL_STRENGTH_LEVEL_COUNT]; 1126 1127 StopwatchTimer mPhoneSignalScanningTimer; 1128 1129 int mPhoneDataConnectionType = -1; 1130 final StopwatchTimer[] mPhoneDataConnectionsTimer = 1131 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 1132 1133 int mNrState = -1; 1134 StopwatchTimer mNrNsaTimer; 1135 1136 @RadioAccessTechnology 1137 int mActiveRat = RADIO_ACCESS_TECHNOLOGY_OTHER; 1138 1139 private static class RadioAccessTechnologyBatteryStats { 1140 /** 1141 * This RAT is currently being used. 1142 */ 1143 private boolean mActive = false; 1144 /** 1145 * Current active frequency range for this RAT. 1146 */ 1147 @ServiceState.FrequencyRange 1148 private int mFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN; 1149 /** 1150 * Current signal strength for this RAT. 1151 */ 1152 private int mSignalStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1153 /** 1154 * Timers for each combination of frequency range and signal strength. 1155 */ 1156 public final StopwatchTimer[][] perStateTimers; 1157 /** 1158 * Counters tracking the time (in milliseconds) spent transmitting data in a given state. 1159 */ 1160 @Nullable 1161 private LongSamplingCounter[][] mPerStateTxDurationMs = null; 1162 /** 1163 * Counters tracking the time (in milliseconds) spent receiving data in at given frequency. 1164 */ 1165 @Nullable 1166 private LongSamplingCounter[] mPerFrequencyRxDurationMs = null; 1167 RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase)1168 RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase) { 1169 perStateTimers = 1170 new StopwatchTimer[freqCount][CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 1171 for (int i = 0; i < freqCount; i++) { 1172 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1173 perStateTimers[i][j] = new StopwatchTimer(clock, null, -1, null, timeBase); 1174 } 1175 } 1176 } 1177 1178 /** 1179 * Note this RAT is currently being used. 1180 */ noteActive(boolean active, long elapsedRealtimeMs)1181 public void noteActive(boolean active, long elapsedRealtimeMs) { 1182 if (mActive == active) return; 1183 mActive = active; 1184 if (mActive) { 1185 perStateTimers[mFrequencyRange][mSignalStrength].startRunningLocked( 1186 elapsedRealtimeMs); 1187 } else { 1188 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked( 1189 elapsedRealtimeMs); 1190 } 1191 } 1192 1193 /** 1194 * Note current frequency range has changed. 1195 */ noteFrequencyRange(@erviceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs)1196 public void noteFrequencyRange(@ServiceState.FrequencyRange int frequencyRange, 1197 long elapsedRealtimeMs) { 1198 if (mFrequencyRange == frequencyRange) return; 1199 1200 if (!mActive) { 1201 // RAT not in use, note the frequency change and move on. 1202 mFrequencyRange = frequencyRange; 1203 return; 1204 } 1205 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked(elapsedRealtimeMs); 1206 perStateTimers[frequencyRange][mSignalStrength].startRunningLocked(elapsedRealtimeMs); 1207 mFrequencyRange = frequencyRange; 1208 } 1209 1210 /** 1211 * Note current signal strength has changed. 1212 */ noteSignalStrength(int signalStrength, long elapsedRealtimeMs)1213 public void noteSignalStrength(int signalStrength, long elapsedRealtimeMs) { 1214 if (mSignalStrength == signalStrength) return; 1215 1216 if (!mActive) { 1217 // RAT not in use, note the signal strength change and move on. 1218 mSignalStrength = signalStrength; 1219 return; 1220 } 1221 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked(elapsedRealtimeMs); 1222 perStateTimers[mFrequencyRange][signalStrength].startRunningLocked(elapsedRealtimeMs); 1223 mSignalStrength = signalStrength; 1224 } 1225 1226 /** 1227 * Returns the duration in milliseconds spent in a given state since the last mark. 1228 */ getTimeSinceMark(@erviceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)1229 public long getTimeSinceMark(@ServiceState.FrequencyRange int frequencyRange, 1230 int signalStrength, long elapsedRealtimeMs) { 1231 return perStateTimers[frequencyRange][signalStrength].getTimeSinceMarkLocked( 1232 elapsedRealtimeMs * 1000) / 1000; 1233 } 1234 1235 /** 1236 * Set mark for all timers. 1237 */ setMark(long elapsedRealtimeMs)1238 public void setMark(long elapsedRealtimeMs) { 1239 final int size = perStateTimers.length; 1240 for (int i = 0; i < size; i++) { 1241 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1242 perStateTimers[i][j].setMark(elapsedRealtimeMs); 1243 } 1244 } 1245 } 1246 1247 /** 1248 * Returns numbers of frequencies tracked for this RAT. 1249 */ getFrequencyRangeCount()1250 public int getFrequencyRangeCount() { 1251 return perStateTimers.length; 1252 } 1253 1254 /** 1255 * Add TX time for a given state. 1256 */ incrementTxDuration(@erviceState.FrequencyRange int frequencyRange, int signalStrength, long durationMs)1257 public void incrementTxDuration(@ServiceState.FrequencyRange int frequencyRange, 1258 int signalStrength, long durationMs) { 1259 getTxDurationCounter(frequencyRange, signalStrength, true).addCountLocked(durationMs); 1260 } 1261 1262 /** 1263 * Add TX time for a given frequency. 1264 */ incrementRxDuration(@erviceState.FrequencyRange int frequencyRange, long durationMs)1265 public void incrementRxDuration(@ServiceState.FrequencyRange int frequencyRange, 1266 long durationMs) { 1267 getRxDurationCounter(frequencyRange, true).addCountLocked(durationMs); 1268 } 1269 1270 /** 1271 * Reset radio access technology timers and counts. 1272 */ reset(long elapsedRealtimeUs)1273 public void reset(long elapsedRealtimeUs) { 1274 final int size = perStateTimers.length; 1275 for (int i = 0; i < size; i++) { 1276 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1277 perStateTimers[i][j].reset(false, elapsedRealtimeUs); 1278 if (mPerStateTxDurationMs == null) continue; 1279 mPerStateTxDurationMs[i][j].reset(false, elapsedRealtimeUs); 1280 } 1281 if (mPerFrequencyRxDurationMs == null) continue; 1282 mPerFrequencyRxDurationMs[i].reset(false, elapsedRealtimeUs); 1283 } 1284 } 1285 1286 /** 1287 * Write data to summary parcel 1288 */ writeSummaryToParcel(Parcel out, long elapsedRealtimeUs)1289 public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { 1290 final int freqCount = perStateTimers.length; 1291 out.writeInt(freqCount); 1292 out.writeInt(CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS); 1293 for (int i = 0; i < freqCount; i++) { 1294 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1295 perStateTimers[i][j].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1296 } 1297 } 1298 1299 if (mPerStateTxDurationMs == null) { 1300 out.writeInt(0); 1301 } else { 1302 out.writeInt(1); 1303 for (int i = 0; i < freqCount; i++) { 1304 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1305 mPerStateTxDurationMs[i][j].writeSummaryFromParcelLocked(out); 1306 } 1307 } 1308 } 1309 1310 if (mPerFrequencyRxDurationMs == null) { 1311 out.writeInt(0); 1312 } else { 1313 out.writeInt(1); 1314 for (int i = 0; i < freqCount; i++) { 1315 mPerFrequencyRxDurationMs[i].writeSummaryFromParcelLocked(out); 1316 } 1317 } 1318 } 1319 1320 /** 1321 * Read data from summary parcel 1322 */ readSummaryFromParcel(Parcel in)1323 public void readSummaryFromParcel(Parcel in) { 1324 final int oldFreqCount = in.readInt(); 1325 final int oldSignalStrengthCount = in.readInt(); 1326 final int currFreqCount = perStateTimers.length; 1327 final int currSignalStrengthCount = CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; 1328 1329 for (int freq = 0; freq < oldFreqCount; freq++) { 1330 for (int strength = 0; strength < oldSignalStrengthCount; strength++) { 1331 if (freq >= currFreqCount || strength >= currSignalStrengthCount) { 1332 // Mismatch with the summary parcel. Consume the data but don't use it. 1333 final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, 1334 new TimeBase()); 1335 // Consume perStateTimers data. 1336 temp.readSummaryFromParcelLocked(in); 1337 } else { 1338 perStateTimers[freq][strength].readSummaryFromParcelLocked(in); 1339 } 1340 } 1341 } 1342 1343 if (in.readInt() == 1) { 1344 for (int freq = 0; freq < oldFreqCount; freq++) { 1345 for (int strength = 0; strength < oldSignalStrengthCount; strength++) { 1346 if (freq >= currFreqCount || strength >= currSignalStrengthCount) { 1347 // Mismatch with the summary parcel. Consume the data but don't use it. 1348 final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, 1349 new TimeBase()); 1350 // Consume mPerStateTxDurationMs data. 1351 temp.readSummaryFromParcelLocked(in); 1352 } 1353 getTxDurationCounter(freq, strength, true).readSummaryFromParcelLocked(in); 1354 } 1355 } 1356 } 1357 1358 if (in.readInt() == 1) { 1359 for (int freq = 0; freq < oldFreqCount; freq++) { 1360 if (freq >= currFreqCount) { 1361 // Mismatch with the summary parcel. Consume the data but don't use it. 1362 final StopwatchTimer 1363 temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); 1364 // Consume mPerFrequencyRxDurationMs data. 1365 temp.readSummaryFromParcelLocked(in); 1366 continue; 1367 } 1368 getRxDurationCounter(freq, true).readSummaryFromParcelLocked(in); 1369 } 1370 } 1371 } 1372 getTxDurationCounter( @erviceState.FrequencyRange int frequencyRange, int signalStrength, boolean make)1373 private LongSamplingCounter getTxDurationCounter( 1374 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, boolean make) { 1375 if (mPerStateTxDurationMs == null) { 1376 if (!make) return null; 1377 1378 final int freqCount = getFrequencyRangeCount(); 1379 final int signalStrengthCount = perStateTimers[0].length; 1380 final TimeBase timeBase = perStateTimers[0][0].mTimeBase; 1381 mPerStateTxDurationMs = new LongSamplingCounter[freqCount][signalStrengthCount]; 1382 for (int freq = 0; freq < freqCount; freq++) { 1383 for (int strength = 0; strength < signalStrengthCount; strength++) { 1384 mPerStateTxDurationMs[freq][strength] = new LongSamplingCounter(timeBase); 1385 } 1386 } 1387 } 1388 if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { 1389 Slog.w(TAG, "Unexpected frequency range (" + frequencyRange 1390 + ") requested in getTxDurationCounter"); 1391 return null; 1392 } 1393 if (signalStrength < 0 || signalStrength >= perStateTimers[0].length) { 1394 Slog.w(TAG, "Unexpected signal strength (" + signalStrength 1395 + ") requested in getTxDurationCounter"); 1396 return null; 1397 } 1398 return mPerStateTxDurationMs[frequencyRange][signalStrength]; 1399 } 1400 getRxDurationCounter( @erviceState.FrequencyRange int frequencyRange, boolean make)1401 private LongSamplingCounter getRxDurationCounter( 1402 @ServiceState.FrequencyRange int frequencyRange, boolean make) { 1403 if (mPerFrequencyRxDurationMs == null) { 1404 if (!make) return null; 1405 1406 final int freqCount = getFrequencyRangeCount(); 1407 final TimeBase timeBase = perStateTimers[0][0].mTimeBase; 1408 mPerFrequencyRxDurationMs = new LongSamplingCounter[freqCount]; 1409 for (int freq = 0; freq < freqCount; freq++) { 1410 mPerFrequencyRxDurationMs[freq] = new LongSamplingCounter(timeBase); 1411 } 1412 } 1413 if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { 1414 Slog.w(TAG, "Unexpected frequency range (" + frequencyRange 1415 + ") requested in getRxDurationCounter"); 1416 return null; 1417 } 1418 return mPerFrequencyRxDurationMs[frequencyRange]; 1419 } 1420 } 1421 1422 /** 1423 * Number of frequency ranges, keep in sync with {@link ServiceState.FrequencyRange} 1424 */ 1425 private static final int NR_FREQUENCY_COUNT = 5; 1426 1427 RadioAccessTechnologyBatteryStats[] mPerRatBatteryStats = 1428 new RadioAccessTechnologyBatteryStats[RADIO_ACCESS_TECHNOLOGY_COUNT]; 1429 1430 @GuardedBy("this") getRatBatteryStatsLocked( @adioAccessTechnology int rat)1431 private RadioAccessTechnologyBatteryStats getRatBatteryStatsLocked( 1432 @RadioAccessTechnology int rat) { 1433 RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 1434 if (stats == null) { 1435 final int freqCount = rat == RADIO_ACCESS_TECHNOLOGY_NR ? NR_FREQUENCY_COUNT : 1; 1436 stats = new RadioAccessTechnologyBatteryStats(freqCount, mClock, mOnBatteryTimeBase); 1437 mPerRatBatteryStats[rat] = stats; 1438 } 1439 return stats; 1440 } 1441 1442 final LongSamplingCounter[] mNetworkByteActivityCounters = 1443 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 1444 1445 final LongSamplingCounter[] mNetworkPacketActivityCounters = 1446 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 1447 1448 /** 1449 * The WiFi Overall wakelock timer 1450 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 1451 * since addition of per UID timers would not result in an accurate value due to overlapp of 1452 * per uid wakelock timers 1453 */ 1454 StopwatchTimer mWifiMulticastWakelockTimer; 1455 1456 /** 1457 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 1458 */ 1459 ControllerActivityCounterImpl mWifiActivity; 1460 1461 /** 1462 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 1463 */ 1464 ControllerActivityCounterImpl mBluetoothActivity; 1465 1466 /** 1467 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 1468 */ 1469 ControllerActivityCounterImpl mModemActivity; 1470 1471 /** 1472 * Whether the device supports WiFi controller energy reporting. This is set to true on 1473 * the first WiFi energy report. See {@link #mWifiActivity}. 1474 */ 1475 boolean mHasWifiReporting = false; 1476 1477 /** 1478 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 1479 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 1480 */ 1481 boolean mHasBluetoothReporting = false; 1482 1483 /** 1484 * Whether the device supports Modem controller energy reporting. This is set to true on 1485 * the first Modem energy report. See {@link #mModemActivity}. 1486 */ 1487 boolean mHasModemReporting = false; 1488 1489 boolean mWifiOn; 1490 StopwatchTimer mWifiOnTimer; 1491 1492 boolean mGlobalWifiRunning; 1493 StopwatchTimer mGlobalWifiRunningTimer; 1494 1495 int mWifiState = -1; 1496 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 1497 1498 int mWifiSupplState = -1; 1499 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 1500 1501 int mWifiSignalStrengthBin = -1; 1502 final StopwatchTimer[] mWifiSignalStrengthsTimer = 1503 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 1504 1505 StopwatchTimer mWifiActiveTimer; 1506 1507 int mBluetoothScanNesting; 1508 StopwatchTimer mBluetoothScanTimer; 1509 1510 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1511 long mMobileRadioActiveStartTimeMs; 1512 StopwatchTimer mMobileRadioActiveTimer; 1513 StopwatchTimer mMobileRadioActivePerAppTimer; 1514 LongSamplingCounter mMobileRadioActiveAdjustedTime; 1515 LongSamplingCounter mMobileRadioActiveUnknownTime; 1516 LongSamplingCounter mMobileRadioActiveUnknownCount; 1517 1518 /** 1519 * The soonest the Mobile Radio stats can be updated due to a mobile radio power state change 1520 * after it was last updated. 1521 */ 1522 @VisibleForTesting 1523 protected static final long MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS = 1000 * 60 * 10; 1524 1525 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1526 1527 @GuardedBy("this") 1528 @VisibleForTesting 1529 protected @Nullable EnergyConsumerStats.Config mEnergyConsumerStatsConfig; 1530 1531 /** 1532 * Accumulated global (generally, device-wide total) charge consumption of various consumers 1533 * while on battery. 1534 * Its '<b>custom</b> power buckets' correspond to the 1535 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 1536 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 1537 * 1538 * If energy consumer data is completely unavailable this will be null. 1539 */ 1540 @GuardedBy("this") 1541 @VisibleForTesting 1542 @Nullable 1543 protected EnergyConsumerStats mGlobalEnergyConsumerStats; 1544 /** Bluetooth Power calculator for attributing bluetooth EnergyConsumer to uids */ 1545 @Nullable BluetoothPowerCalculator mBluetoothPowerCalculator = null; 1546 /** Cpu Power calculator for attributing cpu EnergyConsumer to uids */ 1547 @Nullable CpuPowerCalculator mCpuPowerCalculator = null; 1548 /** Mobile Radio Power calculator for attributing radio EnergyConsumer to uids */ 1549 @Nullable MobileRadioPowerCalculator mMobileRadioPowerCalculator = null; 1550 /** Wifi Power calculator for attributing wifi EnergyConsumer to uids */ 1551 @Nullable WifiPowerCalculator mWifiPowerCalculator = null; 1552 1553 /** 1554 * These provide time bases that discount the time the device is plugged 1555 * in to power. 1556 */ 1557 boolean mOnBattery; 1558 @VisibleForTesting 1559 protected boolean mOnBatteryInternal; 1560 1561 /** 1562 * External reporting of whether the device is actually charging. 1563 */ 1564 boolean mCharging = true; 1565 1566 /* 1567 * These keep track of battery levels (1-100) at the last unplug event. 1568 */ 1569 int mDischargeUnplugLevel; 1570 int mDischargePlugLevel; 1571 int mDischargeCurrentLevel; 1572 int mLowDischargeAmountSinceCharge; 1573 int mHighDischargeAmountSinceCharge; 1574 int mDischargeScreenOnUnplugLevel; 1575 int mDischargeScreenOffUnplugLevel; 1576 int mDischargeScreenDozeUnplugLevel; 1577 int mDischargeAmountScreenOn; 1578 int mDischargeAmountScreenOnSinceCharge; 1579 int mDischargeAmountScreenOff; 1580 int mDischargeAmountScreenOffSinceCharge; 1581 int mDischargeAmountScreenDoze; 1582 int mDischargeAmountScreenDozeSinceCharge; 1583 1584 private LongSamplingCounter mDischargeScreenOffCounter; 1585 private LongSamplingCounter mDischargeScreenDozeCounter; 1586 private LongSamplingCounter mDischargeCounter; 1587 private LongSamplingCounter mDischargeLightDozeCounter; 1588 private LongSamplingCounter mDischargeDeepDozeCounter; 1589 1590 static final int MAX_LEVEL_STEPS = 200; 1591 1592 int mInitStepMode = 0; 1593 int mCurStepMode = 0; 1594 int mModStepMode = 0; 1595 1596 int mLastDischargeStepLevel; 1597 int mMinDischargeStepLevel; 1598 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1599 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1600 ArrayList<PackageChange> mDailyPackageChanges; 1601 1602 int mLastChargeStepLevel; 1603 int mMaxChargeStepLevel; 1604 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1605 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1606 1607 static final int MAX_DAILY_ITEMS = 10; 1608 1609 long mDailyStartTimeMs = 0; 1610 long mNextMinDailyDeadlineMs = 0; 1611 long mNextMaxDailyDeadlineMs = 0; 1612 1613 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 1614 1615 long mLastWriteTimeMs = 0; // Milliseconds 1616 1617 private int mPhoneServiceState = -1; 1618 private int mPhoneServiceStateRaw = -1; 1619 private int mPhoneSimStateRaw = -1; 1620 1621 private int mNumConnectivityChange; 1622 1623 private int mEstimatedBatteryCapacityMah = -1; 1624 1625 private int mLastLearnedBatteryCapacityUah = -1; 1626 private int mMinLearnedBatteryCapacityUah = -1; 1627 private int mMaxLearnedBatteryCapacityUah = -1; 1628 1629 private long mBatteryTimeToFullSeconds = -1; 1630 1631 private LongArrayMultiStateCounter.LongArrayContainer mTmpCpuTimeInFreq; 1632 1633 /** 1634 * Times spent by the system server threads handling incoming binder requests. 1635 */ 1636 private LongSamplingCounterArray mBinderThreadCpuTimesUs; 1637 1638 @VisibleForTesting 1639 protected PowerProfile mPowerProfile; 1640 1641 @VisibleForTesting 1642 @GuardedBy("this") 1643 protected final Constants mConstants; 1644 1645 @VisibleForTesting 1646 protected final BatteryStatsConfig mBatteryStatsConfig; 1647 1648 @GuardedBy("this") 1649 private AlarmManager mAlarmManager = null; 1650 1651 private final AlarmManager.OnAlarmListener mLongPlugInAlarmHandler = () -> 1652 mHandler.post(() -> { 1653 synchronized (BatteryStatsImpl.this) { 1654 maybeResetWhilePluggedInLocked(); 1655 } 1656 }); 1657 1658 /* 1659 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 1660 * recording their times when on-battery (regardless of screen state). 1661 */ 1662 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 1663 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 1664 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 1665 1666 @Override getRpmStats()1667 public Map<String, ? extends Timer> getRpmStats() { 1668 return mRpmStats; 1669 } 1670 1671 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 1672 @Override getScreenOffRpmStats()1673 public Map<String, ? extends Timer> getScreenOffRpmStats() { 1674 return mScreenOffRpmStats; 1675 } 1676 1677 /* 1678 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 1679 */ 1680 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 1681 getKernelWakelockStats()1682 public Map<String, ? extends Timer> getKernelWakelockStats() { 1683 return mKernelWakelockStats; 1684 } 1685 1686 @Override getWakeLockStats()1687 public WakeLockStats getWakeLockStats() { 1688 final long realtimeMs = mClock.elapsedRealtime(); 1689 List<WakeLockStats.WakeLock> uidWakeLockStats = new ArrayList<>(); 1690 List<WakeLockStats.WakeLock> uidAggregatedWakeLockStats = new ArrayList<>(); 1691 for (int i = mUidStats.size() - 1; i >= 0; i--) { 1692 final Uid uid = mUidStats.valueAt(i); 1693 1694 // Converts unaggregated wakelocks. 1695 final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = 1696 uid.mWakelockStats.getMap(); 1697 for (int j = wakelockStats.size() - 1; j >= 0; j--) { 1698 final String name = wakelockStats.keyAt(j); 1699 final Uid.Wakelock wakelock = (Uid.Wakelock) wakelockStats.valueAt(j); 1700 final WakeLockStats.WakeLock wakeLockItem = 1701 createWakeLock(uid, name, /* isAggregated= */ false, wakelock.mTimerPartial, 1702 realtimeMs); 1703 if (wakeLockItem != null) { 1704 uidWakeLockStats.add(wakeLockItem); 1705 } 1706 } 1707 1708 // Converts aggregated wakelocks. 1709 final WakeLockStats.WakeLock aggregatedWakeLockItem = 1710 createWakeLock( 1711 uid, 1712 WakeLockStats.WakeLock.NAME_AGGREGATED, 1713 /* isAggregated= */ true, 1714 uid.mAggregatedPartialWakelockTimer, 1715 realtimeMs); 1716 if (aggregatedWakeLockItem != null) { 1717 uidAggregatedWakeLockStats.add(aggregatedWakeLockItem); 1718 } 1719 } 1720 return new WakeLockStats(uidWakeLockStats, uidAggregatedWakeLockStats); 1721 } 1722 1723 // Returns a valid {@code WakeLockStats.WakeLock} or null. createWakeLock( Uid uid, String name, boolean isAggregated, DualTimer timer, final long realtimeMs)1724 private WakeLockStats.WakeLock createWakeLock( 1725 Uid uid, String name, boolean isAggregated, DualTimer timer, final long realtimeMs) { 1726 if (timer == null) { 1727 return null; 1728 } 1729 // Uses the primary timer for total wakelock data and used the sub timer for background 1730 // wakelock data. 1731 final WakeLockStats.WakeLockData totalWakeLockData = createWakeLockData(timer, realtimeMs); 1732 final WakeLockStats.WakeLockData backgroundWakeLockData = 1733 createWakeLockData(timer.getSubTimer(), realtimeMs); 1734 1735 return WakeLockStats.WakeLock.isDataValid(totalWakeLockData, backgroundWakeLockData) 1736 ? new WakeLockStats.WakeLock( 1737 uid.getUid(), 1738 name, 1739 isAggregated, 1740 totalWakeLockData, 1741 backgroundWakeLockData) : null; 1742 } 1743 1744 @NonNull createWakeLockData( DurationTimer timer, final long realtimeMs)1745 private WakeLockStats.WakeLockData createWakeLockData( 1746 DurationTimer timer, final long realtimeMs) { 1747 if (timer == null) { 1748 return WakeLockStats.WakeLockData.EMPTY; 1749 } 1750 final long totalTimeLockHeldMs = 1751 timer.getTotalTimeLocked(realtimeMs * 1000, STATS_SINCE_CHARGED) / 1000; 1752 if (totalTimeLockHeldMs == 0) { 1753 return WakeLockStats.WakeLockData.EMPTY; 1754 } 1755 return new WakeLockStats.WakeLockData( 1756 timer.getCountLocked(STATS_SINCE_CHARGED), 1757 totalTimeLockHeldMs, 1758 timer.isRunningLocked() ? timer.getCurrentDurationMsLocked(realtimeMs) : 0); 1759 } 1760 1761 @Override 1762 @GuardedBy("this") getBluetoothBatteryStats()1763 public BluetoothBatteryStats getBluetoothBatteryStats() { 1764 final long elapsedRealtimeUs = mClock.elapsedRealtime() * 1000; 1765 ArrayList<BluetoothBatteryStats.UidStats> uidStats = new ArrayList<>(); 1766 for (int i = mUidStats.size() - 1; i >= 0; i--) { 1767 final Uid uid = mUidStats.valueAt(i); 1768 final Timer scanTimer = uid.getBluetoothScanTimer(); 1769 final long scanTimeMs = 1770 scanTimer != null ? scanTimer.getTotalTimeLocked( 1771 elapsedRealtimeUs, STATS_SINCE_CHARGED) / 1000 : 0; 1772 1773 final Timer unoptimizedScanTimer = uid.getBluetoothUnoptimizedScanTimer(); 1774 final long unoptimizedScanTimeMs = 1775 unoptimizedScanTimer != null ? unoptimizedScanTimer.getTotalTimeLocked( 1776 elapsedRealtimeUs, STATS_SINCE_CHARGED) / 1000 : 0; 1777 1778 final Counter scanResultCounter = uid.getBluetoothScanResultCounter(); 1779 final int scanResultCount = 1780 scanResultCounter != null ? scanResultCounter.getCountLocked( 1781 STATS_SINCE_CHARGED) : 0; 1782 1783 final ControllerActivityCounter counter = uid.getBluetoothControllerActivity(); 1784 final long rxTimeMs = counter != null ? counter.getRxTimeCounter().getCountLocked( 1785 STATS_SINCE_CHARGED) : 0; 1786 final long txTimeMs = counter != null ? counter.getTxTimeCounters()[0].getCountLocked( 1787 STATS_SINCE_CHARGED) : 0; 1788 1789 if (scanTimeMs != 0 || unoptimizedScanTimeMs != 0 || scanResultCount != 0 1790 || rxTimeMs != 0 || txTimeMs != 0) { 1791 uidStats.add(new BluetoothBatteryStats.UidStats(uid.getUid(), 1792 scanTimeMs, 1793 unoptimizedScanTimeMs, 1794 scanResultCount, 1795 rxTimeMs, 1796 txTimeMs)); 1797 } 1798 } 1799 1800 return new BluetoothBatteryStats(uidStats); 1801 } 1802 1803 String mLastWakeupReason = null; 1804 long mLastWakeupUptimeMs = 0; 1805 long mLastWakeupElapsedTimeMs = 0; 1806 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 1807 getWakeupReasonStats()1808 public Map<String, ? extends Timer> getWakeupReasonStats() { 1809 return mWakeupReasonStats; 1810 } 1811 1812 @Override getUahDischarge(int which)1813 public long getUahDischarge(int which) { 1814 return mDischargeCounter.getCountLocked(which); 1815 } 1816 1817 @Override getUahDischargeScreenOff(int which)1818 public long getUahDischargeScreenOff(int which) { 1819 return mDischargeScreenOffCounter.getCountLocked(which); 1820 } 1821 1822 @Override getUahDischargeScreenDoze(int which)1823 public long getUahDischargeScreenDoze(int which) { 1824 return mDischargeScreenDozeCounter.getCountLocked(which); 1825 } 1826 1827 @Override getUahDischargeLightDoze(int which)1828 public long getUahDischargeLightDoze(int which) { 1829 return mDischargeLightDozeCounter.getCountLocked(which); 1830 } 1831 1832 @Override getUahDischargeDeepDoze(int which)1833 public long getUahDischargeDeepDoze(int which) { 1834 return mDischargeDeepDozeCounter.getCountLocked(which); 1835 } 1836 1837 @Override getEstimatedBatteryCapacity()1838 public int getEstimatedBatteryCapacity() { 1839 return mEstimatedBatteryCapacityMah; 1840 } 1841 1842 @Override getLearnedBatteryCapacity()1843 public int getLearnedBatteryCapacity() { 1844 return mLastLearnedBatteryCapacityUah; 1845 } 1846 1847 @Override getMinLearnedBatteryCapacity()1848 public int getMinLearnedBatteryCapacity() { 1849 return mMinLearnedBatteryCapacityUah; 1850 } 1851 1852 @Override getMaxLearnedBatteryCapacity()1853 public int getMaxLearnedBatteryCapacity() { 1854 return mMaxLearnedBatteryCapacityUah; 1855 } 1856 1857 public static class FrameworkStatsLogger { uidProcessStateChanged(int uid, int state)1858 public void uidProcessStateChanged(int uid, int state) { 1859 // TODO(b/155216561): It is possible for isolated uids to be in a higher 1860 // state than its parent uid. We should track the highest state within the union of host 1861 // and isolated uids rather than only the parent uid. 1862 FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, 1863 ActivityManager.processStateAmToProto(state)); 1864 } 1865 wakelockStateChanged(int uid, WorkChain wc, String name, int procState, boolean acquired, int powerManagerWakeLockLevel)1866 public void wakelockStateChanged(int uid, WorkChain wc, String name, 1867 int procState, boolean acquired, int powerManagerWakeLockLevel) { 1868 int event = acquired 1869 ? FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE 1870 : FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE; 1871 if (wc != null) { 1872 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 1873 wc.getTags(), powerManagerWakeLockLevel, name, event, procState); 1874 } else { 1875 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, uid, 1876 null, powerManagerWakeLockLevel, name, event, procState); 1877 } 1878 } 1879 kernelWakeupReported(long deltaUptimeUs, String lastWakeupReason, long lastWakeupElapsedTimeMs)1880 public void kernelWakeupReported(long deltaUptimeUs, String lastWakeupReason, 1881 long lastWakeupElapsedTimeMs) { 1882 FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, lastWakeupReason, 1883 /* duration_usec */ deltaUptimeUs, lastWakeupElapsedTimeMs); 1884 } 1885 gpsScanStateChanged(int uid, WorkChain workChain, boolean stateOn)1886 public void gpsScanStateChanged(int uid, WorkChain workChain, boolean stateOn) { 1887 int event = stateOn 1888 ? FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON 1889 : FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF; 1890 if (workChain != null) { 1891 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 1892 workChain.getUids(), workChain.getTags(), event); 1893 } else { 1894 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 1895 uid, null, event); 1896 } 1897 } 1898 batterySaverModeChanged(boolean enabled)1899 public void batterySaverModeChanged(boolean enabled) { 1900 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 1901 enabled 1902 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 1903 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 1904 } 1905 deviceIdlingModeStateChanged(int mode)1906 public void deviceIdlingModeStateChanged(int mode) { 1907 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, mode); 1908 } 1909 deviceIdleModeStateChanged(int mode)1910 public void deviceIdleModeStateChanged(int mode) { 1911 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 1912 } 1913 chargingStateChanged(int status)1914 public void chargingStateChanged(int status) { 1915 FrameworkStatsLog.write(FrameworkStatsLog.CHARGING_STATE_CHANGED, status); 1916 } 1917 pluggedStateChanged(int plugType)1918 public void pluggedStateChanged(int plugType) { 1919 FrameworkStatsLog.write(FrameworkStatsLog.PLUGGED_STATE_CHANGED, plugType); 1920 } 1921 batteryLevelChanged(int level)1922 public void batteryLevelChanged(int level) { 1923 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_LEVEL_CHANGED, level); 1924 } 1925 phoneServiceStateChanged(int state, int simState, int strengthBin)1926 public void phoneServiceStateChanged(int state, int simState, int strengthBin) { 1927 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 1928 simState, strengthBin); 1929 } 1930 phoneSignalStrengthChanged(int strengthBin)1931 public void phoneSignalStrengthChanged(int strengthBin) { 1932 FrameworkStatsLog.write( 1933 FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 1934 } 1935 1936 /** 1937 * Records a statsd event when the batterystats config file is written to disk. 1938 */ writeCommitSysConfigFile(String fileName, long durationMs)1939 public void writeCommitSysConfigFile(String fileName, long durationMs) { 1940 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(fileName, 1941 durationMs); 1942 } 1943 } 1944 1945 private final FrameworkStatsLogger mFrameworkStatsLogger; 1946 initKernelStatsReaders()1947 private void initKernelStatsReaders() { 1948 if (!isKernelStatsAvailable()) { 1949 return; 1950 } 1951 1952 mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(true, mClock); 1953 mCpuUidFreqTimeReader = new KernelCpuUidFreqTimeReader(true, mClock); 1954 mCpuUidActiveTimeReader = new KernelCpuUidActiveTimeReader(true, mClock); 1955 mCpuUidClusterTimeReader = new KernelCpuUidClusterTimeReader(true, mClock); 1956 mKernelWakelockReader = new KernelWakelockReader(); 1957 if (!Flags.disableSystemServicePowerAttr()) { 1958 mSystemServerCpuThreadReader = SystemServerCpuThreadReader.create(); 1959 } 1960 mKernelMemoryBandwidthStats = new KernelMemoryBandwidthStats(); 1961 mTmpRailStats = new RailStats(); 1962 } 1963 1964 private class PowerStatsCollectorInjector implements CpuPowerStatsCollector.Injector, 1965 MobileRadioPowerStatsCollector.Injector, WifiPowerStatsCollector.Injector, 1966 BluetoothPowerStatsCollector.Injector { 1967 private PackageManager mPackageManager; 1968 private PowerStatsCollector.ConsumedEnergyRetriever mConsumedEnergyRetriever; 1969 private NetworkStatsManager mNetworkStatsManager; 1970 private TelephonyManager mTelephonyManager; 1971 private WifiManager mWifiManager; 1972 private BluetoothPowerStatsCollector.BluetoothStatsRetriever mBluetoothStatsRetriever; 1973 setContext(Context context)1974 void setContext(Context context) { 1975 mPackageManager = context.getPackageManager(); 1976 mConsumedEnergyRetriever = new PowerStatsCollector.ConsumedEnergyRetrieverImpl( 1977 LocalServices.getService(PowerStatsInternal.class)); 1978 mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class); 1979 mTelephonyManager = context.getSystemService(TelephonyManager.class); 1980 mWifiManager = context.getSystemService(WifiManager.class); 1981 mBluetoothStatsRetriever = new BluetoothStatsRetrieverImpl( 1982 context.getSystemService(BluetoothManager.class)); 1983 } 1984 1985 @Override getHandler()1986 public Handler getHandler() { 1987 return mHandler; 1988 } 1989 1990 @Override getClock()1991 public Clock getClock() { 1992 return mClock; 1993 } 1994 1995 @Override getPowerStatsCollectionThrottlePeriod(String powerComponentName)1996 public long getPowerStatsCollectionThrottlePeriod(String powerComponentName) { 1997 return mBatteryStatsConfig.getPowerStatsThrottlePeriod(powerComponentName); 1998 } 1999 2000 @Override getUidResolver()2001 public PowerStatsUidResolver getUidResolver() { 2002 return mPowerStatsUidResolver; 2003 } 2004 2005 @Override getCpuScalingPolicies()2006 public CpuScalingPolicies getCpuScalingPolicies() { 2007 return mCpuScalingPolicies; 2008 } 2009 2010 @Override getPowerProfile()2011 public PowerProfile getPowerProfile() { 2012 return mPowerProfile; 2013 } 2014 2015 @Override getKernelCpuStatsReader()2016 public CpuPowerStatsCollector.KernelCpuStatsReader getKernelCpuStatsReader() { 2017 return new CpuPowerStatsCollector.KernelCpuStatsReader(); 2018 } 2019 2020 @Override getPackageManager()2021 public PackageManager getPackageManager() { 2022 return mPackageManager; 2023 } 2024 2025 @Override getConsumedEnergyRetriever()2026 public PowerStatsCollector.ConsumedEnergyRetriever getConsumedEnergyRetriever() { 2027 return mConsumedEnergyRetriever; 2028 } 2029 2030 @Override getVoltageSupplier()2031 public IntSupplier getVoltageSupplier() { 2032 return () -> mBatteryVoltageMv; 2033 } 2034 2035 @Override getMobileNetworkStatsSupplier()2036 public Supplier<NetworkStats> getMobileNetworkStatsSupplier() { 2037 return () -> readMobileNetworkStatsLocked(mNetworkStatsManager); 2038 } 2039 2040 @Override getWifiNetworkStatsSupplier()2041 public Supplier<NetworkStats> getWifiNetworkStatsSupplier() { 2042 return () -> readWifiNetworkStatsLocked(mNetworkStatsManager); 2043 } 2044 2045 @Override getWifiStatsRetriever()2046 public WifiPowerStatsCollector.WifiStatsRetriever getWifiStatsRetriever() { 2047 return mWifiStatsRetriever; 2048 } 2049 2050 @Override getTelephonyManager()2051 public TelephonyManager getTelephonyManager() { 2052 return mTelephonyManager; 2053 } 2054 2055 @Override getWifiManager()2056 public WifiManager getWifiManager() { 2057 return mWifiManager; 2058 } 2059 2060 @Override getBluetoothStatsRetriever()2061 public BluetoothPowerStatsCollector.BluetoothStatsRetriever getBluetoothStatsRetriever() { 2062 return mBluetoothStatsRetriever; 2063 } 2064 2065 @Override getCallDurationSupplier()2066 public LongSupplier getCallDurationSupplier() { 2067 return () -> mPhoneOnTimer.getTotalTimeLocked(mClock.elapsedRealtime() * 1000, 2068 STATS_SINCE_CHARGED); 2069 } 2070 2071 @Override getPhoneSignalScanDurationSupplier()2072 public LongSupplier getPhoneSignalScanDurationSupplier() { 2073 return () -> mPhoneSignalScanningTimer.getTotalTimeLocked( 2074 mClock.elapsedRealtime() * 1000, STATS_SINCE_CHARGED); 2075 } 2076 } 2077 2078 private final PowerStatsCollectorInjector mPowerStatsCollectorInjector = 2079 new PowerStatsCollectorInjector(); 2080 2081 /** 2082 * TimeBase observer. 2083 */ 2084 public interface TimeBaseObs { onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2085 void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2086 void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); 2087 2088 /** 2089 * Reset the observer's state, returns true if the timer/counter is inactive 2090 * so it can be destroyed. 2091 * @param detachIfReset detach if true, no-op if false. 2092 * @return Returns true if the timer/counter is inactive and can be destroyed. 2093 */ reset(boolean detachIfReset)2094 default boolean reset(boolean detachIfReset) { 2095 return reset(detachIfReset, SystemClock.elapsedRealtime() * 1000); 2096 } 2097 2098 /** 2099 * @see #reset(boolean) 2100 * @param detachIfReset detach if true, no-op if false. 2101 * @param elapsedRealtimeUs the timestamp when this reset is actually reequested 2102 * @return Returns true if the timer/counter is inactive and can be destroyed. 2103 */ reset(boolean detachIfReset, long elapsedRealtimeUs)2104 boolean reset(boolean detachIfReset, long elapsedRealtimeUs); 2105 2106 /** 2107 * Detach the observer from TimeBase. 2108 */ detach()2109 void detach(); 2110 } 2111 2112 // methods are protected not private to be VisibleForTesting 2113 public static class TimeBase { 2114 protected final Collection<TimeBaseObs> mObservers; 2115 2116 // All below time metrics are in microseconds. 2117 protected long mUptimeUs; 2118 protected long mRealtimeUs; 2119 2120 protected boolean mRunning; 2121 2122 protected long mPastUptimeUs; 2123 protected long mUptimeStartUs; 2124 protected long mPastRealtimeUs; 2125 protected long mRealtimeStartUs; 2126 protected long mUnpluggedUptimeUs; 2127 protected long mUnpluggedRealtimeUs; 2128 dump(PrintWriter pw, String prefix)2129 public void dump(PrintWriter pw, String prefix) { 2130 StringBuilder sb = new StringBuilder(128); 2131 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 2132 sb.setLength(0); 2133 sb.append(prefix); 2134 sb.append("mUptime="); 2135 formatTimeMs(sb, mUptimeUs / 1000); 2136 pw.println(sb.toString()); 2137 sb.setLength(0); 2138 sb.append(prefix); 2139 sb.append("mRealtime="); 2140 formatTimeMs(sb, mRealtimeUs / 1000); 2141 pw.println(sb.toString()); 2142 sb.setLength(0); 2143 sb.append(prefix); 2144 sb.append("mPastUptime="); 2145 formatTimeMs(sb, mPastUptimeUs / 1000); sb.append("mUptimeStart="); 2146 formatTimeMs(sb, mUptimeStartUs / 1000); 2147 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptimeUs / 1000); 2148 pw.println(sb.toString()); 2149 sb.setLength(0); 2150 sb.append(prefix); 2151 sb.append("mPastRealtime="); 2152 formatTimeMs(sb, mPastRealtimeUs / 1000); sb.append("mRealtimeStart="); 2153 formatTimeMs(sb, mRealtimeStartUs / 1000); 2154 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtimeUs / 1000); 2155 pw.println(sb.toString()); 2156 } 2157 /** 2158 * The mObservers of TimeBase in BatteryStatsImpl object can contain up to 20k entries. 2159 * The mObservers of TimeBase in BatteryStatsImpl.Uid object only contains a few or tens of 2160 * entries. 2161 * mObservers must have good performance on add(), remove(), also be memory efficient. 2162 * This is why we provide isLongList parameter for long and short list user cases. 2163 * @param isLongList If true, use HashSet for mObservers list. 2164 * If false, use ArrayList for mObservers list. 2165 */ TimeBase(boolean isLongList)2166 public TimeBase(boolean isLongList) { 2167 mObservers = isLongList ? new HashSet<>() : new ArrayList<>(); 2168 } 2169 TimeBase()2170 public TimeBase() { 2171 this(false); 2172 } 2173 add(TimeBaseObs observer)2174 public void add(TimeBaseObs observer) { 2175 mObservers.add(observer); 2176 } 2177 remove(TimeBaseObs observer)2178 public void remove(TimeBaseObs observer) { 2179 mObservers.remove(observer); 2180 } 2181 hasObserver(TimeBaseObs observer)2182 public boolean hasObserver(TimeBaseObs observer) { 2183 return mObservers.contains(observer); 2184 } 2185 init(long uptimeUs, long elapsedRealtimeUs)2186 public void init(long uptimeUs, long elapsedRealtimeUs) { 2187 mRealtimeUs = 0; 2188 mUptimeUs = 0; 2189 mPastUptimeUs = 0; 2190 mPastRealtimeUs = 0; 2191 mUptimeStartUs = uptimeUs; 2192 mRealtimeStartUs = elapsedRealtimeUs; 2193 mUnpluggedUptimeUs = getUptime(mUptimeStartUs); 2194 mUnpluggedRealtimeUs = getRealtime(mRealtimeStartUs); 2195 } 2196 reset(long uptimeUs, long elapsedRealtimeUs)2197 public void reset(long uptimeUs, long elapsedRealtimeUs) { 2198 if (!mRunning) { 2199 mPastUptimeUs = 0; 2200 mPastRealtimeUs = 0; 2201 } else { 2202 mUptimeStartUs = uptimeUs; 2203 mRealtimeStartUs = elapsedRealtimeUs; 2204 // TODO: Since mUptimeStartUs was just reset and we are running, getUptime will 2205 // just return mPastUptimeUs. Also, are we sure we don't want to reset that? 2206 mUnpluggedUptimeUs = getUptime(uptimeUs); 2207 // TODO: likewise. 2208 mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 2209 } 2210 } 2211 computeUptime(long curTimeUs, int which)2212 public long computeUptime(long curTimeUs, int which) { 2213 return mUptimeUs + getUptime(curTimeUs); 2214 } 2215 computeRealtime(long curTimeUs, int which)2216 public long computeRealtime(long curTimeUs, int which) { 2217 return mRealtimeUs + getRealtime(curTimeUs); 2218 } 2219 getUptime(long curTimeUs)2220 public long getUptime(long curTimeUs) { 2221 long time = mPastUptimeUs; 2222 if (mRunning) { 2223 time += curTimeUs - mUptimeStartUs; 2224 } 2225 return time; 2226 } 2227 getRealtime(long curTimeUs)2228 public long getRealtime(long curTimeUs) { 2229 long time = mPastRealtimeUs; 2230 if (mRunning) { 2231 time += curTimeUs - mRealtimeStartUs; 2232 } 2233 return time; 2234 } 2235 getUptimeStart()2236 public long getUptimeStart() { 2237 return mUptimeStartUs; 2238 } 2239 getRealtimeStart()2240 public long getRealtimeStart() { 2241 return mRealtimeStartUs; 2242 } 2243 isRunning()2244 public boolean isRunning() { 2245 return mRunning; 2246 } 2247 setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs)2248 public boolean setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs) { 2249 if (mRunning != running) { 2250 mRunning = running; 2251 if (running) { 2252 mUptimeStartUs = uptimeUs; 2253 mRealtimeStartUs = elapsedRealtimeUs; 2254 long batteryUptimeUs = mUnpluggedUptimeUs = getUptime(uptimeUs); 2255 long batteryRealtimeUs = mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 2256 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 2257 // Iterator object, here is an exception because mObservers' type is Collection 2258 // instead of list. 2259 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 2260 while (iter.hasNext()) { 2261 iter.next().onTimeStarted( 2262 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 2263 } 2264 } else { 2265 mPastUptimeUs += uptimeUs - mUptimeStartUs; 2266 mPastRealtimeUs += elapsedRealtimeUs - mRealtimeStartUs; 2267 long batteryUptimeUs = getUptime(uptimeUs); 2268 long batteryRealtimeUs = getRealtime(elapsedRealtimeUs); 2269 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 2270 // Iterator object, here is an exception because mObservers' type is Collection 2271 // instead of list. 2272 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 2273 while (iter.hasNext()) { 2274 iter.next().onTimeStopped( 2275 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 2276 } 2277 } 2278 return true; 2279 } 2280 return false; 2281 } 2282 readSummaryFromParcel(Parcel in)2283 public void readSummaryFromParcel(Parcel in) { 2284 mUptimeUs = in.readLong(); 2285 mRealtimeUs = in.readLong(); 2286 } 2287 writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)2288 public void writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 2289 out.writeLong(computeUptime(uptimeUs, STATS_SINCE_CHARGED)); 2290 out.writeLong(computeRealtime(elapsedRealtimeUs, STATS_SINCE_CHARGED)); 2291 } 2292 readFromParcel(Parcel in)2293 public void readFromParcel(Parcel in) { 2294 mRunning = false; 2295 mUptimeUs = in.readLong(); 2296 mPastUptimeUs = in.readLong(); 2297 mUptimeStartUs = in.readLong(); 2298 mRealtimeUs = in.readLong(); 2299 mPastRealtimeUs = in.readLong(); 2300 mRealtimeStartUs = in.readLong(); 2301 mUnpluggedUptimeUs = in.readLong(); 2302 mUnpluggedRealtimeUs = in.readLong(); 2303 } 2304 writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)2305 public void writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 2306 final long runningUptime = getUptime(uptimeUs); 2307 final long runningRealtime = getRealtime(elapsedRealtimeUs); 2308 out.writeLong(mUptimeUs); 2309 out.writeLong(runningUptime); 2310 out.writeLong(mUptimeStartUs); 2311 out.writeLong(mRealtimeUs); 2312 out.writeLong(runningRealtime); 2313 out.writeLong(mRealtimeStartUs); 2314 out.writeLong(mUnpluggedUptimeUs); 2315 out.writeLong(mUnpluggedRealtimeUs); 2316 } 2317 } 2318 2319 /** 2320 * State for keeping track of counting information. 2321 */ 2322 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 2323 final AtomicInteger mCount = new AtomicInteger(); 2324 final TimeBase mTimeBase; 2325 Counter(TimeBase timeBase, Parcel in)2326 public Counter(TimeBase timeBase, Parcel in) { 2327 mTimeBase = timeBase; 2328 mCount.set(in.readInt()); 2329 timeBase.add(this); 2330 } 2331 Counter(TimeBase timeBase)2332 public Counter(TimeBase timeBase) { 2333 mTimeBase = timeBase; 2334 timeBase.add(this); 2335 } 2336 writeToParcel(Parcel out)2337 public void writeToParcel(Parcel out) { 2338 out.writeInt(mCount.get()); 2339 } 2340 2341 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2342 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2343 } 2344 2345 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2346 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2347 } 2348 2349 @Override getCountLocked(int which)2350 public int getCountLocked(int which) { 2351 return mCount.get(); 2352 } 2353 logState(Printer pw, String prefix)2354 public void logState(Printer pw, String prefix) { 2355 pw.println(prefix + "mCount=" + mCount.get()); 2356 } 2357 2358 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()2359 public void stepAtomic() { 2360 if (mTimeBase.isRunning()) { 2361 mCount.incrementAndGet(); 2362 } 2363 } 2364 addAtomic(int delta)2365 void addAtomic(int delta) { 2366 if (mTimeBase.isRunning()) { 2367 mCount.addAndGet(delta); 2368 } 2369 } 2370 2371 /** 2372 * Clear state of this counter. 2373 */ 2374 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2375 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2376 mCount.set(0); 2377 if (detachIfReset) { 2378 detach(); 2379 } 2380 return true; 2381 } 2382 2383 @Override detach()2384 public void detach() { 2385 mTimeBase.remove(this); 2386 } 2387 2388 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)2389 public void writeSummaryFromParcelLocked(Parcel out) { 2390 out.writeInt(mCount.get()); 2391 } 2392 2393 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)2394 public void readSummaryFromParcelLocked(Parcel in) { 2395 mCount.set(in.readInt()); 2396 } 2397 } 2398 2399 @VisibleForTesting 2400 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 2401 final TimeBase mTimeBase; 2402 public long[] mCounts; 2403 LongSamplingCounterArray(TimeBase timeBase, Parcel in)2404 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 2405 mTimeBase = timeBase; 2406 mCounts = in.createLongArray(); 2407 timeBase.add(this); 2408 } 2409 LongSamplingCounterArray(TimeBase timeBase)2410 public LongSamplingCounterArray(TimeBase timeBase) { 2411 mTimeBase = timeBase; 2412 timeBase.add(this); 2413 } 2414 writeToParcel(Parcel out)2415 private void writeToParcel(Parcel out) { 2416 out.writeLongArray(mCounts); 2417 } 2418 2419 @Override onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs)2420 public void onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs) { 2421 } 2422 2423 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2424 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2425 } 2426 2427 @Override getCountsLocked(int which)2428 public long[] getCountsLocked(int which) { 2429 return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); 2430 } 2431 2432 @Override logState(Printer pw, String prefix)2433 public void logState(Printer pw, String prefix) { 2434 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); 2435 } 2436 addCountLocked(long[] counts)2437 public void addCountLocked(long[] counts) { 2438 addCountLocked(counts, mTimeBase.isRunning()); 2439 } 2440 addCountLocked(long[] counts, boolean isRunning)2441 public void addCountLocked(long[] counts, boolean isRunning) { 2442 if (counts == null) { 2443 return; 2444 } 2445 if (isRunning) { 2446 if (mCounts == null) { 2447 mCounts = new long[counts.length]; 2448 } 2449 for (int i = 0; i < counts.length; ++i) { 2450 mCounts[i] += counts[i]; 2451 } 2452 } 2453 } 2454 getSize()2455 public int getSize() { 2456 return mCounts == null ? 0 : mCounts.length; 2457 } 2458 2459 /** 2460 * Clear state of this counter. 2461 */ 2462 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2463 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2464 if (mCounts != null) { 2465 Arrays.fill(mCounts, 0); 2466 } 2467 if (detachIfReset) { 2468 detach(); 2469 } 2470 return true; 2471 } 2472 2473 @Override detach()2474 public void detach() { 2475 mTimeBase.remove(this); 2476 } 2477 writeSummaryToParcelLocked(Parcel out)2478 private void writeSummaryToParcelLocked(Parcel out) { 2479 out.writeLongArray(mCounts); 2480 } 2481 readSummaryFromParcelLocked(Parcel in)2482 private void readSummaryFromParcelLocked(Parcel in) { 2483 mCounts = in.createLongArray(); 2484 } 2485 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)2486 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 2487 if (counterArray != null) { 2488 out.writeInt(1); 2489 counterArray.writeToParcel(out); 2490 } else { 2491 out.writeInt(0); 2492 } 2493 } 2494 readFromParcel(Parcel in, TimeBase timeBase)2495 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 2496 if (in.readInt() != 0) { 2497 return new LongSamplingCounterArray(timeBase, in); 2498 } else { 2499 return null; 2500 } 2501 } 2502 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)2503 public static void writeSummaryToParcelLocked(Parcel out, 2504 LongSamplingCounterArray counterArray) { 2505 if (counterArray != null) { 2506 out.writeInt(1); 2507 counterArray.writeSummaryToParcelLocked(out); 2508 } else { 2509 out.writeInt(0); 2510 } 2511 } 2512 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)2513 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 2514 TimeBase timeBase) { 2515 if (in.readInt() != 0) { 2516 final LongSamplingCounterArray counterArray 2517 = new LongSamplingCounterArray(timeBase); 2518 counterArray.readSummaryFromParcelLocked(in); 2519 return counterArray; 2520 } else { 2521 return null; 2522 } 2523 } 2524 } 2525 2526 private static class TimeMultiStateCounter extends LongCounter implements TimeBaseObs { 2527 private final TimeBase mTimeBase; 2528 private final LongMultiStateCounter mCounter; 2529 TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs)2530 private TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs) { 2531 this(timeBase, new LongMultiStateCounter(stateCount), timestampMs); 2532 } 2533 TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter, long timestampMs)2534 private TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter, 2535 long timestampMs) { 2536 mTimeBase = timeBase; 2537 mCounter = counter; 2538 mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); 2539 timeBase.add(this); 2540 } 2541 2542 @Nullable readFromParcel(Parcel in, TimeBase timeBase, int stateCount, long timestampMs)2543 private static TimeMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase, 2544 int stateCount, long timestampMs) { 2545 LongMultiStateCounter counter = LongMultiStateCounter.CREATOR.createFromParcel(in); 2546 if (counter.getStateCount() != stateCount) { 2547 return null; 2548 } 2549 return new TimeMultiStateCounter(timeBase, counter, timestampMs); 2550 } 2551 writeToParcel(Parcel out)2552 private void writeToParcel(Parcel out) { 2553 mCounter.writeToParcel(out, 0); 2554 } 2555 2556 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2557 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2558 mCounter.setEnabled(true, elapsedRealtimeUs / 1000); 2559 } 2560 2561 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2562 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2563 mCounter.setEnabled(false, elapsedRealtimeUs / 1000); 2564 } 2565 getStateCount()2566 public int getStateCount() { 2567 return mCounter.getStateCount(); 2568 } 2569 setState(@atteryConsumer.ProcessState int processState, long elapsedRealtimeMs)2570 private void setState(@BatteryConsumer.ProcessState int processState, 2571 long elapsedRealtimeMs) { 2572 mCounter.setState(processState, elapsedRealtimeMs); 2573 } 2574 update(long value, long timestampMs)2575 private long update(long value, long timestampMs) { 2576 return mCounter.updateValue(value, timestampMs); 2577 } 2578 increment(long increment, long timestampMs)2579 private void increment(long increment, long timestampMs) { 2580 mCounter.incrementValue(increment, timestampMs); 2581 } 2582 2583 /** 2584 * Returns accumulated count for the specified state. 2585 */ getCountForProcessState(@atteryConsumer.ProcessState int procState)2586 public long getCountForProcessState(@BatteryConsumer.ProcessState int procState) { 2587 return mCounter.getCount(procState); 2588 } 2589 getTotalCountLocked()2590 public long getTotalCountLocked() { 2591 return mCounter.getTotalCount(); 2592 } 2593 2594 @Override getCountLocked(int statsType)2595 public long getCountLocked(int statsType) { 2596 return getTotalCountLocked(); 2597 } 2598 2599 @Override logState(Printer pw, String prefix)2600 public void logState(Printer pw, String prefix) { 2601 pw.println(prefix + "mCounter=" + mCounter); 2602 } 2603 2604 /** 2605 * Clears state of this counter. 2606 */ 2607 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2608 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2609 mCounter.reset(); 2610 if (detachIfReset) { 2611 detach(); 2612 } 2613 return true; 2614 } 2615 2616 @Override detach()2617 public void detach() { 2618 mTimeBase.remove(this); 2619 } 2620 } 2621 2622 private static class TimeInFreqMultiStateCounter implements TimeBaseObs { 2623 private final TimeBase mTimeBase; 2624 private final LongArrayMultiStateCounter mCounter; 2625 TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount, long timestampMs)2626 private TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount, 2627 long timestampMs) { 2628 this(timeBase, new LongArrayMultiStateCounter(stateCount, cpuFreqCount), timestampMs); 2629 } 2630 TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter, long timestampMs)2631 private TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter, 2632 long timestampMs) { 2633 mTimeBase = timeBase; 2634 mCounter = counter; 2635 mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); 2636 timeBase.add(this); 2637 } 2638 writeToParcel(Parcel out)2639 private void writeToParcel(Parcel out) { 2640 mCounter.writeToParcel(out, 0); 2641 } 2642 2643 @Nullable readFromParcel(Parcel in, TimeBase timeBase, int stateCount, int cpuFreqCount, long timestampMs)2644 private static TimeInFreqMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase, 2645 int stateCount, int cpuFreqCount, long timestampMs) { 2646 // Read the object from the Parcel, whether it's usable or not 2647 LongArrayMultiStateCounter counter = 2648 LongArrayMultiStateCounter.CREATOR.createFromParcel(in); 2649 if (counter.getStateCount() != stateCount 2650 || counter.getArrayLength() != cpuFreqCount) { 2651 return null; 2652 } 2653 return new TimeInFreqMultiStateCounter(timeBase, counter, timestampMs); 2654 } 2655 2656 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2657 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2658 mCounter.setEnabled(true, elapsedRealtimeUs / 1000); 2659 } 2660 2661 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2662 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2663 mCounter.setEnabled(false, elapsedRealtimeUs / 1000); 2664 } 2665 getCounter()2666 public LongArrayMultiStateCounter getCounter() { 2667 return mCounter; 2668 } 2669 getStateCount()2670 public int getStateCount() { 2671 return mCounter.getStateCount(); 2672 } 2673 setTrackingEnabled(boolean enabled, long timestampMs)2674 public void setTrackingEnabled(boolean enabled, long timestampMs) { 2675 mCounter.setEnabled(enabled && mTimeBase.isRunning(), timestampMs); 2676 } 2677 setState(int uidRunningState, long elapsedRealtimeMs)2678 private void setState(int uidRunningState, long elapsedRealtimeMs) { 2679 mCounter.setState(uidRunningState, elapsedRealtimeMs); 2680 } 2681 2682 /** 2683 * Returns accumulated counts for the specified state, or false if all counts are zero. 2684 */ getCountsLocked(long[] counts, int procState)2685 public boolean getCountsLocked(long[] counts, int procState) { 2686 if (counts.length != mCounter.getArrayLength()) { 2687 return false; 2688 } 2689 2690 mCounter.getCounts(counts, procState); 2691 2692 // Return counts only if at least one of the elements is non-zero. 2693 for (int i = counts.length - 1; i >= 0; --i) { 2694 if (counts[i] != 0) { 2695 return true; 2696 } 2697 } 2698 return false; 2699 } 2700 logState(Printer pw, String prefix)2701 public void logState(Printer pw, String prefix) { 2702 pw.println(prefix + "mCounter=" + mCounter); 2703 } 2704 2705 /** 2706 * Clears state of this counter. 2707 */ 2708 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2709 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2710 mCounter.reset(); 2711 if (detachIfReset) { 2712 detach(); 2713 } 2714 return true; 2715 } 2716 2717 @Override detach()2718 public void detach() { 2719 mTimeBase.remove(this); 2720 } 2721 } 2722 2723 @VisibleForTesting 2724 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 2725 final TimeBase mTimeBase; 2726 private long mCount; 2727 LongSamplingCounter(TimeBase timeBase, Parcel in)2728 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 2729 mTimeBase = timeBase; 2730 mCount = in.readLong(); 2731 timeBase.add(this); 2732 } 2733 LongSamplingCounter(TimeBase timeBase)2734 public LongSamplingCounter(TimeBase timeBase) { 2735 mTimeBase = timeBase; 2736 timeBase.add(this); 2737 } 2738 writeToParcel(Parcel out)2739 public void writeToParcel(Parcel out) { 2740 out.writeLong(mCount); 2741 } 2742 2743 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2744 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2745 } 2746 2747 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2748 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2749 } 2750 getCountLocked(int which)2751 public long getCountLocked(int which) { 2752 return mCount; 2753 } 2754 2755 @Override getCountForProcessState(int procState)2756 public long getCountForProcessState(int procState) { 2757 if (procState == BatteryConsumer.PROCESS_STATE_ANY) { 2758 return getCountLocked(STATS_SINCE_CHARGED); 2759 } 2760 return 0; 2761 } 2762 2763 @Override logState(Printer pw, String prefix)2764 public void logState(Printer pw, String prefix) { 2765 pw.println(prefix + "mCount=" + mCount); 2766 } 2767 addCountLocked(long count)2768 public void addCountLocked(long count) { 2769 addCountLocked(count, mTimeBase.isRunning()); 2770 } 2771 addCountLocked(long count, boolean isRunning)2772 public void addCountLocked(long count, boolean isRunning) { 2773 if (isRunning) { 2774 mCount += count; 2775 } 2776 } 2777 2778 /** 2779 * Clear state of this counter. 2780 */ 2781 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2782 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2783 mCount = 0; 2784 if (detachIfReset) { 2785 detach(); 2786 } 2787 return true; 2788 } 2789 2790 @Override detach()2791 public void detach() { 2792 mTimeBase.remove(this); 2793 } 2794 writeSummaryFromParcelLocked(Parcel out)2795 public void writeSummaryFromParcelLocked(Parcel out) { 2796 out.writeLong(mCount); 2797 } 2798 readSummaryFromParcelLocked(Parcel in)2799 public void readSummaryFromParcelLocked(Parcel in) { 2800 mCount = in.readLong(); 2801 } 2802 } 2803 2804 /** 2805 * State for keeping track of timing information. 2806 */ 2807 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 2808 protected final Clock mClock; 2809 protected final int mType; 2810 protected final TimeBase mTimeBase; 2811 2812 protected int mCount; 2813 2814 // Times are in microseconds for better accuracy when dividing by the 2815 // lock count, and are in "battery realtime" units. 2816 2817 /** 2818 * The total time we have accumulated since the start of the original 2819 * boot, to the last time something interesting happened in the 2820 * current run. 2821 */ 2822 protected long mTotalTimeUs; 2823 2824 /** 2825 * The total time this timer has been running until the latest mark has been set. 2826 * Subtract this from mTotalTimeUs to get the time spent running since the mark was set. 2827 */ 2828 protected long mTimeBeforeMarkUs; 2829 2830 /** 2831 * Constructs from a parcel. 2832 * @param type 2833 * @param timeBase 2834 * @param in 2835 */ Timer(Clock clock, int type, TimeBase timeBase, Parcel in)2836 public Timer(Clock clock, int type, TimeBase timeBase, Parcel in) { 2837 mClock = clock; 2838 mType = type; 2839 mTimeBase = timeBase; 2840 2841 mCount = in.readInt(); 2842 mTotalTimeUs = in.readLong(); 2843 mTimeBeforeMarkUs = in.readLong(); 2844 timeBase.add(this); 2845 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTimeUs); 2846 } 2847 Timer(Clock clock, int type, TimeBase timeBase)2848 public Timer(Clock clock, int type, TimeBase timeBase) { 2849 mClock = clock; 2850 mType = type; 2851 mTimeBase = timeBase; 2852 timeBase.add(this); 2853 } 2854 writeToParcel(Parcel out, long elapsedRealtimeUs)2855 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2856 if (DEBUG) { 2857 Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 2858 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2859 elapsedRealtimeUs)); 2860 } 2861 out.writeInt(computeCurrentCountLocked()); 2862 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2863 elapsedRealtimeUs)); 2864 out.writeLong(mTimeBeforeMarkUs); 2865 } 2866 computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)2867 protected abstract long computeRunTimeLocked(long curBatteryRealtime, 2868 long elapsedRealtimeUs); 2869 computeCurrentCountLocked()2870 protected abstract int computeCurrentCountLocked(); 2871 2872 /** 2873 * Clear state of this timer. Returns true if the timer is inactive 2874 * so can be completely dropped. 2875 */ 2876 @Override reset(boolean detachIfReset)2877 public boolean reset(boolean detachIfReset) { 2878 return reset(detachIfReset, mClock.elapsedRealtime() * 1000); 2879 } 2880 2881 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2882 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2883 mTotalTimeUs = mTimeBeforeMarkUs = 0; 2884 mCount = 0; 2885 if (detachIfReset) { 2886 detach(); 2887 } 2888 return true; 2889 } 2890 2891 @Override detach()2892 public void detach() { 2893 mTimeBase.remove(this); 2894 } 2895 2896 @Override onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, long baseRealtimeUs)2897 public void onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, 2898 long baseRealtimeUs) { 2899 } 2900 2901 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2902 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2903 if (DEBUG && mType < 0) { 2904 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtimeUs 2905 + " old mTotalTime=" + mTotalTimeUs); 2906 } 2907 mTotalTimeUs = computeRunTimeLocked(baseRealtimeUs, elapsedRealtimeUs); 2908 mCount = computeCurrentCountLocked(); 2909 if (DEBUG && mType < 0) { 2910 Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTimeUs); 2911 } 2912 } 2913 2914 /** 2915 * Writes a possibly null Timer to a Parcel. 2916 * 2917 * @param out the Parcel to be written to. 2918 * @param timer a Timer, or null. 2919 */ writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)2920 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 2921 if (timer == null) { 2922 out.writeInt(0); // indicates null 2923 return; 2924 } 2925 out.writeInt(1); // indicates non-null 2926 timer.writeToParcel(out, elapsedRealtimeUs); 2927 } 2928 2929 @Override getTotalTimeLocked(long elapsedRealtimeUs, int which)2930 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 2931 return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2932 elapsedRealtimeUs); 2933 } 2934 2935 @Override getCountLocked(int which)2936 public int getCountLocked(int which) { 2937 return computeCurrentCountLocked(); 2938 } 2939 2940 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)2941 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 2942 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2943 elapsedRealtimeUs); 2944 return val - mTimeBeforeMarkUs; 2945 } 2946 2947 @Override logState(Printer pw, String prefix)2948 public void logState(Printer pw, String prefix) { 2949 pw.println(prefix + "mCount=" + mCount); 2950 pw.println(prefix + "mTotalTime=" + mTotalTimeUs); 2951 } 2952 2953 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2954 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2955 long runTimeUs = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2956 elapsedRealtimeUs); 2957 out.writeLong(runTimeUs); 2958 out.writeInt(computeCurrentCountLocked()); 2959 } 2960 readSummaryFromParcelLocked(Parcel in)2961 public void readSummaryFromParcelLocked(Parcel in) { 2962 // Multiply by 1000 for backwards compatibility 2963 mTotalTimeUs = in.readLong(); 2964 mCount = in.readInt(); 2965 // When reading the summary, we set the mark to be the latest information. 2966 mTimeBeforeMarkUs = mTotalTimeUs; 2967 } 2968 } 2969 2970 /** 2971 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 2972 * method. The state of the timer according to its {@link TimeBase} will determine how much 2973 * of the value is recorded. 2974 * 2975 * If the value being recorded resets, {@link #endSample()} can be called in order to 2976 * account for the change. If the value passed in to {@link #update(long, int)} decreased 2977 * between calls, the {@link #endSample()} is automatically called and the new value is 2978 * expected to increase monotonically from that point on. 2979 */ 2980 public static class SamplingTimer extends Timer { 2981 2982 /** 2983 * The most recent reported count from /proc/wakelocks. 2984 */ 2985 int mCurrentReportedCount; 2986 2987 /** 2988 * The reported count from /proc/wakelocks when unplug() was last 2989 * called. 2990 */ 2991 int mBaseReportedCount; 2992 2993 /** 2994 * The most recent reported total_time from /proc/wakelocks. 2995 */ 2996 long mCurrentReportedTotalTimeUs; 2997 2998 /** 2999 * The reported total_time from /proc/wakelocks when unplug() was last 3000 * called. 3001 */ 3002 long mBaseReportedTotalTimeUs; 3003 3004 /** 3005 * Whether we are currently in a discharge cycle. 3006 */ 3007 boolean mTimeBaseRunning; 3008 3009 /** 3010 * Whether we are currently recording reported values. 3011 */ 3012 boolean mTrackingReportedValues; 3013 3014 /* 3015 * A sequence counter, incremented once for each update of the stats. 3016 */ 3017 int mUpdateVersion; 3018 3019 @VisibleForTesting SamplingTimer(Clock clock, TimeBase timeBase, Parcel in)3020 public SamplingTimer(Clock clock, TimeBase timeBase, Parcel in) { 3021 super(clock, 0, timeBase, in); 3022 mCurrentReportedCount = in.readInt(); 3023 mBaseReportedCount = in.readInt(); 3024 mCurrentReportedTotalTimeUs = in.readLong(); 3025 mBaseReportedTotalTimeUs = in.readLong(); 3026 mTrackingReportedValues = in.readInt() == 1; 3027 mTimeBaseRunning = timeBase.isRunning(); 3028 } 3029 3030 @VisibleForTesting SamplingTimer(Clock clock, TimeBase timeBase)3031 public SamplingTimer(Clock clock, TimeBase timeBase) { 3032 super(clock, 0, timeBase); 3033 mTrackingReportedValues = false; 3034 mTimeBaseRunning = timeBase.isRunning(); 3035 } 3036 3037 /** 3038 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 3039 * be less than the values used for a previous invocation. 3040 */ endSample()3041 public void endSample() { 3042 endSample(mClock.elapsedRealtime() * 1000); 3043 } 3044 3045 /** 3046 * @see #endSample() 3047 */ endSample(long elapsedRealtimeUs)3048 public void endSample(long elapsedRealtimeUs) { 3049 mTotalTimeUs = computeRunTimeLocked(0 /* unused by us */, elapsedRealtimeUs); 3050 mCount = computeCurrentCountLocked(); 3051 mBaseReportedTotalTimeUs = mCurrentReportedTotalTimeUs = 0; 3052 mBaseReportedCount = mCurrentReportedCount = 0; 3053 mTrackingReportedValues = false; 3054 } 3055 setUpdateVersion(int version)3056 public void setUpdateVersion(int version) { 3057 mUpdateVersion = version; 3058 } 3059 getUpdateVersion()3060 public int getUpdateVersion() { 3061 return mUpdateVersion; 3062 } 3063 3064 /** 3065 * Updates the current recorded values. These are meant to be monotonically increasing 3066 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 3067 * 3068 * If the values being recorded have been reset, the monotonically increasing requirement 3069 * will be broken. In this case, {@link #endSample()} is automatically called and 3070 * the total value of totalTimeUs and count are recorded, starting a new monotonically 3071 * increasing sample. 3072 * 3073 * @param totalTimeUs total time of sample in microseconds. 3074 * @param count total number of times the event being sampled occurred. 3075 */ update(long totalTimeUs, int count, long elapsedRealtimeUs)3076 public void update(long totalTimeUs, int count, long elapsedRealtimeUs) { 3077 update(totalTimeUs, 0, count, elapsedRealtimeUs); 3078 } 3079 3080 /** 3081 * Updates the current recorded values. See {@link #update(long, int, long)} 3082 * 3083 * @param activeTimeUs Time that the currently active wake lock has been held. 3084 */ update(long totalTimeUs, long activeTimeUs, int count, long elapsedRealtimeUs)3085 public void update(long totalTimeUs, long activeTimeUs, int count, 3086 long elapsedRealtimeUs) { 3087 if (mTimeBaseRunning && !mTrackingReportedValues) { 3088 // Updating the reported value for the first time. If the wake lock is currently 3089 // active, mark the time it was acquired as the base timestamp. 3090 mBaseReportedTotalTimeUs = totalTimeUs - activeTimeUs; 3091 mBaseReportedCount = activeTimeUs == 0 ? count : count - 1; 3092 } 3093 3094 mTrackingReportedValues = true; 3095 3096 if (totalTimeUs < mCurrentReportedTotalTimeUs || count < mCurrentReportedCount) { 3097 endSample(elapsedRealtimeUs); 3098 } 3099 3100 mCurrentReportedTotalTimeUs = totalTimeUs; 3101 mCurrentReportedCount = count; 3102 } 3103 3104 /** 3105 * Adds deltaTime and deltaCount to the current sample. 3106 * 3107 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 3108 * @param deltaCount additional number of times the event being sampled occurred. 3109 */ add(long deltaTimeUs, int deltaCount)3110 public void add(long deltaTimeUs, int deltaCount) { 3111 add(deltaTimeUs, deltaCount, mClock.elapsedRealtime() * 1000); 3112 } 3113 3114 /** 3115 * @see #add(long, int) 3116 */ add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs)3117 public void add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs) { 3118 update(mCurrentReportedTotalTimeUs + deltaTimeUs, mCurrentReportedCount + deltaCount, 3119 elapsedRealtimeUs); 3120 } 3121 3122 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3123 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3124 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3125 if (mTrackingReportedValues) { 3126 mBaseReportedTotalTimeUs = mCurrentReportedTotalTimeUs; 3127 mBaseReportedCount = mCurrentReportedCount; 3128 } 3129 mTimeBaseRunning = true; 3130 } 3131 3132 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3133 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3134 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3135 mTimeBaseRunning = false; 3136 } 3137 3138 @Override logState(Printer pw, String prefix)3139 public void logState(Printer pw, String prefix) { 3140 super.logState(pw, prefix); 3141 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 3142 + " mBaseReportedCount=" + mBaseReportedCount 3143 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTimeUs 3144 + " mBaseReportedTotalTimeUs=" + mBaseReportedTotalTimeUs); 3145 } 3146 3147 @Override computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)3148 protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) { 3149 return mTotalTimeUs + (mTimeBaseRunning && mTrackingReportedValues 3150 ? mCurrentReportedTotalTimeUs - mBaseReportedTotalTimeUs : 0); 3151 } 3152 3153 @Override computeCurrentCountLocked()3154 protected int computeCurrentCountLocked() { 3155 return mCount + (mTimeBaseRunning && mTrackingReportedValues 3156 ? mCurrentReportedCount - mBaseReportedCount : 0); 3157 } 3158 3159 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3160 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3161 super.writeToParcel(out, elapsedRealtimeUs); 3162 out.writeInt(mCurrentReportedCount); 3163 out.writeInt(mBaseReportedCount); 3164 out.writeLong(mCurrentReportedTotalTimeUs); 3165 out.writeLong(mBaseReportedTotalTimeUs); 3166 out.writeInt(mTrackingReportedValues ? 1 : 0); 3167 } 3168 3169 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3170 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3171 super.reset(detachIfReset, elapsedRealtimeUs); 3172 mTrackingReportedValues = false; 3173 mBaseReportedTotalTimeUs = 0; 3174 mBaseReportedCount = 0; 3175 return true; 3176 } 3177 } 3178 3179 /** 3180 * A timer that increments in batches. It does not run for durations, but just jumps 3181 * for a pre-determined amount. 3182 */ 3183 public static class BatchTimer extends Timer { 3184 final Uid mUid; 3185 3186 /** 3187 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 3188 */ 3189 long mLastAddedTimeUs; 3190 3191 /** 3192 * The last duration that we added to the timer. This is in microseconds. 3193 */ 3194 long mLastAddedDurationUs; 3195 3196 /** 3197 * Whether we are currently in a discharge cycle. 3198 */ 3199 boolean mInDischarge; 3200 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase, Parcel in)3201 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase, Parcel in) { 3202 super(clock, type, timeBase, in); 3203 mUid = uid; 3204 mLastAddedTimeUs = in.readLong(); 3205 mLastAddedDurationUs = in.readLong(); 3206 mInDischarge = timeBase.isRunning(); 3207 } 3208 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase)3209 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase) { 3210 super(clock, type, timeBase); 3211 mUid = uid; 3212 mInDischarge = timeBase.isRunning(); 3213 } 3214 3215 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3216 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3217 super.writeToParcel(out, elapsedRealtimeUs); 3218 out.writeLong(mLastAddedTimeUs); 3219 out.writeLong(mLastAddedDurationUs); 3220 } 3221 3222 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3223 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3224 recomputeLastDuration(elapsedRealtimeUs, false); 3225 mInDischarge = false; 3226 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3227 } 3228 3229 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3230 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3231 recomputeLastDuration(elapsedRealtimeUs, false); 3232 mInDischarge = true; 3233 // If we are still within the last added duration, then re-added whatever remains. 3234 if (mLastAddedTimeUs == elapsedRealtimeUs) { 3235 mTotalTimeUs += mLastAddedDurationUs; 3236 } 3237 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3238 } 3239 3240 @Override logState(Printer pw, String prefix)3241 public void logState(Printer pw, String prefix) { 3242 super.logState(pw, prefix); 3243 pw.println(prefix + "mLastAddedTime=" + mLastAddedTimeUs 3244 + " mLastAddedDuration=" + mLastAddedDurationUs); 3245 } 3246 computeOverage(long curTimeUs)3247 private long computeOverage(long curTimeUs) { 3248 if (mLastAddedTimeUs > 0) { 3249 return mLastAddedDurationUs - curTimeUs; 3250 } 3251 return 0; 3252 } 3253 recomputeLastDuration(long curTimeUs, boolean abort)3254 private void recomputeLastDuration(long curTimeUs, boolean abort) { 3255 final long overage = computeOverage(curTimeUs); 3256 if (overage > 0) { 3257 // Aborting before the duration ran out -- roll back the remaining 3258 // duration. Only do this if currently discharging; otherwise we didn't 3259 // actually add the time. 3260 if (mInDischarge) { 3261 mTotalTimeUs -= overage; 3262 } 3263 if (abort) { 3264 mLastAddedTimeUs = 0; 3265 } else { 3266 mLastAddedTimeUs = curTimeUs; 3267 mLastAddedDurationUs -= overage; 3268 } 3269 } 3270 } 3271 addDuration(long durationMs, long elapsedRealtimeMs)3272 public void addDuration(long durationMs, long elapsedRealtimeMs) { 3273 final long nowUs = elapsedRealtimeMs * 1000; 3274 recomputeLastDuration(nowUs, true); 3275 mLastAddedTimeUs = nowUs; 3276 mLastAddedDurationUs = durationMs * 1000; 3277 if (mInDischarge) { 3278 mTotalTimeUs += mLastAddedDurationUs; 3279 mCount++; 3280 } 3281 } 3282 abortLastDuration(long elapsedRealtimeMs)3283 public void abortLastDuration(long elapsedRealtimeMs) { 3284 final long nowUs = elapsedRealtimeMs * 1000; 3285 recomputeLastDuration(nowUs, true); 3286 } 3287 3288 @Override computeCurrentCountLocked()3289 protected int computeCurrentCountLocked() { 3290 return mCount; 3291 } 3292 3293 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)3294 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 3295 final long overage = computeOverage(elapsedRealtimeUs); 3296 if (overage > 0) { 3297 return mTotalTimeUs = overage; 3298 } 3299 return mTotalTimeUs; 3300 } 3301 3302 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3303 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3304 recomputeLastDuration(elapsedRealtimeUs, true); 3305 boolean stillActive = mLastAddedTimeUs == elapsedRealtimeUs; 3306 super.reset(!stillActive && detachIfReset, elapsedRealtimeUs); 3307 return !stillActive; 3308 } 3309 } 3310 3311 3312 /** 3313 * A StopwatchTimer that also tracks the total and max individual 3314 * time spent active according to the given timebase. Whereas 3315 * StopwatchTimer apportions the time amongst all in the pool, 3316 * the total and max durations are not apportioned. 3317 */ 3318 public static class DurationTimer extends StopwatchTimer { 3319 /** 3320 * The time (in ms) that the timer was last acquired or the time base 3321 * last (re-)started. Increasing the nesting depth does not reset this time. 3322 * 3323 * -1 if the timer is currently not running or the time base is not running. 3324 * 3325 * If written to a parcel, the start time is reset, as is mNesting in the base class 3326 * StopwatchTimer. 3327 */ 3328 long mStartTimeMs = -1; 3329 3330 /** 3331 * The longest time period (in ms) that the timer has been active. Not pooled. 3332 */ 3333 long mMaxDurationMs; 3334 3335 /** 3336 * The time (in ms) that that the timer has been active since most recent 3337 * stopRunningLocked() or reset(). Not pooled. 3338 */ 3339 long mCurrentDurationMs; 3340 3341 /** 3342 * The total time (in ms) that that the timer has been active since most recent reset() 3343 * prior to the current startRunningLocked. This is the sum of all past currentDurations 3344 * (but not including the present currentDuration) since reset. Not pooled. 3345 */ 3346 long mTotalDurationMs; 3347 DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)3348 public DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3349 TimeBase timeBase, Parcel in) { 3350 super(clock, uid, type, timerPool, timeBase, in); 3351 mMaxDurationMs = in.readLong(); 3352 mTotalDurationMs = in.readLong(); 3353 mCurrentDurationMs = in.readLong(); 3354 } 3355 DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)3356 public DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3357 TimeBase timeBase) { 3358 super(clock, uid, type, timerPool, timeBase); 3359 } 3360 3361 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3362 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3363 super.writeToParcel(out, elapsedRealtimeUs); 3364 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 3365 out.writeLong(mTotalDurationMs); 3366 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 3367 } 3368 3369 /** 3370 * Write the summary to the parcel. 3371 * 3372 * Since the time base is probably meaningless after we come back, reading 3373 * from this will have the effect of stopping the timer. So here all we write 3374 * is the max and total durations. 3375 */ 3376 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)3377 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 3378 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3379 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 3380 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 3381 } 3382 3383 /** 3384 * Read the summary parcel. 3385 * 3386 * Has the side effect of stopping the timer. 3387 */ 3388 @Override readSummaryFromParcelLocked(Parcel in)3389 public void readSummaryFromParcelLocked(Parcel in) { 3390 super.readSummaryFromParcelLocked(in); 3391 mMaxDurationMs = in.readLong(); 3392 mTotalDurationMs = in.readLong(); 3393 mStartTimeMs = -1; 3394 mCurrentDurationMs = 0; 3395 } 3396 3397 /** 3398 * The TimeBase time started (again). 3399 * 3400 * If the timer is also running, store the start time. 3401 */ onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3402 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3403 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3404 if (mNesting > 0) { 3405 mStartTimeMs = baseRealtimeUs / 1000; 3406 } 3407 } 3408 3409 /** 3410 * The TimeBase stopped running. 3411 * 3412 * If the timer is running, add the duration into mCurrentDurationMs. 3413 */ 3414 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3415 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3416 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3417 if (mNesting > 0) { 3418 // baseRealtimeUs has already been converted to the timebase's realtime. 3419 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 3420 } 3421 mStartTimeMs = -1; 3422 } 3423 3424 @Override logState(Printer pw, String prefix)3425 public void logState(Printer pw, String prefix) { 3426 super.logState(pw, prefix); 3427 } 3428 3429 @Override startRunningLocked(long elapsedRealtimeMs)3430 public void startRunningLocked(long elapsedRealtimeMs) { 3431 super.startRunningLocked(elapsedRealtimeMs); 3432 if (mNesting == 1 && mTimeBase.isRunning()) { 3433 // Just started 3434 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 3435 } 3436 } 3437 3438 /** 3439 * Decrements the mNesting ref-count on this timer. 3440 * 3441 * If it actually stopped (mNesting went to 0), then possibly update 3442 * mMaxDuration if the current duration was the longest ever. 3443 */ 3444 @Override stopRunningLocked(long elapsedRealtimeMs)3445 public void stopRunningLocked(long elapsedRealtimeMs) { 3446 if (mNesting == 1) { 3447 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 3448 mTotalDurationMs += durationMs; 3449 if (durationMs > mMaxDurationMs) { 3450 mMaxDurationMs = durationMs; 3451 } 3452 mStartTimeMs = -1; 3453 mCurrentDurationMs = 0; 3454 } 3455 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 3456 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 3457 super.stopRunningLocked(elapsedRealtimeMs); 3458 } 3459 3460 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3461 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3462 boolean result = super.reset(detachIfReset, elapsedRealtimeUs); 3463 mMaxDurationMs = 0; 3464 mTotalDurationMs = 0; 3465 mCurrentDurationMs = 0; 3466 if (mNesting > 0) { 3467 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeUs) / 1000; 3468 } else { 3469 mStartTimeMs = -1; 3470 } 3471 return result; 3472 } 3473 3474 /** 3475 * Returns the max duration that this timer has ever seen. 3476 * 3477 * Note that this time is NOT split between the timers in the timer group that 3478 * this timer is attached to. It is the TOTAL time. 3479 */ 3480 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)3481 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 3482 if (mNesting > 0) { 3483 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 3484 if (durationMs > mMaxDurationMs) { 3485 return durationMs; 3486 } 3487 } 3488 return mMaxDurationMs; 3489 } 3490 3491 /** 3492 * Returns the time since the timer was started. 3493 * Returns 0 if the timer is not currently running. 3494 * 3495 * Note that this time is NOT split between the timers in the timer group that 3496 * this timer is attached to. It is the TOTAL time. 3497 * 3498 * Note that if running timer is parceled and unparceled, this method will return 3499 * current duration value at the time of parceling even though timer may not be 3500 * currently running. 3501 */ 3502 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)3503 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 3504 long durationMs = mCurrentDurationMs; 3505 if (mNesting > 0 && mTimeBase.isRunning()) { 3506 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) 3507 - mStartTimeMs; 3508 } 3509 return durationMs; 3510 } 3511 3512 /** 3513 * Returns the total cumulative duration that this timer has been on since reset(). 3514 * If mTimerPool == null, this should be the same 3515 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 3516 * 3517 * Note that this time is NOT split between the timers in the timer group that 3518 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 3519 * the result will not be equivalent to getTotalTimeLocked. 3520 */ 3521 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)3522 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 3523 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 3524 } 3525 } 3526 3527 /** 3528 * State for keeping track of timing information. 3529 */ 3530 public static class StopwatchTimer extends Timer { 3531 final Uid mUid; 3532 final ArrayList<StopwatchTimer> mTimerPool; 3533 3534 int mNesting; 3535 3536 /** 3537 * The last time at which we updated the timer. If mNesting is > 0, 3538 * subtract this from the current battery time to find the amount of 3539 * time we have been running since we last computed an update. 3540 */ 3541 long mUpdateTimeUs; 3542 3543 /** 3544 * The total time at which the timer was acquired, to determine if it 3545 * was actually held for an interesting duration. If time base was not running when timer 3546 * was acquired, will be -1. 3547 */ 3548 long mAcquireTimeUs = -1; 3549 3550 long mTimeoutUs; 3551 3552 /** 3553 * For partial wake locks, keep track of whether we are in the list 3554 * to consume CPU cycles. 3555 */ 3556 @VisibleForTesting 3557 public boolean mInList; 3558 StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)3559 public StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3560 TimeBase timeBase, Parcel in) { 3561 super(clock, type, timeBase, in); 3562 mUid = uid; 3563 mTimerPool = timerPool; 3564 mUpdateTimeUs = in.readLong(); 3565 } 3566 StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)3567 public StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3568 TimeBase timeBase) { 3569 super(clock, type, timeBase); 3570 mUid = uid; 3571 mTimerPool = timerPool; 3572 } 3573 setTimeout(long timeoutUs)3574 public void setTimeout(long timeoutUs) { 3575 mTimeoutUs = timeoutUs; 3576 } 3577 writeToParcel(Parcel out, long elapsedRealtimeUs)3578 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3579 super.writeToParcel(out, elapsedRealtimeUs); 3580 out.writeLong(mUpdateTimeUs); 3581 } 3582 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3583 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3584 if (mNesting > 0) { 3585 if (DEBUG && mType < 0) { 3586 Log.v(TAG, "old mUpdateTime=" + mUpdateTimeUs); 3587 } 3588 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3589 mUpdateTimeUs = baseRealtimeUs; 3590 if (DEBUG && mType < 0) { 3591 Log.v(TAG, "new mUpdateTime=" + mUpdateTimeUs); 3592 } 3593 } 3594 } 3595 logState(Printer pw, String prefix)3596 public void logState(Printer pw, String prefix) { 3597 super.logState(pw, prefix); 3598 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTimeUs 3599 + " mAcquireTime=" + mAcquireTimeUs); 3600 } 3601 startRunningLocked(long elapsedRealtimeMs)3602 public void startRunningLocked(long elapsedRealtimeMs) { 3603 if (mNesting++ == 0) { 3604 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3605 mUpdateTimeUs = batteryRealtimeUs; 3606 if (mTimerPool != null) { 3607 // Accumulate time to all currently active timers before adding 3608 // this new one to the pool. 3609 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 3610 // Add this timer to the active pool 3611 mTimerPool.add(this); 3612 } 3613 if (mTimeBase.isRunning()) { 3614 // Increment the count 3615 mCount++; 3616 mAcquireTimeUs = mTotalTimeUs; 3617 } else { 3618 mAcquireTimeUs = -1; 3619 } 3620 if (DEBUG && mType < 0) { 3621 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTimeUs 3622 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 3623 + " mAcquireTime=" + mAcquireTimeUs); 3624 } 3625 } 3626 } 3627 isRunningLocked()3628 public boolean isRunningLocked() { 3629 return mNesting > 0; 3630 } 3631 stopRunningLocked(long elapsedRealtimeMs)3632 public void stopRunningLocked(long elapsedRealtimeMs) { 3633 // Ignore attempt to stop a timer that isn't running 3634 if (mNesting == 0) { 3635 return; 3636 } 3637 if (--mNesting == 0) { 3638 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3639 if (mTimerPool != null) { 3640 // Accumulate time to all active counters, scaled by the total 3641 // active in the pool, before taking this one out of the pool. 3642 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 3643 // Remove this timer from the active pool 3644 mTimerPool.remove(this); 3645 } else { 3646 mNesting = 1; 3647 mTotalTimeUs = computeRunTimeLocked(batteryRealtimeUs, 3648 elapsedRealtimeMs * 1000); 3649 mNesting = 0; 3650 } 3651 3652 if (DEBUG && mType < 0) { 3653 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTimeUs 3654 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 3655 + " mAcquireTime=" + mAcquireTimeUs); 3656 } 3657 3658 if (mAcquireTimeUs >= 0 && mTotalTimeUs == mAcquireTimeUs) { 3659 // If there was no change in the time, then discard this 3660 // count. A somewhat cheezy strategy, but hey. 3661 mCount--; 3662 } 3663 } 3664 } 3665 stopAllRunningLocked(long elapsedRealtimeMs)3666 public void stopAllRunningLocked(long elapsedRealtimeMs) { 3667 if (mNesting > 0) { 3668 mNesting = 1; 3669 stopRunningLocked(elapsedRealtimeMs); 3670 } 3671 } 3672 3673 // Update the total time for all other running Timers with the same type as this Timer 3674 // due to a change in timer count refreshTimersLocked(long batteryRealtimeUs, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)3675 private static long refreshTimersLocked(long batteryRealtimeUs, 3676 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 3677 long selfTimeUs = 0; 3678 final int N = pool.size(); 3679 for (int i=N-1; i>= 0; i--) { 3680 final StopwatchTimer t = pool.get(i); 3681 long heldTimeUs = batteryRealtimeUs - t.mUpdateTimeUs; 3682 if (heldTimeUs > 0) { 3683 final long myTimeUs = heldTimeUs / N; 3684 if (t == self) { 3685 selfTimeUs = myTimeUs; 3686 } 3687 t.mTotalTimeUs += myTimeUs; 3688 } 3689 t.mUpdateTimeUs = batteryRealtimeUs; 3690 } 3691 return selfTimeUs; 3692 } 3693 3694 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)3695 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 3696 if (mTimeoutUs > 0 && curBatteryRealtimeUs > mUpdateTimeUs + mTimeoutUs) { 3697 curBatteryRealtimeUs = mUpdateTimeUs + mTimeoutUs; 3698 } 3699 return mTotalTimeUs + (mNesting > 0 3700 ? (curBatteryRealtimeUs - mUpdateTimeUs) 3701 / (mTimerPool != null && mTimerPool.size() > 0 ? mTimerPool.size() : 1) 3702 : 0); 3703 } 3704 3705 @Override computeCurrentCountLocked()3706 protected int computeCurrentCountLocked() { 3707 return mCount; 3708 } 3709 3710 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3711 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3712 boolean canDetach = mNesting <= 0; 3713 super.reset(canDetach && detachIfReset, elapsedRealtimeUs); 3714 if (mNesting > 0) { 3715 mUpdateTimeUs = mTimeBase.getRealtime(elapsedRealtimeUs); 3716 } 3717 // To ensure mCount isn't decreased to -1 if timer is stopped later. 3718 mAcquireTimeUs = -1; 3719 return canDetach; 3720 } 3721 3722 @Override detach()3723 public void detach() { 3724 super.detach(); 3725 if (mTimerPool != null) { 3726 mTimerPool.remove(this); 3727 } 3728 } 3729 3730 @Override readSummaryFromParcelLocked(Parcel in)3731 public void readSummaryFromParcelLocked(Parcel in) { 3732 super.readSummaryFromParcelLocked(in); 3733 mNesting = 0; 3734 } 3735 3736 /** 3737 * Set the mark so that we can query later for the total time the timer has 3738 * accumulated since this point. The timer can be running or not. 3739 * 3740 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 3741 */ setMark(long elapsedRealtimeMs)3742 public void setMark(long elapsedRealtimeMs) { 3743 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3744 if (mNesting > 0) { 3745 // We are running. 3746 if (mTimerPool != null) { 3747 refreshTimersLocked(batteryRealtimeUs, mTimerPool, this); 3748 } else { 3749 mTotalTimeUs += batteryRealtimeUs - mUpdateTimeUs; 3750 mUpdateTimeUs = batteryRealtimeUs; 3751 } 3752 } 3753 mTimeBeforeMarkUs = mTotalTimeUs; 3754 } 3755 } 3756 3757 /** 3758 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 3759 * TimeBase is effectively a subset of the other. 3760 */ 3761 public static class DualTimer extends DurationTimer { 3762 // This class both is a DurationTimer and also holds a second DurationTimer. 3763 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 3764 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 3765 // STATS_SINCE_CHARGED). 3766 // mSubTimer typically tracks only part of the total time, such as background time, as 3767 // determined by a subTimeBase. It is NOT pooled. 3768 private final DurationTimer mSubTimer; 3769 3770 /** 3771 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 3772 * The main timer (this) is based on the given timeBase and timerPool. 3773 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 3774 * the main timer is. 3775 */ DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)3776 public DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3777 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 3778 super(clock, uid, type, timerPool, timeBase, in); 3779 mSubTimer = new DurationTimer(clock, uid, type, null, subTimeBase, in); 3780 } 3781 3782 /** 3783 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 3784 * The main timer (this) is based on the given timeBase and timerPool. 3785 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 3786 * the main timer is. 3787 */ DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)3788 public DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3789 TimeBase timeBase, TimeBase subTimeBase) { 3790 super(clock, uid, type, timerPool, timeBase); 3791 mSubTimer = new DurationTimer(clock, uid, type, null, subTimeBase); 3792 } 3793 3794 /** Get the secondary timer. */ 3795 @Override getSubTimer()3796 public DurationTimer getSubTimer() { 3797 return mSubTimer; 3798 } 3799 3800 @Override startRunningLocked(long elapsedRealtimeMs)3801 public void startRunningLocked(long elapsedRealtimeMs) { 3802 super.startRunningLocked(elapsedRealtimeMs); 3803 mSubTimer.startRunningLocked(elapsedRealtimeMs); 3804 } 3805 3806 @Override stopRunningLocked(long elapsedRealtimeMs)3807 public void stopRunningLocked(long elapsedRealtimeMs) { 3808 super.stopRunningLocked(elapsedRealtimeMs); 3809 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 3810 } 3811 3812 @Override stopAllRunningLocked(long elapsedRealtimeMs)3813 public void stopAllRunningLocked(long elapsedRealtimeMs) { 3814 super.stopAllRunningLocked(elapsedRealtimeMs); 3815 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 3816 } 3817 3818 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3819 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3820 boolean active = false; 3821 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 3822 active |= !mSubTimer.reset(false, elapsedRealtimeUs); 3823 active |= !super.reset(detachIfReset, elapsedRealtimeUs); 3824 return !active; 3825 } 3826 3827 @Override detach()3828 public void detach() { 3829 mSubTimer.detach(); 3830 super.detach(); 3831 } 3832 3833 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3834 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3835 super.writeToParcel(out, elapsedRealtimeUs); 3836 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 3837 } 3838 3839 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)3840 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 3841 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3842 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3843 } 3844 3845 @Override readSummaryFromParcelLocked(Parcel in)3846 public void readSummaryFromParcelLocked(Parcel in) { 3847 super.readSummaryFromParcelLocked(in); 3848 mSubTimer.readSummaryFromParcelLocked(in); 3849 } 3850 } 3851 3852 3853 public abstract class OverflowArrayMap<T> { 3854 private static final String OVERFLOW_NAME = "*overflow*"; 3855 3856 final int mUid; 3857 final ArrayMap<String, T> mMap = new ArrayMap<>(); 3858 T mCurOverflow; 3859 ArrayMap<String, MutableInt> mActiveOverflow; 3860 long mLastOverflowTimeMs; 3861 long mLastOverflowFinishTimeMs; 3862 long mLastClearTimeMs; 3863 long mLastCleanupTimeMs; 3864 OverflowArrayMap(int uid)3865 public OverflowArrayMap(int uid) { 3866 mUid = uid; 3867 } 3868 getMap()3869 public ArrayMap<String, T> getMap() { 3870 return mMap; 3871 } 3872 clear()3873 public void clear() { 3874 mLastClearTimeMs = SystemClock.elapsedRealtime(); 3875 mMap.clear(); 3876 mCurOverflow = null; 3877 mActiveOverflow = null; 3878 } 3879 add(String name, T obj)3880 public void add(String name, T obj) { 3881 if (name == null) { 3882 name = ""; 3883 } 3884 mMap.put(name, obj); 3885 if (OVERFLOW_NAME.equals(name)) { 3886 mCurOverflow = obj; 3887 } 3888 } 3889 cleanup(long elapsedRealtimeMs)3890 public void cleanup(long elapsedRealtimeMs) { 3891 mLastCleanupTimeMs = elapsedRealtimeMs; 3892 if (mActiveOverflow != null) { 3893 if (mActiveOverflow.size() == 0) { 3894 mActiveOverflow = null; 3895 } 3896 } 3897 if (mActiveOverflow == null) { 3898 // There is no currently active overflow, so we should no longer have 3899 // an overflow entry. 3900 if (mMap.containsKey(OVERFLOW_NAME)) { 3901 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 3902 + mMap.get(OVERFLOW_NAME)); 3903 mMap.remove(OVERFLOW_NAME); 3904 } 3905 mCurOverflow = null; 3906 } else { 3907 // There is currently active overflow, so we should still have an overflow entry. 3908 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 3909 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 3910 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 3911 } 3912 } 3913 } 3914 startObject(String name, long elapsedRealtimeMs)3915 public T startObject(String name, long elapsedRealtimeMs) { 3916 if (name == null) { 3917 name = ""; 3918 } 3919 T obj = mMap.get(name); 3920 if (obj != null) { 3921 return obj; 3922 } 3923 3924 // No object exists for the given name, but do we currently have it 3925 // running as part of the overflow? 3926 if (mActiveOverflow != null) { 3927 MutableInt over = mActiveOverflow.get(name); 3928 if (over != null) { 3929 // We are already actively counting this name in the overflow object. 3930 obj = mCurOverflow; 3931 if (obj == null) { 3932 // Shouldn't be here, but we'll try to recover. 3933 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 3934 obj = mCurOverflow = instantiateObject(); 3935 mMap.put(OVERFLOW_NAME, obj); 3936 } 3937 over.value++; 3938 return obj; 3939 } 3940 } 3941 3942 // No object exists for given name nor in the overflow; we need to make 3943 // a new one. 3944 final int N = mMap.size(); 3945 if (N >= MAX_WAKELOCKS_PER_UID) { 3946 // Went over the limit on number of objects to track; this one goes 3947 // in to the overflow. 3948 obj = mCurOverflow; 3949 if (obj == null) { 3950 // Need to start overflow now... 3951 obj = mCurOverflow = instantiateObject(); 3952 mMap.put(OVERFLOW_NAME, obj); 3953 } 3954 if (mActiveOverflow == null) { 3955 mActiveOverflow = new ArrayMap<>(); 3956 } 3957 mActiveOverflow.put(name, new MutableInt(1)); 3958 mLastOverflowTimeMs = elapsedRealtimeMs; 3959 return obj; 3960 } 3961 3962 // Normal case where we just need to make a new object. 3963 obj = instantiateObject(); 3964 mMap.put(name, obj); 3965 return obj; 3966 } 3967 stopObject(String name, long elapsedRealtimeMs)3968 public T stopObject(String name, long elapsedRealtimeMs) { 3969 if (name == null) { 3970 name = ""; 3971 } 3972 T obj = mMap.get(name); 3973 if (obj != null) { 3974 return obj; 3975 } 3976 3977 // No object exists for the given name, but do we currently have it 3978 // running as part of the overflow? 3979 if (mActiveOverflow != null) { 3980 MutableInt over = mActiveOverflow.get(name); 3981 if (over != null) { 3982 // We are already actively counting this name in the overflow object. 3983 obj = mCurOverflow; 3984 if (obj != null) { 3985 over.value--; 3986 if (over.value <= 0) { 3987 mActiveOverflow.remove(name); 3988 mLastOverflowFinishTimeMs = elapsedRealtimeMs; 3989 } 3990 return obj; 3991 } 3992 } 3993 } 3994 3995 // Huh, they are stopping an active operation but we can't find one! 3996 // That's not good. 3997 StringBuilder sb = new StringBuilder(); 3998 sb.append("Unable to find object for "); 3999 sb.append(name); 4000 sb.append(" in uid "); 4001 sb.append(mUid); 4002 sb.append(" mapsize="); 4003 sb.append(mMap.size()); 4004 sb.append(" activeoverflow="); 4005 sb.append(mActiveOverflow); 4006 sb.append(" curoverflow="); 4007 sb.append(mCurOverflow); 4008 long now = elapsedRealtimeMs; 4009 if (mLastOverflowTimeMs != 0) { 4010 sb.append(" lastOverflowTime="); 4011 TimeUtils.formatDuration(mLastOverflowTimeMs - now, sb); 4012 } 4013 if (mLastOverflowFinishTimeMs != 0) { 4014 sb.append(" lastOverflowFinishTime="); 4015 TimeUtils.formatDuration(mLastOverflowFinishTimeMs - now, sb); 4016 } 4017 if (mLastClearTimeMs != 0) { 4018 sb.append(" lastClearTime="); 4019 TimeUtils.formatDuration(mLastClearTimeMs - now, sb); 4020 } 4021 if (mLastCleanupTimeMs != 0) { 4022 sb.append(" lastCleanupTime="); 4023 TimeUtils.formatDuration(mLastCleanupTimeMs - now, sb); 4024 } 4025 Slog.wtf(TAG, sb.toString()); 4026 return null; 4027 } 4028 instantiateObject()4029 public abstract T instantiateObject(); 4030 } 4031 4032 @SuppressWarnings("ParcelableCreator") 4033 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 4034 implements Parcelable { 4035 private final Clock mClock; 4036 private final TimeBase mTimeBase; 4037 private int mNumTxStates; 4038 private int mProcessState; 4039 private TimeMultiStateCounter mIdleTimeMillis; 4040 private final LongSamplingCounter mScanTimeMillis; 4041 private final LongSamplingCounter mSleepTimeMillis; 4042 private TimeMultiStateCounter mRxTimeMillis; 4043 private TimeMultiStateCounter[] mTxTimeMillis; 4044 private final LongSamplingCounter mPowerDrainMaMs; 4045 private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs; 4046 ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates)4047 public ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates) { 4048 mClock = clock; 4049 mTimeBase = timeBase; 4050 mNumTxStates = numTxStates; 4051 mScanTimeMillis = new LongSamplingCounter(timeBase); 4052 mSleepTimeMillis = new LongSamplingCounter(timeBase); 4053 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 4054 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase); 4055 } 4056 readSummaryFromParcel(Parcel in)4057 public void readSummaryFromParcel(Parcel in) { 4058 mIdleTimeMillis = readTimeMultiStateCounter(in, mTimeBase); 4059 mScanTimeMillis.readSummaryFromParcelLocked(in); 4060 mSleepTimeMillis.readSummaryFromParcelLocked(in); 4061 mRxTimeMillis = readTimeMultiStateCounter(in, mTimeBase); 4062 mTxTimeMillis = readTimeMultiStateCounters(in, mTimeBase, mNumTxStates); 4063 4064 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 4065 mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in); 4066 } 4067 4068 @Override describeContents()4069 public int describeContents() { 4070 return 0; 4071 } 4072 writeSummaryToParcel(Parcel dest)4073 public void writeSummaryToParcel(Parcel dest) { 4074 writeTimeMultiStateCounter(dest, mIdleTimeMillis); 4075 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 4076 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 4077 writeTimeMultiStateCounter(dest, mRxTimeMillis); 4078 writeTimeMultiStateCounters(dest, mTxTimeMillis); 4079 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 4080 mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest); 4081 } 4082 4083 @Override writeToParcel(Parcel dest, int flags)4084 public void writeToParcel(Parcel dest, int flags) { 4085 writeTimeMultiStateCounter(dest, mIdleTimeMillis); 4086 mScanTimeMillis.writeToParcel(dest); 4087 mSleepTimeMillis.writeToParcel(dest); 4088 writeTimeMultiStateCounter(dest, mRxTimeMillis); 4089 writeTimeMultiStateCounters(dest, mTxTimeMillis); 4090 mPowerDrainMaMs.writeToParcel(dest); 4091 mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); 4092 } 4093 readTimeMultiStateCounter(Parcel in, TimeBase timeBase)4094 private TimeMultiStateCounter readTimeMultiStateCounter(Parcel in, TimeBase timeBase) { 4095 if (in.readBoolean()) { 4096 return TimeMultiStateCounter.readFromParcel(in, timeBase, 4097 BatteryConsumer.PROCESS_STATE_COUNT, mClock.elapsedRealtime()); 4098 } 4099 return null; 4100 } 4101 writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter)4102 private void writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter) { 4103 if (counter != null) { 4104 dest.writeBoolean(true); 4105 counter.writeToParcel(dest); 4106 } else { 4107 dest.writeBoolean(false); 4108 } 4109 } 4110 readTimeMultiStateCounters(Parcel in, TimeBase timeBase, int expectedNumCounters)4111 private TimeMultiStateCounter[] readTimeMultiStateCounters(Parcel in, TimeBase timeBase, 4112 int expectedNumCounters) { 4113 if (in.readBoolean()) { 4114 final int numCounters = in.readInt(); 4115 boolean valid = (numCounters == expectedNumCounters); 4116 // Need to read counters out of the Parcel, even if all or some of them are 4117 // invalid. 4118 TimeMultiStateCounter[] counters = new TimeMultiStateCounter[numCounters]; 4119 for (int i = 0; i < numCounters; i++) { 4120 final TimeMultiStateCounter counter = TimeMultiStateCounter.readFromParcel(in, 4121 timeBase, BatteryConsumer.PROCESS_STATE_COUNT, 4122 mClock.elapsedRealtime()); 4123 if (counter != null) { 4124 counters[i] = counter; 4125 } else { 4126 valid = false; 4127 } 4128 } 4129 if (valid) { 4130 return counters; 4131 } 4132 } 4133 return null; 4134 } 4135 writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters)4136 private void writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters) { 4137 if (counters != null) { 4138 dest.writeBoolean(true); 4139 dest.writeInt(counters.length); 4140 for (TimeMultiStateCounter counter : counters) { 4141 counter.writeToParcel(dest); 4142 } 4143 } else { 4144 dest.writeBoolean(false); 4145 } 4146 } 4147 reset(boolean detachIfReset, long elapsedRealtimeUs)4148 public void reset(boolean detachIfReset, long elapsedRealtimeUs) { 4149 resetIfNotNull(mIdleTimeMillis, detachIfReset, elapsedRealtimeUs); 4150 mScanTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 4151 mSleepTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 4152 resetIfNotNull(mRxTimeMillis, detachIfReset, elapsedRealtimeUs); 4153 resetIfNotNull(mTxTimeMillis, detachIfReset, elapsedRealtimeUs); 4154 mPowerDrainMaMs.reset(detachIfReset, elapsedRealtimeUs); 4155 mMonitoredRailChargeConsumedMaMs.reset(detachIfReset, elapsedRealtimeUs); 4156 } 4157 detach()4158 public void detach() { 4159 detachIfNotNull(mIdleTimeMillis); 4160 mScanTimeMillis.detach(); 4161 mSleepTimeMillis.detach(); 4162 detachIfNotNull(mRxTimeMillis); 4163 detachIfNotNull(mTxTimeMillis); 4164 mPowerDrainMaMs.detach(); 4165 mMonitoredRailChargeConsumedMaMs.detach(); 4166 } 4167 4168 /** 4169 * @return a LongSamplingCounter, measuring time spent in the idle state in 4170 * milliseconds. 4171 */ 4172 @Override getIdleTimeCounter()4173 public LongCounter getIdleTimeCounter() { 4174 if (mIdleTimeMillis == null) { 4175 return ZERO_LONG_COUNTER; 4176 } 4177 return mIdleTimeMillis; 4178 } 4179 getOrCreateIdleTimeCounter()4180 private TimeMultiStateCounter getOrCreateIdleTimeCounter() { 4181 if (mIdleTimeMillis == null) { 4182 mIdleTimeMillis = createTimeMultiStateCounter(); 4183 } 4184 return mIdleTimeMillis; 4185 } 4186 4187 /** 4188 * @return a LongSamplingCounter, measuring time spent in the scan state in 4189 * milliseconds. 4190 */ 4191 @Override getScanTimeCounter()4192 public LongSamplingCounter getScanTimeCounter() { 4193 return mScanTimeMillis; 4194 } 4195 4196 /** 4197 * @return a LongSamplingCounter, measuring time spent in the sleep state in 4198 * milliseconds. 4199 */ 4200 @Override getSleepTimeCounter()4201 public LongSamplingCounter getSleepTimeCounter() { 4202 return mSleepTimeMillis; 4203 } 4204 4205 /** 4206 * @return a LongSamplingCounter, measuring time spent in the receive state in 4207 * milliseconds. 4208 */ 4209 @Override getRxTimeCounter()4210 public LongCounter getRxTimeCounter() { 4211 if (mRxTimeMillis == null) { 4212 return ZERO_LONG_COUNTER; 4213 } 4214 return mRxTimeMillis; 4215 } 4216 getOrCreateRxTimeCounter()4217 private TimeMultiStateCounter getOrCreateRxTimeCounter() { 4218 if (mRxTimeMillis == null) { 4219 mRxTimeMillis = createTimeMultiStateCounter(); 4220 } 4221 return mRxTimeMillis; 4222 } 4223 4224 /** 4225 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 4226 * milliseconds. 4227 */ 4228 @Override getTxTimeCounters()4229 public LongCounter[] getTxTimeCounters() { 4230 if (mTxTimeMillis == null) { 4231 return ZERO_LONG_COUNTER_ARRAY; 4232 } 4233 return mTxTimeMillis; 4234 } 4235 getOrCreateTxTimeCounters()4236 private TimeMultiStateCounter[] getOrCreateTxTimeCounters() { 4237 if (mTxTimeMillis == null) { 4238 mTxTimeMillis = new TimeMultiStateCounter[mNumTxStates]; 4239 for (int i = 0; i < mNumTxStates; i++) { 4240 mTxTimeMillis[i] = createTimeMultiStateCounter(); 4241 } 4242 } 4243 return mTxTimeMillis; 4244 } 4245 createTimeMultiStateCounter()4246 private TimeMultiStateCounter createTimeMultiStateCounter() { 4247 final long timestampMs = mClock.elapsedRealtime(); 4248 TimeMultiStateCounter counter = new TimeMultiStateCounter(mTimeBase, 4249 BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 4250 counter.setState(mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 4251 timestampMs); 4252 counter.update(0, timestampMs); 4253 return counter; 4254 } 4255 4256 /** 4257 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 4258 */ 4259 @Override getPowerCounter()4260 public LongSamplingCounter getPowerCounter() { 4261 return mPowerDrainMaMs; 4262 } 4263 4264 /** 4265 * @return a LongSamplingCounter, measuring actual monitored rail energy consumed 4266 * milli-ampere milli-seconds (mAmS). 4267 */ 4268 @Override getMonitoredRailChargeConsumedMaMs()4269 public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() { 4270 return mMonitoredRailChargeConsumedMaMs; 4271 } 4272 setState(int processState, long elapsedTimeMs)4273 private void setState(int processState, long elapsedTimeMs) { 4274 mProcessState = processState; 4275 if (mIdleTimeMillis != null) { 4276 mIdleTimeMillis.setState(processState, elapsedTimeMs); 4277 } 4278 if (mRxTimeMillis != null) { 4279 mRxTimeMillis.setState(processState, elapsedTimeMs); 4280 } 4281 if (mTxTimeMillis != null) { 4282 for (int i = 0; i < mTxTimeMillis.length; i++) { 4283 mTxTimeMillis[i].setState(processState, elapsedTimeMs); 4284 } 4285 } 4286 } 4287 } 4288 4289 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)4290 public SamplingTimer getRpmTimerLocked(String name) { 4291 SamplingTimer rpmt = mRpmStats.get(name); 4292 if (rpmt == null) { 4293 rpmt = new SamplingTimer(mClock, mOnBatteryTimeBase); 4294 mRpmStats.put(name, rpmt); 4295 } 4296 return rpmt; 4297 } 4298 4299 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)4300 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 4301 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 4302 if (rpmt == null) { 4303 rpmt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 4304 mScreenOffRpmStats.put(name, rpmt); 4305 } 4306 return rpmt; 4307 } 4308 4309 /* 4310 * Get the wakeup reason counter, and create a new one if one 4311 * doesn't already exist. 4312 */ getWakeupReasonTimerLocked(String name)4313 public SamplingTimer getWakeupReasonTimerLocked(String name) { 4314 SamplingTimer timer = mWakeupReasonStats.get(name); 4315 if (timer == null) { 4316 timer = new SamplingTimer(mClock, mOnBatteryTimeBase); 4317 mWakeupReasonStats.put(name, timer); 4318 } 4319 return timer; 4320 } 4321 4322 /* 4323 * Get the KernelWakelockTimer associated with name, and create a new one if one 4324 * doesn't already exist. 4325 */ getKernelWakelockTimerLocked(String name)4326 public SamplingTimer getKernelWakelockTimerLocked(String name) { 4327 SamplingTimer kwlt = mKernelWakelockStats.get(name); 4328 if (kwlt == null) { 4329 kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 4330 mKernelWakelockStats.put(name, kwlt); 4331 } 4332 return kwlt; 4333 } 4334 getKernelMemoryTimerLocked(long bucket)4335 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 4336 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 4337 if (kmt == null) { 4338 kmt = new SamplingTimer(mClock, mOnBatteryTimeBase); 4339 mKernelMemoryStats.put(bucket, kmt); 4340 } 4341 return kmt; 4342 } 4343 4344 private class HistoryStepDetailsCalculatorImpl implements HistoryStepDetailsCalculator { 4345 private final HistoryStepDetails mDetails = new HistoryStepDetails(); 4346 4347 private boolean mHasHistoryStepDetails; 4348 private boolean mUpdateRequested; 4349 4350 /** 4351 * Total time (in milliseconds) spent executing in user code. 4352 */ 4353 private long mLastStepCpuUserTimeMs; 4354 private long mCurStepCpuUserTimeMs; 4355 /** 4356 * Total time (in milliseconds) spent executing in kernel code. 4357 */ 4358 private long mLastStepCpuSystemTimeMs; 4359 private long mCurStepCpuSystemTimeMs; 4360 /** 4361 * Times from /proc/stat (but measured in milliseconds). 4362 */ 4363 private long mLastStepStatUserTimeMs; 4364 private long mLastStepStatSystemTimeMs; 4365 private long mLastStepStatIOWaitTimeMs; 4366 private long mLastStepStatIrqTimeMs; 4367 private long mLastStepStatSoftIrqTimeMs; 4368 private long mLastStepStatIdleTimeMs; 4369 private long mCurStepStatUserTimeMs; 4370 private long mCurStepStatSystemTimeMs; 4371 private long mCurStepStatIOWaitTimeMs; 4372 private long mCurStepStatIrqTimeMs; 4373 private long mCurStepStatSoftIrqTimeMs; 4374 private long mCurStepStatIdleTimeMs; 4375 4376 @Override getHistoryStepDetails()4377 public HistoryStepDetails getHistoryStepDetails() { 4378 if (!mUpdateRequested) { 4379 mUpdateRequested = true; 4380 // Perform a CPU update right after we do this collection, so we have started 4381 // collecting good data for the next step. 4382 requestImmediateCpuUpdate(); 4383 4384 if (mPlatformIdleStateCallback != null) { 4385 mDetails.statSubsystemPowerState = 4386 mPlatformIdleStateCallback.getSubsystemLowPowerStats(); 4387 if (DEBUG) { 4388 Slog.i(TAG, 4389 "WRITE SubsystemPowerState:" + mDetails.statSubsystemPowerState); 4390 } 4391 } 4392 } 4393 4394 if (!mHasHistoryStepDetails) { 4395 // We are not generating a delta, so all we need to do is reset the stats 4396 // we will later be doing a delta from. 4397 final int uidCount = mUidStats.size(); 4398 for (int i = 0; i < uidCount; i++) { 4399 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4400 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 4401 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 4402 } 4403 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 4404 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 4405 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 4406 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 4407 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 4408 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 4409 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 4410 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 4411 return null; 4412 } else { 4413 if (DEBUG) { 4414 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTimeMs + " sys=" 4415 + mLastStepStatSystemTimeMs + " io=" + mLastStepStatIOWaitTimeMs 4416 + " irq=" + mLastStepStatIrqTimeMs + " sirq=" 4417 + mLastStepStatSoftIrqTimeMs + " idle=" + mLastStepStatIdleTimeMs); 4418 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTimeMs + " sys=" 4419 + mCurStepStatSystemTimeMs + " io=" + mCurStepStatIOWaitTimeMs 4420 + " irq=" + mCurStepStatIrqTimeMs + " sirq=" 4421 + mCurStepStatSoftIrqTimeMs + " idle=" + mCurStepStatIdleTimeMs); 4422 } 4423 mDetails.userTime = (int) (mCurStepCpuUserTimeMs - mLastStepCpuUserTimeMs); 4424 mDetails.systemTime = (int) (mCurStepCpuSystemTimeMs - mLastStepCpuSystemTimeMs); 4425 mDetails.statUserTime = (int) (mCurStepStatUserTimeMs - mLastStepStatUserTimeMs); 4426 mDetails.statSystemTime = 4427 (int) (mCurStepStatSystemTimeMs - mLastStepStatSystemTimeMs); 4428 mDetails.statIOWaitTime = 4429 (int) (mCurStepStatIOWaitTimeMs - mLastStepStatIOWaitTimeMs); 4430 mDetails.statIrqTime = (int) (mCurStepStatIrqTimeMs - mLastStepStatIrqTimeMs); 4431 mDetails.statSoftIrqTime = 4432 (int) (mCurStepStatSoftIrqTimeMs - mLastStepStatSoftIrqTimeMs); 4433 mDetails.statIdlTime = (int) (mCurStepStatIdleTimeMs - mLastStepStatIdleTimeMs); 4434 mDetails.appCpuUid1 = mDetails.appCpuUid2 = mDetails.appCpuUid3 = -1; 4435 mDetails.appCpuUTime1 = mDetails.appCpuUTime2 = mDetails.appCpuUTime3 = 0; 4436 mDetails.appCpuSTime1 = mDetails.appCpuSTime2 = mDetails.appCpuSTime3 = 0; 4437 final int uidCount = mUidStats.size(); 4438 for (int i = 0; i < uidCount; i++) { 4439 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4440 final int totalUTimeMs = 4441 (int) (uid.mCurStepUserTimeMs - uid.mLastStepUserTimeMs); 4442 final int totalSTimeMs = 4443 (int) (uid.mCurStepSystemTimeMs - uid.mLastStepSystemTimeMs); 4444 final int totalTimeMs = totalUTimeMs + totalSTimeMs; 4445 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 4446 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 4447 if (totalTimeMs <= (mDetails.appCpuUTime3 + mDetails.appCpuSTime3)) { 4448 continue; 4449 } 4450 if (totalTimeMs <= (mDetails.appCpuUTime2 + mDetails.appCpuSTime2)) { 4451 mDetails.appCpuUid3 = uid.mUid; 4452 mDetails.appCpuUTime3 = totalUTimeMs; 4453 mDetails.appCpuSTime3 = totalSTimeMs; 4454 } else { 4455 mDetails.appCpuUid3 = mDetails.appCpuUid2; 4456 mDetails.appCpuUTime3 = mDetails.appCpuUTime2; 4457 mDetails.appCpuSTime3 = mDetails.appCpuSTime2; 4458 if (totalTimeMs <= (mDetails.appCpuUTime1 + mDetails.appCpuSTime1)) { 4459 mDetails.appCpuUid2 = uid.mUid; 4460 mDetails.appCpuUTime2 = totalUTimeMs; 4461 mDetails.appCpuSTime2 = totalSTimeMs; 4462 } else { 4463 mDetails.appCpuUid2 = mDetails.appCpuUid1; 4464 mDetails.appCpuUTime2 = mDetails.appCpuUTime1; 4465 mDetails.appCpuSTime2 = mDetails.appCpuSTime1; 4466 mDetails.appCpuUid1 = uid.mUid; 4467 mDetails.appCpuUTime1 = totalUTimeMs; 4468 mDetails.appCpuSTime1 = totalSTimeMs; 4469 } 4470 } 4471 } 4472 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 4473 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 4474 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 4475 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 4476 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 4477 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 4478 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 4479 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 4480 return mDetails; 4481 } 4482 } 4483 addCpuStats(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs)4484 public void addCpuStats(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, 4485 int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, 4486 int statSoftIrqTimeMs, int statIdleTimeMs) { 4487 if (DEBUG) { 4488 Slog.d(TAG, "Adding cpu: tuser=" + totalUTimeMs + " tsys=" + totalSTimeMs 4489 + " user=" + statUserTimeMs + " sys=" + statSystemTimeMs 4490 + " io=" + statIOWaitTimeMs + " irq=" + statIrqTimeMs 4491 + " sirq=" + statSoftIrqTimeMs + " idle=" + statIdleTimeMs); 4492 } 4493 mCurStepCpuUserTimeMs += totalUTimeMs; 4494 mCurStepCpuSystemTimeMs += totalSTimeMs; 4495 mCurStepStatUserTimeMs += statUserTimeMs; 4496 mCurStepStatSystemTimeMs += statSystemTimeMs; 4497 mCurStepStatIOWaitTimeMs += statIOWaitTimeMs; 4498 mCurStepStatIrqTimeMs += statIrqTimeMs; 4499 mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs; 4500 mCurStepStatIdleTimeMs += statIdleTimeMs; 4501 } 4502 finishAddingCpuLocked()4503 public void finishAddingCpuLocked() { 4504 mHasHistoryStepDetails = true; 4505 mUpdateRequested = false; 4506 } 4507 4508 @Override clear()4509 public void clear() { 4510 mHasHistoryStepDetails = false; 4511 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs = 0; 4512 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs = 0; 4513 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs = 0; 4514 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs = 0; 4515 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs = 0; 4516 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs = 0; 4517 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs = 0; 4518 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs = 0; 4519 } 4520 } 4521 4522 @GuardedBy("this") 4523 @Override commitCurrentHistoryBatchLocked()4524 public void commitCurrentHistoryBatchLocked() { 4525 mHistory.commitCurrentHistoryBatchLocked(); 4526 } 4527 4528 @GuardedBy("this") createFakeHistoryEvents(long numEvents)4529 public void createFakeHistoryEvents(long numEvents) { 4530 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 4531 final long uptimeMs = mClock.uptimeMillis(); 4532 for(long i = 0; i < numEvents; i++) { 4533 noteLongPartialWakelockStart("name1", "historyName1", 1000, 4534 elapsedRealtimeMs, uptimeMs); 4535 noteLongPartialWakelockFinish("name1", "historyName1", 1000, 4536 elapsedRealtimeMs, uptimeMs); 4537 } 4538 } 4539 4540 @GuardedBy("this") recordHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)4541 public void recordHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 4542 String name, int uid) { 4543 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid); 4544 } 4545 4546 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, long realtimeUs)4547 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, 4548 long realtimeUs) { 4549 final boolean screenOff = !Display.isOnState(screenState); 4550 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 4551 final boolean updateOnBatteryScreenOffTimeBase = 4552 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 4553 4554 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 4555 if (updateOnBatteryScreenOffTimeBase) { 4556 updateKernelWakelocksLocked(realtimeUs); 4557 updateBatteryPropertiesLocked(); 4558 } 4559 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 4560 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 4561 // improved, remove the surrounding if{}. 4562 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 4563 // if either OnBattery or OnBatteryScreenOfftimebase changes. 4564 updateRpmStatsLocked(realtimeUs); 4565 } 4566 if (DEBUG_ENERGY_CPU) { 4567 Slog.d(TAG, "Updating cpu time because screen is now " 4568 + Display.stateToString(screenState) 4569 + " and battery is " + (unplugged ? "on" : "off")); 4570 } 4571 4572 mOnBatteryTimeBase.setRunning(unplugged, uptimeUs, realtimeUs); 4573 if (updateOnBatteryTimeBase) { 4574 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4575 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptimeUs, realtimeUs); 4576 } 4577 } 4578 if (updateOnBatteryScreenOffTimeBase) { 4579 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, 4580 uptimeUs, realtimeUs); 4581 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4582 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptimeUs, realtimeUs); 4583 } 4584 } 4585 } 4586 } 4587 4588 @GuardedBy("this") updateBatteryPropertiesLocked()4589 protected void updateBatteryPropertiesLocked() { 4590 try { 4591 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 4592 ServiceManager.getService("batteryproperties")); 4593 if (registrar != null) { 4594 registrar.scheduleUpdate(); 4595 } 4596 } catch (RemoteException e) { 4597 // Ignore. 4598 } 4599 } 4600 onIsolatedUidAdded(int isolatedUid, int parentUid)4601 private void onIsolatedUidAdded(int isolatedUid, int parentUid) { 4602 long realtime = mClock.elapsedRealtime(); 4603 long uptime = mClock.uptimeMillis(); 4604 synchronized (this) { 4605 getUidStatsLocked(parentUid, realtime, uptime).addIsolatedUid(isolatedUid); 4606 } 4607 } 4608 onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid)4609 private void onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid) { 4610 long realtime = mClock.elapsedRealtime(); 4611 mPowerStatsUidResolver.retainIsolatedUid(isolatedUid); 4612 synchronized (this) { 4613 mPendingRemovedUids.add(new UidToRemove(isolatedUid, realtime)); 4614 } 4615 if (mExternalSync != null) { 4616 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 4617 } 4618 } 4619 onAfterIsolatedUidRemoved(int isolatedUid, int parentUid)4620 private void onAfterIsolatedUidRemoved(int isolatedUid, int parentUid) { 4621 long realtime = mClock.elapsedRealtime(); 4622 long uptime = mClock.uptimeMillis(); 4623 synchronized (this) { 4624 getUidStatsLocked(parentUid, realtime, uptime).removeIsolatedUid(isolatedUid); 4625 } 4626 } 4627 4628 /** 4629 * Isolated uid should only be removed after all wakelocks associated with the uid are stopped 4630 * and the cpu time-in-state has been read one last time for the uid. 4631 */ 4632 @GuardedBy("this") releaseIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs)4633 public void releaseIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs) { 4634 mPowerStatsUidResolver.releaseIsolatedUid(isolatedUid); 4635 } 4636 mapUid(int uid)4637 private int mapUid(int uid) { 4638 if (Process.isSdkSandboxUid(uid)) { 4639 return Process.getAppUidForSdkSandboxUid(uid); 4640 } 4641 return mPowerStatsUidResolver.mapUid(uid); 4642 } 4643 mapIsolatedUid(int uid)4644 private int mapIsolatedUid(int uid) { 4645 return mPowerStatsUidResolver.mapUid(uid); 4646 } 4647 4648 @GuardedBy("this") noteEventLocked(int code, String name, int uid, long elapsedRealtimeMs, long uptimeMs)4649 public void noteEventLocked(int code, String name, int uid, 4650 long elapsedRealtimeMs, long uptimeMs) { 4651 uid = mapUid(uid); 4652 if (!mActiveEvents.updateState(code, name, uid, 0)) { 4653 return; 4654 } 4655 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid); 4656 } 4657 4658 @GuardedBy("this") noteCurrentTimeChangedLocked(long currentTimeMs, long elapsedRealtimeMs, long uptimeMs)4659 public void noteCurrentTimeChangedLocked(long currentTimeMs, 4660 long elapsedRealtimeMs, long uptimeMs) { 4661 mHistory.recordCurrentTimeChange(elapsedRealtimeMs, uptimeMs, currentTimeMs); 4662 adjustStartClockTime(currentTimeMs); 4663 } 4664 adjustStartClockTime(long currentTimeMs)4665 private void adjustStartClockTime(long currentTimeMs) { 4666 mStartClockTimeMs = 4667 currentTimeMs - (mClock.elapsedRealtime() - (mRealtimeStartUs / 1000)); 4668 } 4669 4670 @GuardedBy("this") noteProcessStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4671 public void noteProcessStartLocked(String name, int uid, 4672 long elapsedRealtimeMs, long uptimeMs) { 4673 uid = mapUid(uid); 4674 if (isOnBattery()) { 4675 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4676 u.getProcessStatsLocked(name).incStartsLocked(); 4677 } 4678 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 4679 return; 4680 } 4681 if (!mRecordAllHistory) { 4682 return; 4683 } 4684 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid); 4685 } 4686 4687 @GuardedBy("this") noteProcessCrashLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4688 public void noteProcessCrashLocked(String name, int uid, 4689 long elapsedRealtimeMs, long uptimeMs) { 4690 uid = mapUid(uid); 4691 if (isOnBattery()) { 4692 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4693 u.getProcessStatsLocked(name).incNumCrashesLocked(); 4694 } 4695 } 4696 4697 @GuardedBy("this") noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4698 public void noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4699 uid = mapUid(uid); 4700 if (isOnBattery()) { 4701 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4702 u.getProcessStatsLocked(name).incNumAnrsLocked(); 4703 } 4704 } 4705 4706 @GuardedBy("this") noteUidProcessStateLocked(int uid, int state)4707 public void noteUidProcessStateLocked(int uid, int state) { 4708 noteUidProcessStateLocked(uid, state, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4709 } 4710 4711 @GuardedBy("this") 4712 @SuppressWarnings("GuardedBy") // errorprone false positive on u.updateUidProcessStateLocked noteUidProcessStateLocked(int uid, int state, long elapsedRealtimeMs, long uptimeMs)4713 public void noteUidProcessStateLocked(int uid, int state, 4714 long elapsedRealtimeMs, long uptimeMs) { 4715 int parentUid = mapUid(uid); 4716 if (uid != parentUid) { 4717 if (Process.isIsolated(uid)) { 4718 // Isolated UIDs process state is already rolled up into parent, so no need to track 4719 // Otherwise the parent's process state will get downgraded incorrectly 4720 return; 4721 } 4722 } 4723 mFrameworkStatsLogger.uidProcessStateChanged(uid, state); 4724 getUidStatsLocked(parentUid, elapsedRealtimeMs, uptimeMs) 4725 .updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs); 4726 } 4727 4728 @GuardedBy("this") noteProcessFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4729 public void noteProcessFinishLocked(String name, int uid, 4730 long elapsedRealtimeMs, long uptimeMs) { 4731 uid = mapUid(uid); 4732 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4733 return; 4734 } 4735 if (!mRecordAllHistory) { 4736 return; 4737 } 4738 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH, name, uid); 4739 } 4740 4741 @GuardedBy("this") noteSyncStartLocked(String name, int uid)4742 public void noteSyncStartLocked(String name, int uid) { 4743 noteSyncStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4744 } 4745 4746 @GuardedBy("this") noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4747 public void noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4748 uid = mapUid(uid); 4749 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4750 .noteStartSyncLocked(name, elapsedRealtimeMs); 4751 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4752 return; 4753 } 4754 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid); 4755 } 4756 4757 @GuardedBy("this") noteSyncFinishLocked(String name, int uid)4758 public void noteSyncFinishLocked(String name, int uid) { 4759 noteSyncFinishLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4760 } 4761 4762 @GuardedBy("this") noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4763 public void noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4764 uid = mapUid(uid); 4765 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4766 .noteStopSyncLocked(name, elapsedRealtimeMs); 4767 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4768 return; 4769 } 4770 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH, name, uid); 4771 } 4772 4773 @GuardedBy("this") noteJobStartLocked(String name, int uid)4774 public void noteJobStartLocked(String name, int uid) { 4775 noteJobStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4776 } 4777 4778 @GuardedBy("this") noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4779 public void noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4780 uid = mapUid(uid); 4781 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4782 .noteStartJobLocked(name, elapsedRealtimeMs); 4783 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4784 return; 4785 } 4786 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid); 4787 } 4788 4789 @GuardedBy("this") noteJobFinishLocked(String name, int uid, int stopReason)4790 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4791 noteJobFinishLocked(name, uid, stopReason, 4792 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4793 } 4794 4795 @GuardedBy("this") noteJobFinishLocked(String name, int uid, int stopReason, long elapsedRealtimeMs, long uptimeMs)4796 public void noteJobFinishLocked(String name, int uid, int stopReason, 4797 long elapsedRealtimeMs, long uptimeMs) { 4798 uid = mapUid(uid); 4799 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4800 .noteStopJobLocked(name, elapsedRealtimeMs, stopReason); 4801 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4802 return; 4803 } 4804 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid); 4805 } 4806 4807 @GuardedBy("this") noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, long elapsedRealtimeMs, long uptimeMs)4808 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, 4809 long elapsedRealtimeMs, long uptimeMs) { 4810 uid = mapUid(uid); 4811 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4812 .noteJobsDeferredLocked(numDeferred, sinceLast); 4813 } 4814 4815 @GuardedBy("this") noteAlarmStartLocked(String name, WorkSource workSource, int uid)4816 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4817 noteAlarmStartLocked(name, workSource, uid, 4818 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4819 } 4820 4821 @GuardedBy("this") noteAlarmStartLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4822 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid, 4823 long elapsedRealtimeMs, long uptimeMs) { 4824 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid, 4825 elapsedRealtimeMs, uptimeMs); 4826 } 4827 4828 @GuardedBy("this") noteAlarmFinishLocked(String name, WorkSource workSource, int uid)4829 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 4830 noteAlarmFinishLocked(name, workSource, uid, 4831 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4832 } 4833 4834 @GuardedBy("this") noteAlarmFinishLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4835 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid, 4836 long elapsedRealtimeMs, long uptimeMs) { 4837 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid, 4838 elapsedRealtimeMs, uptimeMs); 4839 } 4840 4841 @GuardedBy("this") noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4842 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4843 int uid, long elapsedRealtimeMs, long uptimeMs) { 4844 if (!mRecordAllHistory) { 4845 return; 4846 } 4847 4848 if (workSource != null) { 4849 for (int i = 0; i < workSource.size(); ++i) { 4850 uid = mapUid(workSource.getUid(i)); 4851 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4852 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4853 } 4854 } 4855 4856 List<WorkChain> workChains = workSource.getWorkChains(); 4857 if (workChains != null) { 4858 for (int i = 0; i < workChains.size(); ++i) { 4859 uid = mapUid(workChains.get(i).getAttributionUid()); 4860 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4861 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4862 } 4863 } 4864 } 4865 } else { 4866 uid = mapUid(uid); 4867 4868 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4869 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4870 } 4871 } 4872 } 4873 4874 @GuardedBy("this") noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)4875 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4876 String tag) { 4877 noteWakupAlarmLocked(packageName, uid, workSource, tag, 4878 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4879 } 4880 4881 @GuardedBy("this") noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag, long elapsedRealtimeMs, long uptimeMs)4882 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4883 String tag, long elapsedRealtimeMs, long uptimeMs) { 4884 if (workSource != null) { 4885 for (int i = 0; i < workSource.size(); ++i) { 4886 uid = workSource.getUid(i); 4887 final String workSourceName = workSource.getPackageName(i); 4888 4889 if (isOnBattery()) { 4890 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 4891 workSourceName != null ? workSourceName : packageName, 4892 elapsedRealtimeMs, uptimeMs); 4893 pkg.noteWakeupAlarmLocked(tag); 4894 } 4895 } 4896 4897 List<WorkChain> workChains = workSource.getWorkChains(); 4898 if (workChains != null) { 4899 for (int i = 0; i < workChains.size(); ++i) { 4900 final WorkChain wc = workChains.get(i); 4901 uid = wc.getAttributionUid(); 4902 4903 if (isOnBattery()) { 4904 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4905 elapsedRealtimeMs, uptimeMs); 4906 pkg.noteWakeupAlarmLocked(tag); 4907 } 4908 } 4909 } 4910 } else { 4911 if (isOnBattery()) { 4912 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4913 elapsedRealtimeMs, uptimeMs); 4914 pkg.noteWakeupAlarmLocked(tag); 4915 } 4916 } 4917 } 4918 requestWakelockCpuUpdate()4919 private void requestWakelockCpuUpdate() { 4920 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 4921 } 4922 requestImmediateCpuUpdate()4923 private void requestImmediateCpuUpdate() { 4924 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 4925 } 4926 4927 @GuardedBy("this") setRecordAllHistoryLocked(boolean enabled)4928 public void setRecordAllHistoryLocked(boolean enabled) { 4929 mRecordAllHistory = enabled; 4930 if (!enabled) { 4931 // Clear out any existing state. 4932 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 4933 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 4934 // Record the currently running processes as stopping, now that we are no 4935 // longer tracking them. 4936 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4937 HistoryItem.EVENT_PROC); 4938 if (active != null) { 4939 long mSecRealtime = mClock.elapsedRealtime(); 4940 final long mSecUptime = mClock.uptimeMillis(); 4941 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4942 SparseIntArray uids = ent.getValue(); 4943 for (int j=0; j<uids.size(); j++) { 4944 mHistory.recordEvent(mSecRealtime, mSecUptime, 4945 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 4946 } 4947 } 4948 } 4949 } else { 4950 // Record the currently running processes as starting, now that we are tracking them. 4951 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4952 HistoryItem.EVENT_PROC); 4953 if (active != null) { 4954 long mSecRealtime = mClock.elapsedRealtime(); 4955 final long mSecUptime = mClock.uptimeMillis(); 4956 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4957 SparseIntArray uids = ent.getValue(); 4958 for (int j=0; j<uids.size(); j++) { 4959 mHistory.recordEvent(mSecRealtime, mSecUptime, HistoryItem.EVENT_PROC_START, 4960 ent.getKey(), uids.keyAt(j)); 4961 } 4962 } 4963 } 4964 } 4965 } 4966 setNoAutoReset(boolean enabled)4967 public void setNoAutoReset(boolean enabled) { 4968 mNoAutoReset = enabled; 4969 } 4970 4971 @GuardedBy("this") setPretendScreenOff(boolean pretendScreenOff)4972 public void setPretendScreenOff(boolean pretendScreenOff) { 4973 if (mPretendScreenOff != pretendScreenOff) { 4974 mPretendScreenOff = pretendScreenOff; 4975 final int primaryScreenState = mPerDisplayBatteryStats[0].screenState; 4976 noteScreenStateLocked(0, primaryScreenState, 4977 mClock.elapsedRealtime(), mClock.uptimeMillis(), 4978 mClock.currentTimeMillis()); 4979 } 4980 } 4981 4982 @GuardedBy("this") noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging)4983 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4984 int type, boolean unimportantForLogging) { 4985 noteStartWakeLocked(uid, pid, wc, name, historyName, type, unimportantForLogging, 4986 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4987 } 4988 4989 @GuardedBy("this") noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)4990 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4991 int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs) { 4992 final int mappedUid = mapUid(uid); 4993 if (type == WAKE_TYPE_PARTIAL) { 4994 // Only care about partial wake locks, since full wake locks 4995 // will be canceled when the user puts the screen to sleep. 4996 if (historyName == null) { 4997 historyName = name; 4998 } 4999 if (mRecordAllHistory) { 5000 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 5001 mappedUid, 0)) { 5002 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, 5003 HistoryItem.EVENT_WAKE_LOCK_START, historyName, mappedUid); 5004 } 5005 } 5006 if (mWakeLockNesting == 0) { 5007 mWakeLockImportant = !unimportantForLogging; 5008 mHistory.recordWakelockStartEvent(elapsedRealtimeMs, uptimeMs, historyName, 5009 mappedUid); 5010 } else if (!mWakeLockImportant && !unimportantForLogging) { 5011 if (mHistory.maybeUpdateWakelockTag(elapsedRealtimeMs, uptimeMs, historyName, 5012 mappedUid)) { 5013 mWakeLockImportant = true; 5014 } 5015 } 5016 mWakeLockNesting++; 5017 } 5018 if (mappedUid >= 0) { 5019 if (mappedUid != uid) { 5020 // Prevent the isolated uid mapping from being removed while the wakelock is 5021 // being held. 5022 mPowerStatsUidResolver.retainIsolatedUid(uid); 5023 } 5024 if (mOnBatteryScreenOffTimeBase.isRunning()) { 5025 // We only update the cpu time when a wake lock is acquired if the screen is off. 5026 // If the screen is on, we don't distribute the power amongst partial wakelocks. 5027 if (DEBUG_ENERGY_CPU) { 5028 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 5029 } 5030 requestWakelockCpuUpdate(); 5031 } 5032 5033 Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs); 5034 uidStats.noteStartWakeLocked(pid, name, type, elapsedRealtimeMs); 5035 5036 mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name, 5037 uidStats.mProcessState, true /* acquired */, 5038 getPowerManagerWakeLockLevel(type)); 5039 } 5040 } 5041 5042 @GuardedBy("this") noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type)5043 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5044 int type) { 5045 noteStopWakeLocked(uid, pid, wc, name, historyName, type, 5046 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5047 } 5048 5049 @GuardedBy("this") noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)5050 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5051 int type, long elapsedRealtimeMs, long uptimeMs) { 5052 final int mappedUid = mapUid(uid); 5053 if (type == WAKE_TYPE_PARTIAL) { 5054 mWakeLockNesting--; 5055 if (historyName == null) { 5056 historyName = name; 5057 } 5058 if (mRecordAllHistory) { 5059 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 5060 mappedUid, 0)) { 5061 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, 5062 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, mappedUid); 5063 } 5064 } 5065 if (mWakeLockNesting == 0) { 5066 mHistory.recordWakelockStopEvent(elapsedRealtimeMs, uptimeMs, historyName, 5067 mappedUid); 5068 } 5069 } 5070 if (mappedUid >= 0) { 5071 if (mOnBatteryScreenOffTimeBase.isRunning()) { 5072 if (DEBUG_ENERGY_CPU) { 5073 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 5074 } 5075 requestWakelockCpuUpdate(); 5076 } 5077 5078 Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs); 5079 uidStats.noteStopWakeLocked(pid, name, type, elapsedRealtimeMs); 5080 5081 mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name, 5082 uidStats.mProcessState, false/* acquired */, 5083 getPowerManagerWakeLockLevel(type)); 5084 5085 if (mappedUid != uid) { 5086 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 5087 releaseIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 5088 } 5089 } 5090 } 5091 5092 /** 5093 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 5094 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 5095 * These are estimations, since batterystats loses some of the original data. 5096 * TODO: Delete this. Instead, FrameworkStatsLog.write should be called from 5097 * PowerManager's Notifier. 5098 */ getPowerManagerWakeLockLevel(int batteryStatsWakelockType)5099 private int getPowerManagerWakeLockLevel(int batteryStatsWakelockType) { 5100 switch (batteryStatsWakelockType) { 5101 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 5102 case BatteryStats.WAKE_TYPE_PARTIAL: 5103 return PowerManager.PARTIAL_WAKE_LOCK; 5104 5105 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 5106 case BatteryStats.WAKE_TYPE_FULL: 5107 return PowerManager.FULL_WAKE_LOCK; 5108 5109 case BatteryStats.WAKE_TYPE_DRAW: 5110 return PowerManager.DRAW_WAKE_LOCK; 5111 5112 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 5113 case BatteryStats.WAKE_TYPE_WINDOW: 5114 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 5115 return -1; 5116 5117 default: 5118 Slog.e(TAG, "Illegal wakelock type in batterystats: " + batteryStatsWakelockType); 5119 return -1; 5120 } 5121 } 5122 5123 @GuardedBy("this") noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)5124 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 5125 String historyName, int type, boolean unimportantForLogging, 5126 long elapsedRealtimeMs, long uptimeMs) { 5127 final int N = ws.size(); 5128 for (int i=0; i<N; i++) { 5129 noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type, 5130 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 5131 } 5132 5133 List<WorkChain> wcs = ws.getWorkChains(); 5134 if (wcs != null) { 5135 for (int i = 0; i < wcs.size(); ++i) { 5136 final WorkChain wc = wcs.get(i); 5137 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 5138 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 5139 } 5140 } 5141 } 5142 5143 @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)5144 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 5145 String historyName, int type, WorkSource newWs, int newPid, String newName, 5146 String newHistoryName, int newType, boolean newUnimportantForLogging, 5147 long elapsedRealtimeMs, long uptimeMs) { 5148 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 5149 5150 // For correct semantics, we start the need worksources first, so that we won't 5151 // make inappropriate history items as if all wake locks went away and new ones 5152 // appeared. This is okay because tracking of wake locks allows nesting. 5153 // 5154 // First the starts : 5155 final int NN = newWs.size(); 5156 for (int i=0; i<NN; i++) { 5157 noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType, 5158 newUnimportantForLogging, elapsedRealtimeMs, uptimeMs); 5159 } 5160 if (wcs != null) { 5161 List<WorkChain> newChains = wcs[0]; 5162 if (newChains != null) { 5163 for (int i = 0; i < newChains.size(); ++i) { 5164 final WorkChain newChain = newChains.get(i); 5165 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 5166 newHistoryName, newType, newUnimportantForLogging, elapsedRealtimeMs, 5167 uptimeMs); 5168 } 5169 } 5170 } 5171 5172 // Then the stops : 5173 final int NO = ws.size(); 5174 for (int i=0; i<NO; i++) { 5175 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 5176 uptimeMs); 5177 } 5178 if (wcs != null) { 5179 List<WorkChain> goneChains = wcs[1]; 5180 if (goneChains != null) { 5181 for (int i = 0; i < goneChains.size(); ++i) { 5182 final WorkChain goneChain = goneChains.get(i); 5183 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 5184 historyName, type, elapsedRealtimeMs, uptimeMs); 5185 } 5186 } 5187 } 5188 } 5189 5190 @GuardedBy("this") noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)5191 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 5192 String historyName, int type, long elapsedRealtimeMs, long uptimeMs) { 5193 final int N = ws.size(); 5194 for (int i=0; i<N; i++) { 5195 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 5196 uptimeMs); 5197 } 5198 5199 List<WorkChain> wcs = ws.getWorkChains(); 5200 if (wcs != null) { 5201 for (int i = 0; i < wcs.size(); ++i) { 5202 final WorkChain wc = wcs.get(i); 5203 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 5204 elapsedRealtimeMs, uptimeMs); 5205 } 5206 } 5207 } 5208 5209 @GuardedBy("this") noteLongPartialWakelockStart(String name, String historyName, int uid)5210 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 5211 noteLongPartialWakelockStart(name, historyName, uid, 5212 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5213 } 5214 5215 @GuardedBy("this") noteLongPartialWakelockStart(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5216 public void noteLongPartialWakelockStart(String name, String historyName, int uid, 5217 long elapsedRealtimeMs, long uptimeMs) { 5218 noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 5219 } 5220 5221 @GuardedBy("this") noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)5222 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 5223 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 5224 final int N = workSource.size(); 5225 for (int i = 0; i < N; ++i) { 5226 final int uid = mapUid(workSource.getUid(i)); 5227 noteLongPartialWakeLockStartInternal(name, historyName, uid, 5228 elapsedRealtimeMs, uptimeMs); 5229 } 5230 5231 final List<WorkChain> workChains = workSource.getWorkChains(); 5232 if (workChains != null) { 5233 for (int i = 0; i < workChains.size(); ++i) { 5234 final WorkChain workChain = workChains.get(i); 5235 final int uid = workChain.getAttributionUid(); 5236 noteLongPartialWakeLockStartInternal(name, historyName, uid, 5237 elapsedRealtimeMs, uptimeMs); 5238 } 5239 } 5240 } 5241 5242 @GuardedBy("this") noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5243 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, 5244 long elapsedRealtimeMs, long uptimeMs) { 5245 final int mappedUid = mapUid(uid); 5246 if (historyName == null) { 5247 historyName = name; 5248 } 5249 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, 5250 mappedUid, 0)) { 5251 return; 5252 } 5253 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 5254 historyName, mappedUid); 5255 if (mappedUid != uid) { 5256 // Prevent the isolated uid mapping from being removed while the wakelock is 5257 // being held. 5258 mPowerStatsUidResolver.retainIsolatedUid(uid); 5259 } 5260 } 5261 5262 @GuardedBy("this") noteLongPartialWakelockFinish(String name, String historyName, int uid)5263 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 5264 noteLongPartialWakelockFinish(name, historyName, uid, 5265 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5266 } 5267 5268 @GuardedBy("this") noteLongPartialWakelockFinish(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5269 public void noteLongPartialWakelockFinish(String name, String historyName, int uid, 5270 long elapsedRealtimeMs, long uptimeMs) { 5271 noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 5272 } 5273 5274 @GuardedBy("this") noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)5275 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 5276 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 5277 final int N = workSource.size(); 5278 for (int i = 0; i < N; ++i) { 5279 final int uid = mapUid(workSource.getUid(i)); 5280 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 5281 elapsedRealtimeMs, uptimeMs); 5282 } 5283 5284 final List<WorkChain> workChains = workSource.getWorkChains(); 5285 if (workChains != null) { 5286 for (int i = 0; i < workChains.size(); ++i) { 5287 final WorkChain workChain = workChains.get(i); 5288 final int uid = workChain.getAttributionUid(); 5289 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 5290 elapsedRealtimeMs, uptimeMs); 5291 } 5292 } 5293 } 5294 5295 @GuardedBy("this") noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5296 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, 5297 long elapsedRealtimeMs, long uptimeMs) { 5298 final int mappedUid = mapUid(uid); 5299 if (historyName == null) { 5300 historyName = name; 5301 } 5302 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, 5303 mappedUid, 0)) { 5304 return; 5305 } 5306 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 5307 historyName, mappedUid); 5308 if (mappedUid != uid) { 5309 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 5310 releaseIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 5311 } 5312 } 5313 5314 @GuardedBy("this") noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs)5315 public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) { 5316 if (mLastWakeupReason != null) { 5317 long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs; 5318 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 5319 timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds 5320 mFrameworkStatsLogger.kernelWakeupReported(deltaUptimeMs * 1000, mLastWakeupReason, 5321 mLastWakeupElapsedTimeMs); 5322 } 5323 mHistory.recordWakeupEvent(elapsedRealtimeMs, uptimeMs, reason); 5324 mLastWakeupReason = reason; 5325 mLastWakeupUptimeMs = uptimeMs; 5326 mLastWakeupElapsedTimeMs = elapsedRealtimeMs; 5327 } 5328 5329 @GuardedBy("this") startAddingCpuStatsLocked()5330 public boolean startAddingCpuStatsLocked() { 5331 mExternalSync.cancelCpuSyncDueToWakelockChange(); 5332 return mOnBatteryInternal; 5333 } 5334 5335 @GuardedBy("this") addCpuStatsLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs)5336 public void addCpuStatsLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, 5337 int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, 5338 int statSoftIrqTimeMs, int statIdleTimeMs) { 5339 mStepDetailsCalculator.addCpuStats(totalUTimeMs, totalSTimeMs, statUserTimeMs, 5340 statSystemTimeMs, statIOWaitTimeMs, statIrqTimeMs, 5341 statSoftIrqTimeMs, statIdleTimeMs); 5342 } 5343 5344 /** 5345 * Called after {@link #addCpuStatsLocked} has been invoked for all active apps. 5346 */ 5347 @GuardedBy("this") finishAddingCpuStatsLocked()5348 public void finishAddingCpuStatsLocked() { 5349 mStepDetailsCalculator.finishAddingCpuLocked(); 5350 } 5351 noteProcessDiedLocked(int uid, int pid)5352 public void noteProcessDiedLocked(int uid, int pid) { 5353 uid = mapUid(uid); 5354 Uid u = mUidStats.get(uid); 5355 if (u != null) { 5356 u.mPids.remove(pid); 5357 } 5358 } 5359 reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs)5360 public void reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs) { 5361 uid = mapUid(uid); 5362 Uid u = mUidStats.get(uid); 5363 if (u != null) { 5364 u.reportExcessiveCpuLocked(proc, overTimeMs, usedTimeMs); 5365 } 5366 } 5367 5368 int mSensorNesting; 5369 5370 @GuardedBy("this") noteStartSensorLocked(int uid, int sensor)5371 public void noteStartSensorLocked(int uid, int sensor) { 5372 noteStartSensorLocked(uid, sensor, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5373 } 5374 5375 @GuardedBy("this") noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)5376 public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 5377 uid = mapUid(uid); 5378 if (mSensorNesting == 0) { 5379 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5380 HistoryItem.STATE_SENSOR_ON_FLAG); 5381 } 5382 mSensorNesting++; 5383 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5384 .noteStartSensor(sensor, elapsedRealtimeMs); 5385 } 5386 5387 @GuardedBy("this") noteStopSensorLocked(int uid, int sensor)5388 public void noteStopSensorLocked(int uid, int sensor) { 5389 noteStopSensorLocked(uid, sensor, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5390 } 5391 5392 @GuardedBy("this") noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)5393 public void noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 5394 uid = mapUid(uid); 5395 mSensorNesting--; 5396 if (mSensorNesting == 0) { 5397 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5398 HistoryItem.STATE_SENSOR_ON_FLAG); 5399 } 5400 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5401 .noteStopSensor(sensor, elapsedRealtimeMs); 5402 } 5403 5404 int mGpsNesting; 5405 5406 @GuardedBy("this") noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)5407 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 5408 noteGpsChangedLocked(oldWs, newWs, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5409 } 5410 5411 @GuardedBy("this") noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)5412 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, 5413 long elapsedRealtimeMs, long uptimeMs) { 5414 for (int i = 0; i < newWs.size(); ++i) { 5415 noteStartGpsLocked(newWs.getUid(i), null, elapsedRealtimeMs, uptimeMs); 5416 } 5417 5418 for (int i = 0; i < oldWs.size(); ++i) { 5419 noteStopGpsLocked((oldWs.getUid(i)), null, elapsedRealtimeMs, uptimeMs); 5420 } 5421 5422 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 5423 if (wcs != null) { 5424 if (wcs[0] != null) { 5425 final List<WorkChain> newChains = wcs[0]; 5426 for (int i = 0; i < newChains.size(); ++i) { 5427 noteStartGpsLocked(-1, newChains.get(i), elapsedRealtimeMs, uptimeMs); 5428 } 5429 } 5430 5431 if (wcs[1] != null) { 5432 final List<WorkChain> goneChains = wcs[1]; 5433 for (int i = 0; i < goneChains.size(); ++i) { 5434 noteStopGpsLocked(-1, goneChains.get(i), elapsedRealtimeMs, uptimeMs); 5435 } 5436 } 5437 } 5438 } 5439 5440 @GuardedBy("this") noteStartGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)5441 private void noteStartGpsLocked(int uid, WorkChain workChain, 5442 long elapsedRealtimeMs, long uptimeMs) { 5443 if (workChain != null) { 5444 uid = workChain.getAttributionUid(); 5445 } 5446 final int mappedUid = mapUid(uid); 5447 if (mGpsNesting == 0) { 5448 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5449 HistoryItem.STATE_GPS_ON_FLAG); 5450 } 5451 mGpsNesting++; 5452 5453 mFrameworkStatsLogger.gpsScanStateChanged(mapIsolatedUid(uid), workChain, /* on */true); 5454 5455 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs).noteStartGps(elapsedRealtimeMs); 5456 } 5457 5458 @GuardedBy("this") noteStopGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)5459 private void noteStopGpsLocked(int uid, WorkChain workChain, 5460 long elapsedRealtimeMs, long uptimeMs) { 5461 if (workChain != null) { 5462 uid = workChain.getAttributionUid(); 5463 } 5464 final int mappedUid = mapUid(uid); 5465 mGpsNesting--; 5466 if (mGpsNesting == 0) { 5467 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5468 HistoryItem.STATE_GPS_ON_FLAG); 5469 mHistory.recordGpsSignalQualityEvent(elapsedRealtimeMs, uptimeMs, 5470 GPS_SIGNAL_QUALITY_NONE); 5471 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 5472 mGpsSignalQualityBin = -1; 5473 } 5474 5475 mFrameworkStatsLogger.gpsScanStateChanged(mapIsolatedUid(uid), workChain, /* on */ false); 5476 5477 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs).noteStopGps(elapsedRealtimeMs); 5478 } 5479 5480 @GuardedBy("this") noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs)5481 public void noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs) { 5482 if (mGpsNesting == 0) { 5483 return; 5484 } 5485 if (signalLevel < 0 || signalLevel >= mGpsSignalQualityTimer.length) { 5486 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 5487 return; 5488 } 5489 if (mGpsSignalQualityBin != signalLevel) { 5490 if (mGpsSignalQualityBin >= 0) { 5491 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtimeMs); 5492 } 5493 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 5494 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs); 5495 } 5496 mHistory.recordGpsSignalQualityEvent(elapsedRealtimeMs, uptimeMs, signalLevel); 5497 mGpsSignalQualityBin = signalLevel; 5498 } 5499 } 5500 5501 @GuardedBy("this") noteScreenStateLocked(int display, int state)5502 public void noteScreenStateLocked(int display, int state) { 5503 noteScreenStateLocked(display, state, mClock.elapsedRealtime(), mClock.uptimeMillis(), 5504 mClock.currentTimeMillis()); 5505 } 5506 5507 @GuardedBy("this") noteScreenStateLocked(int display, int displayState, long elapsedRealtimeMs, long uptimeMs, long currentTimeMs)5508 public void noteScreenStateLocked(int display, int displayState, 5509 long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) { 5510 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 5511 // original 4 are mapped to one of the originals. 5512 if (displayState > MAX_TRACKED_SCREEN_STATE) { 5513 if (Display.isOnState(displayState)) { 5514 displayState = Display.STATE_ON; 5515 } else if (Display.isDozeState(displayState)) { 5516 if (Display.isSuspendedState(displayState)) { 5517 displayState = Display.STATE_DOZE_SUSPEND; 5518 } else { 5519 displayState = Display.STATE_DOZE; 5520 } 5521 } else if (Display.isOffState(displayState)) { 5522 displayState = Display.STATE_OFF; 5523 } else { 5524 Slog.wtf(TAG, "Unknown screen state (not mapped): " + displayState); 5525 displayState = Display.STATE_UNKNOWN; 5526 } 5527 } 5528 // As of this point, displayState should be mapped to one of: 5529 // - Display.STATE_ON, 5530 // - Display.STATE_DOZE 5531 // - Display.STATE_DOZE_SUSPEND 5532 // - Display.STATE_OFF 5533 // - Display.STATE_UNKNOWN 5534 5535 int state; 5536 int overallBin = mScreenBrightnessBin; 5537 int externalUpdateFlag = 0; 5538 boolean shouldScheduleSync = false; 5539 final int numDisplay = mPerDisplayBatteryStats.length; 5540 if (display < 0 || display >= numDisplay) { 5541 Slog.wtf(TAG, "Unexpected note screen state for display " + display + " (only " 5542 + mPerDisplayBatteryStats.length + " displays exist...)"); 5543 return; 5544 } 5545 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5546 final int oldDisplayState = displayStats.screenState; 5547 5548 if (oldDisplayState == displayState) { 5549 // Nothing changed 5550 state = mScreenState; 5551 } else { 5552 displayStats.screenState = displayState; 5553 5554 // Stop timer for previous display state. 5555 switch (oldDisplayState) { 5556 case Display.STATE_ON: 5557 displayStats.screenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5558 final int bin = displayStats.screenBrightnessBin; 5559 if (bin >= 0) { 5560 displayStats.screenBrightnessTimers[bin].stopRunningLocked( 5561 elapsedRealtimeMs); 5562 } 5563 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5564 shouldScheduleSync = true; 5565 break; 5566 case Display.STATE_DOZE: 5567 // Transition from doze to doze suspend can be ignored. 5568 if (displayState == Display.STATE_DOZE_SUSPEND) break; 5569 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5570 shouldScheduleSync = true; 5571 break; 5572 case Display.STATE_DOZE_SUSPEND: 5573 // Transition from doze suspend to doze can be ignored. 5574 if (displayState == Display.STATE_DOZE) break; 5575 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5576 shouldScheduleSync = true; 5577 break; 5578 case Display.STATE_OFF: // fallthrough 5579 case Display.STATE_UNKNOWN: 5580 // Not tracked by timers. 5581 break; 5582 default: 5583 Slog.wtf(TAG, 5584 "Attempted to stop timer for unexpected display state " + display); 5585 } 5586 5587 // Start timer for new display state. 5588 switch (displayState) { 5589 case Display.STATE_ON: 5590 displayStats.screenOnTimer.startRunningLocked(elapsedRealtimeMs); 5591 final int bin = displayStats.screenBrightnessBin; 5592 if (bin >= 0) { 5593 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5594 elapsedRealtimeMs); 5595 } 5596 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5597 shouldScheduleSync = true; 5598 break; 5599 case Display.STATE_DOZE: 5600 // Transition from doze suspend to doze can be ignored. 5601 if (oldDisplayState == Display.STATE_DOZE_SUSPEND) break; 5602 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5603 shouldScheduleSync = true; 5604 break; 5605 case Display.STATE_DOZE_SUSPEND: 5606 // Transition from doze to doze suspend can be ignored. 5607 if (oldDisplayState == Display.STATE_DOZE) break; 5608 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5609 shouldScheduleSync = true; 5610 break; 5611 case Display.STATE_OFF: // fallthrough 5612 case Display.STATE_UNKNOWN: 5613 // Not tracked by timers. 5614 break; 5615 default: 5616 Slog.wtf(TAG, 5617 "Attempted to start timer for unexpected display state " + displayState 5618 + " for display " + display); 5619 } 5620 5621 if (shouldScheduleSync 5622 && mGlobalEnergyConsumerStats != null 5623 && mGlobalEnergyConsumerStats.isStandardBucketSupported( 5624 EnergyConsumerStats.POWER_BUCKET_SCREEN_ON)) { 5625 // Display energy consumption stats is available. Prepare to schedule an 5626 // external sync. 5627 externalUpdateFlag |= ExternalStatsSync.UPDATE_DISPLAY; 5628 } 5629 5630 // Reevaluate most important display screen state. 5631 state = Display.STATE_UNKNOWN; 5632 for (int i = 0; i < numDisplay; i++) { 5633 final int tempState = mPerDisplayBatteryStats[i].screenState; 5634 if (tempState == Display.STATE_ON 5635 || state == Display.STATE_ON) { 5636 state = Display.STATE_ON; 5637 } else if (tempState == Display.STATE_DOZE 5638 || state == Display.STATE_DOZE) { 5639 state = Display.STATE_DOZE; 5640 } else if (tempState == Display.STATE_DOZE_SUSPEND 5641 || state == Display.STATE_DOZE_SUSPEND) { 5642 state = Display.STATE_DOZE_SUSPEND; 5643 } else if (tempState == Display.STATE_OFF 5644 || state == Display.STATE_OFF) { 5645 state = Display.STATE_OFF; 5646 } 5647 } 5648 } 5649 5650 final boolean batteryRunning = mOnBatteryTimeBase.isRunning(); 5651 final boolean batteryScreenOffRunning = mOnBatteryScreenOffTimeBase.isRunning(); 5652 5653 state = mPretendScreenOff ? Display.STATE_OFF : state; 5654 if (mScreenState != state) { 5655 recordDailyStatsIfNeededLocked(true, currentTimeMs); 5656 final int oldState = mScreenState; 5657 mScreenState = state; 5658 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 5659 + ", newState=" + Display.stateToString(state)); 5660 5661 if (state != Display.STATE_UNKNOWN) { 5662 int stepState = state-1; 5663 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 5664 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 5665 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 5666 } else { 5667 Slog.wtf(TAG, "Unexpected screen state: " + state); 5668 } 5669 } 5670 5671 int startStates = 0; 5672 int stopStates = 0; 5673 if (Display.isDozeState(state) && !Display.isDozeState(oldState)) { 5674 startStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 5675 mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5676 } else if (Display.isDozeState(oldState) && !Display.isDozeState(state)) { 5677 stopStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 5678 mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5679 } 5680 if (Display.isOnState(state)) { 5681 startStates |= HistoryItem.STATE_SCREEN_ON_FLAG; 5682 mScreenOnTimer.startRunningLocked(elapsedRealtimeMs); 5683 if (mScreenBrightnessBin >= 0) { 5684 mScreenBrightnessTimer[mScreenBrightnessBin] 5685 .startRunningLocked(elapsedRealtimeMs); 5686 } 5687 } else if (Display.isOnState(oldState)) { 5688 stopStates |= HistoryItem.STATE_SCREEN_ON_FLAG; 5689 mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5690 if (mScreenBrightnessBin >= 0) { 5691 mScreenBrightnessTimer[mScreenBrightnessBin] 5692 .stopRunningLocked(elapsedRealtimeMs); 5693 } 5694 } 5695 if (startStates != 0 || stopStates != 0) { 5696 mHistory.recordStateChangeEvent(elapsedRealtimeMs, uptimeMs, startStates, 5697 stopStates); 5698 } 5699 5700 // Per screen state Cpu stats needed. Prepare to schedule an external sync. 5701 externalUpdateFlag |= ExternalStatsSync.UPDATE_CPU; 5702 shouldScheduleSync = true; 5703 5704 if (Display.isOnState(state)) { 5705 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 5706 uptimeMs * 1000, elapsedRealtimeMs * 1000); 5707 // Fake a wake lock, so we consider the device waked as long as the screen is on. 5708 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 5709 elapsedRealtimeMs, uptimeMs); 5710 } else if (Display.isOnState(oldState)) { 5711 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 5712 elapsedRealtimeMs, uptimeMs); 5713 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 5714 uptimeMs * 1000, elapsedRealtimeMs * 1000); 5715 } 5716 // Update discharge amounts. 5717 if (mOnBatteryInternal) { 5718 updateDischargeScreenLevelsLocked(oldState, state); 5719 } 5720 } 5721 5722 // Changing display states might have changed the screen used to determine the overall 5723 // brightness. 5724 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 5725 5726 if (shouldScheduleSync) { 5727 final int numDisplays = mPerDisplayBatteryStats.length; 5728 final int[] displayStates = new int[numDisplays]; 5729 for (int i = 0; i < numDisplays; i++) { 5730 displayStates[i] = mPerDisplayBatteryStats[i].screenState; 5731 } 5732 mExternalSync.scheduleSyncDueToScreenStateChange(externalUpdateFlag, 5733 batteryRunning, batteryScreenOffRunning, state, displayStates); 5734 } 5735 } 5736 5737 /** 5738 * Note screen brightness change for a display. 5739 */ 5740 @GuardedBy("this") noteScreenBrightnessLocked(int display, int brightness)5741 public void noteScreenBrightnessLocked(int display, int brightness) { 5742 noteScreenBrightnessLocked(display, brightness, mClock.elapsedRealtime(), 5743 mClock.uptimeMillis()); 5744 } 5745 5746 5747 /** 5748 * Note screen brightness change for a display. 5749 */ 5750 @GuardedBy("this") noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, long uptimeMs)5751 public void noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, 5752 long uptimeMs) { 5753 // Bin the brightness. 5754 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 5755 if (bin < 0) bin = 0; 5756 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 5757 5758 final int overallBin; 5759 5760 final int numDisplays = mPerDisplayBatteryStats.length; 5761 if (display < 0 || display >= numDisplays) { 5762 Slog.wtf(TAG, "Unexpected note screen brightness for display " + display + " (only " 5763 + mPerDisplayBatteryStats.length + " displays exist...)"); 5764 return; 5765 } 5766 5767 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5768 final int oldBin = displayStats.screenBrightnessBin; 5769 if (oldBin == bin) { 5770 // Nothing changed 5771 overallBin = mScreenBrightnessBin; 5772 } else { 5773 displayStats.screenBrightnessBin = bin; 5774 if (displayStats.screenState == Display.STATE_ON) { 5775 if (oldBin >= 0) { 5776 displayStats.screenBrightnessTimers[oldBin].stopRunningLocked( 5777 elapsedRealtimeMs); 5778 } 5779 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5780 elapsedRealtimeMs); 5781 } 5782 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5783 } 5784 5785 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 5786 } 5787 5788 @GuardedBy("this") evaluateOverallScreenBrightnessBinLocked()5789 private int evaluateOverallScreenBrightnessBinLocked() { 5790 int overallBin = -1; 5791 final int numDisplays = getDisplayCount(); 5792 for (int display = 0; display < numDisplays; display++) { 5793 final int displayBrightnessBin; 5794 if (mPerDisplayBatteryStats[display].screenState == Display.STATE_ON) { 5795 displayBrightnessBin = mPerDisplayBatteryStats[display].screenBrightnessBin; 5796 } else { 5797 displayBrightnessBin = -1; 5798 } 5799 if (displayBrightnessBin > overallBin) { 5800 overallBin = displayBrightnessBin; 5801 } 5802 } 5803 return overallBin; 5804 } 5805 5806 @GuardedBy("this") maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, long uptimeMs)5807 private void maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, 5808 long uptimeMs) { 5809 if (mScreenBrightnessBin != overallBin) { 5810 if (overallBin >= 0) { 5811 mHistory.recordScreenBrightnessEvent(elapsedRealtimeMs, uptimeMs, overallBin); 5812 } 5813 if (mScreenState == Display.STATE_ON) { 5814 if (mScreenBrightnessBin >= 0) { 5815 mScreenBrightnessTimer[mScreenBrightnessBin] 5816 .stopRunningLocked(elapsedRealtimeMs); 5817 } 5818 if (overallBin >= 0) { 5819 mScreenBrightnessTimer[overallBin] 5820 .startRunningLocked(elapsedRealtimeMs); 5821 } 5822 } 5823 mScreenBrightnessBin = overallBin; 5824 } 5825 } 5826 5827 @GuardedBy("this") noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event, long elapsedRealtimeMs, long uptimeMs)5828 public void noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event, 5829 long elapsedRealtimeMs, long uptimeMs) { 5830 if (mOnBatteryInternal) { 5831 uid = mapUid(uid); 5832 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteUserActivityLocked(event); 5833 } 5834 } 5835 5836 @GuardedBy("this") noteWakeUpLocked(String reason, int reasonUid, long elapsedRealtimeMs, long uptimeMs)5837 public void noteWakeUpLocked(String reason, int reasonUid, 5838 long elapsedRealtimeMs, long uptimeMs) { 5839 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP, reason, 5840 reasonUid); 5841 } 5842 5843 @GuardedBy("this") noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs)5844 public void noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs) { 5845 if (mInteractive != interactive) { 5846 mInteractive = interactive; 5847 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 5848 if (interactive) { 5849 mInteractiveTimer.startRunningLocked(elapsedRealtimeMs); 5850 } else { 5851 mInteractiveTimer.stopRunningLocked(elapsedRealtimeMs); 5852 } 5853 } 5854 } 5855 5856 @GuardedBy("this") noteConnectivityChangedLocked(int type, String extra, long elapsedRealtimeMs, long uptimeMs)5857 public void noteConnectivityChangedLocked(int type, String extra, 5858 long elapsedRealtimeMs, long uptimeMs) { 5859 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 5860 extra, type); 5861 mNumConnectivityChange++; 5862 } 5863 5864 @GuardedBy("this") noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5865 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 5866 final long uptimeMillis, int uid) { 5867 uid = mapUid(uid); 5868 mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5869 uid); 5870 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked(); 5871 } 5872 5873 /** 5874 * Updates the radio power state and returns true if an external stats collection should occur. 5875 */ 5876 @GuardedBy("this") noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)5877 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 5878 return noteMobileRadioPowerStateLocked(powerState, timestampNs, uid, 5879 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5880 } 5881 5882 @GuardedBy("this") noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)5883 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, 5884 long elapsedRealtimeMs, long uptimeMs) { 5885 if (mMobileRadioPowerState != powerState) { 5886 long realElapsedRealtimeMs; 5887 final boolean active = isActiveRadioPowerState(powerState); 5888 if (active) { 5889 if (uid > 0) { 5890 noteMobileRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 5891 } 5892 5893 mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 5894 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5895 HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG); 5896 } else { 5897 realElapsedRealtimeMs = timestampNs / (1000*1000); 5898 long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs; 5899 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 5900 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 5901 + " is before start time " + lastUpdateTimeMs); 5902 realElapsedRealtimeMs = elapsedRealtimeMs; 5903 } else if (realElapsedRealtimeMs < elapsedRealtimeMs) { 5904 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs 5905 - realElapsedRealtimeMs); 5906 } 5907 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5908 HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG); 5909 } 5910 mMobileRadioPowerState = powerState; 5911 5912 // Inform current RatBatteryStats that the modem active state might have changed. 5913 getRatBatteryStatsLocked(mActiveRat).noteActive(active, elapsedRealtimeMs); 5914 5915 if (active) { 5916 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtimeMs); 5917 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtimeMs); 5918 } else { 5919 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 5920 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 5921 5922 if (mMobileRadioPowerStatsCollector.isEnabled()) { 5923 mMobileRadioPowerStatsCollector.schedule(); 5924 } else { 5925 // Check if modem Activity info has been collected recently, don't bother 5926 // triggering another update. 5927 if (mLastModemActivityInfo == null 5928 || elapsedRealtimeMs >= mLastModemActivityInfo.getTimestampMillis() 5929 + MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS) { 5930 mExternalSync.scheduleSync("modem-data", 5931 BatteryExternalStatsWorker.UPDATE_RADIO); 5932 return true; 5933 } 5934 } 5935 } 5936 } 5937 return false; 5938 } 5939 isActiveRadioPowerState(int powerState)5940 private static boolean isActiveRadioPowerState(int powerState) { 5941 return powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5942 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5943 } 5944 5945 /** 5946 * Toggles the power save mode state. 5947 */ 5948 @GuardedBy("this") notePowerSaveModeLockedInit(boolean enabled, long elapsedRealtimeMs, long uptimeMs)5949 public void notePowerSaveModeLockedInit(boolean enabled, long elapsedRealtimeMs, 5950 long uptimeMs) { 5951 if (mPowerSaveModeEnabled != enabled) { 5952 notePowerSaveModeLocked(enabled, elapsedRealtimeMs, uptimeMs); 5953 } else { 5954 // Log an initial value for BATTERY_SAVER_MODE_STATE_CHANGED in order to 5955 // allow the atom to read all future state changes. 5956 mFrameworkStatsLogger.batterySaverModeChanged(enabled); 5957 } 5958 } 5959 5960 @GuardedBy("this") notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs)5961 public void notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs) { 5962 if (mPowerSaveModeEnabled != enabled) { 5963 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 5964 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 5965 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 5966 mPowerSaveModeEnabled = enabled; 5967 if (enabled) { 5968 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 5969 HistoryItem.STATE2_POWER_SAVE_FLAG); 5970 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs); 5971 } else { 5972 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 5973 HistoryItem.STATE2_POWER_SAVE_FLAG); 5974 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs); 5975 } 5976 mFrameworkStatsLogger.batterySaverModeChanged(enabled); 5977 } 5978 } 5979 5980 @GuardedBy("this") noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, long elapsedRealtimeMs, long uptimeMs)5981 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, 5982 long elapsedRealtimeMs, long uptimeMs) { 5983 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 5984 if (mDeviceIdling && !nowIdling && activeReason == null) { 5985 // We don't go out of general idling mode until explicitly taken out of 5986 // device idle through going active or significant motion. 5987 nowIdling = true; 5988 } 5989 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 5990 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 5991 // We don't go out of general light idling mode until explicitly taken out of 5992 // device idle through going active or significant motion. 5993 nowLightIdling = true; 5994 } 5995 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 5996 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE, 5997 activeReason, activeUid); 5998 } 5999 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 6000 int statsmode; 6001 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 6002 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 6003 else statsmode = DEVICE_IDLE_MODE_OFF; 6004 mFrameworkStatsLogger.deviceIdlingModeStateChanged(statsmode); 6005 } 6006 if (mDeviceIdling != nowIdling) { 6007 mDeviceIdling = nowIdling; 6008 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 6009 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 6010 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 6011 if (nowIdling) { 6012 mDeviceIdlingTimer.startRunningLocked(elapsedRealtimeMs); 6013 } else { 6014 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 6015 } 6016 } 6017 if (mDeviceLightIdling != nowLightIdling) { 6018 mDeviceLightIdling = nowLightIdling; 6019 if (nowLightIdling) { 6020 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtimeMs); 6021 } else { 6022 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 6023 } 6024 } 6025 if (mDeviceIdleMode != mode) { 6026 mHistory.recordDeviceIdleEvent(elapsedRealtimeMs, uptimeMs, mode); 6027 long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs; 6028 mLastIdleTimeStartMs = elapsedRealtimeMs; 6029 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 6030 if (lastDuration > mLongestLightIdleTimeMs) { 6031 mLongestLightIdleTimeMs = lastDuration; 6032 } 6033 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtimeMs); 6034 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 6035 if (lastDuration > mLongestFullIdleTimeMs) { 6036 mLongestFullIdleTimeMs = lastDuration; 6037 } 6038 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtimeMs); 6039 } 6040 if (mode == DEVICE_IDLE_MODE_LIGHT) { 6041 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtimeMs); 6042 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 6043 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtimeMs); 6044 } 6045 mDeviceIdleMode = mode; 6046 mFrameworkStatsLogger.deviceIdleModeStateChanged(mode); 6047 } 6048 } 6049 6050 @GuardedBy("this") notePackageInstalledLocked(String pkgName, long versionCode, long elapsedRealtimeMs, long uptimeMs)6051 public void notePackageInstalledLocked(String pkgName, long versionCode, 6052 long elapsedRealtimeMs, long uptimeMs) { 6053 // XXX need to figure out what to do with long version codes. 6054 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED, 6055 pkgName, (int)versionCode); 6056 PackageChange pc = new PackageChange(); 6057 pc.mPackageName = pkgName; 6058 pc.mUpdate = true; 6059 pc.mVersionCode = versionCode; 6060 addPackageChange(pc); 6061 } 6062 6063 @GuardedBy("this") notePackageUninstalledLocked(String pkgName, long elapsedRealtimeMs, long uptimeMs)6064 public void notePackageUninstalledLocked(String pkgName, 6065 long elapsedRealtimeMs, long uptimeMs) { 6066 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_UNINSTALLED, 6067 pkgName, 0); 6068 PackageChange pc = new PackageChange(); 6069 pc.mPackageName = pkgName; 6070 pc.mUpdate = true; 6071 addPackageChange(pc); 6072 } 6073 addPackageChange(PackageChange pc)6074 private void addPackageChange(PackageChange pc) { 6075 if (mDailyPackageChanges == null) { 6076 mDailyPackageChanges = new ArrayList<>(); 6077 } 6078 mDailyPackageChanges.add(pc); 6079 } 6080 6081 @GuardedBy("this") stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs)6082 void stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs) { 6083 for (int i = 0; i < mGpsSignalQualityTimer.length; i++) { 6084 if (i == except) { 6085 continue; 6086 } 6087 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 6088 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtimeMs); 6089 } 6090 } 6091 } 6092 6093 @GuardedBy("this") notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs)6094 public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) { 6095 if (!mPhoneOn) { 6096 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6097 HistoryItem.STATE2_PHONE_IN_CALL_FLAG); 6098 mPhoneOn = true; 6099 mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs); 6100 if (mConstants.PHONE_ON_EXTERNAL_STATS_COLLECTION) { 6101 scheduleSyncExternalStatsLocked("phone-on", ExternalStatsSync.UPDATE_RADIO); 6102 mMobileRadioPowerStatsCollector.schedule(); 6103 } 6104 } 6105 } 6106 6107 @GuardedBy("this") notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs)6108 public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) { 6109 if (mPhoneOn) { 6110 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6111 HistoryItem.STATE2_PHONE_IN_CALL_FLAG); 6112 mPhoneOn = false; 6113 mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs); 6114 scheduleSyncExternalStatsLocked("phone-off", ExternalStatsSync.UPDATE_RADIO); 6115 mMobileRadioPowerStatsCollector.schedule(); 6116 } 6117 } 6118 6119 @GuardedBy("this") registerUsbStateReceiver(Context context)6120 private void registerUsbStateReceiver(Context context) { 6121 final IntentFilter usbStateFilter = new IntentFilter(); 6122 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 6123 context.registerReceiver(new BroadcastReceiver() { 6124 @Override 6125 public void onReceive(Context context, Intent intent) { 6126 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 6127 synchronized (BatteryStatsImpl.this) { 6128 noteUsbConnectionStateLocked(state, mClock.elapsedRealtime(), 6129 mClock.uptimeMillis()); 6130 } 6131 } 6132 }, usbStateFilter); 6133 synchronized (this) { 6134 if (mUsbDataState == USB_DATA_UNKNOWN) { 6135 final Intent usbState = context.registerReceiver(null, usbStateFilter); 6136 final boolean initState = usbState != null && usbState.getBooleanExtra( 6137 UsbManager.USB_CONNECTED, false); 6138 noteUsbConnectionStateLocked(initState, mClock.elapsedRealtime(), 6139 mClock.uptimeMillis()); 6140 } 6141 } 6142 } 6143 6144 @GuardedBy("this") noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, long uptimeMs)6145 private void noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, 6146 long uptimeMs) { 6147 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 6148 if (mUsbDataState != newState) { 6149 mUsbDataState = newState; 6150 if (connected) { 6151 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6152 HistoryItem.STATE2_USB_DATA_LINK_FLAG); 6153 } else { 6154 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6155 HistoryItem.STATE2_USB_DATA_LINK_FLAG); 6156 } 6157 } 6158 } 6159 6160 @GuardedBy("this") stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)6161 void stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 6162 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 6163 if (i == except) { 6164 continue; 6165 } 6166 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 6167 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 6168 } 6169 } 6170 } 6171 6172 @GuardedBy("this") updateAllPhoneStateLocked(int state, int simState, int strengthBin, long elapsedRealtimeMs, long uptimeMs)6173 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin, 6174 long elapsedRealtimeMs, long uptimeMs) { 6175 boolean scanning = false; 6176 boolean newHistory = false; 6177 int addStateFlag = 0; 6178 int removeStateFlag = 0; 6179 int newState = -1; 6180 int newSignalStrength = -1; 6181 6182 mPhoneServiceStateRaw = state; 6183 mPhoneSimStateRaw = simState; 6184 mPhoneSignalStrengthBinRaw = strengthBin; 6185 6186 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 6187 // In this case we will always be STATE_OUT_OF_SERVICE, so need 6188 // to infer that we are scanning from other data. 6189 if (state == ServiceState.STATE_OUT_OF_SERVICE 6190 && strengthBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 6191 state = ServiceState.STATE_IN_SERVICE; 6192 } 6193 } 6194 6195 // If the phone is powered off, stop all timers. 6196 if (state == ServiceState.STATE_POWER_OFF) { 6197 strengthBin = -1; 6198 6199 // If we are in service, make sure the correct signal string timer is running. 6200 } else if (state == ServiceState.STATE_IN_SERVICE) { 6201 // Bin will be changed below. 6202 6203 // If we're out of service, we are in the lowest signal strength 6204 // bin and have the scanning bit set. 6205 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 6206 scanning = true; 6207 strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 6208 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 6209 addStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG; 6210 newHistory = true; 6211 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtimeMs); 6212 mFrameworkStatsLogger.phoneServiceStateChanged(state, simState, strengthBin); 6213 } 6214 } 6215 6216 if (!scanning) { 6217 // If we are no longer scanning, then stop the scanning timer. 6218 if (mPhoneSignalScanningTimer.isRunningLocked()) { 6219 removeStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG; 6220 newHistory = true; 6221 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs); 6222 mFrameworkStatsLogger.phoneServiceStateChanged(state, simState, strengthBin); 6223 } 6224 } 6225 6226 if (mPhoneServiceState != state) { 6227 newState = state; 6228 newHistory = true; 6229 mPhoneServiceState = state; 6230 } 6231 6232 if (mPhoneSignalStrengthBin != strengthBin) { 6233 if (mPhoneSignalStrengthBin >= 0) { 6234 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 6235 elapsedRealtimeMs); 6236 } 6237 if (strengthBin >= 0) { 6238 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 6239 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 6240 } 6241 newSignalStrength = strengthBin; 6242 newHistory = true; 6243 mFrameworkStatsLogger.phoneSignalStrengthChanged(strengthBin); 6244 } else { 6245 stopAllPhoneSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 6246 } 6247 mPhoneSignalStrengthBin = strengthBin; 6248 } 6249 6250 if (newHistory) { 6251 mHistory.recordPhoneStateChangeEvent(elapsedRealtimeMs, uptimeMs, 6252 addStateFlag, removeStateFlag, newState, newSignalStrength); 6253 } 6254 } 6255 6256 @GuardedBy("this") notePhoneStateLocked(int state, int simState, long elapsedRealtimeMs, long uptimeMs)6257 public void notePhoneStateLocked(int state, int simState, 6258 long elapsedRealtimeMs, long uptimeMs) { 6259 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw, 6260 elapsedRealtimeMs, uptimeMs); 6261 } 6262 6263 @GuardedBy("this") notePhoneSignalStrengthLocked(SignalStrength signalStrength, long elapsedRealtimeMs, long uptimeMs)6264 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength, 6265 long elapsedRealtimeMs, long uptimeMs) { 6266 final int overallSignalStrength = signalStrength.getLevel(); 6267 final SparseIntArray perRatSignalStrength = new SparseIntArray( 6268 BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT); 6269 6270 // Extract signal strength level for each RAT. 6271 final List<CellSignalStrength> cellSignalStrengths = 6272 signalStrength.getCellSignalStrengths(); 6273 final int size = cellSignalStrengths.size(); 6274 for (int i = 0; i < size; i++) { 6275 CellSignalStrength cellSignalStrength = cellSignalStrengths.get(i); 6276 // Map each CellSignalStrength to a BatteryStats.RadioAccessTechnology 6277 final int ratType; 6278 final int level; 6279 if (cellSignalStrength instanceof CellSignalStrengthNr) { 6280 ratType = RADIO_ACCESS_TECHNOLOGY_NR; 6281 level = cellSignalStrength.getLevel(); 6282 } else if (cellSignalStrength instanceof CellSignalStrengthLte) { 6283 ratType = RADIO_ACCESS_TECHNOLOGY_LTE; 6284 level = cellSignalStrength.getLevel(); 6285 } else { 6286 ratType = RADIO_ACCESS_TECHNOLOGY_OTHER; 6287 level = cellSignalStrength.getLevel(); 6288 } 6289 6290 // According to SignalStrength#getCellSignalStrengths(), multiple of the same 6291 // cellSignalStrength can be present. Just take the highest level one for each RAT. 6292 if (perRatSignalStrength.get(ratType, -1) < level) { 6293 perRatSignalStrength.put(ratType, level); 6294 } 6295 } 6296 6297 notePhoneSignalStrengthLocked(overallSignalStrength, perRatSignalStrength, 6298 elapsedRealtimeMs, uptimeMs); 6299 } 6300 6301 /** 6302 * Note phone signal strength change, including per RAT signal strength. 6303 * 6304 * @param signalStrength overall signal strength {@see SignalStrength#getLevel()} 6305 * @param perRatSignalStrength signal strength of available RATs 6306 */ 6307 @GuardedBy("this") notePhoneSignalStrengthLocked(int signalStrength, SparseIntArray perRatSignalStrength)6308 public void notePhoneSignalStrengthLocked(int signalStrength, 6309 SparseIntArray perRatSignalStrength) { 6310 notePhoneSignalStrengthLocked(signalStrength, perRatSignalStrength, 6311 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6312 } 6313 6314 /** 6315 * Note phone signal strength change, including per RAT signal strength. 6316 * 6317 * @param signalStrength overall signal strength {@see SignalStrength#getLevel()} 6318 * @param perRatSignalStrength signal strength of available RATs 6319 */ 6320 @GuardedBy("this") notePhoneSignalStrengthLocked(int signalStrength, SparseIntArray perRatSignalStrength, long elapsedRealtimeMs, long uptimeMs)6321 public void notePhoneSignalStrengthLocked(int signalStrength, 6322 SparseIntArray perRatSignalStrength, 6323 long elapsedRealtimeMs, long uptimeMs) { 6324 // Note each RAT's signal strength. 6325 final int size = perRatSignalStrength.size(); 6326 for (int i = 0; i < size; i++) { 6327 final int rat = perRatSignalStrength.keyAt(i); 6328 final int ratSignalStrength = perRatSignalStrength.valueAt(i); 6329 getRatBatteryStatsLocked(rat).noteSignalStrength(ratSignalStrength, elapsedRealtimeMs); 6330 } 6331 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, signalStrength, 6332 elapsedRealtimeMs, uptimeMs); 6333 } 6334 6335 @GuardedBy("this") notePhoneDataConnectionStateLocked(@etworkType int dataType, boolean hasData, @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, @ServiceState.FrequencyRange int nrFrequency)6336 public void notePhoneDataConnectionStateLocked(@NetworkType int dataType, boolean hasData, 6337 @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, 6338 @ServiceState.FrequencyRange int nrFrequency) { 6339 notePhoneDataConnectionStateLocked(dataType, hasData, serviceType, nrState, nrFrequency, 6340 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6341 } 6342 6343 @GuardedBy("this") notePhoneDataConnectionStateLocked(@etworkType int dataType, boolean hasData, @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, @ServiceState.FrequencyRange int nrFrequency, long elapsedRealtimeMs, long uptimeMs)6344 public void notePhoneDataConnectionStateLocked(@NetworkType int dataType, boolean hasData, 6345 @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, 6346 @ServiceState.FrequencyRange int nrFrequency, long elapsedRealtimeMs, long uptimeMs) { 6347 // BatteryStats uses 0 to represent no network type. 6348 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 6349 // Unknown is included in DATA_CONNECTION_OTHER. 6350 int bin = DATA_CONNECTION_OUT_OF_SERVICE; 6351 if (hasData) { 6352 if (dataType > 0 && dataType <= NUM_ALL_NETWORK_TYPES) { 6353 bin = dataType; 6354 } else { 6355 switch (serviceType) { 6356 case ServiceState.STATE_OUT_OF_SERVICE: 6357 bin = DATA_CONNECTION_OUT_OF_SERVICE; 6358 break; 6359 case ServiceState.STATE_EMERGENCY_ONLY: 6360 bin = DATA_CONNECTION_EMERGENCY_SERVICE; 6361 break; 6362 default: 6363 bin = DATA_CONNECTION_OTHER; 6364 break; 6365 } 6366 } 6367 } 6368 6369 6370 6371 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 6372 if (mPhoneDataConnectionType != bin) { 6373 mHistory.recordDataConnectionTypeChangeEvent(elapsedRealtimeMs, uptimeMs, bin); 6374 if (mPhoneDataConnectionType >= 0) { 6375 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 6376 elapsedRealtimeMs); 6377 } 6378 mPhoneDataConnectionType = bin; 6379 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtimeMs); 6380 } 6381 6382 if (mNrState != nrState) { 6383 mHistory.recordNrStateChangeEvent(elapsedRealtimeMs, uptimeMs, nrState); 6384 mNrState = nrState; 6385 } 6386 6387 final boolean newNrNsaActive = isNrNsa(bin, nrState); 6388 final boolean nrNsaActive = mNrNsaTimer.isRunningLocked(); 6389 if (newNrNsaActive != nrNsaActive) { 6390 if (newNrNsaActive) { 6391 mNrNsaTimer.startRunningLocked(elapsedRealtimeMs); 6392 } else { 6393 mNrNsaTimer.stopRunningLocked(elapsedRealtimeMs); 6394 } 6395 } 6396 6397 final int newRat = mapNetworkTypeToRadioAccessTechnology(bin, nrState); 6398 if (newRat == RADIO_ACCESS_TECHNOLOGY_NR) { 6399 // Note possible frequency change for the NR RAT. 6400 getRatBatteryStatsLocked(newRat).noteFrequencyRange(nrFrequency, elapsedRealtimeMs); 6401 } 6402 if (mActiveRat != newRat) { 6403 getRatBatteryStatsLocked(mActiveRat).noteActive(false, elapsedRealtimeMs); 6404 mActiveRat = newRat; 6405 } 6406 final boolean modemActive = mMobileRadioActiveTimer.isRunningLocked(); 6407 getRatBatteryStatsLocked(newRat).noteActive(modemActive, elapsedRealtimeMs); 6408 } 6409 6410 /** 6411 * Non-standalone (NSA) mode for 5G NR will have an LTE network type. If NR state is 6412 * connected while on an LTE network, the device is in NR NSA mode. 6413 */ isNrNsa(@etworkType int dataType, @NetworkRegistrationInfo.NRState int nrState)6414 private static boolean isNrNsa(@NetworkType int dataType, 6415 @NetworkRegistrationInfo.NRState int nrState) { 6416 return dataType == TelephonyManager.NETWORK_TYPE_LTE 6417 && nrState == NetworkRegistrationInfo.NR_STATE_CONNECTED; 6418 } 6419 6420 @RadioAccessTechnology mapNetworkTypeToRadioAccessTechnology(@etworkType int dataType, @NetworkRegistrationInfo.NRState int nrState)6421 private static int mapNetworkTypeToRadioAccessTechnology(@NetworkType int dataType, 6422 @NetworkRegistrationInfo.NRState int nrState) { 6423 if (isNrNsa(dataType, nrState)) { 6424 // Treat an NR NSA connection as RADIO_ACCESS_TECHNOLOGY_NR 6425 return RADIO_ACCESS_TECHNOLOGY_NR; 6426 } 6427 6428 switch (dataType) { 6429 case TelephonyManager.NETWORK_TYPE_NR: 6430 return RADIO_ACCESS_TECHNOLOGY_NR; 6431 case TelephonyManager.NETWORK_TYPE_LTE: 6432 return RADIO_ACCESS_TECHNOLOGY_LTE; 6433 case TelephonyManager.NETWORK_TYPE_UNKNOWN: //fallthrough 6434 case TelephonyManager.NETWORK_TYPE_GPRS: //fallthrough 6435 case TelephonyManager.NETWORK_TYPE_EDGE: //fallthrough 6436 case TelephonyManager.NETWORK_TYPE_UMTS: //fallthrough 6437 case TelephonyManager.NETWORK_TYPE_CDMA: //fallthrough 6438 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fallthrough 6439 case TelephonyManager.NETWORK_TYPE_EVDO_A: //fallthrough 6440 case TelephonyManager.NETWORK_TYPE_1xRTT: //fallthrough 6441 case TelephonyManager.NETWORK_TYPE_HSDPA: //fallthrough 6442 case TelephonyManager.NETWORK_TYPE_HSUPA: //fallthrough 6443 case TelephonyManager.NETWORK_TYPE_HSPA: //fallthrough 6444 case TelephonyManager.NETWORK_TYPE_IDEN: //fallthrough 6445 case TelephonyManager.NETWORK_TYPE_EVDO_B: //fallthrough 6446 case TelephonyManager.NETWORK_TYPE_EHRPD: //fallthrough 6447 case TelephonyManager.NETWORK_TYPE_HSPAP: //fallthrough 6448 case TelephonyManager.NETWORK_TYPE_GSM: //fallthrough 6449 case TelephonyManager.NETWORK_TYPE_TD_SCDMA: //fallthrough 6450 case TelephonyManager.NETWORK_TYPE_IWLAN: //fallthrough 6451 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6452 default: 6453 Slog.w(TAG, "Unhandled NetworkType (" + dataType + "), mapping to OTHER"); 6454 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6455 } 6456 } 6457 6458 @GuardedBy("this") noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs)6459 public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) { 6460 if (!mWifiOn) { 6461 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6462 HistoryItem.STATE2_WIFI_ON_FLAG); 6463 mWifiOn = true; 6464 mWifiOnTimer.startRunningLocked(elapsedRealtimeMs); 6465 if (mWifiPowerStatsCollector.isEnabled()) { 6466 mWifiPowerStatsCollector.schedule(); 6467 } else { 6468 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 6469 } 6470 } 6471 } 6472 6473 @GuardedBy("this") noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs)6474 public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) { 6475 if (mWifiOn) { 6476 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6477 HistoryItem.STATE2_WIFI_ON_FLAG); 6478 mWifiOn = false; 6479 mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs); 6480 if (mWifiPowerStatsCollector.isEnabled()) { 6481 mWifiPowerStatsCollector.schedule(); 6482 } else { 6483 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 6484 } 6485 } 6486 } 6487 6488 @GuardedBy("this") noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6489 public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6490 uid = mapUid(uid); 6491 if (mAudioOnNesting == 0) { 6492 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6493 HistoryItem.STATE_AUDIO_ON_FLAG, uid, "audio"); 6494 mAudioOnTimer.startRunningLocked(elapsedRealtimeMs); 6495 } 6496 mAudioOnNesting++; 6497 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_AUDIO)) { 6498 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6499 .noteAudioTurnedOnLocked(elapsedRealtimeMs); 6500 } 6501 } 6502 6503 @GuardedBy("this") noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6504 public void noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6505 if (mAudioOnNesting == 0) { 6506 return; 6507 } 6508 uid = mapUid(uid); 6509 if (--mAudioOnNesting == 0) { 6510 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6511 HistoryItem.STATE_AUDIO_ON_FLAG, uid, "audio"); 6512 mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs); 6513 } 6514 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_AUDIO)) { 6515 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6516 .noteAudioTurnedOffLocked(elapsedRealtimeMs); 6517 } 6518 } 6519 6520 @GuardedBy("this") noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6521 public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6522 uid = mapUid(uid); 6523 if (mVideoOnNesting == 0) { 6524 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6525 HistoryItem.STATE2_VIDEO_ON_FLAG, uid, "video"); 6526 mVideoOnTimer.startRunningLocked(elapsedRealtimeMs); 6527 } 6528 mVideoOnNesting++; 6529 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_VIDEO)) { 6530 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6531 .noteVideoTurnedOnLocked(elapsedRealtimeMs); 6532 } 6533 } 6534 6535 @GuardedBy("this") noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6536 public void noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6537 if (mVideoOnNesting == 0) { 6538 return; 6539 } 6540 uid = mapUid(uid); 6541 if (--mVideoOnNesting == 0) { 6542 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6543 HistoryItem.STATE2_VIDEO_ON_FLAG, uid, "video"); 6544 mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs); 6545 } 6546 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_VIDEO)) { 6547 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6548 .noteVideoTurnedOffLocked(elapsedRealtimeMs); 6549 } 6550 } 6551 6552 @GuardedBy("this") noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs)6553 public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) { 6554 if (mAudioOnNesting > 0) { 6555 mAudioOnNesting = 0; 6556 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6557 HistoryItem.STATE_AUDIO_ON_FLAG); 6558 mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6559 for (int i=0; i<mUidStats.size(); i++) { 6560 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6561 uid.noteResetAudioLocked(elapsedRealtimeMs); 6562 } 6563 } 6564 } 6565 6566 @GuardedBy("this") noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs)6567 public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) { 6568 if (mVideoOnNesting > 0) { 6569 mVideoOnNesting = 0; 6570 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6571 HistoryItem.STATE2_VIDEO_ON_FLAG); 6572 mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6573 for (int i=0; i<mUidStats.size(); i++) { 6574 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6575 uid.noteResetVideoLocked(elapsedRealtimeMs); 6576 } 6577 } 6578 } 6579 6580 @GuardedBy("this") noteActivityResumedLocked(int uid)6581 public void noteActivityResumedLocked(int uid) { 6582 noteActivityResumedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6583 } 6584 6585 @GuardedBy("this") noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6586 public void noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6587 uid = mapUid(uid); 6588 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6589 .noteActivityResumedLocked(elapsedRealtimeMs); 6590 } 6591 6592 @GuardedBy("this") noteActivityPausedLocked(int uid)6593 public void noteActivityPausedLocked(int uid) { 6594 noteActivityPausedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6595 } 6596 6597 @GuardedBy("this") noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6598 public void noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6599 uid = mapUid(uid); 6600 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6601 .noteActivityPausedLocked(elapsedRealtimeMs); 6602 } 6603 6604 @GuardedBy("this") noteVibratorOnLocked(int uid, long durationMillis, long elapsedRealtimeMs, long uptimeMs)6605 public void noteVibratorOnLocked(int uid, long durationMillis, 6606 long elapsedRealtimeMs, long uptimeMs) { 6607 uid = mapUid(uid); 6608 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6609 .noteVibratorOnLocked(durationMillis, elapsedRealtimeMs); 6610 } 6611 6612 @GuardedBy("this") noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6613 public void noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6614 uid = mapUid(uid); 6615 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6616 .noteVibratorOffLocked(elapsedRealtimeMs); 6617 } 6618 6619 @GuardedBy("this") noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6620 public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6621 uid = mapUid(uid); 6622 if (mFlashlightOnNesting++ == 0) { 6623 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6624 HistoryItem.STATE2_FLASHLIGHT_FLAG, uid, "flashlight"); 6625 mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs); 6626 } 6627 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) { 6628 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6629 .noteFlashlightTurnedOnLocked(elapsedRealtimeMs); 6630 } 6631 } 6632 6633 @GuardedBy("this") noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6634 public void noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6635 if (mFlashlightOnNesting == 0) { 6636 return; 6637 } 6638 uid = mapUid(uid); 6639 if (--mFlashlightOnNesting == 0) { 6640 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6641 HistoryItem.STATE2_FLASHLIGHT_FLAG, uid, "flashlight"); 6642 mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs); 6643 } 6644 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) { 6645 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6646 .noteFlashlightTurnedOffLocked(elapsedRealtimeMs); 6647 } 6648 } 6649 6650 @GuardedBy("this") noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6651 public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6652 uid = mapUid(uid); 6653 if (mCameraOnNesting++ == 0) { 6654 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6655 HistoryItem.STATE2_CAMERA_FLAG); 6656 mCameraOnTimer.startRunningLocked(elapsedRealtimeMs); 6657 } 6658 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6659 .noteCameraTurnedOnLocked(elapsedRealtimeMs); 6660 6661 scheduleSyncExternalStatsLocked("camera-on", ExternalStatsSync.UPDATE_CAMERA); 6662 } 6663 6664 @GuardedBy("this") noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6665 public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6666 if (mCameraOnNesting == 0) { 6667 return; 6668 } 6669 uid = mapUid(uid); 6670 if (--mCameraOnNesting == 0) { 6671 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6672 HistoryItem.STATE2_CAMERA_FLAG); 6673 mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs); 6674 } 6675 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6676 .noteCameraTurnedOffLocked(elapsedRealtimeMs); 6677 6678 scheduleSyncExternalStatsLocked("camera-off", ExternalStatsSync.UPDATE_CAMERA); 6679 } 6680 6681 @GuardedBy("this") noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs)6682 public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) { 6683 if (mCameraOnNesting > 0) { 6684 mCameraOnNesting = 0; 6685 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6686 HistoryItem.STATE2_CAMERA_FLAG); 6687 mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6688 for (int i=0; i<mUidStats.size(); i++) { 6689 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6690 uid.noteResetCameraLocked(elapsedRealtimeMs); 6691 } 6692 } 6693 6694 scheduleSyncExternalStatsLocked("camera-reset", ExternalStatsSync.UPDATE_CAMERA); 6695 } 6696 6697 @GuardedBy("this") noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs)6698 public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) { 6699 if (mFlashlightOnNesting > 0) { 6700 mFlashlightOnNesting = 0; 6701 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6702 HistoryItem.STATE2_FLASHLIGHT_FLAG); 6703 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6704 for (int i=0; i<mUidStats.size(); i++) { 6705 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6706 uid.noteResetFlashlightLocked(elapsedRealtimeMs); 6707 } 6708 } 6709 } 6710 6711 @GuardedBy("this") noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6712 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 6713 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 6714 if (workChain != null) { 6715 uid = workChain.getAttributionUid(); 6716 } 6717 uid = mapUid(uid); 6718 if (mBluetoothScanNesting == 0) { 6719 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6720 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6721 mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs); 6722 } 6723 mBluetoothScanNesting++; 6724 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6725 .noteBluetoothScanStartedLocked(elapsedRealtimeMs, isUnoptimized); 6726 } 6727 6728 @GuardedBy("this") noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)6729 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 6730 noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized, 6731 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6732 } 6733 6734 @GuardedBy("this") noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6735 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 6736 long elapsedRealtimeMs, long uptimeMs) { 6737 final int N = ws.size(); 6738 for (int i = 0; i < N; i++) { 6739 noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized, 6740 elapsedRealtimeMs, uptimeMs); 6741 } 6742 6743 final List<WorkChain> workChains = ws.getWorkChains(); 6744 if (workChains != null) { 6745 for (int i = 0; i < workChains.size(); ++i) { 6746 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized, 6747 elapsedRealtimeMs, uptimeMs); 6748 } 6749 } 6750 } 6751 6752 @GuardedBy("this") noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6753 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 6754 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 6755 if (workChain != null) { 6756 uid = workChain.getAttributionUid(); 6757 } 6758 uid = mapUid(uid); 6759 mBluetoothScanNesting--; 6760 if (mBluetoothScanNesting == 0) { 6761 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6762 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6763 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 6764 } 6765 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6766 .noteBluetoothScanStoppedLocked(elapsedRealtimeMs, isUnoptimized); 6767 } 6768 6769 @GuardedBy("this") noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)6770 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 6771 noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized, 6772 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6773 } 6774 6775 @GuardedBy("this") noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6776 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 6777 long elapsedRealtimeMs, long uptimeMs) { 6778 final int N = ws.size(); 6779 for (int i = 0; i < N; i++) { 6780 noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized, 6781 elapsedRealtimeMs, uptimeMs); 6782 } 6783 6784 final List<WorkChain> workChains = ws.getWorkChains(); 6785 if (workChains != null) { 6786 for (int i = 0; i < workChains.size(); ++i) { 6787 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized, 6788 elapsedRealtimeMs, uptimeMs); 6789 } 6790 } 6791 } 6792 6793 @GuardedBy("this") noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs)6794 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) { 6795 if (mBluetoothScanNesting > 0) { 6796 mBluetoothScanNesting = 0; 6797 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6798 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6799 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 6800 for (int i=0; i<mUidStats.size(); i++) { 6801 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6802 uid.noteResetBluetoothScanLocked(elapsedRealtimeMs); 6803 } 6804 } 6805 } 6806 6807 @GuardedBy("this") noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)6808 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 6809 noteBluetoothScanResultsFromSourceLocked(ws, numNewResults, 6810 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6811 } 6812 6813 @GuardedBy("this") noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, long elapsedRealtimeMs, long uptimeMs)6814 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, 6815 long elapsedRealtimeMs, long uptimeMs) { 6816 final int N = ws.size(); 6817 for (int i = 0; i < N; i++) { 6818 int uid = mapUid(ws.getUid(i)); 6819 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6820 .noteBluetoothScanResultsLocked(numNewResults); 6821 } 6822 6823 final List<WorkChain> workChains = ws.getWorkChains(); 6824 if (workChains != null) { 6825 for (int i = 0; i < workChains.size(); ++i) { 6826 final WorkChain wc = workChains.get(i); 6827 int uid = mapUid(wc.getAttributionUid()); 6828 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6829 .noteBluetoothScanResultsLocked(numNewResults); 6830 } 6831 } 6832 } 6833 retrieveBluetoothScanTimesLocked( BluetoothPowerStatsCollector.BluetoothStatsRetriever.Callback callback)6834 private void retrieveBluetoothScanTimesLocked( 6835 BluetoothPowerStatsCollector.BluetoothStatsRetriever.Callback callback) { 6836 long elapsedTimeUs = mClock.elapsedRealtime() * 1000; 6837 for (int i = mUidStats.size() - 1; i >= 0; i--) { 6838 Uid uidStats = mUidStats.valueAt(i); 6839 if (uidStats.mBluetoothScanTimer == null) { 6840 continue; 6841 } 6842 6843 long scanTimeUs = mBluetoothScanTimer.getTotalTimeLocked(elapsedTimeUs, 6844 STATS_SINCE_CHARGED); 6845 if (scanTimeUs != 0) { 6846 int uid = mUidStats.keyAt(i); 6847 callback.onBluetoothScanTime(uid, (scanTimeUs + 500) / 1000); 6848 } 6849 } 6850 } 6851 6852 @GuardedBy("this") noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)6853 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 6854 final long uptimeMillis, int uid) { 6855 uid = mapUid(uid); 6856 mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 6857 uid); 6858 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked(); 6859 } 6860 6861 @GuardedBy("this") noteWifiRadioPowerState(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)6862 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid, 6863 long elapsedRealtimeMs, long uptimeMs) { 6864 if (mWifiRadioPowerState != powerState) { 6865 final boolean active = 6866 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 6867 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 6868 if (active) { 6869 if (uid > 0) { 6870 noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 6871 } 6872 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6873 HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG); 6874 mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs); 6875 } else { 6876 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6877 HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG); 6878 mWifiActiveTimer.stopRunningLocked(timestampNs / (1000 * 1000)); 6879 } 6880 mWifiRadioPowerState = powerState; 6881 } 6882 } 6883 6884 @GuardedBy("this") noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6885 public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6886 if (!mGlobalWifiRunning) { 6887 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6888 HistoryItem.STATE2_WIFI_RUNNING_FLAG); 6889 mGlobalWifiRunning = true; 6890 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 6891 int N = ws.size(); 6892 for (int i=0; i<N; i++) { 6893 int uid = mapUid(ws.getUid(i)); 6894 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6895 .noteWifiRunningLocked(elapsedRealtimeMs); 6896 } 6897 6898 List<WorkChain> workChains = ws.getWorkChains(); 6899 if (workChains != null) { 6900 for (int i = 0; i < workChains.size(); ++i) { 6901 int uid = mapUid(workChains.get(i).getAttributionUid()); 6902 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6903 .noteWifiRunningLocked(elapsedRealtimeMs); 6904 } 6905 } 6906 if (mWifiPowerStatsCollector.isEnabled()) { 6907 mWifiPowerStatsCollector.schedule(); 6908 } else { 6909 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 6910 } 6911 } else { 6912 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 6913 } 6914 } 6915 6916 @GuardedBy("this") noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)6917 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, 6918 long elapsedRealtimeMs, long uptimeMs) { 6919 if (mGlobalWifiRunning) { 6920 int N = oldWs.size(); 6921 for (int i=0; i<N; i++) { 6922 int uid = mapUid(oldWs.getUid(i)); 6923 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6924 .noteWifiStoppedLocked(elapsedRealtimeMs); 6925 } 6926 6927 List<WorkChain> workChains = oldWs.getWorkChains(); 6928 if (workChains != null) { 6929 for (int i = 0; i < workChains.size(); ++i) { 6930 int uid = mapUid(workChains.get(i).getAttributionUid()); 6931 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6932 .noteWifiStoppedLocked(elapsedRealtimeMs); 6933 } 6934 } 6935 6936 N = newWs.size(); 6937 for (int i=0; i<N; i++) { 6938 int uid = mapUid(newWs.getUid(i)); 6939 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6940 .noteWifiRunningLocked(elapsedRealtimeMs); 6941 } 6942 6943 workChains = newWs.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 .noteWifiRunningLocked(elapsedRealtimeMs); 6949 } 6950 } 6951 } else { 6952 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 6953 } 6954 } 6955 6956 @GuardedBy("this") noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6957 public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6958 if (mGlobalWifiRunning) { 6959 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6960 HistoryItem.STATE2_WIFI_RUNNING_FLAG); 6961 mGlobalWifiRunning = false; 6962 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 6963 int N = ws.size(); 6964 for (int i=0; i<N; i++) { 6965 int uid = mapUid(ws.getUid(i)); 6966 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6967 .noteWifiStoppedLocked(elapsedRealtimeMs); 6968 } 6969 6970 List<WorkChain> workChains = ws.getWorkChains(); 6971 if (workChains != null) { 6972 for (int i = 0; i < workChains.size(); ++i) { 6973 int uid = mapUid(workChains.get(i).getAttributionUid()); 6974 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6975 .noteWifiStoppedLocked(elapsedRealtimeMs); 6976 } 6977 } 6978 6979 if (mWifiPowerStatsCollector.isEnabled()) { 6980 mWifiPowerStatsCollector.schedule(); 6981 } else { 6982 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 6983 } 6984 } else { 6985 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 6986 } 6987 } 6988 6989 @GuardedBy("this") noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs)6990 public void noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs) { 6991 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 6992 if (mWifiState != wifiState) { 6993 if (mWifiState >= 0) { 6994 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtimeMs); 6995 } 6996 mWifiState = wifiState; 6997 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtimeMs); 6998 if (mWifiPowerStatsCollector.isEnabled()) { 6999 mWifiPowerStatsCollector.schedule(); 7000 } else { 7001 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 7002 } 7003 } 7004 } 7005 7006 @GuardedBy("this") noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, long elapsedRealtimeMs, long uptimeMs)7007 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, 7008 long elapsedRealtimeMs, long uptimeMs) { 7009 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 7010 if (mWifiSupplState != supplState) { 7011 if (mWifiSupplState >= 0) { 7012 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtimeMs); 7013 } 7014 mWifiSupplState = supplState; 7015 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs); 7016 mHistory.recordWifiSupplicantStateChangeEvent(elapsedRealtimeMs, uptimeMs, supplState); 7017 } 7018 } 7019 7020 @GuardedBy("this") stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)7021 void stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 7022 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 7023 if (i == except) { 7024 continue; 7025 } 7026 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 7027 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 7028 } 7029 } 7030 } 7031 7032 @GuardedBy("this") noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs)7033 public void noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs) { 7034 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 7035 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 7036 if (mWifiSignalStrengthBin != strengthBin) { 7037 if (mWifiSignalStrengthBin >= 0) { 7038 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 7039 elapsedRealtimeMs); 7040 } 7041 if (strengthBin >= 0) { 7042 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 7043 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 7044 } 7045 mHistory.recordWifiSignalStrengthChangeEvent(elapsedRealtimeMs, uptimeMs, 7046 strengthBin); 7047 } else { 7048 stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 7049 } 7050 mWifiSignalStrengthBin = strengthBin; 7051 } 7052 } 7053 7054 private int mWifiFullLockNesting = 0; 7055 7056 @GuardedBy("this") noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7057 public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7058 if (mWifiFullLockNesting == 0) { 7059 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 7060 HistoryItem.STATE_WIFI_FULL_LOCK_FLAG); 7061 } 7062 mWifiFullLockNesting++; 7063 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7064 .noteFullWifiLockAcquiredLocked(elapsedRealtimeMs); 7065 } 7066 7067 @GuardedBy("this") noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7068 public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7069 mWifiFullLockNesting--; 7070 if (mWifiFullLockNesting == 0) { 7071 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 7072 HistoryItem.STATE_WIFI_FULL_LOCK_FLAG); 7073 } 7074 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7075 .noteFullWifiLockReleasedLocked(elapsedRealtimeMs); 7076 } 7077 7078 int mWifiScanNesting = 0; 7079 7080 @GuardedBy("this") noteWifiScanStartedLocked(int uid)7081 public void noteWifiScanStartedLocked(int uid) { 7082 noteWifiScanStartedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7083 } 7084 7085 @GuardedBy("this") noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7086 public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7087 if (mWifiScanNesting == 0) { 7088 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 7089 HistoryItem.STATE_WIFI_SCAN_FLAG); 7090 } 7091 mWifiScanNesting++; 7092 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7093 .noteWifiScanStartedLocked(elapsedRealtimeMs); 7094 } 7095 7096 @GuardedBy("this") noteWifiScanStoppedLocked(int uid)7097 public void noteWifiScanStoppedLocked(int uid) { 7098 noteWifiScanStoppedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7099 } 7100 7101 @GuardedBy("this") noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7102 public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7103 mWifiScanNesting--; 7104 if (mWifiScanNesting == 0) { 7105 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 7106 HistoryItem.STATE_WIFI_SCAN_FLAG); 7107 } 7108 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7109 .noteWifiScanStoppedLocked(elapsedRealtimeMs); 7110 } 7111 noteWifiBatchedScanStartedLocked(int uid, int csph, long elapsedRealtimeMs, long uptimeMs)7112 public void noteWifiBatchedScanStartedLocked(int uid, int csph, 7113 long elapsedRealtimeMs, long uptimeMs) { 7114 uid = mapUid(uid); 7115 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7116 .noteWifiBatchedScanStartedLocked(csph, elapsedRealtimeMs); 7117 } 7118 noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7119 public void noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7120 uid = mapUid(uid); 7121 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7122 .noteWifiBatchedScanStoppedLocked(elapsedRealtimeMs); 7123 } 7124 retrieveWifiScanTimesLocked( WifiPowerStatsCollector.WifiStatsRetriever.Callback callback)7125 private void retrieveWifiScanTimesLocked( 7126 WifiPowerStatsCollector.WifiStatsRetriever.Callback callback) { 7127 long elapsedTimeUs = mClock.elapsedRealtime() * 1000; 7128 for (int i = mUidStats.size() - 1; i >= 0; i--) { 7129 int uid = mUidStats.keyAt(i); 7130 Uid uidStats = mUidStats.valueAt(i); 7131 long scanTimeUs = uidStats.getWifiScanTime(elapsedTimeUs, STATS_SINCE_CHARGED); 7132 long batchScanTimeUs = 0; 7133 for (int bucket = 0; bucket < NUM_WIFI_BATCHED_SCAN_BINS; bucket++) { 7134 batchScanTimeUs += uidStats.getWifiBatchedScanTime(bucket, elapsedTimeUs, 7135 STATS_SINCE_CHARGED); 7136 } 7137 if (scanTimeUs != 0 || batchScanTimeUs != 0) { 7138 callback.onWifiScanTime(uid, (scanTimeUs + 500) / 1000, 7139 (batchScanTimeUs + 500) / 1000); 7140 } 7141 } 7142 } 7143 7144 private int mWifiMulticastNesting = 0; 7145 7146 @GuardedBy("this") noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7147 public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7148 uid = mapUid(uid); 7149 if (mWifiMulticastNesting == 0) { 7150 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 7151 HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG); 7152 // Start Wifi Multicast overall timer 7153 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 7154 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs); 7155 } 7156 } 7157 mWifiMulticastNesting++; 7158 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7159 .noteWifiMulticastEnabledLocked(elapsedRealtimeMs); 7160 } 7161 7162 @GuardedBy("this") noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7163 public void noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7164 uid = mapUid(uid); 7165 mWifiMulticastNesting--; 7166 if (mWifiMulticastNesting == 0) { 7167 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 7168 HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG); 7169 7170 // Stop Wifi Multicast overall timer 7171 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 7172 if (DEBUG) Slog.v(TAG, "Multicast Overall Timer Stopped"); 7173 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 7174 } 7175 } 7176 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7177 .noteWifiMulticastDisabledLocked(elapsedRealtimeMs); 7178 } 7179 7180 @GuardedBy("this") noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7181 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, 7182 long elapsedRealtimeMs, long uptimeMs) { 7183 int N = ws.size(); 7184 for (int i=0; i<N; i++) { 7185 final int uid = mapUid(ws.getUid(i)); 7186 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 7187 } 7188 7189 final List<WorkChain> workChains = ws.getWorkChains(); 7190 if (workChains != null) { 7191 for (int i = 0; i < workChains.size(); ++i) { 7192 final WorkChain workChain = workChains.get(i); 7193 final int uid = mapUid(workChain.getAttributionUid()); 7194 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 7195 } 7196 } 7197 } 7198 7199 @GuardedBy("this") noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7200 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, 7201 long elapsedRealtimeMs, long uptimeMs) { 7202 int N = ws.size(); 7203 for (int i=0; i<N; i++) { 7204 final int uid = mapUid(ws.getUid(i)); 7205 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 7206 } 7207 7208 final List<WorkChain> workChains = ws.getWorkChains(); 7209 if (workChains != null) { 7210 for (int i = 0; i < workChains.size(); ++i) { 7211 final WorkChain workChain = workChains.get(i); 7212 final int uid = mapUid(workChain.getAttributionUid()); 7213 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 7214 } 7215 } 7216 } 7217 7218 @GuardedBy("this") noteWifiScanStartedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7219 public void noteWifiScanStartedFromSourceLocked(WorkSource ws, 7220 long elapsedRealtimeMs, long uptimeMs) { 7221 int N = ws.size(); 7222 for (int i=0; i<N; i++) { 7223 final int uid = mapUid(ws.getUid(i)); 7224 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 7225 } 7226 7227 final List<WorkChain> workChains = ws.getWorkChains(); 7228 if (workChains != null) { 7229 for (int i = 0; i < workChains.size(); ++i) { 7230 final WorkChain workChain = workChains.get(i); 7231 final int uid = mapUid(workChain.getAttributionUid()); 7232 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 7233 } 7234 } 7235 } 7236 7237 @GuardedBy("this") noteWifiScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7238 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws, 7239 long elapsedRealtimeMs, long uptimeMs) { 7240 int N = ws.size(); 7241 for (int i=0; i<N; i++) { 7242 final int uid = mapUid(ws.getUid(i)); 7243 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 7244 } 7245 7246 final List<WorkChain> workChains = ws.getWorkChains(); 7247 if (workChains != null) { 7248 for (int i = 0; i < workChains.size(); ++i) { 7249 final WorkChain workChain = workChains.get(i); 7250 final int uid = mapUid(workChain.getAttributionUid()); 7251 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 7252 } 7253 } 7254 } 7255 7256 @GuardedBy("this") noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, long elapsedRealtimeMs, long uptimeMs)7257 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, 7258 long elapsedRealtimeMs, long uptimeMs) { 7259 int N = ws.size(); 7260 for (int i=0; i<N; i++) { 7261 noteWifiBatchedScanStartedLocked(ws.getUid(i), csph, elapsedRealtimeMs, uptimeMs); 7262 } 7263 7264 final List<WorkChain> workChains = ws.getWorkChains(); 7265 if (workChains != null) { 7266 for (int i = 0; i < workChains.size(); ++i) { 7267 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph, 7268 elapsedRealtimeMs, uptimeMs); 7269 } 7270 } 7271 } 7272 7273 @GuardedBy("this") noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7274 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, 7275 long elapsedRealtimeMs, long uptimeMs) { 7276 int N = ws.size(); 7277 for (int i=0; i<N; i++) { 7278 noteWifiBatchedScanStoppedLocked(ws.getUid(i), elapsedRealtimeMs, uptimeMs); 7279 } 7280 7281 final List<WorkChain> workChains = ws.getWorkChains(); 7282 if (workChains != null) { 7283 for (int i = 0; i < workChains.size(); ++i) { 7284 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid(), 7285 elapsedRealtimeMs, uptimeMs); 7286 } 7287 } 7288 } 7289 includeInStringArray(String[] array, String str)7290 private static String[] includeInStringArray(String[] array, String str) { 7291 if (ArrayUtils.indexOf(array, str) >= 0) { 7292 return array; 7293 } 7294 String[] newArray = new String[array.length+1]; 7295 System.arraycopy(array, 0, newArray, 0, array.length); 7296 newArray[array.length] = str; 7297 return newArray; 7298 } 7299 excludeFromStringArray(String[] array, String str)7300 private static String[] excludeFromStringArray(String[] array, String str) { 7301 int index = ArrayUtils.indexOf(array, str); 7302 if (index >= 0) { 7303 String[] newArray = new String[array.length-1]; 7304 if (index > 0) { 7305 System.arraycopy(array, 0, newArray, 0, index); 7306 } 7307 if (index < array.length-1) { 7308 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 7309 } 7310 return newArray; 7311 } 7312 return array; 7313 } 7314 7315 /** @hide */ noteNetworkInterfaceForTransports(String iface, int[] transportTypes)7316 public void noteNetworkInterfaceForTransports(String iface, int[] transportTypes) { 7317 if (TextUtils.isEmpty(iface)) return; 7318 final int displayTransport = getDisplayTransport(transportTypes); 7319 7320 synchronized (mModemNetworkLock) { 7321 if (displayTransport == TRANSPORT_CELLULAR) { 7322 mModemIfaces = includeInStringArray(mModemIfaces, iface); 7323 if (DEBUG) { 7324 Slog.d(TAG, "Note mobile iface " + iface + ": " 7325 + Arrays.toString(mModemIfaces)); 7326 } 7327 } else { 7328 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 7329 if (DEBUG) { 7330 Slog.d(TAG, "Note non-mobile iface " + iface + ": " 7331 + Arrays.toString(mModemIfaces)); 7332 } 7333 } 7334 } 7335 7336 synchronized (mWifiNetworkLock) { 7337 if (displayTransport == TRANSPORT_WIFI) { 7338 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 7339 if (DEBUG) { 7340 Slog.d(TAG, "Note wifi iface " + iface + ": " + Arrays.toString(mWifiIfaces)); 7341 } 7342 } else { 7343 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 7344 if (DEBUG) { 7345 Slog.d(TAG, "Note non-wifi iface " + iface + ": " 7346 + Arrays.toString(mWifiIfaces)); 7347 } 7348 } 7349 } 7350 } 7351 7352 /** 7353 * Records timing data related to an incoming Binder call in order to attribute 7354 * the power consumption to the calling app. 7355 */ noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)7356 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 7357 Collection<BinderCallsStats.CallStat> callStats) { 7358 noteBinderCallStats(workSourceUid, incrementalCallCount, callStats, 7359 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7360 } 7361 noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats, long elapsedRealtimeMs, long uptimeMs)7362 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 7363 Collection<BinderCallsStats.CallStat> callStats, 7364 long elapsedRealtimeMs, long uptimeMs) { 7365 synchronized (this) { 7366 getUidStatsLocked(workSourceUid, elapsedRealtimeMs, uptimeMs) 7367 .noteBinderCallStatsLocked(incrementalCallCount, callStats); 7368 } 7369 } 7370 7371 /** 7372 * Takes note of native IDs of threads taking incoming binder calls. The CPU time 7373 * of these threads is attributed to the apps making those binder calls. 7374 */ noteBinderThreadNativeIds(int[] binderThreadNativeTids)7375 public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) { 7376 mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids); 7377 } 7378 7379 /** 7380 * Estimates the proportion of system server CPU activity handling incoming binder calls 7381 * that can be attributed to each app 7382 */ 7383 @VisibleForTesting updateSystemServiceCallStats()7384 public void updateSystemServiceCallStats() { 7385 // Start off by computing the average duration of recorded binder calls, 7386 // regardless of which binder or transaction. We will use this as a fallback 7387 // for calls that were not sampled at all. 7388 int totalRecordedCallCount = 0; 7389 long totalRecordedCallTimeMicros = 0; 7390 for (int i = 0; i < mUidStats.size(); i++) { 7391 Uid uid = mUidStats.valueAt(i); 7392 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 7393 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 7394 BinderCallStats stats = binderCallStats.valueAt(j); 7395 totalRecordedCallCount += stats.recordedCallCount; 7396 totalRecordedCallTimeMicros += stats.recordedCpuTimeMicros; 7397 } 7398 } 7399 7400 long totalSystemServiceTimeMicros = 0; 7401 7402 // For every UID, use recorded durations of sampled binder calls to estimate 7403 // the total time the system server spent handling requests from this UID. 7404 for (int i = 0; i < mUidStats.size(); i++) { 7405 Uid uid = mUidStats.valueAt(i); 7406 7407 long totalTimeForUidUs = 0; 7408 int totalCallCountForUid = 0; 7409 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 7410 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 7411 BinderCallStats stats = binderCallStats.valueAt(j); 7412 totalCallCountForUid += stats.callCount; 7413 if (stats.recordedCallCount > 0) { 7414 totalTimeForUidUs += 7415 stats.callCount * stats.recordedCpuTimeMicros / stats.recordedCallCount; 7416 } else if (totalRecordedCallCount > 0) { 7417 totalTimeForUidUs += 7418 stats.callCount * totalRecordedCallTimeMicros / totalRecordedCallCount; 7419 } 7420 } 7421 7422 if (totalCallCountForUid < uid.mBinderCallCount && totalRecordedCallCount > 0) { 7423 // Estimate remaining calls, which were not tracked because of binder call 7424 // stats sampling 7425 totalTimeForUidUs += 7426 (uid.mBinderCallCount - totalCallCountForUid) * totalRecordedCallTimeMicros 7427 / totalRecordedCallCount; 7428 } 7429 7430 uid.mSystemServiceTimeUs = totalTimeForUidUs; 7431 totalSystemServiceTimeMicros += totalTimeForUidUs; 7432 } 7433 7434 for (int i = 0; i < mUidStats.size(); i++) { 7435 Uid uid = mUidStats.valueAt(i); 7436 if (totalSystemServiceTimeMicros > 0) { 7437 uid.mProportionalSystemServiceUsage = 7438 (double) uid.mSystemServiceTimeUs / totalSystemServiceTimeMicros; 7439 } else { 7440 uid.mProportionalSystemServiceUsage = 0; 7441 } 7442 } 7443 } 7444 getWifiIfaces()7445 public String[] getWifiIfaces() { 7446 synchronized (mWifiNetworkLock) { 7447 return mWifiIfaces; 7448 } 7449 } 7450 getMobileIfaces()7451 public String[] getMobileIfaces() { 7452 synchronized (mModemNetworkLock) { 7453 return mModemIfaces; 7454 } 7455 } 7456 getScreenOnTime(long elapsedRealtimeUs, int which)7457 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 7458 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7459 } 7460 getScreenOnCount(int which)7461 @Override public int getScreenOnCount(int which) { 7462 return mScreenOnTimer.getCountLocked(which); 7463 } 7464 getScreenDozeTime(long elapsedRealtimeUs, int which)7465 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 7466 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7467 } 7468 getScreenDozeCount(int which)7469 @Override public int getScreenDozeCount(int which) { 7470 return mScreenDozeTimer.getCountLocked(which); 7471 } 7472 getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)7473 @Override public long getScreenBrightnessTime(int brightnessBin, 7474 long elapsedRealtimeUs, int which) { 7475 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 7476 elapsedRealtimeUs, which); 7477 } 7478 getScreenBrightnessTimer(int brightnessBin)7479 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 7480 return mScreenBrightnessTimer[brightnessBin]; 7481 } 7482 7483 @Override getDisplayCount()7484 public int getDisplayCount() { 7485 return mPerDisplayBatteryStats.length; 7486 } 7487 7488 @Override getDisplayScreenOnTime(int display, long elapsedRealtimeUs)7489 public long getDisplayScreenOnTime(int display, long elapsedRealtimeUs) { 7490 return mPerDisplayBatteryStats[display].screenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, 7491 STATS_SINCE_CHARGED); 7492 } 7493 7494 @Override getDisplayScreenDozeTime(int display, long elapsedRealtimeUs)7495 public long getDisplayScreenDozeTime(int display, long elapsedRealtimeUs) { 7496 return mPerDisplayBatteryStats[display].screenDozeTimer.getTotalTimeLocked( 7497 elapsedRealtimeUs, STATS_SINCE_CHARGED); 7498 } 7499 7500 @Override getDisplayScreenBrightnessTime(int display, int brightnessBin, long elapsedRealtimeUs)7501 public long getDisplayScreenBrightnessTime(int display, int brightnessBin, 7502 long elapsedRealtimeUs) { 7503 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 7504 return displayStats.screenBrightnessTimers[brightnessBin].getTotalTimeLocked( 7505 elapsedRealtimeUs, STATS_SINCE_CHARGED); 7506 } 7507 getInteractiveTime(long elapsedRealtimeUs, int which)7508 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 7509 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7510 } 7511 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)7512 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 7513 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7514 } 7515 getPowerSaveModeEnabledCount(int which)7516 @Override public int getPowerSaveModeEnabledCount(int which) { 7517 return mPowerSaveModeEnabledTimer.getCountLocked(which); 7518 } 7519 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)7520 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 7521 int which) { 7522 switch (mode) { 7523 case DEVICE_IDLE_MODE_LIGHT: 7524 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7525 case DEVICE_IDLE_MODE_DEEP: 7526 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7527 } 7528 return 0; 7529 } 7530 getDeviceIdleModeCount(int mode, int which)7531 @Override public int getDeviceIdleModeCount(int mode, int which) { 7532 switch (mode) { 7533 case DEVICE_IDLE_MODE_LIGHT: 7534 return mDeviceIdleModeLightTimer.getCountLocked(which); 7535 case DEVICE_IDLE_MODE_DEEP: 7536 return mDeviceIdleModeFullTimer.getCountLocked(which); 7537 } 7538 return 0; 7539 } 7540 getLongestDeviceIdleModeTime(int mode)7541 @Override public long getLongestDeviceIdleModeTime(int mode) { 7542 switch (mode) { 7543 case DEVICE_IDLE_MODE_LIGHT: 7544 return mLongestLightIdleTimeMs; 7545 case DEVICE_IDLE_MODE_DEEP: 7546 return mLongestFullIdleTimeMs; 7547 } 7548 return 0; 7549 } 7550 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)7551 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 7552 switch (mode) { 7553 case DEVICE_IDLE_MODE_LIGHT: 7554 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7555 case DEVICE_IDLE_MODE_DEEP: 7556 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7557 } 7558 return 0; 7559 } 7560 getDeviceIdlingCount(int mode, int which)7561 @Override public int getDeviceIdlingCount(int mode, int which) { 7562 switch (mode) { 7563 case DEVICE_IDLE_MODE_LIGHT: 7564 return mDeviceLightIdlingTimer.getCountLocked(which); 7565 case DEVICE_IDLE_MODE_DEEP: 7566 return mDeviceIdlingTimer.getCountLocked(which); 7567 } 7568 return 0; 7569 } 7570 getNumConnectivityChange(int which)7571 @Override public int getNumConnectivityChange(int which) { 7572 return mNumConnectivityChange; 7573 } 7574 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)7575 @Override public long getGpsSignalQualityTime(int strengthBin, 7576 long elapsedRealtimeUs, int which) { 7577 if (strengthBin < 0 || strengthBin >= mGpsSignalQualityTimer.length) { 7578 return 0; 7579 } 7580 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 7581 elapsedRealtimeUs, which); 7582 } 7583 getGpsBatteryDrainMaMs()7584 @Override public long getGpsBatteryDrainMaMs() { 7585 final double opVolt = mPowerProfile.getAveragePower( 7586 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 7587 if (opVolt == 0) { 7588 return 0; 7589 } 7590 double energyUsedMaMs = 0.0; 7591 final int which = STATS_SINCE_CHARGED; 7592 final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000; 7593 for(int i=0; i < mGpsSignalQualityTimer.length; i++) { 7594 energyUsedMaMs 7595 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 7596 * (getGpsSignalQualityTime(i, rawRealtimeUs, which) / 1000); 7597 } 7598 return (long) energyUsedMaMs; 7599 } 7600 getPhoneOnTime(long elapsedRealtimeUs, int which)7601 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 7602 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7603 } 7604 getPhoneOnCount(int which)7605 @Override public int getPhoneOnCount(int which) { 7606 return mPhoneOnTimer.getCountLocked(which); 7607 } 7608 getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)7609 @Override public long getPhoneSignalStrengthTime(int strengthBin, 7610 long elapsedRealtimeUs, int which) { 7611 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 7612 elapsedRealtimeUs, which); 7613 } 7614 getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)7615 @Override public long getPhoneSignalScanningTime( 7616 long elapsedRealtimeUs, int which) { 7617 return mPhoneSignalScanningTimer.getTotalTimeLocked( 7618 elapsedRealtimeUs, which); 7619 } 7620 getPhoneSignalScanningTimer()7621 @Override public Timer getPhoneSignalScanningTimer() { 7622 return mPhoneSignalScanningTimer; 7623 } 7624 getPhoneSignalStrengthCount(int strengthBin, int which)7625 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 7626 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 7627 } 7628 getPhoneSignalStrengthTimer(int strengthBin)7629 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 7630 return mPhoneSignalStrengthsTimer[strengthBin]; 7631 } 7632 getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)7633 @Override public long getPhoneDataConnectionTime(int dataType, 7634 long elapsedRealtimeUs, int which) { 7635 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 7636 elapsedRealtimeUs, which); 7637 } 7638 getPhoneDataConnectionCount(int dataType, int which)7639 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 7640 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 7641 } 7642 getPhoneDataConnectionTimer(int dataType)7643 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 7644 return mPhoneDataConnectionsTimer[dataType]; 7645 } 7646 getNrNsaTime(long elapsedRealtimeUs)7647 @Override public long getNrNsaTime(long elapsedRealtimeUs) { 7648 return mNrNsaTimer.getTotalTimeLocked(elapsedRealtimeUs, STATS_SINCE_CHARGED); 7649 } 7650 getActiveRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)7651 @Override public long getActiveRadioDurationMs(@RadioAccessTechnology int rat, 7652 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, 7653 long elapsedRealtimeMs) { 7654 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7655 if (stats == null) return 0L; 7656 7657 final int freqCount = stats.perStateTimers.length; 7658 if (frequencyRange < 0 || frequencyRange >= freqCount) return 0L; 7659 7660 final StopwatchTimer[] strengthTimers = stats.perStateTimers[frequencyRange]; 7661 final int strengthCount = strengthTimers.length; 7662 if (signalStrength < 0 || signalStrength >= strengthCount) return 0L; 7663 7664 return stats.perStateTimers[frequencyRange][signalStrength].getTotalTimeLocked( 7665 elapsedRealtimeMs * 1000, STATS_SINCE_CHARGED) / 1000; 7666 } 7667 7668 @Override getActiveTxRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)7669 public long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat, 7670 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, 7671 long elapsedRealtimeMs) { 7672 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7673 if (stats == null) return DURATION_UNAVAILABLE; 7674 7675 final LongSamplingCounter counter = stats.getTxDurationCounter(frequencyRange, 7676 signalStrength, false); 7677 if (counter == null) return DURATION_UNAVAILABLE; 7678 7679 return counter.getCountLocked(STATS_SINCE_CHARGED); 7680 } 7681 7682 @Override getActiveRxRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs)7683 public long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat, 7684 @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs) { 7685 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7686 if (stats == null) return DURATION_UNAVAILABLE; 7687 7688 final LongSamplingCounter counter = stats.getRxDurationCounter(frequencyRange, false); 7689 if (counter == null) return DURATION_UNAVAILABLE; 7690 7691 return counter.getCountLocked(STATS_SINCE_CHARGED); 7692 } 7693 getMobileRadioActiveTime(long elapsedRealtimeUs, int which)7694 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 7695 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7696 } 7697 getMobileRadioActiveCount(int which)7698 @Override public int getMobileRadioActiveCount(int which) { 7699 return mMobileRadioActiveTimer.getCountLocked(which); 7700 } 7701 getMobileRadioActiveAdjustedTime(int which)7702 @Override public long getMobileRadioActiveAdjustedTime(int which) { 7703 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 7704 } 7705 getMobileRadioActiveUnknownTime(int which)7706 @Override public long getMobileRadioActiveUnknownTime(int which) { 7707 return mMobileRadioActiveUnknownTime.getCountLocked(which); 7708 } 7709 getMobileRadioActiveUnknownCount(int which)7710 @Override public int getMobileRadioActiveUnknownCount(int which) { 7711 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 7712 } 7713 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)7714 @Override public long getWifiMulticastWakelockTime( 7715 long elapsedRealtimeUs, int which) { 7716 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 7717 elapsedRealtimeUs, which); 7718 } 7719 getWifiMulticastWakelockCount(int which)7720 @Override public int getWifiMulticastWakelockCount(int which) { 7721 return mWifiMulticastWakelockTimer.getCountLocked(which); 7722 } 7723 getWifiOnTime(long elapsedRealtimeUs, int which)7724 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 7725 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7726 } 7727 getWifiActiveTime(long elapsedRealtimeUs, int which)7728 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 7729 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7730 } 7731 getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)7732 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 7733 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7734 } 7735 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)7736 @Override public long getWifiStateTime(int wifiState, 7737 long elapsedRealtimeUs, int which) { 7738 return mWifiStateTimer[wifiState].getTotalTimeLocked( 7739 elapsedRealtimeUs, which); 7740 } 7741 getWifiStateCount(int wifiState, int which)7742 @Override public int getWifiStateCount(int wifiState, int which) { 7743 return mWifiStateTimer[wifiState].getCountLocked(which); 7744 } 7745 getWifiStateTimer(int wifiState)7746 @Override public Timer getWifiStateTimer(int wifiState) { 7747 return mWifiStateTimer[wifiState]; 7748 } 7749 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)7750 @Override public long getWifiSupplStateTime(int state, 7751 long elapsedRealtimeUs, int which) { 7752 return mWifiSupplStateTimer[state].getTotalTimeLocked( 7753 elapsedRealtimeUs, which); 7754 } 7755 getWifiSupplStateCount(int state, int which)7756 @Override public int getWifiSupplStateCount(int state, int which) { 7757 return mWifiSupplStateTimer[state].getCountLocked(which); 7758 } 7759 getWifiSupplStateTimer(int state)7760 @Override public Timer getWifiSupplStateTimer(int state) { 7761 return mWifiSupplStateTimer[state]; 7762 } 7763 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)7764 @Override public long getWifiSignalStrengthTime(int strengthBin, 7765 long elapsedRealtimeUs, int which) { 7766 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 7767 elapsedRealtimeUs, which); 7768 } 7769 getWifiSignalStrengthCount(int strengthBin, int which)7770 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 7771 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 7772 } 7773 getWifiSignalStrengthTimer(int strengthBin)7774 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 7775 return mWifiSignalStrengthsTimer[strengthBin]; 7776 } 7777 7778 @Override getBluetoothControllerActivity()7779 public ControllerActivityCounter getBluetoothControllerActivity() { 7780 return mBluetoothActivity; 7781 } 7782 7783 @Override getWifiControllerActivity()7784 public ControllerActivityCounter getWifiControllerActivity() { 7785 return mWifiActivity; 7786 } 7787 7788 @Override getModemControllerActivity()7789 public ControllerActivityCounter getModemControllerActivity() { 7790 return mModemActivity; 7791 } 7792 7793 @Override hasBluetoothActivityReporting()7794 public boolean hasBluetoothActivityReporting() { 7795 return mHasBluetoothReporting; 7796 } 7797 7798 @Override hasWifiActivityReporting()7799 public boolean hasWifiActivityReporting() { 7800 return mHasWifiReporting; 7801 } 7802 7803 @Override hasModemActivityReporting()7804 public boolean hasModemActivityReporting() { 7805 return mHasModemReporting; 7806 } 7807 7808 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)7809 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 7810 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7811 } 7812 7813 @Override getFlashlightOnCount(int which)7814 public long getFlashlightOnCount(int which) { 7815 return mFlashlightOnTimer.getCountLocked(which); 7816 } 7817 7818 @Override getCameraOnTime(long elapsedRealtimeUs, int which)7819 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 7820 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7821 } 7822 7823 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)7824 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 7825 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7826 } 7827 7828 @Override getNetworkActivityBytes(int type, int which)7829 public long getNetworkActivityBytes(int type, int which) { 7830 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 7831 return mNetworkByteActivityCounters[type].getCountLocked(which); 7832 } else { 7833 return 0; 7834 } 7835 } 7836 7837 @Override getNetworkActivityPackets(int type, int which)7838 public long getNetworkActivityPackets(int type, int which) { 7839 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 7840 return mNetworkPacketActivityCounters[type].getCountLocked(which); 7841 } else { 7842 return 0; 7843 } 7844 } 7845 7846 @GuardedBy("this") 7847 @Override getBluetoothEnergyConsumptionUC()7848 public long getBluetoothEnergyConsumptionUC() { 7849 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH); 7850 } 7851 7852 @GuardedBy("this") 7853 @Override getCpuEnergyConsumptionUC()7854 public long getCpuEnergyConsumptionUC() { 7855 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU); 7856 } 7857 7858 @GuardedBy("this") 7859 @Override getGnssEnergyConsumptionUC()7860 public long getGnssEnergyConsumptionUC() { 7861 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_GNSS); 7862 } 7863 7864 @GuardedBy("this") 7865 @Override getMobileRadioEnergyConsumptionUC()7866 public long getMobileRadioEnergyConsumptionUC() { 7867 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 7868 } 7869 7870 @GuardedBy("this") 7871 @Override getPhoneEnergyConsumptionUC()7872 public long getPhoneEnergyConsumptionUC() { 7873 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_PHONE); 7874 } 7875 7876 @GuardedBy("this") 7877 @Override getScreenOnEnergyConsumptionUC()7878 public long getScreenOnEnergyConsumptionUC() { 7879 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON); 7880 } 7881 7882 @GuardedBy("this") 7883 @Override getScreenDozeEnergyConsumptionUC()7884 public long getScreenDozeEnergyConsumptionUC() { 7885 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_DOZE); 7886 } 7887 7888 @GuardedBy("this") 7889 @Override getWifiEnergyConsumptionUC()7890 public long getWifiEnergyConsumptionUC() { 7891 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI); 7892 } 7893 7894 @GuardedBy("this") 7895 @Override getCameraEnergyConsumptionUC()7896 public long getCameraEnergyConsumptionUC() { 7897 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CAMERA); 7898 } 7899 7900 /** 7901 * Returns the consumption (in microcoulombs) that the given standard power bucket consumed. 7902 * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable 7903 * 7904 * @param bucket standard power bucket of interest 7905 * @return charge (in microcoulombs) used for this power bucket 7906 */ 7907 @GuardedBy("this") getPowerBucketConsumptionUC(@tandardPowerBucket int bucket)7908 private long getPowerBucketConsumptionUC(@StandardPowerBucket int bucket) { 7909 if (mGlobalEnergyConsumerStats == null) { 7910 return POWER_DATA_UNAVAILABLE; 7911 } 7912 return mGlobalEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket); 7913 } 7914 7915 @GuardedBy("this") 7916 @Override getCustomEnergyConsumerBatteryConsumptionUC()7917 public @Nullable long[] getCustomEnergyConsumerBatteryConsumptionUC() { 7918 if (mGlobalEnergyConsumerStats == null) { 7919 return null; 7920 } 7921 return mGlobalEnergyConsumerStats.getAccumulatedCustomBucketCharges(); 7922 } 7923 7924 /** 7925 * Returns the names of custom power components. 7926 */ 7927 @Override getCustomEnergyConsumerNames()7928 public @NonNull String[] getCustomEnergyConsumerNames() { 7929 synchronized (this) { 7930 if (mEnergyConsumerStatsConfig == null) { 7931 return new String[0]; 7932 } 7933 final String[] names = mEnergyConsumerStatsConfig.getCustomBucketNames(); 7934 for (int i = 0; i < names.length; i++) { 7935 if (TextUtils.isEmpty(names[i])) { 7936 names[i] = "CUSTOM_" + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i; 7937 } 7938 } 7939 return names; 7940 } 7941 } 7942 7943 @Override getStartClockTime()7944 public long getStartClockTime() { 7945 synchronized (this) { 7946 final long currentTimeMs = mClock.currentTimeMillis(); 7947 if ((currentTimeMs > MILLISECONDS_IN_YEAR 7948 && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR)) 7949 || (mStartClockTimeMs > currentTimeMs)) { 7950 // If the start clock time has changed by more than a year, then presumably 7951 // the previous time was completely bogus. So we are going to figure out a 7952 // new time based on how much time has elapsed since we started counting. 7953 mHistory.recordCurrentTimeChange(mClock.elapsedRealtime(), mClock.uptimeMillis(), 7954 currentTimeMs); 7955 adjustStartClockTime(currentTimeMs); 7956 } 7957 return mStartClockTimeMs; 7958 } 7959 } 7960 7961 /** 7962 * Returns the monotonic time when the BatteryStats session started. 7963 */ getMonotonicStartTime()7964 public long getMonotonicStartTime() { 7965 return mMonotonicStartTime; 7966 } 7967 7968 /** 7969 * Returns the monotonic time when the BatteryStats session ended, or 7970 * {@link MonotonicClock#UNDEFINED} if the session is still ongoing. 7971 */ getMonotonicEndTime()7972 public long getMonotonicEndTime() { 7973 return mMonotonicEndTime; 7974 } 7975 getStartPlatformVersion()7976 @Override public String getStartPlatformVersion() { 7977 return mStartPlatformVersion; 7978 } 7979 getEndPlatformVersion()7980 @Override public String getEndPlatformVersion() { 7981 return mEndPlatformVersion; 7982 } 7983 getParcelVersion()7984 @Override public int getParcelVersion() { 7985 return VERSION; 7986 } 7987 getIsOnBattery()7988 @Override public boolean getIsOnBattery() { 7989 return mOnBattery; 7990 } 7991 getStatsStartRealtime()7992 @Override public long getStatsStartRealtime() { 7993 return mRealtimeStartUs; 7994 } 7995 getUidStats()7996 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 7997 return mUidStats; 7998 } 7999 resetIfNotNull(T t, boolean detachIfReset, long elapsedRealtimeUs)8000 private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset, 8001 long elapsedRealtimeUs) { 8002 if (t != null) { 8003 return t.reset(detachIfReset, elapsedRealtimeUs); 8004 } 8005 return true; 8006 } 8007 resetIfNotNull(T[] t, boolean detachIfReset, long elapsedRealtimeUs)8008 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset, 8009 long elapsedRealtimeUs) { 8010 if (t != null) { 8011 boolean ret = true; 8012 for (int i = 0; i < t.length; i++) { 8013 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 8014 } 8015 return ret; 8016 } 8017 return true; 8018 } 8019 resetIfNotNull(T[][] t, boolean detachIfReset, long elapsedRealtimeUs)8020 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset, 8021 long elapsedRealtimeUs) { 8022 if (t != null) { 8023 boolean ret = true; 8024 for (int i = 0; i < t.length; i++) { 8025 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 8026 } 8027 return ret; 8028 } 8029 return true; 8030 } 8031 resetIfNotNull(ControllerActivityCounterImpl counter, boolean detachIfReset, long elapsedRealtimeUs)8032 private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, 8033 boolean detachIfReset, long elapsedRealtimeUs) { 8034 if (counter != null) { 8035 counter.reset(detachIfReset, elapsedRealtimeUs); 8036 } 8037 return true; 8038 } 8039 detachIfNotNull(T t)8040 private static <T extends TimeBaseObs> void detachIfNotNull(T t) { 8041 if (t != null) { 8042 t.detach(); 8043 } 8044 } 8045 detachIfNotNull(T[] t)8046 private static <T extends TimeBaseObs> void detachIfNotNull(T[] t) { 8047 if (t != null) { 8048 for (int i = 0; i < t.length; i++) { 8049 detachIfNotNull(t[i]); 8050 } 8051 } 8052 } 8053 detachIfNotNull(T[][] t)8054 private static <T extends TimeBaseObs> void detachIfNotNull(T[][] t) { 8055 if (t != null) { 8056 for (int i = 0; i < t.length; i++) { 8057 detachIfNotNull(t[i]); 8058 } 8059 } 8060 } 8061 detachIfNotNull(ControllerActivityCounterImpl counter)8062 private static void detachIfNotNull(ControllerActivityCounterImpl counter) { 8063 if (counter != null) { 8064 counter.detach(); 8065 } 8066 } 8067 8068 /** 8069 * Accumulates stats for a specific binder transaction. 8070 */ 8071 @VisibleForTesting 8072 protected static class BinderCallStats { 8073 public Class<? extends Binder> binderClass; 8074 public int transactionCode; 8075 public String methodName; 8076 8077 public long callCount; 8078 public long recordedCallCount; 8079 public long recordedCpuTimeMicros; 8080 8081 8082 @Override hashCode()8083 public int hashCode() { 8084 return binderClass.hashCode() * 31 + transactionCode; 8085 } 8086 8087 @Override equals(Object obj)8088 public boolean equals(Object obj) { 8089 if (!(obj instanceof BinderCallStats)) { 8090 return false; 8091 } 8092 BinderCallStats bcsk = (BinderCallStats) obj; 8093 return binderClass.equals(bcsk.binderClass) && transactionCode == bcsk.transactionCode; 8094 } 8095 getClassName()8096 public String getClassName() { 8097 return binderClass.getName(); 8098 } 8099 getMethodName()8100 public String getMethodName() { 8101 return methodName; 8102 } 8103 8104 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) ensureMethodName(BinderTransactionNameResolver resolver)8105 public void ensureMethodName(BinderTransactionNameResolver resolver) { 8106 if (methodName == null) { 8107 methodName = resolver.getMethodName(binderClass, transactionCode); 8108 } 8109 } 8110 8111 @Override toString()8112 public String toString() { 8113 return "BinderCallStats{" 8114 + binderClass 8115 + " transaction=" + transactionCode 8116 + " callCount=" + callCount 8117 + " recordedCallCount=" + recordedCallCount 8118 + " recorderCpuTimeMicros=" + recordedCpuTimeMicros 8119 + "}"; 8120 } 8121 } 8122 8123 /** 8124 * The statistics associated with a particular uid. 8125 */ 8126 public static class Uid extends BatteryStats.Uid { 8127 /** 8128 * BatteryStatsImpl that we are associated with. 8129 */ 8130 protected BatteryStatsImpl mBsi; 8131 8132 final int mUid; 8133 8134 /** TimeBase for when uid is in background and device is on battery. */ 8135 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 8136 public final TimeBase mOnBatteryBackgroundTimeBase; 8137 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 8138 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 8139 8140 boolean mWifiRunning; 8141 StopwatchTimer mWifiRunningTimer; 8142 8143 boolean mFullWifiLockOut; 8144 StopwatchTimer mFullWifiLockTimer; 8145 8146 boolean mWifiScanStarted; 8147 DualTimer mWifiScanTimer; 8148 8149 static final int NO_BATCHED_SCAN_STARTED = -1; 8150 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8151 StopwatchTimer[] mWifiBatchedScanTimer; 8152 8153 int mWifiMulticastWakelockCount; 8154 StopwatchTimer mWifiMulticastTimer; 8155 8156 StopwatchTimer mAudioTurnedOnTimer; 8157 StopwatchTimer mVideoTurnedOnTimer; 8158 StopwatchTimer mFlashlightTurnedOnTimer; 8159 StopwatchTimer mCameraTurnedOnTimer; 8160 StopwatchTimer mForegroundActivityTimer; 8161 StopwatchTimer mForegroundServiceTimer; 8162 /** Total time spent by the uid holding any partial wakelocks. */ 8163 DualTimer mAggregatedPartialWakelockTimer; 8164 DualTimer mBluetoothScanTimer; 8165 DualTimer mBluetoothUnoptimizedScanTimer; 8166 Counter mBluetoothScanResultCounter; 8167 Counter mBluetoothScanResultBgCounter; 8168 8169 int mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 8170 StopwatchTimer[] mProcessStateTimer; 8171 8172 boolean mInForegroundService = false; 8173 8174 BatchTimer mVibratorOnTimer; 8175 8176 Counter[] mUserActivityCounters; 8177 8178 LongSamplingCounter[] mNetworkByteActivityCounters; 8179 LongSamplingCounter[] mNetworkPacketActivityCounters; 8180 TimeMultiStateCounter mMobileRadioActiveTime; 8181 LongSamplingCounter mMobileRadioActiveCount; 8182 8183 /** 8184 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 8185 */ 8186 private LongSamplingCounter mMobileRadioApWakeupCount; 8187 8188 /** 8189 * How many times this UID woke up the Application Processor due to a Wifi packet. 8190 */ 8191 private LongSamplingCounter mWifiRadioApWakeupCount; 8192 8193 /** 8194 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 8195 * Can be null if the UID has had no such activity. 8196 */ 8197 private ControllerActivityCounterImpl mWifiControllerActivity; 8198 8199 /** 8200 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 8201 * Can be null if the UID has had no such activity. 8202 */ 8203 private ControllerActivityCounterImpl mBluetoothControllerActivity; 8204 8205 /** 8206 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 8207 * Can be null if the UID has had no such activity. 8208 */ 8209 private ControllerActivityCounterImpl mModemControllerActivity; 8210 8211 /** 8212 * The CPU times we had at the last history details update. 8213 */ 8214 long mLastStepUserTimeMs; 8215 long mLastStepSystemTimeMs; 8216 long mCurStepUserTimeMs; 8217 long mCurStepSystemTimeMs; 8218 8219 LongSamplingCounter mUserCpuTime; 8220 LongSamplingCounter mSystemCpuTime; 8221 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 8222 TimeMultiStateCounter mCpuActiveTimeMs; 8223 8224 LongSamplingCounterArray mCpuFreqTimeMs; 8225 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 8226 LongSamplingCounterArray mCpuClusterTimesMs; 8227 8228 TimeInFreqMultiStateCounter mProcStateTimeMs; 8229 TimeInFreqMultiStateCounter mProcStateScreenOffTimeMs; 8230 8231 SparseArray<ChildUid> mChildUids; 8232 8233 /** 8234 * The statistics we have collected for this uid's wake locks. 8235 */ 8236 final OverflowArrayMap<Wakelock> mWakelockStats; 8237 8238 /** 8239 * The statistics we have collected for this uid's syncs. 8240 */ 8241 final OverflowArrayMap<DualTimer> mSyncStats; 8242 8243 /** 8244 * The statistics we have collected for this uid's jobs. 8245 */ 8246 final OverflowArrayMap<DualTimer> mJobStats; 8247 8248 /** 8249 * Count of the jobs that have completed and the reasons why they completed. 8250 */ 8251 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 8252 8253 /** 8254 * Count of app launch events that had associated deferred job counts or info about 8255 * last time a job was run. 8256 */ 8257 Counter mJobsDeferredEventCount; 8258 8259 /** 8260 * Count of deferred jobs that were pending when the app was launched or brought to 8261 * the foreground through a user interaction. 8262 */ 8263 Counter mJobsDeferredCount; 8264 8265 /** 8266 * Sum of time since the last time a job was run for this app before it was launched. 8267 */ 8268 LongSamplingCounter mJobsFreshnessTimeMs; 8269 8270 /** 8271 * Array of counts of instances where the time since the last job was run for the app 8272 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 8273 */ 8274 final Counter[] mJobsFreshnessBuckets; 8275 8276 /** 8277 * The statistics we have collected for this uid's sensor activations. 8278 */ 8279 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 8280 8281 /** 8282 * The statistics we have collected for this uid's processes. 8283 */ 8284 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 8285 8286 /** 8287 * The statistics we have collected for this uid's processes. 8288 */ 8289 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 8290 8291 /** 8292 * The transient wake stats we have collected for this uid's pids. 8293 */ 8294 final SparseArray<Pid> mPids = new SparseArray<>(); 8295 8296 /** 8297 * Grand total of system server binder calls made by this uid. 8298 */ 8299 private long mBinderCallCount; 8300 8301 /** 8302 * Detailed information about system server binder calls made by this uid. 8303 */ 8304 private final ArraySet<BinderCallStats> mBinderCallStats = new ArraySet<>(); 8305 8306 /** 8307 * EnergyConsumer consumption by this uid while on battery. 8308 * Its '<b>custom</b> power buckets' correspond to the 8309 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 8310 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 8311 * 8312 * Will be null if energy consumer data is completely unavailable (in which case 8313 * {@link #mGlobalEnergyConsumerStats} will also be null) or if the power usage by this uid 8314 * is 0 for every bucket. 8315 */ 8316 private EnergyConsumerStats mUidEnergyConsumerStats; 8317 8318 /** 8319 * Estimated total time spent by the system server handling requests from this uid. 8320 */ 8321 private long mSystemServiceTimeUs; 8322 8323 /** 8324 * Estimated proportion of system server binder call CPU cost for this uid. 8325 */ 8326 private double mProportionalSystemServiceUsage; 8327 Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs)8328 public Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs) { 8329 mBsi = bsi; 8330 mUid = uid; 8331 8332 /* Observer list of TimeBase object in Uid is short */ 8333 mOnBatteryBackgroundTimeBase = new TimeBase(false); 8334 mOnBatteryBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 8335 /* Observer list of TimeBase object in Uid is short */ 8336 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); 8337 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 8338 8339 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8340 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8341 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 8342 8343 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 8344 @Override public Wakelock instantiateObject() { 8345 return new Wakelock(mBsi, Uid.this); 8346 } 8347 }; 8348 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 8349 @Override public DualTimer instantiateObject() { 8350 return new DualTimer(mBsi.mClock, Uid.this, SYNC, null, 8351 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8352 } 8353 }; 8354 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 8355 @Override public DualTimer instantiateObject() { 8356 return new DualTimer(mBsi.mClock, Uid.this, JOB, null, 8357 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8358 } 8359 }; 8360 8361 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, this, WIFI_RUNNING, 8362 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 8363 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, this, FULL_WIFI_LOCK, 8364 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 8365 mWifiScanTimer = new DualTimer(mBsi.mClock, this, WIFI_SCAN, 8366 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8367 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 8368 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, this, WIFI_MULTICAST_ENABLED, 8369 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 8370 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 8371 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 8372 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 8373 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8374 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 8375 } 8376 8377 @GuardedBy("mBsi") 8378 @VisibleForTesting setProcessStateForTest(int procState, long elapsedTimeMs)8379 public void setProcessStateForTest(int procState, long elapsedTimeMs) { 8380 mProcessState = procState; 8381 getProcStateTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs); 8382 getProcStateScreenOffTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs); 8383 final int batteryConsumerProcessState = 8384 mapUidProcessStateToBatteryConsumerProcessState(procState); 8385 getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); 8386 getMobileRadioActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); 8387 final ControllerActivityCounterImpl wifiControllerActivity = 8388 getWifiControllerActivity(); 8389 if (wifiControllerActivity != null) { 8390 wifiControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs); 8391 } 8392 final ControllerActivityCounterImpl bluetoothControllerActivity = 8393 getBluetoothControllerActivity(); 8394 if (bluetoothControllerActivity != null) { 8395 bluetoothControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs); 8396 } 8397 final EnergyConsumerStats energyStats = 8398 getOrCreateEnergyConsumerStatsIfSupportedLocked(); 8399 if (energyStats != null) { 8400 energyStats.setState(batteryConsumerProcessState, elapsedTimeMs); 8401 } 8402 } 8403 8404 @Override getCpuFreqTimes(int which)8405 public long[] getCpuFreqTimes(int which) { 8406 return nullIfAllZeros(mCpuFreqTimeMs, which); 8407 } 8408 8409 @Override getScreenOffCpuFreqTimes(int which)8410 public long[] getScreenOffCpuFreqTimes(int which) { 8411 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 8412 } 8413 getCpuActiveTimeCounter()8414 private TimeMultiStateCounter getCpuActiveTimeCounter() { 8415 if (mCpuActiveTimeMs == null) { 8416 final long timestampMs = mBsi.mClock.elapsedRealtime(); 8417 mCpuActiveTimeMs = new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, 8418 BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 8419 mCpuActiveTimeMs.setState( 8420 mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 8421 timestampMs); 8422 } 8423 return mCpuActiveTimeMs; 8424 } 8425 8426 @Override getCpuActiveTime()8427 public long getCpuActiveTime() { 8428 if (mCpuActiveTimeMs == null) { 8429 return 0; 8430 } 8431 8432 long activeTime = 0; 8433 for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { 8434 activeTime += mCpuActiveTimeMs.getCountForProcessState(procState); 8435 } 8436 return activeTime; 8437 } 8438 8439 @Override getCpuActiveTime(int procState)8440 public long getCpuActiveTime(int procState) { 8441 if (mCpuActiveTimeMs == null 8442 || procState < 0 || procState >= BatteryConsumer.PROCESS_STATE_COUNT) { 8443 return 0; 8444 } 8445 8446 return mCpuActiveTimeMs.getCountForProcessState(procState); 8447 } 8448 8449 @Override getCpuClusterTimes()8450 public long[] getCpuClusterTimes() { 8451 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 8452 } 8453 8454 @GuardedBy("mBsi") 8455 @Override getCpuFreqTimes(long[] timesInFreqMs, int procState)8456 public boolean getCpuFreqTimes(long[] timesInFreqMs, int procState) { 8457 if (procState < 0 || procState >= NUM_PROCESS_STATE) { 8458 return false; 8459 } 8460 if (mProcStateTimeMs == null) { 8461 return false; 8462 } 8463 if (!mBsi.mPerProcStateCpuTimesAvailable) { 8464 mProcStateTimeMs = null; 8465 return false; 8466 } 8467 return mProcStateTimeMs.getCountsLocked(timesInFreqMs, procState); 8468 } 8469 8470 @GuardedBy("mBsi") 8471 @Override getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState)8472 public boolean getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState) { 8473 if (procState < 0 || procState >= NUM_PROCESS_STATE) { 8474 return false; 8475 } 8476 if (mProcStateScreenOffTimeMs == null) { 8477 return false; 8478 } 8479 if (!mBsi.mPerProcStateCpuTimesAvailable) { 8480 mProcStateScreenOffTimeMs = null; 8481 return false; 8482 } 8483 return mProcStateScreenOffTimeMs.getCountsLocked(timesInFreqMs, procState); 8484 } 8485 getBinderCallCount()8486 public long getBinderCallCount() { 8487 return mBinderCallCount; 8488 } 8489 8490 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) getBinderCallStats()8491 public ArraySet<BinderCallStats> getBinderCallStats() { 8492 return mBinderCallStats; 8493 } 8494 8495 @Override getProportionalSystemServiceUsage()8496 public double getProportionalSystemServiceUsage() { 8497 return mProportionalSystemServiceUsage; 8498 } 8499 8500 /** 8501 * Adds isolated UID to the list of children. 8502 */ addIsolatedUid(int isolatedUid)8503 public void addIsolatedUid(int isolatedUid) { 8504 if (mChildUids == null) { 8505 mChildUids = new SparseArray<>(); 8506 } else if (mChildUids.indexOfKey(isolatedUid) >= 0) { 8507 return; 8508 } 8509 mChildUids.put(isolatedUid, new ChildUid()); 8510 } 8511 8512 /** 8513 * Removes isolated UID from the list of children. 8514 */ removeIsolatedUid(int isolatedUid)8515 public void removeIsolatedUid(int isolatedUid) { 8516 final int idx = mChildUids == null ? -1 : mChildUids.indexOfKey(isolatedUid); 8517 if (idx < 0) { 8518 return; 8519 } 8520 mChildUids.remove(idx); 8521 } 8522 8523 @GuardedBy("mBsi") getChildUid(int childUid)8524 ChildUid getChildUid(int childUid) { 8525 return mChildUids == null ? null : mChildUids.get(childUid); 8526 } 8527 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)8528 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 8529 if (cpuTimesMs == null) { 8530 return null; 8531 } 8532 final long[] counts = cpuTimesMs.getCountsLocked(which); 8533 if (counts == null) { 8534 return null; 8535 } 8536 // Return counts only if at least one of the elements is non-zero. 8537 for (int i = counts.length - 1; i >= 0; --i) { 8538 if (counts[i] != 0) { 8539 return counts; 8540 } 8541 } 8542 return null; 8543 } 8544 8545 @GuardedBy("mBsi") ensureMultiStateCounters(long timestampMs)8546 private void ensureMultiStateCounters(long timestampMs) { 8547 if (mBsi.mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 8548 throw new IllegalStateException("Multi-state counters used in streamlined mode"); 8549 } 8550 8551 if (mProcStateTimeMs == null) { 8552 mProcStateTimeMs = 8553 new TimeInFreqMultiStateCounter(mBsi.mOnBatteryTimeBase, 8554 PROC_STATE_TIME_COUNTER_STATE_COUNT, 8555 mBsi.mCpuScalingPolicies.getScalingStepCount(), 8556 timestampMs); 8557 } 8558 if (mProcStateScreenOffTimeMs == null) { 8559 mProcStateScreenOffTimeMs = 8560 new TimeInFreqMultiStateCounter(mBsi.mOnBatteryScreenOffTimeBase, 8561 PROC_STATE_TIME_COUNTER_STATE_COUNT, 8562 mBsi.mCpuScalingPolicies.getScalingStepCount(), 8563 timestampMs); 8564 } 8565 } 8566 8567 @GuardedBy("mBsi") getProcStateTimeCounter(long timestampMs)8568 private TimeInFreqMultiStateCounter getProcStateTimeCounter(long timestampMs) { 8569 ensureMultiStateCounters(timestampMs); 8570 return mProcStateTimeMs; 8571 } 8572 8573 @GuardedBy("mBsi") getProcStateScreenOffTimeCounter(long timestampMs)8574 private TimeInFreqMultiStateCounter getProcStateScreenOffTimeCounter(long timestampMs) { 8575 ensureMultiStateCounters(timestampMs); 8576 return mProcStateScreenOffTimeMs; 8577 } 8578 8579 @Override getAggregatedPartialWakelockTimer()8580 public Timer getAggregatedPartialWakelockTimer() { 8581 return mAggregatedPartialWakelockTimer; 8582 } 8583 8584 @Override getWakelockStats()8585 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 8586 return mWakelockStats.getMap(); 8587 } 8588 8589 @Override getMulticastWakelockStats()8590 public Timer getMulticastWakelockStats() { 8591 return mWifiMulticastTimer; 8592 } 8593 8594 @Override getSyncStats()8595 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 8596 return mSyncStats.getMap(); 8597 } 8598 8599 @Override getJobStats()8600 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 8601 return mJobStats.getMap(); 8602 } 8603 8604 @Override getJobCompletionStats()8605 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 8606 return mJobCompletions; 8607 } 8608 8609 @Override getSensorStats()8610 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 8611 return mSensorStats; 8612 } 8613 8614 @Override getProcessStats()8615 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 8616 return mProcessStats; 8617 } 8618 8619 @Override getPackageStats()8620 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 8621 return mPackageStats; 8622 } 8623 8624 @Override getUid()8625 public int getUid() { 8626 return mUid; 8627 } 8628 8629 @Override noteWifiRunningLocked(long elapsedRealtimeMs)8630 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 8631 if (!mWifiRunning) { 8632 mWifiRunning = true; 8633 if (mWifiRunningTimer == null) { 8634 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, Uid.this, WIFI_RUNNING, 8635 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 8636 } 8637 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 8638 } 8639 } 8640 8641 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)8642 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 8643 if (mWifiRunning) { 8644 mWifiRunning = false; 8645 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 8646 } 8647 } 8648 8649 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)8650 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 8651 if (!mFullWifiLockOut) { 8652 mFullWifiLockOut = true; 8653 if (mFullWifiLockTimer == null) { 8654 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, Uid.this, FULL_WIFI_LOCK, 8655 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 8656 } 8657 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 8658 } 8659 } 8660 8661 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)8662 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 8663 if (mFullWifiLockOut) { 8664 mFullWifiLockOut = false; 8665 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 8666 } 8667 } 8668 8669 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)8670 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 8671 if (!mWifiScanStarted) { 8672 mWifiScanStarted = true; 8673 if (mWifiScanTimer == null) { 8674 mWifiScanTimer = new DualTimer(mBsi.mClock, Uid.this, WIFI_SCAN, 8675 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 8676 mOnBatteryBackgroundTimeBase); 8677 } 8678 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 8679 } 8680 } 8681 8682 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)8683 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 8684 if (mWifiScanStarted) { 8685 mWifiScanStarted = false; 8686 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 8687 } 8688 } 8689 8690 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)8691 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 8692 int bin = 0; 8693 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 8694 csph = csph >> 3; 8695 bin++; 8696 } 8697 8698 if (mWifiBatchedScanBinStarted == bin) return; 8699 8700 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 8701 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 8702 stopRunningLocked(elapsedRealtimeMs); 8703 } 8704 mWifiBatchedScanBinStarted = bin; 8705 if (mWifiBatchedScanTimer[bin] == null) { 8706 makeWifiBatchedScanBin(bin, null); 8707 } 8708 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 8709 } 8710 8711 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)8712 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 8713 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 8714 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 8715 stopRunningLocked(elapsedRealtimeMs); 8716 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8717 } 8718 } 8719 8720 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)8721 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 8722 if (mWifiMulticastWakelockCount == 0) { 8723 if (mWifiMulticastTimer == null) { 8724 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 8725 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 8726 } 8727 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 8728 } 8729 mWifiMulticastWakelockCount++; 8730 } 8731 8732 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)8733 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 8734 if (mWifiMulticastWakelockCount == 0) { 8735 return; 8736 } 8737 8738 mWifiMulticastWakelockCount--; 8739 if (mWifiMulticastWakelockCount == 0) { 8740 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 8741 } 8742 } 8743 8744 @Override getWifiControllerActivity()8745 public ControllerActivityCounterImpl getWifiControllerActivity() { 8746 return mWifiControllerActivity; 8747 } 8748 8749 @Override getBluetoothControllerActivity()8750 public ControllerActivityCounterImpl getBluetoothControllerActivity() { 8751 return mBluetoothControllerActivity; 8752 } 8753 8754 @Override getModemControllerActivity()8755 public ControllerActivityCounter getModemControllerActivity() { 8756 return mModemControllerActivity; 8757 } 8758 getOrCreateWifiControllerActivityLocked()8759 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 8760 if (mWifiControllerActivity == null) { 8761 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8762 mBsi.mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 8763 } 8764 return mWifiControllerActivity; 8765 } 8766 getOrCreateBluetoothControllerActivityLocked()8767 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 8768 if (mBluetoothControllerActivity == null) { 8769 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8770 mBsi.mOnBatteryTimeBase, NUM_BT_TX_LEVELS); 8771 } 8772 return mBluetoothControllerActivity; 8773 } 8774 getOrCreateModemControllerActivityLocked()8775 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 8776 if (mModemControllerActivity == null) { 8777 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8778 mBsi.mOnBatteryTimeBase, mBsi.MODEM_TX_POWER_LEVEL_COUNT); 8779 } 8780 return mModemControllerActivity; 8781 } 8782 8783 @GuardedBy("mBsi") getOrCreateEnergyConsumerStatsLocked()8784 private EnergyConsumerStats getOrCreateEnergyConsumerStatsLocked() { 8785 if (mUidEnergyConsumerStats == null) { 8786 mUidEnergyConsumerStats = new EnergyConsumerStats(mBsi.mEnergyConsumerStatsConfig); 8787 } 8788 return mUidEnergyConsumerStats; 8789 } 8790 8791 @GuardedBy("mBsi") getOrCreateEnergyConsumerStatsIfSupportedLocked()8792 private EnergyConsumerStats getOrCreateEnergyConsumerStatsIfSupportedLocked() { 8793 if (mUidEnergyConsumerStats == null && mBsi.mEnergyConsumerStatsConfig != null) { 8794 mUidEnergyConsumerStats = new EnergyConsumerStats(mBsi.mEnergyConsumerStatsConfig); 8795 } 8796 return mUidEnergyConsumerStats; 8797 } 8798 8799 /** Adds the given charge to the given standard power bucket for this uid. */ 8800 @GuardedBy("mBsi") addChargeToStandardBucketLocked(long chargeDeltaUC, @StandardPowerBucket int powerBucket, long timestampMs)8801 private void addChargeToStandardBucketLocked(long chargeDeltaUC, 8802 @StandardPowerBucket int powerBucket, long timestampMs) { 8803 final EnergyConsumerStats energyConsumerStats = 8804 getOrCreateEnergyConsumerStatsLocked(); 8805 energyConsumerStats.updateStandardBucket(powerBucket, chargeDeltaUC, timestampMs); 8806 } 8807 8808 /** Adds the given charge to the given custom power bucket for this uid. */ 8809 @GuardedBy("mBsi") addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket)8810 private void addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket) { 8811 getOrCreateEnergyConsumerStatsLocked().updateCustomBucket(powerBucket, chargeDeltaUC, 8812 mBsi.mClock.elapsedRealtime()); 8813 } 8814 8815 /** 8816 * Returns the battery consumption (in microcoulomb) of this uid for a standard power bucket 8817 * of interest. 8818 * @param bucket standard power bucket of interest 8819 * @return consumption (in microcolombs) used by this uid for this power bucket 8820 */ 8821 @GuardedBy("mBsi") getEnergyConsumptionUC(@tandardPowerBucket int bucket)8822 public long getEnergyConsumptionUC(@StandardPowerBucket int bucket) { 8823 if (mBsi.mGlobalEnergyConsumerStats == null 8824 || !mBsi.mGlobalEnergyConsumerStats.isStandardBucketSupported(bucket)) { 8825 return POWER_DATA_UNAVAILABLE; 8826 } 8827 if (mUidEnergyConsumerStats == null) { 8828 return 0L; // It is supported, but was never filled, so it must be 0 8829 } 8830 return mUidEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket); 8831 } 8832 8833 /** 8834 * Returns the battery consumption (in microcoulombs) of this uid for a standard power 8835 * bucket and a process state, such as Uid.PROCESS_STATE_TOP. 8836 */ 8837 @GuardedBy("mBsi") getEnergyConsumptionUC(@tandardPowerBucket int bucket, int processState)8838 public long getEnergyConsumptionUC(@StandardPowerBucket int bucket, 8839 int processState) { 8840 if (mBsi.mGlobalEnergyConsumerStats == null 8841 || !mBsi.mGlobalEnergyConsumerStats.isStandardBucketSupported(bucket)) { 8842 return POWER_DATA_UNAVAILABLE; 8843 } 8844 if (mUidEnergyConsumerStats == null) { 8845 return 0L; // It is supported, but was never filled, so it must be 0 8846 } 8847 return mUidEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket, processState); 8848 } 8849 8850 @GuardedBy("mBsi") 8851 @Override getCustomEnergyConsumerBatteryConsumptionUC()8852 public long[] getCustomEnergyConsumerBatteryConsumptionUC() { 8853 if (mBsi.mGlobalEnergyConsumerStats == null) { 8854 return null; 8855 } 8856 if (mUidEnergyConsumerStats == null) { 8857 // Custom buckets may exist. But all values for this uid are 0 so we report all 0s. 8858 return new long[mBsi.mGlobalEnergyConsumerStats.getNumberCustomPowerBuckets()]; 8859 } 8860 return mUidEnergyConsumerStats.getAccumulatedCustomBucketCharges(); 8861 } 8862 8863 @GuardedBy("mBsi") 8864 @Override getBluetoothEnergyConsumptionUC()8865 public long getBluetoothEnergyConsumptionUC() { 8866 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH); 8867 } 8868 8869 @GuardedBy("mBsi") 8870 @Override getBluetoothEnergyConsumptionUC( @atteryConsumer.ProcessState int processState)8871 public long getBluetoothEnergyConsumptionUC( 8872 @BatteryConsumer.ProcessState int processState) { 8873 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 8874 processState); 8875 } 8876 8877 @GuardedBy("mBsi") 8878 @Override getCpuEnergyConsumptionUC()8879 public long getCpuEnergyConsumptionUC() { 8880 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU); 8881 } 8882 8883 @GuardedBy("mBsi") 8884 @Override getCpuEnergyConsumptionUC( @atteryConsumer.ProcessState int processState)8885 public long getCpuEnergyConsumptionUC( 8886 @BatteryConsumer.ProcessState int processState) { 8887 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU, 8888 processState); 8889 } 8890 8891 @GuardedBy("mBsi") 8892 @Override getGnssEnergyConsumptionUC()8893 public long getGnssEnergyConsumptionUC() { 8894 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_GNSS); 8895 } 8896 8897 @GuardedBy("mBsi") 8898 @Override getMobileRadioEnergyConsumptionUC()8899 public long getMobileRadioEnergyConsumptionUC() { 8900 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 8901 } 8902 8903 @GuardedBy("mBsi") 8904 @Override getMobileRadioEnergyConsumptionUC(int processState)8905 public long getMobileRadioEnergyConsumptionUC(int processState) { 8906 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 8907 processState); 8908 } 8909 8910 @GuardedBy("mBsi") 8911 @Override getScreenOnEnergyConsumptionUC()8912 public long getScreenOnEnergyConsumptionUC() { 8913 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON); 8914 } 8915 8916 @GuardedBy("mBsi") 8917 @Override getWifiEnergyConsumptionUC()8918 public long getWifiEnergyConsumptionUC() { 8919 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI); 8920 } 8921 8922 @GuardedBy("mBsi") 8923 @Override getWifiEnergyConsumptionUC(int processState)8924 public long getWifiEnergyConsumptionUC(int processState) { 8925 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI, 8926 processState); 8927 } 8928 8929 @GuardedBy("mBsi") 8930 @Override getCameraEnergyConsumptionUC()8931 public long getCameraEnergyConsumptionUC() { 8932 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CAMERA); 8933 } 8934 8935 /** 8936 * Gets the minimum of the uid's foreground activity time and its PROCESS_STATE_TOP time 8937 * since last marked. Also sets the mark time for both these timers. 8938 * 8939 * @see CpuPowerCalculator 8940 * 8941 * @param doCalc if true, then calculate the minimum; else don't bother and return 0. Either 8942 * way, the mark is set. 8943 */ markProcessForegroundTimeUs(long elapsedRealtimeMs, boolean doCalc)8944 private long markProcessForegroundTimeUs(long elapsedRealtimeMs, 8945 boolean doCalc) { 8946 long fgTimeUs = 0; 8947 final StopwatchTimer fgTimer = mForegroundActivityTimer; 8948 if (fgTimer != null) { 8949 if (doCalc) fgTimeUs = fgTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8950 fgTimer.setMark(elapsedRealtimeMs); 8951 } 8952 8953 long topTimeUs = 0; 8954 final StopwatchTimer topTimer = mProcessStateTimer[PROCESS_STATE_TOP]; 8955 if (topTimer != null) { 8956 if (doCalc) topTimeUs = topTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8957 topTimer.setMark(elapsedRealtimeMs); 8958 } 8959 8960 // Return the min of the two 8961 return (topTimeUs < fgTimeUs) ? topTimeUs : fgTimeUs; 8962 } 8963 8964 8965 /** 8966 * Gets the uid's time spent using the GNSS since last marked. Also sets the mark time for 8967 * the GNSS timer. 8968 */ markGnssTimeUs(long elapsedRealtimeMs)8969 private long markGnssTimeUs(long elapsedRealtimeMs) { 8970 final Sensor sensor = mSensorStats.get(Sensor.GPS); 8971 if (sensor == null) { 8972 return 0; 8973 } 8974 8975 final StopwatchTimer timer = sensor.mTimer; 8976 if (timer == null) { 8977 return 0; 8978 } 8979 8980 final long gnssTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8981 timer.setMark(elapsedRealtimeMs); 8982 return gnssTimeUs; 8983 } 8984 8985 /** 8986 * Gets the uid's time spent using the camera since last marked. Also sets the mark time for 8987 * the camera timer. 8988 */ markCameraTimeUs(long elapsedRealtimeMs)8989 private long markCameraTimeUs(long elapsedRealtimeMs) { 8990 final StopwatchTimer timer = mCameraTurnedOnTimer; 8991 if (timer == null) { 8992 return 0; 8993 } 8994 final long cameraTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8995 timer.setMark(elapsedRealtimeMs); 8996 return cameraTimeUs; 8997 } 8998 createAudioTurnedOnTimerLocked()8999 public StopwatchTimer createAudioTurnedOnTimerLocked() { 9000 if (mAudioTurnedOnTimer == null) { 9001 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, AUDIO_TURNED_ON, 9002 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9003 } 9004 return mAudioTurnedOnTimer; 9005 } 9006 noteAudioTurnedOnLocked(long elapsedRealtimeMs)9007 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 9008 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9009 } 9010 noteAudioTurnedOffLocked(long elapsedRealtimeMs)9011 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 9012 if (mAudioTurnedOnTimer != null) { 9013 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9014 } 9015 } 9016 noteResetAudioLocked(long elapsedRealtimeMs)9017 public void noteResetAudioLocked(long elapsedRealtimeMs) { 9018 if (mAudioTurnedOnTimer != null) { 9019 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9020 } 9021 } 9022 createVideoTurnedOnTimerLocked()9023 public StopwatchTimer createVideoTurnedOnTimerLocked() { 9024 if (mVideoTurnedOnTimer == null) { 9025 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, VIDEO_TURNED_ON, 9026 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9027 } 9028 return mVideoTurnedOnTimer; 9029 } 9030 noteVideoTurnedOnLocked(long elapsedRealtimeMs)9031 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 9032 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9033 } 9034 noteVideoTurnedOffLocked(long elapsedRealtimeMs)9035 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 9036 if (mVideoTurnedOnTimer != null) { 9037 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9038 } 9039 } 9040 noteResetVideoLocked(long elapsedRealtimeMs)9041 public void noteResetVideoLocked(long elapsedRealtimeMs) { 9042 if (mVideoTurnedOnTimer != null) { 9043 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9044 } 9045 } 9046 createFlashlightTurnedOnTimerLocked()9047 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 9048 if (mFlashlightTurnedOnTimer == null) { 9049 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9050 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9051 } 9052 return mFlashlightTurnedOnTimer; 9053 } 9054 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)9055 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 9056 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9057 } 9058 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)9059 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 9060 if (mFlashlightTurnedOnTimer != null) { 9061 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9062 } 9063 } 9064 noteResetFlashlightLocked(long elapsedRealtimeMs)9065 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 9066 if (mFlashlightTurnedOnTimer != null) { 9067 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9068 } 9069 } 9070 createCameraTurnedOnTimerLocked()9071 public StopwatchTimer createCameraTurnedOnTimerLocked() { 9072 if (mCameraTurnedOnTimer == null) { 9073 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, CAMERA_TURNED_ON, 9074 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9075 } 9076 return mCameraTurnedOnTimer; 9077 } 9078 noteCameraTurnedOnLocked(long elapsedRealtimeMs)9079 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 9080 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9081 } 9082 noteCameraTurnedOffLocked(long elapsedRealtimeMs)9083 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 9084 if (mCameraTurnedOnTimer != null) { 9085 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9086 } 9087 } 9088 noteResetCameraLocked(long elapsedRealtimeMs)9089 public void noteResetCameraLocked(long elapsedRealtimeMs) { 9090 if (mCameraTurnedOnTimer != null) { 9091 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9092 } 9093 } 9094 createForegroundActivityTimerLocked()9095 public StopwatchTimer createForegroundActivityTimerLocked() { 9096 if (mForegroundActivityTimer == null) { 9097 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9098 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 9099 } 9100 return mForegroundActivityTimer; 9101 } 9102 createForegroundServiceTimerLocked()9103 public StopwatchTimer createForegroundServiceTimerLocked() { 9104 if (mForegroundServiceTimer == null) { 9105 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9106 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 9107 } 9108 return mForegroundServiceTimer; 9109 } 9110 createAggregatedPartialWakelockTimerLocked()9111 public DualTimer createAggregatedPartialWakelockTimerLocked() { 9112 if (mAggregatedPartialWakelockTimer == null) { 9113 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClock, this, 9114 AGGREGATED_WAKE_TYPE_PARTIAL, null, 9115 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 9116 } 9117 return mAggregatedPartialWakelockTimer; 9118 } 9119 createBluetoothScanTimerLocked()9120 public DualTimer createBluetoothScanTimerLocked() { 9121 if (mBluetoothScanTimer == null) { 9122 mBluetoothScanTimer = new DualTimer(mBsi.mClock, Uid.this, BLUETOOTH_SCAN_ON, 9123 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 9124 mOnBatteryBackgroundTimeBase); 9125 } 9126 return mBluetoothScanTimer; 9127 } 9128 createBluetoothUnoptimizedScanTimerLocked()9129 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 9130 if (mBluetoothUnoptimizedScanTimer == null) { 9131 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClock, Uid.this, 9132 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 9133 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 9134 } 9135 return mBluetoothUnoptimizedScanTimer; 9136 } 9137 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)9138 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 9139 boolean isUnoptimized) { 9140 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 9141 if (isUnoptimized) { 9142 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 9143 } 9144 } 9145 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)9146 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 9147 if (mBluetoothScanTimer != null) { 9148 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 9149 } 9150 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 9151 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 9152 } 9153 } 9154 noteResetBluetoothScanLocked(long elapsedRealtimeMs)9155 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 9156 if (mBluetoothScanTimer != null) { 9157 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 9158 } 9159 if (mBluetoothUnoptimizedScanTimer != null) { 9160 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 9161 } 9162 } 9163 createBluetoothScanResultCounterLocked()9164 public Counter createBluetoothScanResultCounterLocked() { 9165 if (mBluetoothScanResultCounter == null) { 9166 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 9167 } 9168 return mBluetoothScanResultCounter; 9169 } 9170 createBluetoothScanResultBgCounterLocked()9171 public Counter createBluetoothScanResultBgCounterLocked() { 9172 if (mBluetoothScanResultBgCounter == null) { 9173 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 9174 } 9175 return mBluetoothScanResultBgCounter; 9176 } 9177 noteBluetoothScanResultsLocked(int numNewResults)9178 public void noteBluetoothScanResultsLocked(int numNewResults) { 9179 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 9180 // Uses background timebase, so the count will only be incremented if uid in background. 9181 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 9182 } 9183 9184 @Override noteActivityResumedLocked(long elapsedRealtimeMs)9185 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 9186 // We always start, since we want multiple foreground PIDs to nest 9187 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 9188 } 9189 9190 @Override noteActivityPausedLocked(long elapsedRealtimeMs)9191 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 9192 if (mForegroundActivityTimer != null) { 9193 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 9194 } 9195 } 9196 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)9197 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 9198 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 9199 } 9200 noteForegroundServicePausedLocked(long elapsedRealtimeMs)9201 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 9202 if (mForegroundServiceTimer != null) { 9203 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 9204 } 9205 } 9206 createVibratorOnTimerLocked()9207 public BatchTimer createVibratorOnTimerLocked() { 9208 if (mVibratorOnTimer == null) { 9209 mVibratorOnTimer = new BatchTimer(mBsi.mClock, Uid.this, VIBRATOR_ON, 9210 mBsi.mOnBatteryTimeBase); 9211 } 9212 return mVibratorOnTimer; 9213 } 9214 noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs)9215 public void noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs) { 9216 createVibratorOnTimerLocked().addDuration(durationMillis, elapsedRealtimeMs); 9217 } 9218 noteVibratorOffLocked(long elapsedRealtimeMs)9219 public void noteVibratorOffLocked(long elapsedRealtimeMs) { 9220 if (mVibratorOnTimer != null) { 9221 mVibratorOnTimer.abortLastDuration(elapsedRealtimeMs); 9222 } 9223 } 9224 9225 @Override getWifiRunningTime(long elapsedRealtimeUs, int which)9226 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 9227 if (mWifiRunningTimer == null) { 9228 return 0; 9229 } 9230 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9231 } 9232 9233 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)9234 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 9235 if (mFullWifiLockTimer == null) { 9236 return 0; 9237 } 9238 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9239 } 9240 9241 @Override getWifiScanTime(long elapsedRealtimeUs, int which)9242 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 9243 if (mWifiScanTimer == null) { 9244 return 0; 9245 } 9246 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9247 } 9248 9249 @Override getWifiScanCount(int which)9250 public int getWifiScanCount(int which) { 9251 if (mWifiScanTimer == null) { 9252 return 0; 9253 } 9254 return mWifiScanTimer.getCountLocked(which); 9255 } 9256 9257 @Override getWifiScanTimer()9258 public Timer getWifiScanTimer() { 9259 return mWifiScanTimer; 9260 } 9261 9262 @Override getWifiScanBackgroundCount(int which)9263 public int getWifiScanBackgroundCount(int which) { 9264 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 9265 return 0; 9266 } 9267 return mWifiScanTimer.getSubTimer().getCountLocked(which); 9268 } 9269 9270 @Override getWifiScanActualTime(final long elapsedRealtimeUs)9271 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 9272 if (mWifiScanTimer == null) { 9273 return 0; 9274 } 9275 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 9276 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 9277 } 9278 9279 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)9280 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 9281 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 9282 return 0; 9283 } 9284 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 9285 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 9286 } 9287 9288 @Override getWifiScanBackgroundTimer()9289 public Timer getWifiScanBackgroundTimer() { 9290 if (mWifiScanTimer == null) { 9291 return null; 9292 } 9293 return mWifiScanTimer.getSubTimer(); 9294 } 9295 9296 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)9297 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 9298 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 9299 if (mWifiBatchedScanTimer[csphBin] == null) { 9300 return 0; 9301 } 9302 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 9303 } 9304 9305 @Override getWifiBatchedScanCount(int csphBin, int which)9306 public int getWifiBatchedScanCount(int csphBin, int which) { 9307 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 9308 if (mWifiBatchedScanTimer[csphBin] == null) { 9309 return 0; 9310 } 9311 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 9312 } 9313 9314 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)9315 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 9316 if (mWifiMulticastTimer == null) { 9317 return 0; 9318 } 9319 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9320 } 9321 9322 @Override getAudioTurnedOnTimer()9323 public Timer getAudioTurnedOnTimer() { 9324 return mAudioTurnedOnTimer; 9325 } 9326 9327 @Override getVideoTurnedOnTimer()9328 public Timer getVideoTurnedOnTimer() { 9329 return mVideoTurnedOnTimer; 9330 } 9331 9332 @Override getFlashlightTurnedOnTimer()9333 public Timer getFlashlightTurnedOnTimer() { 9334 return mFlashlightTurnedOnTimer; 9335 } 9336 9337 @Override getCameraTurnedOnTimer()9338 public Timer getCameraTurnedOnTimer() { 9339 return mCameraTurnedOnTimer; 9340 } 9341 9342 @Override getForegroundActivityTimer()9343 public Timer getForegroundActivityTimer() { 9344 return mForegroundActivityTimer; 9345 } 9346 9347 @Override getForegroundServiceTimer()9348 public Timer getForegroundServiceTimer() { 9349 return mForegroundServiceTimer; 9350 } 9351 9352 @Override getBluetoothScanTimer()9353 public Timer getBluetoothScanTimer() { 9354 return mBluetoothScanTimer; 9355 } 9356 9357 @Override getBluetoothScanBackgroundTimer()9358 public Timer getBluetoothScanBackgroundTimer() { 9359 if (mBluetoothScanTimer == null) { 9360 return null; 9361 } 9362 return mBluetoothScanTimer.getSubTimer(); 9363 } 9364 9365 @Override getBluetoothUnoptimizedScanTimer()9366 public Timer getBluetoothUnoptimizedScanTimer() { 9367 return mBluetoothUnoptimizedScanTimer; 9368 } 9369 9370 @Override getBluetoothUnoptimizedScanBackgroundTimer()9371 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 9372 if (mBluetoothUnoptimizedScanTimer == null) { 9373 return null; 9374 } 9375 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 9376 } 9377 9378 @Override getBluetoothScanResultCounter()9379 public Counter getBluetoothScanResultCounter() { 9380 return mBluetoothScanResultCounter; 9381 } 9382 9383 @Override getBluetoothScanResultBgCounter()9384 public Counter getBluetoothScanResultBgCounter() { 9385 return mBluetoothScanResultBgCounter; 9386 } 9387 makeProcessState(int i, Parcel in)9388 void makeProcessState(int i, Parcel in) { 9389 if (i < 0 || i >= NUM_PROCESS_STATE) return; 9390 9391 detachIfNotNull(mProcessStateTimer[i]); 9392 if (in == null) { 9393 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClock, this, PROCESS_STATE, null, 9394 mBsi.mOnBatteryTimeBase); 9395 } else { 9396 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClock, this, PROCESS_STATE, null, 9397 mBsi.mOnBatteryTimeBase, in); 9398 } 9399 } 9400 9401 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)9402 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 9403 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 9404 if (mProcessStateTimer[state] == null) { 9405 return 0; 9406 } 9407 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 9408 } 9409 9410 @Override getProcessStateTimer(int state)9411 public Timer getProcessStateTimer(int state) { 9412 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 9413 return mProcessStateTimer[state]; 9414 } 9415 9416 @Override getVibratorOnTimer()9417 public Timer getVibratorOnTimer() { 9418 return mVibratorOnTimer; 9419 } 9420 9421 @Override noteUserActivityLocked(@owerManager.UserActivityEvent int event)9422 public void noteUserActivityLocked(@PowerManager.UserActivityEvent int event) { 9423 if (mUserActivityCounters == null) { 9424 initUserActivityLocked(); 9425 } 9426 if (event >= 0 && event < NUM_USER_ACTIVITY_TYPES) { 9427 mUserActivityCounters[event].stepAtomic(); 9428 } else { 9429 Slog.w(TAG, "Unknown user activity type " + event + " was specified.", 9430 new Throwable()); 9431 } 9432 } 9433 9434 @Override hasUserActivity()9435 public boolean hasUserActivity() { 9436 return mUserActivityCounters != null; 9437 } 9438 9439 @Override getUserActivityCount(int type, int which)9440 public int getUserActivityCount(int type, int which) { 9441 if (mUserActivityCounters == null) { 9442 return 0; 9443 } 9444 return mUserActivityCounters[type].getCountLocked(which); 9445 } 9446 makeWifiBatchedScanBin(int i, Parcel in)9447 void makeWifiBatchedScanBin(int i, Parcel in) { 9448 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 9449 9450 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 9451 if (collected == null) { 9452 collected = new ArrayList<StopwatchTimer>(); 9453 mBsi.mWifiBatchedScanTimers.put(i, collected); 9454 } 9455 detachIfNotNull(mWifiBatchedScanTimer[i]); 9456 if (in == null) { 9457 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClock, this, WIFI_BATCHED_SCAN, 9458 collected, mBsi.mOnBatteryTimeBase); 9459 } else { 9460 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClock, this, WIFI_BATCHED_SCAN, 9461 collected, mBsi.mOnBatteryTimeBase, in); 9462 } 9463 } 9464 9465 initUserActivityLocked()9466 void initUserActivityLocked() { 9467 detachIfNotNull(mUserActivityCounters); 9468 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 9469 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 9470 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 9471 } 9472 } 9473 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)9474 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 9475 ensureNetworkActivityLocked(); 9476 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 9477 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 9478 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 9479 } else { 9480 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 9481 new Throwable()); 9482 } 9483 } 9484 noteMobileRadioActiveTimeLocked(long batteryUptimeDeltaUs, long elapsedTimeMs)9485 void noteMobileRadioActiveTimeLocked(long batteryUptimeDeltaUs, long elapsedTimeMs) { 9486 ensureNetworkActivityLocked(); 9487 getMobileRadioActiveTimeCounter().increment(batteryUptimeDeltaUs, elapsedTimeMs); 9488 mMobileRadioActiveCount.addCountLocked(1); 9489 } 9490 getMobileRadioActiveTimeCounter()9491 private TimeMultiStateCounter getMobileRadioActiveTimeCounter() { 9492 if (mMobileRadioActiveTime == null) { 9493 final long timestampMs = mBsi.mClock.elapsedRealtime(); 9494 mMobileRadioActiveTime = new TimeMultiStateCounter( 9495 mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 9496 mMobileRadioActiveTime.setState( 9497 mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 9498 timestampMs); 9499 mMobileRadioActiveTime.update(0, timestampMs); 9500 } 9501 return mMobileRadioActiveTime; 9502 } 9503 9504 @Override hasNetworkActivity()9505 public boolean hasNetworkActivity() { 9506 return mNetworkByteActivityCounters != null; 9507 } 9508 9509 @Override getNetworkActivityBytes(int type, int which)9510 public long getNetworkActivityBytes(int type, int which) { 9511 if (mNetworkByteActivityCounters != null && type >= 0 9512 && type < mNetworkByteActivityCounters.length) { 9513 return mNetworkByteActivityCounters[type].getCountLocked(which); 9514 } else { 9515 return 0; 9516 } 9517 } 9518 9519 @Override getNetworkActivityPackets(int type, int which)9520 public long getNetworkActivityPackets(int type, int which) { 9521 if (mNetworkPacketActivityCounters != null && type >= 0 9522 && type < mNetworkPacketActivityCounters.length) { 9523 return mNetworkPacketActivityCounters[type].getCountLocked(which); 9524 } else { 9525 return 0; 9526 } 9527 } 9528 9529 @Override getMobileRadioActiveTime(int which)9530 public long getMobileRadioActiveTime(int which) { 9531 return getMobileRadioActiveTimeInProcessState(BatteryConsumer.PROCESS_STATE_ANY); 9532 } 9533 9534 @Override getMobileRadioActiveTimeInProcessState( @atteryConsumer.ProcessState int processState)9535 public long getMobileRadioActiveTimeInProcessState( 9536 @BatteryConsumer.ProcessState int processState) { 9537 if (mMobileRadioActiveTime == null) { 9538 return 0; 9539 } 9540 if (processState == BatteryConsumer.PROCESS_STATE_ANY) { 9541 return mMobileRadioActiveTime.getTotalCountLocked(); 9542 } else { 9543 return mMobileRadioActiveTime.getCountForProcessState(processState); 9544 } 9545 } 9546 9547 @Override getMobileRadioActiveCount(int which)9548 public int getMobileRadioActiveCount(int which) { 9549 return mMobileRadioActiveCount != null 9550 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 9551 } 9552 9553 @Override getUserCpuTimeUs(int which)9554 public long getUserCpuTimeUs(int which) { 9555 return mUserCpuTime.getCountLocked(which); 9556 } 9557 9558 @Override getSystemCpuTimeUs(int which)9559 public long getSystemCpuTimeUs(int which) { 9560 return mSystemCpuTime.getCountLocked(which); 9561 } 9562 9563 @Override 9564 @Deprecated getTimeAtCpuSpeed(int cluster, int step, int which)9565 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 9566 if (mCpuClusterSpeedTimesUs != null) { 9567 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 9568 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 9569 if (cpuSpeedTimesUs != null) { 9570 if (step >= 0 && step < cpuSpeedTimesUs.length) { 9571 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 9572 if (c != null) { 9573 return c.getCountLocked(which); 9574 } 9575 } 9576 } 9577 } 9578 } 9579 return 0; 9580 } 9581 noteMobileRadioApWakeupLocked()9582 public void noteMobileRadioApWakeupLocked() { 9583 if (mMobileRadioApWakeupCount == null) { 9584 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9585 } 9586 mMobileRadioApWakeupCount.addCountLocked(1); 9587 } 9588 9589 @Override getMobileRadioApWakeupCount(int which)9590 public long getMobileRadioApWakeupCount(int which) { 9591 if (mMobileRadioApWakeupCount != null) { 9592 return mMobileRadioApWakeupCount.getCountLocked(which); 9593 } 9594 return 0; 9595 } 9596 noteWifiRadioApWakeupLocked()9597 public void noteWifiRadioApWakeupLocked() { 9598 if (mWifiRadioApWakeupCount == null) { 9599 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9600 } 9601 mWifiRadioApWakeupCount.addCountLocked(1); 9602 } 9603 9604 @Override getWifiRadioApWakeupCount(int which)9605 public long getWifiRadioApWakeupCount(int which) { 9606 if (mWifiRadioApWakeupCount != null) { 9607 return mWifiRadioApWakeupCount.getCountLocked(which); 9608 } 9609 return 0; 9610 } 9611 9612 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)9613 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 9614 sb.setLength(0); 9615 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 9616 if (deferredEventCount == 0) { 9617 return; 9618 } 9619 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 9620 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 9621 sb.append(deferredEventCount); sb.append(','); 9622 sb.append(deferredCount); sb.append(','); 9623 sb.append(totalLatency); 9624 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9625 if (mJobsFreshnessBuckets[i] == null) { 9626 sb.append(",0"); 9627 } else { 9628 sb.append(","); 9629 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 9630 } 9631 } 9632 } 9633 9634 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)9635 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 9636 sb.setLength(0); 9637 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 9638 if (deferredEventCount == 0) { 9639 return; 9640 } 9641 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 9642 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 9643 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 9644 sb.append("count="); sb.append(deferredCount); sb.append(", "); 9645 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 9646 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9647 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 9648 if (mJobsFreshnessBuckets[i] == null) { 9649 sb.append("0"); 9650 } else { 9651 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 9652 } 9653 sb.append(" "); 9654 } 9655 } 9656 ensureNetworkActivityLocked()9657 void ensureNetworkActivityLocked() { 9658 if (mNetworkByteActivityCounters != null) { 9659 return; 9660 } 9661 9662 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9663 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9664 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9665 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9666 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9667 } 9668 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9669 } 9670 9671 /** 9672 * Clear all stats for this uid. Returns true if the uid is completely 9673 * inactive so can be dropped. 9674 */ 9675 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptimeUs, long realtimeUs, int resetReason)9676 public boolean reset(long uptimeUs, long realtimeUs, int resetReason) { 9677 boolean active = false; 9678 9679 mOnBatteryBackgroundTimeBase.init(uptimeUs, realtimeUs); 9680 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeUs, realtimeUs); 9681 9682 if (mWifiRunningTimer != null) { 9683 active |= !mWifiRunningTimer.reset(false, realtimeUs); 9684 active |= mWifiRunning; 9685 } 9686 if (mFullWifiLockTimer != null) { 9687 active |= !mFullWifiLockTimer.reset(false, realtimeUs); 9688 active |= mFullWifiLockOut; 9689 } 9690 if (mWifiScanTimer != null) { 9691 active |= !mWifiScanTimer.reset(false, realtimeUs); 9692 active |= mWifiScanStarted; 9693 } 9694 if (mWifiBatchedScanTimer != null) { 9695 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 9696 if (mWifiBatchedScanTimer[i] != null) { 9697 active |= !mWifiBatchedScanTimer[i].reset(false, realtimeUs); 9698 } 9699 } 9700 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 9701 } 9702 if (mWifiMulticastTimer != null) { 9703 active |= !mWifiMulticastTimer.reset(false, realtimeUs); 9704 active |= (mWifiMulticastWakelockCount > 0); 9705 } 9706 9707 active |= !resetIfNotNull(mAudioTurnedOnTimer, false, realtimeUs); 9708 active |= !resetIfNotNull(mVideoTurnedOnTimer, false, realtimeUs); 9709 active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false, realtimeUs); 9710 active |= !resetIfNotNull(mCameraTurnedOnTimer, false, realtimeUs); 9711 active |= !resetIfNotNull(mForegroundActivityTimer, false, realtimeUs); 9712 active |= !resetIfNotNull(mForegroundServiceTimer, false, realtimeUs); 9713 active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false, realtimeUs); 9714 active |= !resetIfNotNull(mBluetoothScanTimer, false, realtimeUs); 9715 active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false, realtimeUs); 9716 9717 resetIfNotNull(mBluetoothScanResultCounter, false, realtimeUs); 9718 resetIfNotNull(mBluetoothScanResultBgCounter, false, realtimeUs); 9719 9720 if (mProcessStateTimer != null) { 9721 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 9722 active |= !resetIfNotNull(mProcessStateTimer[i], false, realtimeUs); 9723 } 9724 active |= (mProcessState != Uid.PROCESS_STATE_NONEXISTENT); 9725 } 9726 if (mVibratorOnTimer != null) { 9727 if (mVibratorOnTimer.reset(false, realtimeUs)) { 9728 mVibratorOnTimer.detach(); 9729 mVibratorOnTimer = null; 9730 } else { 9731 active = true; 9732 } 9733 } 9734 9735 resetIfNotNull(mUserActivityCounters, false, realtimeUs); 9736 9737 resetIfNotNull(mNetworkByteActivityCounters, false, realtimeUs); 9738 resetIfNotNull(mNetworkPacketActivityCounters, false, realtimeUs); 9739 resetIfNotNull(mMobileRadioActiveTime, false, realtimeUs); 9740 resetIfNotNull(mMobileRadioActiveCount, false, realtimeUs); 9741 9742 resetIfNotNull(mWifiControllerActivity, false, realtimeUs); 9743 resetIfNotNull(mBluetoothControllerActivity, false, realtimeUs); 9744 resetIfNotNull(mModemControllerActivity, false, realtimeUs); 9745 9746 if (resetReason == RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE) { 9747 mUidEnergyConsumerStats = null; 9748 } else { 9749 EnergyConsumerStats.resetIfNotNull(mUidEnergyConsumerStats); 9750 } 9751 9752 resetIfNotNull(mUserCpuTime, false, realtimeUs); 9753 resetIfNotNull(mSystemCpuTime, false, realtimeUs); 9754 9755 resetIfNotNull(mCpuClusterSpeedTimesUs, false, realtimeUs); 9756 9757 resetIfNotNull(mCpuFreqTimeMs, false, realtimeUs /* unused */); 9758 resetIfNotNull(mScreenOffCpuFreqTimeMs, false, realtimeUs /* unused */); 9759 9760 9761 resetIfNotNull(mCpuActiveTimeMs, false, realtimeUs /* unused */); 9762 resetIfNotNull(mCpuClusterTimesMs, false, realtimeUs /* unused */); 9763 9764 resetIfNotNull(mProcStateTimeMs, false, realtimeUs /* unused */); 9765 9766 resetIfNotNull(mProcStateScreenOffTimeMs, false, realtimeUs /* unused */); 9767 9768 resetIfNotNull(mMobileRadioApWakeupCount, false, realtimeUs); 9769 9770 resetIfNotNull(mWifiRadioApWakeupCount, false, realtimeUs); 9771 9772 9773 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9774 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 9775 Wakelock wl = wakeStats.valueAt(iw); 9776 if (wl.reset(realtimeUs)) { 9777 wakeStats.removeAt(iw); 9778 } else { 9779 active = true; 9780 } 9781 } 9782 final long realtimeMs = realtimeUs / 1000; 9783 mWakelockStats.cleanup(realtimeMs); 9784 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9785 for (int is=syncStats.size()-1; is>=0; is--) { 9786 DualTimer timer = syncStats.valueAt(is); 9787 if (timer.reset(false, realtimeUs)) { 9788 syncStats.removeAt(is); 9789 timer.detach(); 9790 } else { 9791 active = true; 9792 } 9793 } 9794 mSyncStats.cleanup(realtimeMs); 9795 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9796 for (int ij=jobStats.size()-1; ij>=0; ij--) { 9797 DualTimer timer = jobStats.valueAt(ij); 9798 if (timer.reset(false, realtimeUs)) { 9799 jobStats.removeAt(ij); 9800 timer.detach(); 9801 } else { 9802 active = true; 9803 } 9804 } 9805 mJobStats.cleanup(realtimeMs); 9806 mJobCompletions.clear(); 9807 9808 resetIfNotNull(mJobsDeferredEventCount, false, realtimeUs); 9809 resetIfNotNull(mJobsDeferredCount, false, realtimeUs); 9810 resetIfNotNull(mJobsFreshnessTimeMs, false, realtimeUs /* unused */); 9811 resetIfNotNull(mJobsFreshnessBuckets, false, realtimeUs); 9812 9813 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 9814 Sensor s = mSensorStats.valueAt(ise); 9815 if (s.reset(realtimeUs)) { 9816 mSensorStats.removeAt(ise); 9817 } else { 9818 active = true; 9819 } 9820 } 9821 9822 for (int ip = mProcessStats.size() - 1; ip >= 0; ip--) { 9823 Proc proc = mProcessStats.valueAt(ip); 9824 proc.detach(); 9825 } 9826 mProcessStats.clear(); 9827 9828 for (int i = mPids.size() - 1; i >= 0; i--) { 9829 Pid pid = mPids.valueAt(i); 9830 if (pid.mWakeNesting > 0) { 9831 active = true; 9832 } else { 9833 mPids.removeAt(i); 9834 } 9835 } 9836 9837 9838 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 9839 Pkg p = mPackageStats.valueAt(i); 9840 p.detach(); 9841 } 9842 mPackageStats.clear(); 9843 9844 mBinderCallCount = 0; 9845 mBinderCallStats.clear(); 9846 9847 mProportionalSystemServiceUsage = 0; 9848 9849 mLastStepUserTimeMs = mLastStepSystemTimeMs = 0; 9850 mCurStepUserTimeMs = mCurStepSystemTimeMs = 0; 9851 9852 9853 return !active; 9854 } 9855 9856 /** 9857 * This method MUST be called whenever the Uid object is destructed, otherwise it is a 9858 * memory leak in {@link TimeBase#mObservers} list. 9859 * Typically the Uid object is destructed when it is removed from 9860 * {@link BatteryStatsImpl#mUidStats} 9861 */ detachFromTimeBase()9862 void detachFromTimeBase() { 9863 detachIfNotNull(mWifiRunningTimer); 9864 detachIfNotNull(mFullWifiLockTimer); 9865 detachIfNotNull(mWifiScanTimer); 9866 detachIfNotNull(mWifiBatchedScanTimer); 9867 detachIfNotNull(mWifiMulticastTimer); 9868 detachIfNotNull(mAudioTurnedOnTimer); 9869 detachIfNotNull(mVideoTurnedOnTimer); 9870 detachIfNotNull(mFlashlightTurnedOnTimer); 9871 9872 detachIfNotNull(mCameraTurnedOnTimer); 9873 detachIfNotNull(mForegroundActivityTimer); 9874 detachIfNotNull(mForegroundServiceTimer); 9875 9876 detachIfNotNull(mAggregatedPartialWakelockTimer); 9877 9878 detachIfNotNull(mBluetoothScanTimer); 9879 detachIfNotNull(mBluetoothUnoptimizedScanTimer); 9880 detachIfNotNull(mBluetoothScanResultCounter); 9881 detachIfNotNull(mBluetoothScanResultBgCounter); 9882 9883 detachIfNotNull(mProcessStateTimer); 9884 9885 detachIfNotNull(mVibratorOnTimer); 9886 9887 detachIfNotNull(mUserActivityCounters); 9888 9889 detachIfNotNull(mNetworkByteActivityCounters); 9890 detachIfNotNull(mNetworkPacketActivityCounters); 9891 9892 detachIfNotNull(mMobileRadioActiveTime); 9893 detachIfNotNull(mMobileRadioActiveCount); 9894 detachIfNotNull(mMobileRadioApWakeupCount); 9895 detachIfNotNull(mWifiRadioApWakeupCount); 9896 9897 detachIfNotNull(mWifiControllerActivity); 9898 detachIfNotNull(mBluetoothControllerActivity); 9899 detachIfNotNull(mModemControllerActivity); 9900 9901 mPids.clear(); 9902 9903 detachIfNotNull(mUserCpuTime); 9904 detachIfNotNull(mSystemCpuTime); 9905 9906 detachIfNotNull(mCpuClusterSpeedTimesUs); 9907 9908 detachIfNotNull(mCpuActiveTimeMs); 9909 detachIfNotNull(mCpuFreqTimeMs); 9910 9911 detachIfNotNull(mScreenOffCpuFreqTimeMs); 9912 9913 detachIfNotNull(mCpuClusterTimesMs); 9914 9915 detachIfNotNull(mProcStateTimeMs); 9916 9917 detachIfNotNull(mProcStateScreenOffTimeMs); 9918 9919 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9920 for (int iw = wakeStats.size() - 1; iw >= 0; iw--) { 9921 Wakelock wl = wakeStats.valueAt(iw); 9922 wl.detachFromTimeBase(); 9923 } 9924 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9925 for (int is = syncStats.size() - 1; is >= 0; is--) { 9926 DualTimer timer = syncStats.valueAt(is); 9927 detachIfNotNull(timer); 9928 } 9929 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9930 for (int ij = jobStats.size() - 1; ij >= 0; ij--) { 9931 DualTimer timer = jobStats.valueAt(ij); 9932 detachIfNotNull(timer); 9933 } 9934 9935 detachIfNotNull(mJobsDeferredEventCount); 9936 detachIfNotNull(mJobsDeferredCount); 9937 detachIfNotNull(mJobsFreshnessTimeMs); 9938 detachIfNotNull(mJobsFreshnessBuckets); 9939 9940 9941 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 9942 Sensor s = mSensorStats.valueAt(ise); 9943 s.detachFromTimeBase(); 9944 } 9945 9946 for (int ip= mProcessStats.size() - 1; ip >= 0; ip--) { 9947 Proc proc = mProcessStats.valueAt(ip); 9948 proc.detach(); 9949 } 9950 mProcessStats.clear(); 9951 9952 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 9953 Pkg p = mPackageStats.valueAt(i); 9954 p.detach(); 9955 } 9956 mPackageStats.clear(); 9957 } 9958 writeJobCompletionsToParcelLocked(Parcel out)9959 void writeJobCompletionsToParcelLocked(Parcel out) { 9960 int NJC = mJobCompletions.size(); 9961 out.writeInt(NJC); 9962 for (int ijc=0; ijc<NJC; ijc++) { 9963 out.writeString(mJobCompletions.keyAt(ijc)); 9964 SparseIntArray types = mJobCompletions.valueAt(ijc); 9965 int NT = types.size(); 9966 out.writeInt(NT); 9967 for (int it=0; it<NT; it++) { 9968 out.writeInt(types.keyAt(it)); 9969 out.writeInt(types.valueAt(it)); 9970 } 9971 } 9972 } 9973 readJobCompletionsFromParcelLocked(Parcel in)9974 void readJobCompletionsFromParcelLocked(Parcel in) { 9975 int numJobCompletions = in.readInt(); 9976 mJobCompletions.clear(); 9977 for (int j = 0; j < numJobCompletions; j++) { 9978 String jobName = in.readString(); 9979 int numTypes = in.readInt(); 9980 if (numTypes > 0) { 9981 SparseIntArray types = new SparseIntArray(); 9982 for (int k = 0; k < numTypes; k++) { 9983 int type = in.readInt(); 9984 int count = in.readInt(); 9985 types.put(type, count); 9986 } 9987 mJobCompletions.put(jobName, types); 9988 } 9989 } 9990 } 9991 noteJobsDeferredLocked(int numDeferred, long sinceLast)9992 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 9993 mJobsDeferredEventCount.addAtomic(1); 9994 mJobsDeferredCount.addAtomic(numDeferred); 9995 if (sinceLast != 0) { 9996 // Add the total time, which can be divided by the event count to get an average 9997 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 9998 // Also keep track of how many times there were in these different buckets. 9999 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 10000 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 10001 if (mJobsFreshnessBuckets[i] == null) { 10002 mJobsFreshnessBuckets[i] = new Counter( 10003 mBsi.mOnBatteryTimeBase); 10004 } 10005 mJobsFreshnessBuckets[i].addAtomic(1); 10006 break; 10007 } 10008 } 10009 } 10010 } 10011 10012 // Reusable object used as a key to lookup values in mBinderCallStats 10013 private static BinderCallStats sTempBinderCallStats = new BinderCallStats(); 10014 10015 /** 10016 * Notes incoming binder call stats associated with this work source UID. 10017 */ noteBinderCallStatsLocked(long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)10018 public void noteBinderCallStatsLocked(long incrementalCallCount, 10019 Collection<BinderCallsStats.CallStat> callStats) { 10020 if (DEBUG) { 10021 Slog.d(TAG, "noteBinderCalls() workSourceUid = [" + mUid + "], " 10022 + " incrementalCallCount: " + incrementalCallCount + " callStats = [" 10023 + new ArrayList<>(callStats) + "]"); 10024 } 10025 mBinderCallCount += incrementalCallCount; 10026 for (BinderCallsStats.CallStat stat : callStats) { 10027 BinderCallStats bcs; 10028 sTempBinderCallStats.binderClass = stat.binderClass; 10029 sTempBinderCallStats.transactionCode = stat.transactionCode; 10030 int index = mBinderCallStats.indexOf(sTempBinderCallStats); 10031 if (index >= 0) { 10032 bcs = mBinderCallStats.valueAt(index); 10033 } else { 10034 bcs = new BinderCallStats(); 10035 bcs.binderClass = stat.binderClass; 10036 bcs.transactionCode = stat.transactionCode; 10037 mBinderCallStats.add(bcs); 10038 } 10039 10040 bcs.callCount += stat.incrementalCallCount; 10041 bcs.recordedCallCount = stat.recordedCallCount; 10042 bcs.recordedCpuTimeMicros = stat.cpuTimeMicros; 10043 } 10044 } 10045 10046 /** 10047 * The statistics associated with a particular wake lock. 10048 */ 10049 public static class Wakelock extends BatteryStats.Uid.Wakelock { 10050 /** 10051 * BatteryStatsImpl that we are associated with. 10052 */ 10053 protected BatteryStatsImpl mBsi; 10054 10055 /** 10056 * BatteryStatsImpl that we are associated with. 10057 */ 10058 protected Uid mUid; 10059 10060 /** 10061 * How long (in ms) this uid has been keeping the device partially awake. 10062 * Tracks both the total time and the time while the app was in the background. 10063 */ 10064 DualTimer mTimerPartial; 10065 10066 /** 10067 * How long (in ms) this uid has been keeping the device fully awake. 10068 */ 10069 StopwatchTimer mTimerFull; 10070 10071 /** 10072 * How long (in ms) this uid has had a window keeping the device awake. 10073 */ 10074 StopwatchTimer mTimerWindow; 10075 10076 /** 10077 * How long (in ms) this uid has had a draw wake lock. 10078 */ 10079 StopwatchTimer mTimerDraw; 10080 Wakelock(BatteryStatsImpl bsi, Uid uid)10081 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 10082 mBsi = bsi; 10083 mUid = uid; 10084 } 10085 10086 /** 10087 * Reads a possibly null Timer from a Parcel. The timer is associated with the 10088 * proper timer pool from the given BatteryStatsImpl object. 10089 * 10090 * @param in the Parcel to be read from. 10091 * return a new Timer, or null. 10092 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)10093 private StopwatchTimer readStopwatchTimerFromParcel(int type, 10094 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 10095 if (in.readInt() == 0) { 10096 return null; 10097 } 10098 10099 return new StopwatchTimer(mBsi.mClock, mUid, type, pool, timeBase, in); 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 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10109 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 10110 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10111 if (in.readInt() == 0) { 10112 return null; 10113 } 10114 10115 return new DualTimer(mBsi.mClock, mUid, type, pool, timeBase, bgTimeBase, in); 10116 } 10117 reset(long elapsedRealtimeUs)10118 boolean reset(long elapsedRealtimeUs) { 10119 boolean wlactive = false; 10120 10121 wlactive |= !resetIfNotNull(mTimerFull, false, elapsedRealtimeUs); 10122 wlactive |= !resetIfNotNull(mTimerPartial, false, elapsedRealtimeUs); 10123 wlactive |= !resetIfNotNull(mTimerWindow, false, elapsedRealtimeUs); 10124 wlactive |= !resetIfNotNull(mTimerDraw, false, elapsedRealtimeUs); 10125 10126 if (!wlactive) { 10127 detachIfNotNull(mTimerFull); 10128 mTimerFull = null; 10129 10130 detachIfNotNull(mTimerPartial); 10131 mTimerPartial = null; 10132 10133 detachIfNotNull(mTimerWindow); 10134 mTimerWindow = null; 10135 10136 detachIfNotNull(mTimerDraw); 10137 mTimerDraw = null; 10138 } 10139 return !wlactive; 10140 } 10141 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)10142 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 10143 TimeBase screenOffBgTimeBase, Parcel in) { 10144 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 10145 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 10146 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 10147 mBsi.mFullTimers, timeBase, in); 10148 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 10149 mBsi.mWindowTimers, timeBase, in); 10150 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 10151 mBsi.mDrawTimers, timeBase, in); 10152 } 10153 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)10154 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 10155 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 10156 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 10157 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 10158 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 10159 } 10160 10161 @Override getWakeTime(int type)10162 public Timer getWakeTime(int type) { 10163 switch (type) { 10164 case WAKE_TYPE_FULL: return mTimerFull; 10165 case WAKE_TYPE_PARTIAL: return mTimerPartial; 10166 case WAKE_TYPE_WINDOW: return mTimerWindow; 10167 case WAKE_TYPE_DRAW: return mTimerDraw; 10168 default: throw new IllegalArgumentException("type = " + type); 10169 } 10170 } 10171 detachFromTimeBase()10172 public void detachFromTimeBase() { 10173 detachIfNotNull(mTimerPartial); 10174 detachIfNotNull(mTimerFull); 10175 detachIfNotNull(mTimerWindow); 10176 detachIfNotNull(mTimerDraw); 10177 } 10178 } 10179 10180 public static class Sensor extends BatteryStats.Uid.Sensor { 10181 /** 10182 * BatteryStatsImpl that we are associated with. 10183 */ 10184 protected BatteryStatsImpl mBsi; 10185 10186 /** 10187 * Uid that we are associated with. 10188 */ 10189 protected Uid mUid; 10190 10191 final int mHandle; 10192 DualTimer mTimer; 10193 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)10194 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 10195 mBsi = bsi; 10196 mUid = uid; 10197 mHandle = handle; 10198 } 10199 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10200 private DualTimer readTimersFromParcel( 10201 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10202 if (in.readInt() == 0) { 10203 return null; 10204 } 10205 10206 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 10207 if (pool == null) { 10208 pool = new ArrayList<StopwatchTimer>(); 10209 mBsi.mSensorTimers.put(mHandle, pool); 10210 } 10211 return new DualTimer(mBsi.mClock, mUid, 0, pool, timeBase, bgTimeBase, in); 10212 } 10213 reset(long elapsedRealtimeUs)10214 boolean reset(long elapsedRealtimeUs) { 10215 if (mTimer.reset(true, elapsedRealtimeUs)) { 10216 mTimer = null; 10217 return true; 10218 } 10219 return false; 10220 } 10221 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10222 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10223 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 10224 } 10225 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)10226 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 10227 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 10228 } 10229 10230 @Override getSensorTime()10231 public Timer getSensorTime() { 10232 return mTimer; 10233 } 10234 10235 @Override getSensorBackgroundTime()10236 public Timer getSensorBackgroundTime() { 10237 if (mTimer == null) { 10238 return null; 10239 } 10240 return mTimer.getSubTimer(); 10241 } 10242 10243 @Override getHandle()10244 public int getHandle() { 10245 return mHandle; 10246 } 10247 detachFromTimeBase()10248 public void detachFromTimeBase() { 10249 detachIfNotNull(mTimer); 10250 } 10251 } 10252 10253 /** 10254 * The statistics associated with a particular process. 10255 */ 10256 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 10257 /** 10258 * BatteryStatsImpl that we are associated with. 10259 */ 10260 protected BatteryStatsImpl mBsi; 10261 10262 /** 10263 * The name of this process. 10264 */ 10265 final String mName; 10266 10267 /** 10268 * Remains true until removed from the stats. 10269 */ 10270 boolean mActive = true; 10271 10272 /** 10273 * Total time (in ms) spent executing in user code. 10274 */ 10275 long mUserTimeMs; 10276 10277 /** 10278 * Total time (in ms) spent executing in kernel code. 10279 */ 10280 long mSystemTimeMs; 10281 10282 /** 10283 * Amount of time (in ms) the process was running in the foreground. 10284 */ 10285 long mForegroundTimeMs; 10286 10287 /** 10288 * Number of times the process has been started. 10289 */ 10290 int mStarts; 10291 10292 /** 10293 * Number of times the process has crashed. 10294 */ 10295 int mNumCrashes; 10296 10297 /** 10298 * Number of times the process has had an ANR. 10299 */ 10300 int mNumAnrs; 10301 10302 ArrayList<ExcessivePower> mExcessivePower; 10303 Proc(BatteryStatsImpl bsi, String name)10304 public Proc(BatteryStatsImpl bsi, String name) { 10305 mBsi = bsi; 10306 mName = name; 10307 mBsi.mOnBatteryTimeBase.add(this); 10308 } 10309 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10310 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10311 long baseRealtimeUs) { 10312 } 10313 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10314 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10315 long baseRealtimeUs) { 10316 } 10317 10318 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10319 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10320 if (detachIfReset) { 10321 this.detach(); 10322 } 10323 return true; 10324 } 10325 10326 @Override detach()10327 public void detach() { 10328 mActive = false; 10329 mBsi.mOnBatteryTimeBase.remove(this); 10330 } 10331 countExcessivePowers()10332 public int countExcessivePowers() { 10333 return mExcessivePower != null ? mExcessivePower.size() : 0; 10334 } 10335 getExcessivePower(int i)10336 public ExcessivePower getExcessivePower(int i) { 10337 if (mExcessivePower != null) { 10338 return mExcessivePower.get(i); 10339 } 10340 return null; 10341 } 10342 addExcessiveCpu(long overTimeMs, long usedTimeMs)10343 public void addExcessiveCpu(long overTimeMs, long usedTimeMs) { 10344 if (mExcessivePower == null) { 10345 mExcessivePower = new ArrayList<ExcessivePower>(); 10346 } 10347 ExcessivePower ew = new ExcessivePower(); 10348 ew.type = ExcessivePower.TYPE_CPU; 10349 ew.overTime = overTimeMs; 10350 ew.usedTime = usedTimeMs; 10351 mExcessivePower.add(ew); 10352 } 10353 writeExcessivePowerToParcelLocked(Parcel out)10354 void writeExcessivePowerToParcelLocked(Parcel out) { 10355 if (mExcessivePower == null) { 10356 out.writeInt(0); 10357 return; 10358 } 10359 10360 final int N = mExcessivePower.size(); 10361 out.writeInt(N); 10362 for (int i=0; i<N; i++) { 10363 ExcessivePower ew = mExcessivePower.get(i); 10364 out.writeInt(ew.type); 10365 out.writeLong(ew.overTime); 10366 out.writeLong(ew.usedTime); 10367 } 10368 } 10369 readExcessivePowerFromParcelLocked(Parcel in)10370 void readExcessivePowerFromParcelLocked(Parcel in) { 10371 final int N = in.readInt(); 10372 if (N == 0) { 10373 mExcessivePower = null; 10374 return; 10375 } 10376 10377 if (N > 10000) { 10378 throw new ParcelFormatException( 10379 "File corrupt: too many excessive power entries " + N); 10380 } 10381 10382 mExcessivePower = new ArrayList<>(); 10383 for (int i=0; i<N; i++) { 10384 ExcessivePower ew = new ExcessivePower(); 10385 ew.type = in.readInt(); 10386 ew.overTime = in.readLong(); 10387 ew.usedTime = in.readLong(); 10388 mExcessivePower.add(ew); 10389 } 10390 } 10391 writeToParcelLocked(Parcel out)10392 void writeToParcelLocked(Parcel out) { 10393 out.writeLong(mUserTimeMs); 10394 out.writeLong(mSystemTimeMs); 10395 out.writeLong(mForegroundTimeMs); 10396 out.writeInt(mStarts); 10397 out.writeInt(mNumCrashes); 10398 out.writeInt(mNumAnrs); 10399 writeExcessivePowerToParcelLocked(out); 10400 } 10401 readFromParcelLocked(Parcel in)10402 void readFromParcelLocked(Parcel in) { 10403 mUserTimeMs = in.readLong(); 10404 mSystemTimeMs = in.readLong(); 10405 mForegroundTimeMs = in.readLong(); 10406 mStarts = in.readInt(); 10407 mNumCrashes = in.readInt(); 10408 mNumAnrs = in.readInt(); 10409 readExcessivePowerFromParcelLocked(in); 10410 } 10411 addCpuTimeLocked(int utimeMs, int stimeMs)10412 public void addCpuTimeLocked(int utimeMs, int stimeMs) { 10413 addCpuTimeLocked(utimeMs, stimeMs, mBsi.mOnBatteryTimeBase.isRunning()); 10414 } 10415 addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning)10416 public void addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning) { 10417 if (isRunning) { 10418 mUserTimeMs += utimeMs; 10419 mSystemTimeMs += stimeMs; 10420 } 10421 } 10422 addForegroundTimeLocked(long ttimeMs)10423 public void addForegroundTimeLocked(long ttimeMs) { 10424 mForegroundTimeMs += ttimeMs; 10425 } 10426 incStartsLocked()10427 public void incStartsLocked() { 10428 mStarts++; 10429 } 10430 incNumCrashesLocked()10431 public void incNumCrashesLocked() { 10432 mNumCrashes++; 10433 } 10434 incNumAnrsLocked()10435 public void incNumAnrsLocked() { 10436 mNumAnrs++; 10437 } 10438 10439 @Override isActive()10440 public boolean isActive() { 10441 return mActive; 10442 } 10443 10444 @Override getUserTime(int which)10445 public long getUserTime(int which) { 10446 return mUserTimeMs; 10447 } 10448 10449 @Override getSystemTime(int which)10450 public long getSystemTime(int which) { 10451 return mSystemTimeMs; 10452 } 10453 10454 @Override getForegroundTime(int which)10455 public long getForegroundTime(int which) { 10456 return mForegroundTimeMs; 10457 } 10458 10459 @Override getStarts(int which)10460 public int getStarts(int which) { 10461 return mStarts; 10462 } 10463 10464 @Override getNumCrashes(int which)10465 public int getNumCrashes(int which) { 10466 return mNumCrashes; 10467 } 10468 10469 @Override getNumAnrs(int which)10470 public int getNumAnrs(int which) { 10471 return mNumAnrs; 10472 } 10473 } 10474 10475 /** 10476 * The statistics associated with a particular package. 10477 */ 10478 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 10479 /** 10480 * BatteryStatsImpl that we are associated with. 10481 */ 10482 protected BatteryStatsImpl mBsi; 10483 10484 /** 10485 * Number of times wakeup alarms have occurred for this app. 10486 * On screen-off timebase starting in report v25. 10487 */ 10488 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 10489 10490 /** 10491 * The statics we have collected for this package's services. 10492 */ 10493 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 10494 Pkg(BatteryStatsImpl bsi)10495 public Pkg(BatteryStatsImpl bsi) { 10496 mBsi = bsi; 10497 mBsi.mOnBatteryScreenOffTimeBase.add(this); 10498 } 10499 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10500 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10501 long baseRealtimeUs) { 10502 } 10503 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10504 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10505 long baseRealtimeUs) { 10506 } 10507 10508 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10509 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10510 if (detachIfReset) { 10511 this.detach(); 10512 } 10513 return true; 10514 } 10515 10516 @Override detach()10517 public void detach() { 10518 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 10519 for (int j = mWakeupAlarms.size() - 1; j >= 0; j--) { 10520 detachIfNotNull(mWakeupAlarms.valueAt(j)); 10521 } 10522 for (int j = mServiceStats.size() - 1; j >= 0; j--) { 10523 detachIfNotNull(mServiceStats.valueAt(j)); 10524 } 10525 } 10526 readFromParcelLocked(Parcel in)10527 void readFromParcelLocked(Parcel in) { 10528 int numWA = in.readInt(); 10529 mWakeupAlarms.clear(); 10530 for (int i=0; i<numWA; i++) { 10531 String tag = in.readString(); 10532 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 10533 } 10534 10535 int numServs = in.readInt(); 10536 mServiceStats.clear(); 10537 for (int m = 0; m < numServs; m++) { 10538 String serviceName = in.readString(); 10539 Uid.Pkg.Serv serv = new Serv(mBsi); 10540 mServiceStats.put(serviceName, serv); 10541 10542 serv.readFromParcelLocked(in); 10543 } 10544 } 10545 writeToParcelLocked(Parcel out)10546 void writeToParcelLocked(Parcel out) { 10547 int numWA = mWakeupAlarms.size(); 10548 out.writeInt(numWA); 10549 for (int i=0; i<numWA; i++) { 10550 out.writeString(mWakeupAlarms.keyAt(i)); 10551 mWakeupAlarms.valueAt(i).writeToParcel(out); 10552 } 10553 10554 final int NS = mServiceStats.size(); 10555 out.writeInt(NS); 10556 for (int i=0; i<NS; i++) { 10557 out.writeString(mServiceStats.keyAt(i)); 10558 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 10559 serv.writeToParcelLocked(out); 10560 } 10561 } 10562 10563 @Override getWakeupAlarmStats()10564 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 10565 return mWakeupAlarms; 10566 } 10567 noteWakeupAlarmLocked(String tag)10568 public void noteWakeupAlarmLocked(String tag) { 10569 Counter c = mWakeupAlarms.get(tag); 10570 if (c == null) { 10571 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 10572 mWakeupAlarms.put(tag, c); 10573 } 10574 c.stepAtomic(); 10575 } 10576 10577 @Override getServiceStats()10578 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 10579 return mServiceStats; 10580 } 10581 10582 /** 10583 * The statistics associated with a particular service. 10584 */ 10585 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 10586 /** 10587 * BatteryStatsImpl that we are associated with. 10588 */ 10589 protected BatteryStatsImpl mBsi; 10590 10591 /** 10592 * The android package in which this service resides. 10593 */ 10594 protected Pkg mPkg; 10595 10596 /** 10597 * Total time (ms in battery uptime) the service has been left started. 10598 */ 10599 protected long mStartTimeMs; 10600 10601 /** 10602 * If service has been started and not yet stopped, this is 10603 * when it was started. 10604 */ 10605 protected long mRunningSinceMs; 10606 10607 /** 10608 * True if we are currently running. 10609 */ 10610 protected boolean mRunning; 10611 10612 /** 10613 * Total number of times startService() has been called. 10614 */ 10615 protected int mStarts; 10616 10617 /** 10618 * Total time (ms in battery uptime) the service has been left launched. 10619 */ 10620 protected long mLaunchedTimeMs; 10621 10622 /** 10623 * If service has been launched and not yet exited, this is 10624 * when it was launched (ms in battery uptime). 10625 */ 10626 protected long mLaunchedSinceMs; 10627 10628 /** 10629 * True if we are currently launched. 10630 */ 10631 protected boolean mLaunched; 10632 10633 /** 10634 * Total number times the service has been launched. 10635 */ 10636 protected int mLaunches; 10637 10638 /** 10639 * Construct a Serv. Also adds it to the on-battery time base as a listener. 10640 */ Serv(BatteryStatsImpl bsi)10641 public Serv(BatteryStatsImpl bsi) { 10642 mBsi = bsi; 10643 mBsi.mOnBatteryTimeBase.add(this); 10644 } 10645 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10646 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10647 long baseRealtimeUs) { 10648 } 10649 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10650 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10651 long baseRealtimeUs) { 10652 } 10653 10654 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10655 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10656 if (detachIfReset) { 10657 this.detach(); 10658 } 10659 return true; 10660 } 10661 10662 /** 10663 * Remove this Serv as a listener from the time base. 10664 Ms*/ 10665 @Override detach()10666 public void detach() { 10667 mBsi.mOnBatteryTimeBase.remove(this); 10668 } 10669 readFromParcelLocked(Parcel in)10670 public void readFromParcelLocked(Parcel in) { 10671 mStartTimeMs = in.readLong(); 10672 mRunningSinceMs = in.readLong(); 10673 mRunning = in.readInt() != 0; 10674 mStarts = in.readInt(); 10675 mLaunchedTimeMs = in.readLong(); 10676 mLaunchedSinceMs = in.readLong(); 10677 mLaunched = in.readInt() != 0; 10678 mLaunches = in.readInt(); 10679 } 10680 writeToParcelLocked(Parcel out)10681 public void writeToParcelLocked(Parcel out) { 10682 out.writeLong(mStartTimeMs); 10683 out.writeLong(mRunningSinceMs); 10684 out.writeInt(mRunning ? 1 : 0); 10685 out.writeInt(mStarts); 10686 out.writeLong(mLaunchedTimeMs); 10687 out.writeLong(mLaunchedSinceMs); 10688 out.writeInt(mLaunched ? 1 : 0); 10689 out.writeInt(mLaunches); 10690 } 10691 getLaunchTimeToNowLocked(long batteryUptimeMs)10692 public long getLaunchTimeToNowLocked(long batteryUptimeMs) { 10693 if (!mLaunched) return mLaunchedTimeMs; 10694 return mLaunchedTimeMs + batteryUptimeMs - mLaunchedSinceMs; 10695 } 10696 getStartTimeToNowLocked(long batteryUptimeMs)10697 public long getStartTimeToNowLocked(long batteryUptimeMs) { 10698 if (!mRunning) return mStartTimeMs; 10699 return mStartTimeMs + batteryUptimeMs - mRunningSinceMs; 10700 } 10701 startLaunchedLocked()10702 public void startLaunchedLocked() { 10703 startLaunchedLocked(mBsi.mClock.uptimeMillis()); 10704 } 10705 startLaunchedLocked(long uptimeMs)10706 public void startLaunchedLocked(long uptimeMs) { 10707 if (!mLaunched) { 10708 mLaunches++; 10709 mLaunchedSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10710 mLaunched = true; 10711 } 10712 } 10713 stopLaunchedLocked()10714 public void stopLaunchedLocked() { 10715 stopLaunchedLocked(mBsi.mClock.uptimeMillis()); 10716 } 10717 stopLaunchedLocked(long uptimeMs)10718 public void stopLaunchedLocked(long uptimeMs) { 10719 if (mLaunched) { 10720 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10721 - mLaunchedSinceMs; 10722 if (timeMs > 0) { 10723 mLaunchedTimeMs += timeMs; 10724 } else { 10725 mLaunches--; 10726 } 10727 mLaunched = false; 10728 } 10729 } 10730 startRunningLocked()10731 public void startRunningLocked() { 10732 startRunningLocked(mBsi.mClock.uptimeMillis()); 10733 } 10734 startRunningLocked(long uptimeMs)10735 public void startRunningLocked(long uptimeMs) { 10736 if (!mRunning) { 10737 mStarts++; 10738 mRunningSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10739 mRunning = true; 10740 } 10741 } 10742 stopRunningLocked()10743 public void stopRunningLocked() { 10744 stopRunningLocked(mBsi.mClock.uptimeMillis()); 10745 } 10746 stopRunningLocked(long uptimeMs)10747 public void stopRunningLocked(long uptimeMs) { 10748 if (mRunning) { 10749 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10750 - mRunningSinceMs; 10751 if (timeMs > 0) { 10752 mStartTimeMs += timeMs; 10753 } else { 10754 mStarts--; 10755 } 10756 mRunning = false; 10757 } 10758 } 10759 getBatteryStats()10760 public BatteryStatsImpl getBatteryStats() { 10761 return mBsi; 10762 } 10763 10764 @Override getLaunches(int which)10765 public int getLaunches(int which) { 10766 return mLaunches; 10767 } 10768 10769 @Override getStartTime(long now, int which)10770 public long getStartTime(long now, int which) { 10771 return getStartTimeToNowLocked(now); 10772 } 10773 10774 @Override getStarts(int which)10775 public int getStarts(int which) { 10776 return mStarts; 10777 } 10778 } 10779 newServiceStatsLocked()10780 final Serv newServiceStatsLocked() { 10781 return new Serv(mBsi); 10782 } 10783 } 10784 10785 private class ChildUid { 10786 public final TimeMultiStateCounter cpuActiveCounter; 10787 public final LongArrayMultiStateCounter cpuTimeInFreqCounter; 10788 ChildUid()10789 ChildUid() { 10790 final long timestampMs = mBsi.mClock.elapsedRealtime(); 10791 cpuActiveCounter = 10792 new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, 1, timestampMs); 10793 cpuActiveCounter.setState(0, timestampMs); 10794 10795 if (mBsi.trackPerProcStateCpuTimes()) { 10796 final int cpuFreqCount = mBsi.mCpuScalingPolicies.getScalingStepCount(); 10797 10798 cpuTimeInFreqCounter = new LongArrayMultiStateCounter(1, cpuFreqCount); 10799 10800 // Set initial values to all 0. This is a child UID and we want to include 10801 // the entirety of its CPU time-in-freq stats into the parent's stats. 10802 cpuTimeInFreqCounter.updateValues( 10803 new LongArrayMultiStateCounter.LongArrayContainer(cpuFreqCount), 10804 timestampMs); 10805 } else { 10806 cpuTimeInFreqCounter = null; 10807 } 10808 } 10809 } 10810 10811 /** 10812 * Retrieve the statistics object for a particular process, creating 10813 * if needed. 10814 */ getProcessStatsLocked(String name)10815 public Proc getProcessStatsLocked(String name) { 10816 Proc ps = mProcessStats.get(name); 10817 if (ps == null) { 10818 ps = new Proc(mBsi, name); 10819 mProcessStats.put(name, ps); 10820 } 10821 10822 return ps; 10823 } 10824 10825 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState, long elapsedRealtimeMs, long uptimeMs)10826 public void updateUidProcessStateLocked(int procState, 10827 long elapsedRealtimeMs, long uptimeMs) { 10828 int uidRunningState; 10829 // Make special note of Foreground Services 10830 final boolean userAwareService = ActivityManager.isForegroundService(procState); 10831 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 10832 10833 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 10834 return; 10835 } 10836 10837 if (mProcessState != uidRunningState) { 10838 if (mProcessState != Uid.PROCESS_STATE_NONEXISTENT) { 10839 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 10840 } 10841 if (uidRunningState != Uid.PROCESS_STATE_NONEXISTENT) { 10842 if (mProcessStateTimer[uidRunningState] == null) { 10843 makeProcessState(uidRunningState, null); 10844 } 10845 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 10846 } 10847 10848 if (!mBsi.mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU) 10849 && mBsi.trackPerProcStateCpuTimes()) { 10850 mBsi.updateProcStateCpuTimesLocked(mUid, elapsedRealtimeMs, uptimeMs); 10851 10852 LongArrayMultiStateCounter onBatteryCounter = 10853 getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 10854 LongArrayMultiStateCounter onBatteryScreenOffCounter = 10855 getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 10856 10857 onBatteryCounter.setState(uidRunningState, elapsedRealtimeMs); 10858 onBatteryScreenOffCounter.setState(uidRunningState, elapsedRealtimeMs); 10859 } 10860 10861 final int prevBatteryConsumerProcessState = 10862 mapUidProcessStateToBatteryConsumerProcessState(mProcessState); 10863 10864 mProcessState = uidRunningState; 10865 10866 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10867 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10868 10869 final int batteryConsumerProcessState = 10870 mapUidProcessStateToBatteryConsumerProcessState(uidRunningState); 10871 if (mBsi.mSystemReady && mBsi.mPowerStatsCollectorEnabled.get( 10872 BatteryConsumer.POWER_COMPONENT_CPU)) { 10873 mBsi.mHistory.recordProcessStateChange(elapsedRealtimeMs, uptimeMs, mUid, 10874 batteryConsumerProcessState); 10875 } 10876 getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedRealtimeMs); 10877 10878 getMobileRadioActiveTimeCounter() 10879 .setState(batteryConsumerProcessState, elapsedRealtimeMs); 10880 10881 final ControllerActivityCounterImpl wifiControllerActivity = 10882 getWifiControllerActivity(); 10883 if (wifiControllerActivity != null) { 10884 wifiControllerActivity.setState(batteryConsumerProcessState, elapsedRealtimeMs); 10885 } 10886 10887 final ControllerActivityCounterImpl bluetoothControllerActivity = 10888 getBluetoothControllerActivity(); 10889 if (bluetoothControllerActivity != null) { 10890 bluetoothControllerActivity.setState(batteryConsumerProcessState, 10891 elapsedRealtimeMs); 10892 } 10893 10894 final EnergyConsumerStats energyStats = 10895 getOrCreateEnergyConsumerStatsIfSupportedLocked(); 10896 if (energyStats != null) { 10897 energyStats.setState(batteryConsumerProcessState, elapsedRealtimeMs); 10898 } 10899 maybeScheduleExternalStatsSync(prevBatteryConsumerProcessState, 10900 batteryConsumerProcessState); 10901 } 10902 10903 if (userAwareService != mInForegroundService) { 10904 if (userAwareService) { 10905 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 10906 } else { 10907 noteForegroundServicePausedLocked(elapsedRealtimeMs); 10908 } 10909 mInForegroundService = userAwareService; 10910 } 10911 } 10912 10913 @GuardedBy("mBsi") maybeScheduleExternalStatsSync( @atteryConsumer.ProcessState int oldProcessState, @BatteryConsumer.ProcessState int newProcessState)10914 private void maybeScheduleExternalStatsSync( 10915 @BatteryConsumer.ProcessState int oldProcessState, 10916 @BatteryConsumer.ProcessState int newProcessState) { 10917 if (oldProcessState == newProcessState) { 10918 return; 10919 } 10920 // Transitions between BACKGROUND and such non-foreground states like cached 10921 // or nonexistent do not warrant doing a sync. If some of the stats for those 10922 // proc states bleed into the PROCESS_STATE_BACKGROUND, that's ok. 10923 if ((oldProcessState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED 10924 && newProcessState == BatteryConsumer.PROCESS_STATE_BACKGROUND) 10925 || (oldProcessState == BatteryConsumer.PROCESS_STATE_BACKGROUND 10926 && newProcessState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED)) { 10927 return; 10928 } 10929 10930 int flags = ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE; 10931 // Skip querying for inactive radio, where power usage is probably negligible. 10932 if (!BatteryStatsImpl.isActiveRadioPowerState(mBsi.mMobileRadioPowerState)) { 10933 flags &= ~ExternalStatsSync.UPDATE_RADIO; 10934 } 10935 10936 mBsi.mExternalSync.scheduleSyncDueToProcessStateChange(flags, 10937 mBsi.mConstants.PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 10938 } 10939 10940 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()10941 public boolean isInBackground() { 10942 // Note that PROCESS_STATE_CACHED and Uid.PROCESS_STATE_NONEXISTENT is 10943 // also considered to be 'background' for our purposes, because it's not foreground. 10944 return mProcessState >= PROCESS_STATE_BACKGROUND; 10945 } 10946 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)10947 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 10948 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 10949 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 10950 } 10951 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)10952 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 10953 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 10954 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 10955 } 10956 getPidStats()10957 public SparseArray<? extends Pid> getPidStats() { 10958 return mPids; 10959 } 10960 getPidStatsLocked(int pid)10961 public Pid getPidStatsLocked(int pid) { 10962 Pid p = mPids.get(pid); 10963 if (p == null) { 10964 p = new Pid(); 10965 mPids.put(pid, p); 10966 } 10967 return p; 10968 } 10969 10970 /** 10971 * Retrieve the statistics object for a particular service, creating 10972 * if needed. 10973 */ getPackageStatsLocked(String name)10974 public Pkg getPackageStatsLocked(String name) { 10975 Pkg ps = mPackageStats.get(name); 10976 if (ps == null) { 10977 ps = new Pkg(mBsi); 10978 mPackageStats.put(name, ps); 10979 } 10980 10981 return ps; 10982 } 10983 10984 /** 10985 * Retrieve the statistics object for a particular service, creating 10986 * if needed. 10987 */ getServiceStatsLocked(String pkg, String serv)10988 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 10989 Pkg ps = getPackageStatsLocked(pkg); 10990 Pkg.Serv ss = ps.mServiceStats.get(serv); 10991 if (ss == null) { 10992 ss = ps.newServiceStatsLocked(); 10993 ps.mServiceStats.put(serv, ss); 10994 } 10995 10996 return ss; 10997 } 10998 readSyncSummaryFromParcelLocked(String name, Parcel in)10999 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 11000 DualTimer timer = mSyncStats.instantiateObject(); 11001 timer.readSummaryFromParcelLocked(in); 11002 mSyncStats.add(name, timer); 11003 } 11004 readJobSummaryFromParcelLocked(String name, Parcel in)11005 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 11006 DualTimer timer = mJobStats.instantiateObject(); 11007 timer.readSummaryFromParcelLocked(in); 11008 mJobStats.add(name, timer); 11009 } 11010 readWakeSummaryFromParcelLocked(String wlName, Parcel in)11011 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 11012 Wakelock wl = new Wakelock(mBsi, this); 11013 mWakelockStats.add(wlName, wl); 11014 if (in.readInt() != 0) { 11015 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 11016 } 11017 if (in.readInt() != 0) { 11018 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 11019 } 11020 if (in.readInt() != 0) { 11021 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 11022 } 11023 if (in.readInt() != 0) { 11024 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 11025 } 11026 } 11027 getSensorTimerLocked(int sensor, boolean create)11028 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 11029 Sensor se = mSensorStats.get(sensor); 11030 if (se == null) { 11031 if (!create) { 11032 return null; 11033 } 11034 se = new Sensor(mBsi, this, sensor); 11035 mSensorStats.put(sensor, se); 11036 } 11037 DualTimer t = se.mTimer; 11038 if (t != null) { 11039 return t; 11040 } 11041 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 11042 if (timers == null) { 11043 timers = new ArrayList<StopwatchTimer>(); 11044 mBsi.mSensorTimers.put(sensor, timers); 11045 } 11046 t = new DualTimer(mBsi.mClock, this, BatteryStats.SENSOR, timers, 11047 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 11048 se.mTimer = t; 11049 return t; 11050 } 11051 noteStartSyncLocked(String name, long elapsedRealtimeMs)11052 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 11053 DualTimer t = mSyncStats.startObject(name, elapsedRealtimeMs); 11054 if (t != null) { 11055 t.startRunningLocked(elapsedRealtimeMs); 11056 } 11057 } 11058 noteStopSyncLocked(String name, long elapsedRealtimeMs)11059 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 11060 DualTimer t = mSyncStats.stopObject(name, elapsedRealtimeMs); 11061 if (t != null) { 11062 t.stopRunningLocked(elapsedRealtimeMs); 11063 } 11064 } 11065 noteStartJobLocked(String name, long elapsedRealtimeMs)11066 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 11067 DualTimer t = mJobStats.startObject(name, elapsedRealtimeMs); 11068 if (t != null) { 11069 t.startRunningLocked(elapsedRealtimeMs); 11070 } 11071 } 11072 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)11073 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 11074 DualTimer t = mJobStats.stopObject(name, elapsedRealtimeMs); 11075 if (t != null) { 11076 t.stopRunningLocked(elapsedRealtimeMs); 11077 } 11078 if (mBsi.mOnBatteryTimeBase.isRunning()) { 11079 SparseIntArray types = mJobCompletions.get(name); 11080 if (types == null) { 11081 types = new SparseIntArray(); 11082 mJobCompletions.put(name, types); 11083 } 11084 int last = types.get(stopReason, 0); 11085 types.put(stopReason, last + 1); 11086 } 11087 } 11088 getWakelockTimerLocked(Wakelock wl, int type)11089 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 11090 if (wl == null) { 11091 return null; 11092 } 11093 switch (type) { 11094 case WAKE_TYPE_PARTIAL: { 11095 DualTimer t = wl.mTimerPartial; 11096 if (t == null) { 11097 t = new DualTimer(mBsi.mClock, this, WAKE_TYPE_PARTIAL, 11098 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 11099 mOnBatteryScreenOffBackgroundTimeBase); 11100 wl.mTimerPartial = t; 11101 } 11102 return t; 11103 } 11104 case WAKE_TYPE_FULL: { 11105 StopwatchTimer t = wl.mTimerFull; 11106 if (t == null) { 11107 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_FULL, 11108 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 11109 wl.mTimerFull = t; 11110 } 11111 return t; 11112 } 11113 case WAKE_TYPE_WINDOW: { 11114 StopwatchTimer t = wl.mTimerWindow; 11115 if (t == null) { 11116 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_WINDOW, 11117 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 11118 wl.mTimerWindow = t; 11119 } 11120 return t; 11121 } 11122 case WAKE_TYPE_DRAW: { 11123 StopwatchTimer t = wl.mTimerDraw; 11124 if (t == null) { 11125 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_DRAW, 11126 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 11127 wl.mTimerDraw = t; 11128 } 11129 return t; 11130 } 11131 default: 11132 throw new IllegalArgumentException("type=" + type); 11133 } 11134 } 11135 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)11136 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 11137 Wakelock wl = mWakelockStats.startObject(name, elapsedRealtimeMs); 11138 if (wl != null) { 11139 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 11140 } 11141 if (type == WAKE_TYPE_PARTIAL) { 11142 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 11143 if (pid >= 0) { 11144 Pid p = getPidStatsLocked(pid); 11145 if (p.mWakeNesting++ == 0) { 11146 p.mWakeStartMs = elapsedRealtimeMs; 11147 } 11148 } 11149 } 11150 } 11151 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)11152 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 11153 Wakelock wl = mWakelockStats.stopObject(name, elapsedRealtimeMs); 11154 if (wl != null) { 11155 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 11156 wlt.stopRunningLocked(elapsedRealtimeMs); 11157 } 11158 if (type == WAKE_TYPE_PARTIAL) { 11159 if (mAggregatedPartialWakelockTimer != null) { 11160 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 11161 } 11162 if (pid >= 0) { 11163 Pid p = mPids.get(pid); 11164 if (p != null && p.mWakeNesting > 0) { 11165 if (p.mWakeNesting-- == 1) { 11166 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 11167 p.mWakeStartMs = 0; 11168 } 11169 } 11170 } 11171 } 11172 } 11173 reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs)11174 public void reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs) { 11175 Proc p = getProcessStatsLocked(proc); 11176 if (p != null) { 11177 p.addExcessiveCpu(overTimeMs, usedTimeMs); 11178 } 11179 } 11180 noteStartSensor(int sensor, long elapsedRealtimeMs)11181 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 11182 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 11183 t.startRunningLocked(elapsedRealtimeMs); 11184 } 11185 noteStopSensor(int sensor, long elapsedRealtimeMs)11186 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 11187 // Don't create a timer if one doesn't already exist 11188 DualTimer t = getSensorTimerLocked(sensor, false); 11189 if (t != null) { 11190 t.stopRunningLocked(elapsedRealtimeMs); 11191 } 11192 } 11193 noteStartGps(long elapsedRealtimeMs)11194 public void noteStartGps(long elapsedRealtimeMs) { 11195 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 11196 } 11197 noteStopGps(long elapsedRealtimeMs)11198 public void noteStopGps(long elapsedRealtimeMs) { 11199 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 11200 } 11201 } 11202 11203 @GuardedBy("this") getCpuScalingPolicies()11204 public CpuScalingPolicies getCpuScalingPolicies() { 11205 return mCpuScalingPolicies; 11206 } 11207 11208 @GuardedBy("this") getCpuTimeInFreqContainer()11209 private LongArrayMultiStateCounter.LongArrayContainer getCpuTimeInFreqContainer() { 11210 if (mTmpCpuTimeInFreq == null) { 11211 mTmpCpuTimeInFreq = 11212 new LongArrayMultiStateCounter.LongArrayContainer( 11213 mCpuScalingPolicies.getScalingStepCount()); 11214 } 11215 return mTmpCpuTimeInFreq; 11216 } 11217 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)11218 public BatteryStatsImpl(@NonNull BatteryStatsConfig config, @NonNull Clock clock, 11219 @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, 11220 @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback, 11221 @Nullable EnergyStatsRetriever energyStatsRetriever, 11222 @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile, 11223 @NonNull CpuScalingPolicies cpuScalingPolicies, 11224 @NonNull PowerStatsUidResolver powerStatsUidResolver) { 11225 this(config, clock, monotonicClock, systemDir, handler, platformIdleStateCallback, 11226 energyStatsRetriever, userInfoProvider, powerProfile, cpuScalingPolicies, 11227 powerStatsUidResolver, new FrameworkStatsLogger(), 11228 new BatteryStatsHistory.TraceDelegate(), new BatteryStatsHistory.EventLogger()); 11229 } 11230 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)11231 public BatteryStatsImpl(@NonNull BatteryStatsConfig config, @NonNull Clock clock, 11232 @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, 11233 @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback, 11234 @Nullable EnergyStatsRetriever energyStatsRetriever, 11235 @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile, 11236 @NonNull CpuScalingPolicies cpuScalingPolicies, 11237 @NonNull PowerStatsUidResolver powerStatsUidResolver, 11238 @NonNull FrameworkStatsLogger frameworkStatsLogger, 11239 @NonNull BatteryStatsHistory.TraceDelegate traceDelegate, 11240 @NonNull BatteryStatsHistory.EventLogger eventLogger) { 11241 mClock = clock; 11242 initKernelStatsReaders(); 11243 11244 mBatteryStatsConfig = config; 11245 mMonotonicClock = monotonicClock; 11246 mHandler = new MyHandler(handler.getLooper()); 11247 mConstants = new Constants(mHandler); 11248 11249 mPowerProfile = powerProfile; 11250 mCpuScalingPolicies = cpuScalingPolicies; 11251 mPowerStatsUidResolver = powerStatsUidResolver; 11252 mFrameworkStatsLogger = frameworkStatsLogger; 11253 11254 initPowerProfile(); 11255 11256 if (systemDir != null) { 11257 mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); 11258 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 11259 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 11260 } else { 11261 mStatsFile = null; 11262 mCheckinFile = null; 11263 mDailyFile = null; 11264 } 11265 11266 mHistory = new BatteryStatsHistory(null /* historyBuffer */, systemDir, 11267 mConstants.MAX_HISTORY_FILES, mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, 11268 mClock, mMonotonicClock, traceDelegate, eventLogger); 11269 11270 mCpuPowerStatsCollector = new CpuPowerStatsCollector(mPowerStatsCollectorInjector); 11271 mCpuPowerStatsCollector.addConsumer(this::recordPowerStats); 11272 11273 mMobileRadioPowerStatsCollector = new MobileRadioPowerStatsCollector( 11274 mPowerStatsCollectorInjector); 11275 mMobileRadioPowerStatsCollector.addConsumer(this::recordPowerStats); 11276 11277 mWifiPowerStatsCollector = new WifiPowerStatsCollector(mPowerStatsCollectorInjector); 11278 mWifiPowerStatsCollector.addConsumer(this::recordPowerStats); 11279 11280 mBluetoothPowerStatsCollector = new BluetoothPowerStatsCollector( 11281 mPowerStatsCollectorInjector); 11282 mBluetoothPowerStatsCollector.addConsumer(this::recordPowerStats); 11283 11284 mStartCount++; 11285 initTimersAndCounters(); 11286 mOnBattery = mOnBatteryInternal = false; 11287 long uptimeUs = mClock.uptimeMillis() * 1000; 11288 long realtimeUs = mClock.elapsedRealtime() * 1000; 11289 initTimes(uptimeUs, realtimeUs); 11290 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 11291 initDischarge(realtimeUs); 11292 updateDailyDeadlineLocked(); 11293 mPlatformIdleStateCallback = platformIdleStateCallback; 11294 mEnergyConsumerRetriever = energyStatsRetriever; 11295 mUserInfoProvider = userInfoProvider; 11296 11297 mPowerStatsUidResolver.addListener(new PowerStatsUidResolver.Listener() { 11298 @Override 11299 public void onIsolatedUidAdded(int isolatedUid, int parentUid) { 11300 BatteryStatsImpl.this.onIsolatedUidAdded(isolatedUid, parentUid); 11301 } 11302 11303 @Override 11304 public void onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid) { 11305 BatteryStatsImpl.this.onBeforeIsolatedUidRemoved(isolatedUid, parentUid); 11306 } 11307 11308 @Override 11309 public void onAfterIsolatedUidRemoved(int isolatedUid, int parentUid) { 11310 BatteryStatsImpl.this.onAfterIsolatedUidRemoved(isolatedUid, parentUid); 11311 } 11312 }); 11313 11314 // Notify statsd that the system is initially not in doze. 11315 mDeviceIdleMode = DEVICE_IDLE_MODE_OFF; 11316 mFrameworkStatsLogger.deviceIdleModeStateChanged(mDeviceIdleMode); 11317 } 11318 recordPowerStats(PowerStats stats)11319 private void recordPowerStats(PowerStats stats) { 11320 if (stats.durationMs > 0) { 11321 synchronized (this) { 11322 mHistory.recordPowerStats(mClock.elapsedRealtime(), mClock.uptimeMillis(), stats); 11323 } 11324 } 11325 } 11326 11327 @VisibleForTesting initTimersAndCounters()11328 protected void initTimersAndCounters() { 11329 mScreenOnTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase); 11330 mScreenDozeTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase); 11331 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11332 mScreenBrightnessTimer[i] = new StopwatchTimer(mClock, null, -100 - i, null, 11333 mOnBatteryTimeBase); 11334 } 11335 11336 mPerDisplayBatteryStats = new DisplayBatteryStats[1]; 11337 mPerDisplayBatteryStats[0] = new DisplayBatteryStats(mClock, mOnBatteryTimeBase); 11338 11339 mInteractiveTimer = new StopwatchTimer(mClock, null, -10, null, mOnBatteryTimeBase); 11340 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClock, null, -2, null, 11341 mOnBatteryTimeBase); 11342 mDeviceIdleModeLightTimer = new StopwatchTimer(mClock, null, -11, null, 11343 mOnBatteryTimeBase); 11344 mDeviceIdleModeFullTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase); 11345 mDeviceLightIdlingTimer = new StopwatchTimer(mClock, null, -15, null, mOnBatteryTimeBase); 11346 mDeviceIdlingTimer = new StopwatchTimer(mClock, null, -12, null, mOnBatteryTimeBase); 11347 mPhoneOnTimer = new StopwatchTimer(mClock, null, -3, null, mOnBatteryTimeBase); 11348 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 11349 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -200 - i, null, 11350 mOnBatteryTimeBase); 11351 } 11352 mPhoneSignalScanningTimer = new StopwatchTimer(mClock, null, -200 + 1, null, 11353 mOnBatteryTimeBase); 11354 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11355 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClock, null, -300 - i, null, 11356 mOnBatteryTimeBase); 11357 } 11358 mNrNsaTimer = new StopwatchTimer(mClock, null, -200 + 2, null, mOnBatteryTimeBase); 11359 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11360 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 11361 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 11362 } 11363 mWifiActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 11364 NUM_WIFI_TX_LEVELS); 11365 mBluetoothActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 11366 NUM_BT_TX_LEVELS); 11367 mModemActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 11368 MODEM_TX_POWER_LEVEL_COUNT); 11369 mMobileRadioActiveTimer = new StopwatchTimer(mClock, null, -400, null, mOnBatteryTimeBase); 11370 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClock, null, -401, null, 11371 mOnBatteryTimeBase); 11372 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 11373 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 11374 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 11375 mWifiMulticastWakelockTimer = new StopwatchTimer(mClock, null, 11376 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 11377 mWifiOnTimer = new StopwatchTimer(mClock, null, -4, null, mOnBatteryTimeBase); 11378 mGlobalWifiRunningTimer = new StopwatchTimer(mClock, null, -5, null, mOnBatteryTimeBase); 11379 for (int i=0; i<NUM_WIFI_STATES; i++) { 11380 mWifiStateTimer[i] = new StopwatchTimer(mClock, null, -600 - i, null, 11381 mOnBatteryTimeBase); 11382 } 11383 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11384 mWifiSupplStateTimer[i] = new StopwatchTimer(mClock, null, -700 - i, null, 11385 mOnBatteryTimeBase); 11386 } 11387 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11388 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -800 - i, null, 11389 mOnBatteryTimeBase); 11390 } 11391 mWifiActiveTimer = new StopwatchTimer(mClock, null, -900, null, mOnBatteryTimeBase); 11392 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 11393 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClock, null, -1000 - i, null, 11394 mOnBatteryTimeBase); 11395 } 11396 mAudioOnTimer = new StopwatchTimer(mClock, null, -7, null, mOnBatteryTimeBase); 11397 mVideoOnTimer = new StopwatchTimer(mClock, null, -8, null, mOnBatteryTimeBase); 11398 mFlashlightOnTimer = new StopwatchTimer(mClock, null, -9, null, mOnBatteryTimeBase); 11399 mCameraOnTimer = new StopwatchTimer(mClock, null, -13, null, mOnBatteryTimeBase); 11400 mBluetoothScanTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase); 11401 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 11402 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11403 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11404 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11405 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11406 mDischargeUnplugLevel = 0; 11407 mDischargePlugLevel = -1; 11408 mDischargeCurrentLevel = 0; 11409 mBatteryLevel = 0; 11410 } 11411 initPowerProfile()11412 private void initPowerProfile() { 11413 int[] policies = mCpuScalingPolicies.getPolicies(); 11414 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[policies.length]; 11415 for (int i = 0; i < policies.length; i++) { 11416 int[] cpus = mCpuScalingPolicies.getRelatedCpus(policies[i]); 11417 int[] freqs = mCpuScalingPolicies.getFrequencies(policies[i]); 11418 // We need to initialize the KernelCpuSpeedReaders to read from 11419 // the first cpu of each core. Once we have the CpuScalingPolicy, we have access to this 11420 // information. 11421 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(cpus[0], freqs.length); 11422 } 11423 11424 // Initialize CPU power bracket map, which combines CPU states (cluster/freq pairs) 11425 // into a small number of brackets 11426 mCpuPowerBracketMap = new int[mCpuScalingPolicies.getScalingStepCount()]; 11427 int index = 0; 11428 for (int policy : policies) { 11429 int steps = mCpuScalingPolicies.getFrequencies(policy).length; 11430 for (int step = 0; step < steps; step++) { 11431 mCpuPowerBracketMap[index++] = 11432 mPowerProfile.getCpuPowerBracketForScalingStep(policy, step); 11433 } 11434 } 11435 11436 if (mEstimatedBatteryCapacityMah == -1) { 11437 // Initialize the estimated battery capacity to a known preset one. 11438 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 11439 } 11440 11441 setDisplayCountLocked(mPowerProfile.getNumDisplays()); 11442 } 11443 getPowerProfile()11444 PowerProfile getPowerProfile() { 11445 return mPowerProfile; 11446 } 11447 11448 /** 11449 * Starts tracking CPU time-in-state for threads of the system server process, 11450 * keeping a separate account of threads receiving incoming binder calls. 11451 */ startTrackingSystemServerCpuTime()11452 public void startTrackingSystemServerCpuTime() { 11453 mSystemServerCpuThreadReader.startTrackingThreadCpuTime(); 11454 } 11455 getSystemServiceCpuThreadTimes()11456 public SystemServiceCpuThreadTimes getSystemServiceCpuThreadTimes() { 11457 return mSystemServerCpuThreadReader.readAbsolute(); 11458 } 11459 setCallback(BatteryCallback cb)11460 public void setCallback(BatteryCallback cb) { 11461 mCallback = cb; 11462 } 11463 setRadioScanningTimeoutLocked(long timeoutUs)11464 public void setRadioScanningTimeoutLocked(long timeoutUs) { 11465 if (mPhoneSignalScanningTimer != null) { 11466 mPhoneSignalScanningTimer.setTimeout(timeoutUs); 11467 } 11468 } 11469 setExternalStatsSyncLocked(ExternalStatsSync sync)11470 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 11471 mExternalSync = sync; 11472 } 11473 11474 /** 11475 * Initialize and set multi display timers and states. 11476 */ setDisplayCountLocked(int numDisplays)11477 public void setDisplayCountLocked(int numDisplays) { 11478 mPerDisplayBatteryStats = new DisplayBatteryStats[numDisplays]; 11479 for (int i = 0; i < numDisplays; i++) { 11480 mPerDisplayBatteryStats[i] = new DisplayBatteryStats(mClock, mOnBatteryTimeBase); 11481 } 11482 } 11483 updateDailyDeadlineLocked()11484 public void updateDailyDeadlineLocked() { 11485 // Get the current time. 11486 long currentTimeMs = mDailyStartTimeMs = mClock.currentTimeMillis(); 11487 Calendar calDeadline = Calendar.getInstance(); 11488 calDeadline.setTimeInMillis(currentTimeMs); 11489 11490 // Move time up to the next day, ranging from 1am to 3pm. 11491 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 11492 calDeadline.set(Calendar.MILLISECOND, 0); 11493 calDeadline.set(Calendar.SECOND, 0); 11494 calDeadline.set(Calendar.MINUTE, 0); 11495 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 11496 mNextMinDailyDeadlineMs = calDeadline.getTimeInMillis(); 11497 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 11498 mNextMaxDailyDeadlineMs = calDeadline.getTimeInMillis(); 11499 } 11500 recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs)11501 public void recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs) { 11502 if (currentTimeMs >= mNextMaxDailyDeadlineMs) { 11503 recordDailyStatsLocked(); 11504 } else if (settled && currentTimeMs >= mNextMinDailyDeadlineMs) { 11505 recordDailyStatsLocked(); 11506 } else if (currentTimeMs < (mDailyStartTimeMs - (1000 * 60 * 60 * 24))) { 11507 recordDailyStatsLocked(); 11508 } 11509 } 11510 recordDailyStatsLocked()11511 public void recordDailyStatsLocked() { 11512 DailyItem item = new DailyItem(); 11513 item.mStartTime = mDailyStartTimeMs; 11514 item.mEndTime = mClock.currentTimeMillis(); 11515 boolean hasData = false; 11516 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 11517 hasData = true; 11518 item.mDischargeSteps = new LevelStepTracker( 11519 mDailyDischargeStepTracker.mNumStepDurations, 11520 mDailyDischargeStepTracker.mStepDurations); 11521 } 11522 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 11523 hasData = true; 11524 item.mChargeSteps = new LevelStepTracker( 11525 mDailyChargeStepTracker.mNumStepDurations, 11526 mDailyChargeStepTracker.mStepDurations); 11527 } 11528 if (mDailyPackageChanges != null) { 11529 hasData = true; 11530 item.mPackageChanges = mDailyPackageChanges; 11531 mDailyPackageChanges = null; 11532 } 11533 mDailyDischargeStepTracker.init(); 11534 mDailyChargeStepTracker.init(); 11535 updateDailyDeadlineLocked(); 11536 11537 if (hasData) { 11538 final long startTimeMs = SystemClock.uptimeMillis(); 11539 mDailyItems.add(item); 11540 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 11541 mDailyItems.remove(0); 11542 } 11543 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 11544 try { 11545 TypedXmlSerializer out = Xml.resolveSerializer(memStream); 11546 writeDailyItemsLocked(out); 11547 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 11548 BackgroundThread.getHandler().post(new Runnable() { 11549 @Override 11550 public void run() { 11551 synchronized (mCheckinFile) { 11552 final long startTimeMs2 = SystemClock.uptimeMillis(); 11553 FileOutputStream stream = null; 11554 try { 11555 stream = mDailyFile.startWrite(); 11556 memStream.writeTo(stream); 11557 stream.flush(); 11558 mDailyFile.finishWrite(stream); 11559 mFrameworkStatsLogger.writeCommitSysConfigFile("batterystats-daily", 11560 initialTimeMs + SystemClock.uptimeMillis() - startTimeMs2); 11561 } catch (IOException e) { 11562 Slog.w("BatteryStats", 11563 "Error writing battery daily items", e); 11564 mDailyFile.failWrite(stream); 11565 } 11566 } 11567 } 11568 }); 11569 } catch (IOException e) { 11570 } 11571 } 11572 } 11573 writeDailyItemsLocked(TypedXmlSerializer out)11574 private void writeDailyItemsLocked(TypedXmlSerializer out) throws IOException { 11575 StringBuilder sb = new StringBuilder(64); 11576 out.startDocument(null, true); 11577 out.startTag(null, "daily-items"); 11578 for (int i=0; i<mDailyItems.size(); i++) { 11579 final DailyItem dit = mDailyItems.get(i); 11580 out.startTag(null, "item"); 11581 out.attributeLong(null, "start", dit.mStartTime); 11582 out.attributeLong(null, "end", dit.mEndTime); 11583 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 11584 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 11585 if (dit.mPackageChanges != null) { 11586 for (int j=0; j<dit.mPackageChanges.size(); j++) { 11587 PackageChange pc = dit.mPackageChanges.get(j); 11588 if (pc.mUpdate) { 11589 out.startTag(null, "upd"); 11590 out.attribute(null, "pkg", pc.mPackageName); 11591 out.attributeLong(null, "ver", pc.mVersionCode); 11592 out.endTag(null, "upd"); 11593 } else { 11594 out.startTag(null, "rem"); 11595 out.attribute(null, "pkg", pc.mPackageName); 11596 out.endTag(null, "rem"); 11597 } 11598 } 11599 } 11600 out.endTag(null, "item"); 11601 } 11602 out.endTag(null, "daily-items"); 11603 out.endDocument(); 11604 } 11605 writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)11606 private void writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, 11607 StringBuilder tmpBuilder) throws IOException { 11608 if (steps != null) { 11609 out.startTag(null, tag); 11610 out.attributeInt(null, "n", steps.mNumStepDurations); 11611 for (int i=0; i<steps.mNumStepDurations; i++) { 11612 out.startTag(null, "s"); 11613 tmpBuilder.setLength(0); 11614 steps.encodeEntryAt(i, tmpBuilder); 11615 out.attribute(null, "v", tmpBuilder.toString()); 11616 out.endTag(null, "s"); 11617 } 11618 out.endTag(null, tag); 11619 } 11620 } 11621 11622 @GuardedBy("this") readDailyStatsLocked()11623 public void readDailyStatsLocked() { 11624 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 11625 mDailyItems.clear(); 11626 FileInputStream stream; 11627 try { 11628 stream = mDailyFile.openRead(); 11629 } catch (FileNotFoundException e) { 11630 return; 11631 } 11632 try { 11633 TypedXmlPullParser parser = Xml.resolvePullParser(stream); 11634 readDailyItemsLocked(parser); 11635 } catch (IOException e) { 11636 } finally { 11637 try { 11638 stream.close(); 11639 } catch (IOException e) { 11640 } 11641 } 11642 } 11643 readDailyItemsLocked(TypedXmlPullParser parser)11644 private void readDailyItemsLocked(TypedXmlPullParser parser) { 11645 try { 11646 int type; 11647 while ((type = parser.next()) != XmlPullParser.START_TAG 11648 && type != XmlPullParser.END_DOCUMENT) { 11649 ; 11650 } 11651 11652 if (type != XmlPullParser.START_TAG) { 11653 throw new IllegalStateException("no start tag found"); 11654 } 11655 11656 int outerDepth = parser.getDepth(); 11657 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11658 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11659 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11660 continue; 11661 } 11662 11663 String tagName = parser.getName(); 11664 if (tagName.equals("item")) { 11665 readDailyItemTagLocked(parser); 11666 } else { 11667 Slog.w(TAG, "Unknown element under <daily-items>: " 11668 + parser.getName()); 11669 XmlUtils.skipCurrentTag(parser); 11670 } 11671 } 11672 11673 } catch (IllegalStateException e) { 11674 Slog.w(TAG, "Failed parsing daily " + e); 11675 } catch (NullPointerException e) { 11676 Slog.w(TAG, "Failed parsing daily " + e); 11677 } catch (NumberFormatException e) { 11678 Slog.w(TAG, "Failed parsing daily " + e); 11679 } catch (XmlPullParserException e) { 11680 Slog.w(TAG, "Failed parsing daily " + e); 11681 } catch (IOException e) { 11682 Slog.w(TAG, "Failed parsing daily " + e); 11683 } catch (IndexOutOfBoundsException e) { 11684 Slog.w(TAG, "Failed parsing daily " + e); 11685 } 11686 } 11687 readDailyItemTagLocked(TypedXmlPullParser parser)11688 void readDailyItemTagLocked(TypedXmlPullParser parser) throws NumberFormatException, 11689 XmlPullParserException, IOException { 11690 DailyItem dit = new DailyItem(); 11691 dit.mStartTime = parser.getAttributeLong(null, "start", 0); 11692 dit.mEndTime = parser.getAttributeLong(null, "end", 0); 11693 int outerDepth = parser.getDepth(); 11694 int type; 11695 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11696 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11697 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11698 continue; 11699 } 11700 11701 String tagName = parser.getName(); 11702 if (tagName.equals("dis")) { 11703 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 11704 } else if (tagName.equals("chg")) { 11705 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 11706 } else if (tagName.equals("upd")) { 11707 if (dit.mPackageChanges == null) { 11708 dit.mPackageChanges = new ArrayList<>(); 11709 } 11710 PackageChange pc = new PackageChange(); 11711 pc.mUpdate = true; 11712 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11713 pc.mVersionCode = parser.getAttributeLong(null, "ver", 0); 11714 dit.mPackageChanges.add(pc); 11715 XmlUtils.skipCurrentTag(parser); 11716 } else if (tagName.equals("rem")) { 11717 if (dit.mPackageChanges == null) { 11718 dit.mPackageChanges = new ArrayList<>(); 11719 } 11720 PackageChange pc = new PackageChange(); 11721 pc.mUpdate = false; 11722 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11723 dit.mPackageChanges.add(pc); 11724 XmlUtils.skipCurrentTag(parser); 11725 } else { 11726 Slog.w(TAG, "Unknown element under <item>: " 11727 + parser.getName()); 11728 XmlUtils.skipCurrentTag(parser); 11729 } 11730 } 11731 mDailyItems.add(dit); 11732 } 11733 readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, String tag)11734 void readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, 11735 String tag) 11736 throws NumberFormatException, XmlPullParserException, IOException { 11737 final int num = parser.getAttributeInt(null, "n", -1); 11738 if (num == -1) { 11739 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 11740 XmlUtils.skipCurrentTag(parser); 11741 return; 11742 } 11743 LevelStepTracker steps = new LevelStepTracker(num); 11744 if (isCharge) { 11745 dit.mChargeSteps = steps; 11746 } else { 11747 dit.mDischargeSteps = steps; 11748 } 11749 int i = 0; 11750 int outerDepth = parser.getDepth(); 11751 int type; 11752 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11753 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11754 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11755 continue; 11756 } 11757 11758 String tagName = parser.getName(); 11759 if ("s".equals(tagName)) { 11760 if (i < num) { 11761 String valueAttr = parser.getAttributeValue(null, "v"); 11762 if (valueAttr != null) { 11763 steps.decodeEntryAt(i, valueAttr); 11764 i++; 11765 } 11766 } 11767 } else { 11768 Slog.w(TAG, "Unknown element under <" + tag + ">: " 11769 + parser.getName()); 11770 XmlUtils.skipCurrentTag(parser); 11771 } 11772 } 11773 steps.mNumStepDurations = i; 11774 } 11775 11776 @Override getDailyItemLocked(int daysAgo)11777 public DailyItem getDailyItemLocked(int daysAgo) { 11778 int index = mDailyItems.size()-1-daysAgo; 11779 return index >= 0 ? mDailyItems.get(index) : null; 11780 } 11781 11782 @Override getCurrentDailyStartTime()11783 public long getCurrentDailyStartTime() { 11784 return mDailyStartTimeMs; 11785 } 11786 11787 @Override getNextMinDailyDeadline()11788 public long getNextMinDailyDeadline() { 11789 return mNextMinDailyDeadlineMs; 11790 } 11791 11792 @Override getNextMaxDailyDeadline()11793 public long getNextMaxDailyDeadline() { 11794 return mNextMaxDailyDeadlineMs; 11795 } 11796 11797 @GuardedBy("this") getHistoryTotalSize()11798 public int getHistoryTotalSize() { 11799 return mConstants.MAX_HISTORY_BUFFER * mConstants.MAX_HISTORY_FILES; 11800 } 11801 getHistoryUsedSize()11802 public int getHistoryUsedSize() { 11803 return mHistory.getHistoryUsedSize(); 11804 } 11805 11806 /** 11807 * Creates an iterator for battery stats history. 11808 */ 11809 @Override iterateBatteryStatsHistory(long startTimeMs, long endTimeMs)11810 public BatteryStatsHistoryIterator iterateBatteryStatsHistory(long startTimeMs, 11811 long endTimeMs) { 11812 return mHistory.iterate(startTimeMs, endTimeMs); 11813 } 11814 11815 @Override getHistoryStringPoolSize()11816 public int getHistoryStringPoolSize() { 11817 return mHistory.getHistoryStringPoolSize(); 11818 } 11819 11820 @Override getHistoryStringPoolBytes()11821 public int getHistoryStringPoolBytes() { 11822 return mHistory.getHistoryStringPoolBytes(); 11823 } 11824 11825 @Override getHistoryTagPoolString(int index)11826 public String getHistoryTagPoolString(int index) { 11827 return mHistory.getHistoryTagPoolString(index); 11828 } 11829 11830 @Override getHistoryTagPoolUid(int index)11831 public int getHistoryTagPoolUid(int index) { 11832 return mHistory.getHistoryTagPoolUid(index); 11833 } 11834 11835 @Override getStartCount()11836 public int getStartCount() { 11837 return mStartCount; 11838 } 11839 isOnBattery()11840 public boolean isOnBattery() { 11841 return mOnBattery; 11842 } 11843 isCharging()11844 public boolean isCharging() { 11845 return mCharging; 11846 } 11847 initTimes(long uptimeUs, long realtimeUs)11848 void initTimes(long uptimeUs, long realtimeUs) { 11849 mStartClockTimeMs = mClock.currentTimeMillis(); 11850 mOnBatteryTimeBase.init(uptimeUs, realtimeUs); 11851 mOnBatteryScreenOffTimeBase.init(uptimeUs, realtimeUs); 11852 mRealtimeUs = 0; 11853 mUptimeUs = 0; 11854 mRealtimeStartUs = realtimeUs; 11855 mUptimeStartUs = uptimeUs; 11856 mMonotonicStartTime = mMonotonicClock.monotonicTime(); 11857 } 11858 initDischarge(long elapsedRealtimeUs)11859 void initDischarge(long elapsedRealtimeUs) { 11860 mLowDischargeAmountSinceCharge = 0; 11861 mHighDischargeAmountSinceCharge = 0; 11862 mDischargeAmountScreenOn = 0; 11863 mDischargeAmountScreenOnSinceCharge = 0; 11864 mDischargeAmountScreenOff = 0; 11865 mDischargeAmountScreenOffSinceCharge = 0; 11866 mDischargeAmountScreenDoze = 0; 11867 mDischargeAmountScreenDozeSinceCharge = 0; 11868 mDischargeStepTracker.init(); 11869 mChargeStepTracker.init(); 11870 mDischargeScreenOffCounter.reset(false, elapsedRealtimeUs); 11871 mDischargeScreenDozeCounter.reset(false, elapsedRealtimeUs); 11872 mDischargeLightDozeCounter.reset(false, elapsedRealtimeUs); 11873 mDischargeDeepDozeCounter.reset(false, elapsedRealtimeUs); 11874 mDischargeCounter.reset(false, elapsedRealtimeUs); 11875 } 11876 11877 /** 11878 * Associates the BatteryStatsImpl object with a BatteryUsageStatsProvider and PowerStatsStore 11879 * to allow for a snapshot of battery usage stats to be taken and stored just before battery 11880 * reset. 11881 */ saveBatteryUsageStatsOnReset( @onNull BatteryUsageStatsProvider batteryUsageStatsProvider, @NonNull PowerStatsStore powerStatsStore)11882 public void saveBatteryUsageStatsOnReset( 11883 @NonNull BatteryUsageStatsProvider batteryUsageStatsProvider, 11884 @NonNull PowerStatsStore powerStatsStore) { 11885 mSaveBatteryUsageStatsOnReset = true; 11886 mBatteryUsageStatsProvider = batteryUsageStatsProvider; 11887 mPowerStatsStore = powerStatsStore; 11888 } 11889 11890 @GuardedBy("this") resetAllStatsAndHistoryLocked(int reason)11891 public void resetAllStatsAndHistoryLocked(int reason) { 11892 final long mSecUptime = mClock.uptimeMillis(); 11893 long uptimeUs = mSecUptime * 1000; 11894 long mSecRealtime = mClock.elapsedRealtime(); 11895 long realtimeUs = mSecRealtime * 1000; 11896 resetAllStatsLocked(mSecUptime, mSecRealtime, reason); 11897 pullPendingStateUpdatesLocked(); 11898 mHistory.writeHistoryItem(mSecRealtime, mSecUptime); 11899 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel = mBatteryLevel; 11900 mOnBatteryTimeBase.reset(uptimeUs, realtimeUs); 11901 mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs); 11902 if (!mBatteryPluggedIn) { 11903 if (Display.isOnState(mScreenState)) { 11904 mDischargeScreenOnUnplugLevel = mBatteryLevel; 11905 mDischargeScreenDozeUnplugLevel = 0; 11906 mDischargeScreenOffUnplugLevel = 0; 11907 } else if (Display.isDozeState(mScreenState)) { 11908 mDischargeScreenOnUnplugLevel = 0; 11909 mDischargeScreenDozeUnplugLevel = mBatteryLevel; 11910 mDischargeScreenOffUnplugLevel = 0; 11911 } else { 11912 mDischargeScreenOnUnplugLevel = 0; 11913 mDischargeScreenDozeUnplugLevel = 0; 11914 mDischargeScreenOffUnplugLevel = mBatteryLevel; 11915 } 11916 mDischargeAmountScreenOn = 0; 11917 mDischargeAmountScreenOff = 0; 11918 mDischargeAmountScreenDoze = 0; 11919 } 11920 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 11921 } 11922 11923 @GuardedBy("this") resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, int resetReason)11924 private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, 11925 int resetReason) { 11926 saveBatteryUsageStatsOnReset(resetReason); 11927 11928 final long uptimeUs = uptimeMillis * 1000; 11929 final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000; 11930 mStartCount = 0; 11931 initTimes(uptimeUs, elapsedRealtimeUs); 11932 mScreenOnTimer.reset(false, elapsedRealtimeUs); 11933 mScreenDozeTimer.reset(false, elapsedRealtimeUs); 11934 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11935 mScreenBrightnessTimer[i].reset(false, elapsedRealtimeUs); 11936 } 11937 11938 final int numDisplays = mPerDisplayBatteryStats.length; 11939 for (int i = 0; i < numDisplays; i++) { 11940 mPerDisplayBatteryStats[i].reset(elapsedRealtimeUs); 11941 } 11942 11943 if (mPowerProfile != null) { 11944 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 11945 } else { 11946 mEstimatedBatteryCapacityMah = -1; 11947 } 11948 mLastLearnedBatteryCapacityUah = -1; 11949 mMinLearnedBatteryCapacityUah = -1; 11950 mMaxLearnedBatteryCapacityUah = -1; 11951 mInteractiveTimer.reset(false, elapsedRealtimeUs); 11952 mPowerSaveModeEnabledTimer.reset(false, elapsedRealtimeUs); 11953 mLastIdleTimeStartMs = elapsedRealtimeMillis; 11954 mLongestLightIdleTimeMs = 0; 11955 mLongestFullIdleTimeMs = 0; 11956 mDeviceIdleModeLightTimer.reset(false, elapsedRealtimeUs); 11957 mDeviceIdleModeFullTimer.reset(false, elapsedRealtimeUs); 11958 mDeviceLightIdlingTimer.reset(false, elapsedRealtimeUs); 11959 mDeviceIdlingTimer.reset(false, elapsedRealtimeUs); 11960 mPhoneOnTimer.reset(false, elapsedRealtimeUs); 11961 mAudioOnTimer.reset(false, elapsedRealtimeUs); 11962 mVideoOnTimer.reset(false, elapsedRealtimeUs); 11963 mFlashlightOnTimer.reset(false, elapsedRealtimeUs); 11964 mCameraOnTimer.reset(false, elapsedRealtimeUs); 11965 mBluetoothScanTimer.reset(false, elapsedRealtimeUs); 11966 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 11967 mPhoneSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 11968 } 11969 mPhoneSignalScanningTimer.reset(false, elapsedRealtimeUs); 11970 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11971 mPhoneDataConnectionsTimer[i].reset(false, elapsedRealtimeUs); 11972 } 11973 mNrNsaTimer.reset(false, elapsedRealtimeUs); 11974 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11975 mNetworkByteActivityCounters[i].reset(false, elapsedRealtimeUs); 11976 mNetworkPacketActivityCounters[i].reset(false, elapsedRealtimeUs); 11977 } 11978 for (int i = 0; i < RADIO_ACCESS_TECHNOLOGY_COUNT; i++) { 11979 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[i]; 11980 if (stats == null) continue; 11981 stats.reset(elapsedRealtimeUs); 11982 } 11983 mMobileRadioActiveTimer.reset(false, elapsedRealtimeUs); 11984 mMobileRadioActivePerAppTimer.reset(false, elapsedRealtimeUs); 11985 mMobileRadioActiveAdjustedTime.reset(false, elapsedRealtimeUs); 11986 mMobileRadioActiveUnknownTime.reset(false, elapsedRealtimeUs); 11987 mMobileRadioActiveUnknownCount.reset(false, elapsedRealtimeUs); 11988 mWifiOnTimer.reset(false, elapsedRealtimeUs); 11989 mGlobalWifiRunningTimer.reset(false, elapsedRealtimeUs); 11990 for (int i=0; i<NUM_WIFI_STATES; i++) { 11991 mWifiStateTimer[i].reset(false, elapsedRealtimeUs); 11992 } 11993 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11994 mWifiSupplStateTimer[i].reset(false, elapsedRealtimeUs); 11995 } 11996 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11997 mWifiSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 11998 } 11999 mWifiMulticastWakelockTimer.reset(false, elapsedRealtimeUs); 12000 mWifiActiveTimer.reset(false, elapsedRealtimeUs); 12001 mWifiActivity.reset(false, elapsedRealtimeUs); 12002 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 12003 mGpsSignalQualityTimer[i].reset(false, elapsedRealtimeUs); 12004 } 12005 mBluetoothActivity.reset(false, elapsedRealtimeUs); 12006 mModemActivity.reset(false, elapsedRealtimeUs); 12007 mNumConnectivityChange = 0; 12008 12009 for (int i=0; i<mUidStats.size(); i++) { 12010 if (mUidStats.valueAt(i).reset(uptimeUs, elapsedRealtimeUs, resetReason)) { 12011 mUidStats.valueAt(i).detachFromTimeBase(); 12012 mUidStats.remove(mUidStats.keyAt(i)); 12013 i--; 12014 } 12015 } 12016 12017 if (mRpmStats.size() > 0) { 12018 for (SamplingTimer timer : mRpmStats.values()) { 12019 mOnBatteryTimeBase.remove(timer); 12020 } 12021 mRpmStats.clear(); 12022 } 12023 if (mScreenOffRpmStats.size() > 0) { 12024 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 12025 mOnBatteryScreenOffTimeBase.remove(timer); 12026 } 12027 mScreenOffRpmStats.clear(); 12028 } 12029 12030 if (mKernelWakelockStats.size() > 0) { 12031 for (SamplingTimer timer : mKernelWakelockStats.values()) { 12032 mOnBatteryScreenOffTimeBase.remove(timer); 12033 } 12034 mKernelWakelockStats.clear(); 12035 } 12036 12037 if (mKernelMemoryStats.size() > 0) { 12038 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 12039 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 12040 } 12041 mKernelMemoryStats.clear(); 12042 } 12043 12044 if (mWakeupReasonStats.size() > 0) { 12045 for (SamplingTimer timer : mWakeupReasonStats.values()) { 12046 mOnBatteryTimeBase.remove(timer); 12047 } 12048 mWakeupReasonStats.clear(); 12049 } 12050 12051 if (mTmpRailStats != null) { 12052 mTmpRailStats.reset(); 12053 } 12054 12055 EnergyConsumerStats.resetIfNotNull(mGlobalEnergyConsumerStats); 12056 12057 if (!Flags.disableSystemServicePowerAttr()) { 12058 resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs); 12059 } 12060 12061 mNumAllUidCpuTimeReads = 0; 12062 mNumUidsRemoved = 0; 12063 12064 initDischarge(elapsedRealtimeUs); 12065 12066 mHistory.reset(); 12067 12068 // Store the empty state to disk to ensure consistency 12069 writeSyncLocked(); 12070 12071 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 12072 schedulePowerStatsSampleCollection(); 12073 } 12074 12075 // Flush external data, gathering snapshots, but don't process it since it is pre-reset data 12076 mIgnoreNextExternalStats = true; 12077 mExternalSync.scheduleSync("reset", ExternalStatsSync.UPDATE_ON_RESET); 12078 12079 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 12080 } 12081 saveBatteryUsageStatsOnReset(int resetReason)12082 private void saveBatteryUsageStatsOnReset(int resetReason) { 12083 if (!mSaveBatteryUsageStatsOnReset 12084 || resetReason == BatteryStatsImpl.RESET_REASON_CORRUPT_FILE) { 12085 return; 12086 } 12087 12088 final BatteryUsageStats batteryUsageStats; 12089 synchronized (this) { 12090 batteryUsageStats = mBatteryUsageStatsProvider.getBatteryUsageStats(this, 12091 new BatteryUsageStatsQuery.Builder() 12092 .setMaxStatsAgeMs(0) 12093 .includePowerModels() 12094 .includeProcessStateData() 12095 .build()); 12096 } 12097 12098 // TODO(b/188068523): BatteryUsageStats should use monotonic time for start and end 12099 // Once that change is made, we will be able to use the BatteryUsageStats' monotonic 12100 // start time 12101 long monotonicStartTime = 12102 mMonotonicClock.monotonicTime() - batteryUsageStats.getStatsDuration(); 12103 mHandler.post(() -> { 12104 mPowerStatsStore.storeBatteryUsageStats(monotonicStartTime, batteryUsageStats); 12105 try { 12106 batteryUsageStats.close(); 12107 } catch (IOException e) { 12108 Log.e(TAG, "Cannot close BatteryUsageStats", e); 12109 } 12110 }); 12111 } 12112 12113 @GuardedBy("this") initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)12114 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 12115 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 12116 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 12117 // Not recording process starts/stops. 12118 continue; 12119 } 12120 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 12121 if (active == null) { 12122 continue; 12123 } 12124 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 12125 SparseIntArray uids = ent.getValue(); 12126 for (int j=0; j<uids.size(); j++) { 12127 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 12128 uids.keyAt(j)); 12129 } 12130 } 12131 } 12132 } 12133 12134 @GuardedBy("this") updateDischargeScreenLevelsLocked(int oldState, int newState)12135 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 12136 updateOldDischargeScreenLevelLocked(oldState); 12137 updateNewDischargeScreenLevelLocked(newState); 12138 } 12139 12140 @GuardedBy("this") updateOldDischargeScreenLevelLocked(int state)12141 private void updateOldDischargeScreenLevelLocked(int state) { 12142 if (Display.isOnState(state)) { 12143 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 12144 if (diff > 0) { 12145 mDischargeAmountScreenOn += diff; 12146 mDischargeAmountScreenOnSinceCharge += diff; 12147 } 12148 } else if (Display.isDozeState(state)) { 12149 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 12150 if (diff > 0) { 12151 mDischargeAmountScreenDoze += diff; 12152 mDischargeAmountScreenDozeSinceCharge += diff; 12153 } 12154 } else if (Display.isOffState(state)) { 12155 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 12156 if (diff > 0) { 12157 mDischargeAmountScreenOff += diff; 12158 mDischargeAmountScreenOffSinceCharge += diff; 12159 } 12160 } 12161 } 12162 12163 @GuardedBy("this") updateNewDischargeScreenLevelLocked(int state)12164 private void updateNewDischargeScreenLevelLocked(int state) { 12165 if (Display.isOnState(state)) { 12166 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 12167 mDischargeScreenOffUnplugLevel = 0; 12168 mDischargeScreenDozeUnplugLevel = 0; 12169 } else if (Display.isDozeState(state)) { 12170 mDischargeScreenOnUnplugLevel = 0; 12171 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 12172 mDischargeScreenOffUnplugLevel = 0; 12173 } else if (Display.isOffState(state)) { 12174 mDischargeScreenOnUnplugLevel = 0; 12175 mDischargeScreenDozeUnplugLevel = 0; 12176 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 12177 } 12178 } 12179 12180 @GuardedBy("this") pullPendingStateUpdatesLocked()12181 public void pullPendingStateUpdatesLocked() { 12182 if (mOnBatteryInternal) { 12183 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 12184 } 12185 } 12186 12187 private final Object mWifiNetworkLock = new Object(); 12188 12189 @GuardedBy("mWifiNetworkLock") 12190 private String[] mWifiIfaces = EmptyArray.STRING; 12191 12192 @GuardedBy("mWifiNetworkLock") 12193 private NetworkStats mLastWifiNetworkStats; 12194 12195 private final Object mModemNetworkLock = new Object(); 12196 12197 @GuardedBy("mModemNetworkLock") 12198 private String[] mModemIfaces = EmptyArray.STRING; 12199 12200 @GuardedBy("mModemNetworkLock") 12201 private NetworkStats mLastModemNetworkStats; 12202 12203 @VisibleForTesting readMobileNetworkStatsLocked( @onNull NetworkStatsManager networkStatsManager)12204 protected NetworkStats readMobileNetworkStatsLocked( 12205 @NonNull NetworkStatsManager networkStatsManager) { 12206 return networkStatsManager.getMobileUidStats(); 12207 } 12208 12209 @VisibleForTesting readWifiNetworkStatsLocked( @onNull NetworkStatsManager networkStatsManager)12210 protected NetworkStats readWifiNetworkStatsLocked( 12211 @NonNull NetworkStatsManager networkStatsManager) { 12212 return networkStatsManager.getWifiUidStats(); 12213 } 12214 12215 static class NetworkStatsDelta { 12216 int mUid; 12217 int mSet; 12218 long mRxBytes; 12219 long mRxPackets; 12220 long mTxBytes; 12221 long mTxPackets; 12222 getUid()12223 public int getUid() { 12224 return mUid; 12225 } 12226 12227 getSet()12228 public int getSet() { 12229 return mSet; 12230 } 12231 getRxBytes()12232 public long getRxBytes() { 12233 return mRxBytes; 12234 } 12235 getRxPackets()12236 public long getRxPackets() { 12237 return mRxPackets; 12238 } 12239 getTxBytes()12240 public long getTxBytes() { 12241 return mTxBytes; 12242 } 12243 getTxPackets()12244 public long getTxPackets() { 12245 return mTxPackets; 12246 } 12247 12248 @Override toString()12249 public String toString() { 12250 return "NetworkStatsDelta{mUid=" + mUid + ", mSet=" + mSet + ", mRxBytes=" + mRxBytes 12251 + ", mRxPackets=" + mRxPackets + ", mTxBytes=" + mTxBytes + ", mTxPackets=" 12252 + mTxPackets + '}'; 12253 } 12254 } 12255 computeDelta(NetworkStats currentStats, NetworkStats lastStats)12256 static List<NetworkStatsDelta> computeDelta(NetworkStats currentStats, 12257 NetworkStats lastStats) { 12258 List<NetworkStatsDelta> deltaList = new ArrayList<>(); 12259 for (NetworkStats.Entry entry : currentStats) { 12260 NetworkStatsDelta delta = new NetworkStatsDelta(); 12261 delta.mUid = entry.getUid(); 12262 delta.mSet = entry.getSet(); 12263 NetworkStats.Entry lastEntry = null; 12264 if (lastStats != null) { 12265 for (NetworkStats.Entry e : lastStats) { 12266 if (e.getUid() == entry.getUid() && e.getSet() == entry.getSet() 12267 && e.getTag() == entry.getTag() 12268 && e.getMetered() == entry.getMetered() 12269 && e.getRoaming() == entry.getRoaming() 12270 && e.getDefaultNetwork() == entry.getDefaultNetwork() 12271 /*&& Objects.equals(e.getIface(), entry.getIface())*/) { 12272 lastEntry = e; 12273 break; 12274 } 12275 } 12276 } 12277 if (lastEntry != null) { 12278 delta.mRxBytes = Math.max(0, entry.getRxBytes() - lastEntry.getRxBytes()); 12279 delta.mRxPackets = Math.max(0, entry.getRxPackets() - lastEntry.getRxPackets()); 12280 delta.mTxBytes = Math.max(0, entry.getTxBytes() - lastEntry.getTxBytes()); 12281 delta.mTxPackets = Math.max(0, entry.getTxPackets() - lastEntry.getTxPackets()); 12282 } else { 12283 delta.mRxBytes = entry.getRxBytes(); 12284 delta.mRxPackets = entry.getRxPackets(); 12285 delta.mTxBytes = entry.getTxBytes(); 12286 delta.mTxPackets = entry.getTxPackets(); 12287 } 12288 deltaList.add(delta); 12289 } 12290 12291 return deltaList; 12292 } 12293 12294 /** 12295 * Distribute WiFi energy info and network traffic to apps. 12296 * @param info The energy information from the WiFi controller. 12297 */ 12298 @GuardedBy("this") updateWifiState(@ullable final WifiActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, @NonNull NetworkStatsManager networkStatsManager)12299 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info, 12300 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, 12301 @NonNull NetworkStatsManager networkStatsManager) { 12302 if (mWifiPowerStatsCollector.isEnabled()) { 12303 return; 12304 } 12305 12306 if (DEBUG_ENERGY) { 12307 synchronized (mWifiNetworkLock) { 12308 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 12309 } 12310 } 12311 12312 // Grab a separate lock to acquire the network stats, which may do I/O. 12313 List<NetworkStatsDelta> delta; 12314 synchronized (mWifiNetworkLock) { 12315 final NetworkStats latestStats = readWifiNetworkStatsLocked(networkStatsManager); 12316 if (latestStats != null) { 12317 delta = computeDelta(latestStats, mLastWifiNetworkStats); 12318 mLastWifiNetworkStats = latestStats; 12319 } else { 12320 delta = null; 12321 } 12322 } 12323 12324 synchronized (this) { 12325 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12326 if (mIgnoreNextExternalStats) { 12327 // TODO: Strictly speaking, we should re-mark all 5 timers for each uid (and the 12328 // global one) here like we do for display. But I'm not sure it's worth the 12329 // complicated code for a codepath that shouldn't ever actually happen in real 12330 // life. 12331 } 12332 return; 12333 } 12334 12335 final SparseDoubleArray uidEstimatedConsumptionMah = 12336 (mGlobalEnergyConsumerStats != null 12337 && mWifiPowerCalculator != null && consumedChargeUC > 0) ? 12338 new SparseDoubleArray() : null; 12339 double totalEstimatedConsumptionMah = 0; 12340 12341 SparseLongArray rxPackets = new SparseLongArray(); 12342 SparseLongArray txPackets = new SparseLongArray(); 12343 SparseLongArray rxTimesMs = new SparseLongArray(); 12344 SparseLongArray txTimesMs = new SparseLongArray(); 12345 long totalTxPackets = 0; 12346 long totalRxPackets = 0; 12347 if (delta != null) { 12348 for (NetworkStatsDelta entry : delta) { 12349 if (DEBUG_ENERGY) { 12350 Slog.d(TAG, "Wifi uid " + entry.getUid() 12351 + ": delta rx=" + entry.getRxBytes() 12352 + " tx=" + entry.getTxBytes() 12353 + " rxPackets=" + entry.getRxPackets() 12354 + " txPackets=" + entry.getTxPackets()); 12355 } 12356 12357 if (entry.getRxBytes() == 0 && entry.getTxBytes() == 0) { 12358 // Skip the lookup below since there is no work to do. 12359 continue; 12360 } 12361 12362 final int uid = mapUid(entry.getUid()); 12363 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 12364 if (entry.getRxBytes() != 0) { 12365 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.getRxBytes(), 12366 entry.getRxPackets()); 12367 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 12368 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.getRxBytes(), 12369 entry.getRxPackets()); 12370 } 12371 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 12372 entry.getRxBytes()); 12373 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 12374 entry.getRxPackets()); 12375 12376 rxPackets.incrementValue(uid, entry.getRxPackets()); 12377 12378 // Sum the total number of packets so that the Rx Power can 12379 // be evenly distributed amongst the apps. 12380 totalRxPackets += entry.getRxPackets(); 12381 } 12382 12383 if (entry.getTxBytes() != 0) { 12384 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.getTxBytes(), 12385 entry.getTxPackets()); 12386 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 12387 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.getTxBytes(), 12388 entry.getTxPackets()); 12389 } 12390 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 12391 entry.getTxBytes()); 12392 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 12393 entry.getTxPackets()); 12394 12395 txPackets.incrementValue(uid, entry.getTxPackets()); 12396 12397 // Sum the total number of packets so that the Tx Power can 12398 // be evenly distributed amongst the apps. 12399 totalTxPackets += entry.getTxPackets(); 12400 } 12401 12402 // Calculate consumed energy for this uid. Only do so if WifiReporting isn't 12403 // enabled (if it is, we'll do it later instead using info). 12404 if (uidEstimatedConsumptionMah != null && info == null && !mHasWifiReporting) { 12405 final long uidRunningMs = u.mWifiRunningTimer 12406 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12407 if (uidRunningMs > 0) u.mWifiRunningTimer.setMark(elapsedRealtimeMs); 12408 12409 final long uidScanMs = u.mWifiScanTimer 12410 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12411 if (uidScanMs > 0) u.mWifiScanTimer.setMark(elapsedRealtimeMs); 12412 12413 long uidBatchScanMs = 0; 12414 for (int bn = 0; bn < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bn++) { 12415 if (u.mWifiBatchedScanTimer[bn] != null) { 12416 long bnMs = u.mWifiBatchedScanTimer[bn] 12417 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12418 if (bnMs > 0) { 12419 u.mWifiBatchedScanTimer[bn].setMark(elapsedRealtimeMs); 12420 } 12421 uidBatchScanMs += bnMs; 12422 } 12423 } 12424 12425 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 12426 mWifiPowerCalculator.calcPowerWithoutControllerDataMah( 12427 entry.getRxPackets(), entry.getTxPackets(), 12428 uidRunningMs, uidScanMs, uidBatchScanMs)); 12429 } 12430 } 12431 delta = null; 12432 } 12433 12434 if (info != null) { 12435 mHasWifiReporting = true; 12436 12437 // Measured in mAms 12438 final long txTimeMs = info.getControllerTxDurationMillis(); 12439 final long rxTimeMs = info.getControllerRxDurationMillis(); 12440 final long scanTimeMs = info.getControllerScanDurationMillis(); 12441 final long idleTimeMs = info.getControllerIdleDurationMillis(); 12442 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 12443 12444 long leftOverRxTimeMs = rxTimeMs; 12445 long leftOverTxTimeMs = txTimeMs; 12446 12447 if (DEBUG_ENERGY) { 12448 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 12449 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 12450 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 12451 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 12452 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 12453 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 12454 } 12455 12456 long totalWifiLockTimeMs = 0; 12457 long totalScanTimeMs = 0; 12458 12459 // On the first pass, collect some totals so that we can normalize power 12460 // calculations if we need to. 12461 final int uidStatsSize = mUidStats.size(); 12462 for (int i = 0; i < uidStatsSize; i++) { 12463 final Uid uid = mUidStats.valueAt(i); 12464 12465 // Sum the total scan power for all apps. 12466 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 12467 elapsedRealtimeMs * 1000) / 1000; 12468 12469 // Sum the total time holding wifi lock for all apps. 12470 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 12471 elapsedRealtimeMs * 1000) / 1000; 12472 } 12473 12474 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 12475 Slog.d(TAG, 12476 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 12477 + rxTimeMs + " ms). Normalizing scan time."); 12478 } 12479 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 12480 Slog.d(TAG, 12481 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 12482 + txTimeMs + " ms). Normalizing scan time."); 12483 } 12484 12485 // Actually assign and distribute power usage to apps. 12486 for (int i = 0; i < uidStatsSize; i++) { 12487 final Uid uid = mUidStats.valueAt(i); 12488 12489 final long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 12490 elapsedRealtimeMs * 1000) / 1000; 12491 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 12492 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 12493 if (scanTimeSinceMarkMs > 0) { 12494 // Set the new mark so that next time we get new data since this point. 12495 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 12496 12497 // Our total scan time is more than the reported Tx/Rx time. 12498 // This is possible because the cost of a scan is approximate. 12499 // Let's normalize the result so that we evenly blame each app 12500 // scanning. 12501 // 12502 // This means that we may have apps that transmitted/received packets not be 12503 // blamed for this, but this is fine as scans are relatively more expensive. 12504 if (totalScanTimeMs > rxTimeMs) { 12505 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 12506 totalScanTimeMs; 12507 } 12508 if (totalScanTimeMs > txTimeMs) { 12509 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 12510 totalScanTimeMs; 12511 } 12512 12513 if (DEBUG_ENERGY) { 12514 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 12515 + scanRxTimeSinceMarkMs + " ms Tx:" 12516 + scanTxTimeSinceMarkMs + " ms)"); 12517 } 12518 12519 rxTimesMs.incrementValue(uid.getUid(), scanRxTimeSinceMarkMs); 12520 txTimesMs.incrementValue(uid.getUid(), scanTxTimeSinceMarkMs); 12521 12522 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 12523 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 12524 } 12525 12526 // Distribute evenly the power consumed while Idle to each app holding a WiFi 12527 // lock. 12528 long myIdleTimeMs = 0; 12529 final long wifiLockTimeSinceMarkMs = 12530 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 12531 elapsedRealtimeMs * 1000) / 1000; 12532 if (wifiLockTimeSinceMarkMs > 0) { 12533 // Set the new mark so that next time we get new data since this point. 12534 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 12535 12536 myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) / totalWifiLockTimeMs; 12537 if (DEBUG_ENERGY) { 12538 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 12539 + myIdleTimeMs + " ms"); 12540 } 12541 uid.getOrCreateWifiControllerActivityLocked().getOrCreateIdleTimeCounter() 12542 .increment(myIdleTimeMs, elapsedRealtimeMs); 12543 } 12544 12545 if (uidEstimatedConsumptionMah != null) { 12546 double uidEstMah = mWifiPowerCalculator.calcPowerFromControllerDataMah( 12547 scanRxTimeSinceMarkMs, scanTxTimeSinceMarkMs, myIdleTimeMs); 12548 uidEstimatedConsumptionMah.incrementValue(uid.getUid(), uidEstMah); 12549 } 12550 } 12551 12552 if (DEBUG_ENERGY) { 12553 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 12554 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 12555 } 12556 12557 // Distribute the remaining Tx power appropriately between all apps that transmitted 12558 // packets. 12559 for (int i = 0; i < txPackets.size(); i++) { 12560 final int uid = txPackets.keyAt(i); 12561 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 12562 / totalTxPackets; 12563 txTimesMs.incrementValue(uid, myTxTimeMs); 12564 } 12565 12566 // Distribute the remaining Rx power appropriately between all apps that received 12567 // packets. 12568 for (int i = 0; i < rxPackets.size(); i++) { 12569 final int uid = rxPackets.keyAt(i); 12570 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 12571 / totalRxPackets; 12572 rxTimesMs.incrementValue(uid, myRxTimeMs); 12573 } 12574 12575 for (int i = 0; i < txTimesMs.size(); i++) { 12576 final int uid = txTimesMs.keyAt(i); 12577 final long myTxTimeMs = txTimesMs.valueAt(i); 12578 if (DEBUG_ENERGY) { 12579 Slog.d(TAG, " TxTime for UID " + uid + ": " + myTxTimeMs + " ms"); 12580 } 12581 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 12582 .getOrCreateWifiControllerActivityLocked() 12583 .getOrCreateTxTimeCounters()[0] 12584 .increment(myTxTimeMs, elapsedRealtimeMs); 12585 if (uidEstimatedConsumptionMah != null) { 12586 uidEstimatedConsumptionMah.incrementValue(uid, 12587 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12588 0, myTxTimeMs, 0)); 12589 } 12590 } 12591 12592 for (int i = 0; i < rxTimesMs.size(); i++) { 12593 final int uid = rxTimesMs.keyAt(i); 12594 final long myRxTimeMs = rxTimesMs.valueAt(i); 12595 if (DEBUG_ENERGY) { 12596 Slog.d(TAG, " RxTime for UID " + uid + ": " + myRxTimeMs + " ms"); 12597 } 12598 12599 getUidStatsLocked(rxTimesMs.keyAt(i), elapsedRealtimeMs, uptimeMs) 12600 .getOrCreateWifiControllerActivityLocked() 12601 .getOrCreateRxTimeCounter() 12602 .increment(myRxTimeMs, elapsedRealtimeMs); 12603 if (uidEstimatedConsumptionMah != null) { 12604 uidEstimatedConsumptionMah.incrementValue(uid, 12605 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12606 myRxTimeMs, 0, 0)); 12607 } 12608 } 12609 12610 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 12611 12612 // Update WiFi controller stats. 12613 mWifiActivity.getOrCreateRxTimeCounter().increment( 12614 info.getControllerRxDurationMillis(), elapsedRealtimeMs); 12615 mWifiActivity.getOrCreateTxTimeCounters()[0].increment( 12616 info.getControllerTxDurationMillis(), elapsedRealtimeMs); 12617 mWifiActivity.getScanTimeCounter().addCountLocked( 12618 info.getControllerScanDurationMillis()); 12619 mWifiActivity.getOrCreateIdleTimeCounter().increment( 12620 info.getControllerIdleDurationMillis(), elapsedRealtimeMs); 12621 12622 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12623 final double opVolt = mPowerProfile.getAveragePower( 12624 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12625 double controllerMaMs = 0; 12626 if (opVolt != 0) { 12627 // We store the power drain as mAms. 12628 controllerMaMs = info.getControllerEnergyUsedMicroJoules() / opVolt; 12629 mWifiActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 12630 } 12631 // Converting uWs to mAms. 12632 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 12633 long monitoredRailChargeConsumedMaMs = mTmpRailStats != null 12634 ? (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt) 12635 : 0L; 12636 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 12637 monitoredRailChargeConsumedMaMs); 12638 mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs, 12639 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR)); 12640 if (mTmpRailStats != null) { 12641 mTmpRailStats.resetWifiTotalEnergyUsed(); 12642 } 12643 12644 if (uidEstimatedConsumptionMah != null) { 12645 totalEstimatedConsumptionMah = Math.max(controllerMaMs / MILLISECONDS_IN_HOUR, 12646 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12647 rxTimeMs, txTimeMs, idleTimeMs)); 12648 } 12649 } 12650 12651 // Update the EnergyConsumerStats information. 12652 if (uidEstimatedConsumptionMah != null) { 12653 mGlobalEnergyConsumerStats.updateStandardBucket( 12654 EnergyConsumerStats.POWER_BUCKET_WIFI, consumedChargeUC); 12655 12656 // Now calculate the consumption for each uid, according to its proportional usage. 12657 if (!mHasWifiReporting) { 12658 final long globalTimeMs = mGlobalWifiRunningTimer 12659 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12660 mGlobalWifiRunningTimer.setMark(elapsedRealtimeMs); 12661 totalEstimatedConsumptionMah = mWifiPowerCalculator 12662 .calcGlobalPowerWithoutControllerDataMah(globalTimeMs); 12663 } 12664 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_WIFI, 12665 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedConsumptionMah, 12666 elapsedRealtimeMs); 12667 } 12668 } 12669 } 12670 12671 private ModemActivityInfo mLastModemActivityInfo = null; 12672 12673 /** 12674 * Distribute Cell radio energy info and network traffic to apps. 12675 */ noteModemControllerActivity(@ullable final ModemActivityInfo activityInfo, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, @NonNull NetworkStatsManager networkStatsManager)12676 public void noteModemControllerActivity(@Nullable final ModemActivityInfo activityInfo, 12677 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, 12678 @NonNull NetworkStatsManager networkStatsManager) { 12679 if (DEBUG_ENERGY) { 12680 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 12681 } 12682 ModemActivityInfo deltaInfo = mLastModemActivityInfo == null 12683 ? (activityInfo == null ? null : activityInfo.getDelta(activityInfo)) 12684 : mLastModemActivityInfo.getDelta(activityInfo); 12685 mLastModemActivityInfo = activityInfo; 12686 12687 // Add modem tx power to history. 12688 addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs); 12689 12690 // Grab a separate lock to acquire the network stats, which may do I/O. 12691 List<NetworkStatsDelta> delta = null; 12692 synchronized (mModemNetworkLock) { 12693 final NetworkStats latestStats = readMobileNetworkStatsLocked(networkStatsManager); 12694 if (latestStats != null) { 12695 delta = computeDelta(latestStats, mLastModemNetworkStats); 12696 mLastModemNetworkStats = latestStats; 12697 } 12698 } 12699 12700 synchronized (this) { 12701 final long totalRadioDurationMs = 12702 mMobileRadioActiveTimer.getTimeSinceMarkLocked( 12703 elapsedRealtimeMs * 1000) / 1000; 12704 mMobileRadioActiveTimer.setMark(elapsedRealtimeMs); 12705 final long phoneOnDurationMs = Math.min(totalRadioDurationMs, 12706 mPhoneOnTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000); 12707 mPhoneOnTimer.setMark(elapsedRealtimeMs); 12708 12709 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12710 return; 12711 } 12712 12713 final SparseDoubleArray uidEstimatedConsumptionMah; 12714 final long dataConsumedChargeUC; 12715 if (consumedChargeUC > 0 && isMobileRadioEnergyConsumerSupportedLocked()) { 12716 final long phoneConsumedChargeUC; 12717 if (totalRadioDurationMs == 0) { 12718 phoneConsumedChargeUC = 0; 12719 } else { 12720 // Crudely attribute power consumption. Added (totalRadioDurationMs / 2) to the 12721 // numerator for long rounding. 12722 phoneConsumedChargeUC = 12723 (consumedChargeUC * phoneOnDurationMs + totalRadioDurationMs / 2) 12724 / totalRadioDurationMs; 12725 } 12726 dataConsumedChargeUC = consumedChargeUC - phoneConsumedChargeUC; 12727 12728 mGlobalEnergyConsumerStats.updateStandardBucket( 12729 EnergyConsumerStats.POWER_BUCKET_PHONE, phoneConsumedChargeUC); 12730 mGlobalEnergyConsumerStats.updateStandardBucket( 12731 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, dataConsumedChargeUC); 12732 uidEstimatedConsumptionMah = new SparseDoubleArray(); 12733 } else { 12734 uidEstimatedConsumptionMah = null; 12735 dataConsumedChargeUC = POWER_DATA_UNAVAILABLE; 12736 } 12737 12738 RxTxConsumption rxTxConsumption = null; 12739 boolean attributeWithModemActivityInfo = false; 12740 if (deltaInfo != null) { 12741 mHasModemReporting = true; 12742 mModemActivity.getOrCreateIdleTimeCounter() 12743 .increment(deltaInfo.getIdleTimeMillis(), elapsedRealtimeMs); 12744 mModemActivity.getSleepTimeCounter().addCountLocked( 12745 deltaInfo.getSleepTimeMillis()); 12746 mModemActivity.getOrCreateRxTimeCounter() 12747 .increment(deltaInfo.getReceiveTimeMillis(), elapsedRealtimeMs); 12748 for (int lvl = 0; lvl < MODEM_TX_POWER_LEVEL_COUNT; lvl++) { 12749 mModemActivity.getOrCreateTxTimeCounters()[lvl] 12750 .increment(deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl), 12751 elapsedRealtimeMs); 12752 } 12753 12754 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12755 final double opVolt = mPowerProfile.getAveragePower( 12756 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12757 if (opVolt != 0) { 12758 double energyUsed = 12759 deltaInfo.getSleepTimeMillis() * 12760 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 12761 + deltaInfo.getIdleTimeMillis() * 12762 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 12763 + deltaInfo.getReceiveTimeMillis() * 12764 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 12765 for (int i = 0; i < Math.min(MODEM_TX_POWER_LEVEL_COUNT, 12766 CELL_SIGNAL_STRENGTH_LEVEL_COUNT); i++) { 12767 energyUsed += deltaInfo.getTransmitDurationMillisAtPowerLevel(i) 12768 * mPowerProfile.getAveragePower( 12769 PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 12770 } 12771 12772 // We store the power drain as mAms. 12773 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 12774 // Converting uWs to mAms. 12775 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 12776 long monitoredRailChargeConsumedMaMs = 12777 (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt); 12778 mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 12779 monitoredRailChargeConsumedMaMs); 12780 mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs, 12781 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR)); 12782 mTmpRailStats.resetCellularTotalEnergyUsed(); 12783 } 12784 12785 rxTxConsumption = incrementPerRatDataLocked(deltaInfo, elapsedRealtimeMs); 12786 12787 attributeWithModemActivityInfo = mConstants.PER_UID_MODEM_MODEL 12788 == PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX 12789 && rxTxConsumption != null; 12790 } 12791 long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 12792 elapsedRealtimeMs * 1000); 12793 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 12794 12795 long totalRxPackets = 0; 12796 long totalTxPackets = 0; 12797 if (delta != null) { 12798 for (NetworkStatsDelta entry : delta) { 12799 if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { 12800 continue; 12801 } 12802 12803 if (DEBUG_ENERGY) { 12804 Slog.d(TAG, "Mobile uid " + entry.getUid() + ": delta rx=" 12805 + entry.getRxBytes() + " tx=" + entry.getTxBytes() 12806 + " rxPackets=" + entry.getRxPackets() 12807 + " txPackets=" + entry.getTxPackets()); 12808 } 12809 12810 totalRxPackets += entry.getRxPackets(); 12811 totalTxPackets += entry.getTxPackets(); 12812 12813 final Uid u = getUidStatsLocked( 12814 mapUid(entry.getUid()), elapsedRealtimeMs, uptimeMs); 12815 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.getRxBytes(), 12816 entry.getRxPackets()); 12817 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.getTxBytes(), 12818 entry.getTxPackets()); 12819 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 12820 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 12821 entry.getRxBytes(), entry.getRxPackets()); 12822 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 12823 entry.getTxBytes(), entry.getTxPackets()); 12824 } 12825 12826 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 12827 entry.getRxBytes()); 12828 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12829 entry.getTxBytes()); 12830 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 12831 entry.getRxPackets()); 12832 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12833 entry.getTxPackets()); 12834 } 12835 12836 // Now distribute proportional blame to the apps that did networking. 12837 long totalPackets = totalRxPackets + totalTxPackets; 12838 if (totalPackets > 0) { 12839 for (NetworkStatsDelta entry : delta) { 12840 if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { 12841 continue; 12842 } 12843 12844 final Uid u = getUidStatsLocked(mapUid(entry.getUid()), 12845 elapsedRealtimeMs, uptimeMs); 12846 12847 // Distribute total radio active time in to this app. 12848 final long appPackets = entry.getRxPackets() + entry.getTxPackets(); 12849 final long appRadioTimeUs = 12850 (totalAppRadioTimeUs * appPackets) / totalPackets; 12851 u.noteMobileRadioActiveTimeLocked(appRadioTimeUs, elapsedRealtimeMs); 12852 12853 if (uidEstimatedConsumptionMah != null) { 12854 final double uidConsumptionMah; 12855 if (attributeWithModemActivityInfo) { 12856 // Distribute measured mobile radio charge consumption based on 12857 // rx/tx packets and estimated rx/tx charge consumption. 12858 uidConsumptionMah = smearModemActivityInfoRxTxConsumptionMah( 12859 rxTxConsumption, entry.getRxPackets(), entry.getTxPackets(), 12860 totalRxPackets, totalTxPackets); 12861 } else { 12862 // Distribute mobile radio charge consumption based on app radio 12863 // active time 12864 uidConsumptionMah = 12865 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12866 appRadioTimeUs / 1000); 12867 } 12868 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 12869 uidConsumptionMah); 12870 } 12871 12872 // Remove this app from the totals, so that we don't lose any time 12873 // due to rounding. 12874 totalAppRadioTimeUs -= appRadioTimeUs; 12875 totalPackets -= appPackets; 12876 12877 if (deltaInfo != null) { 12878 ControllerActivityCounterImpl activityCounter = 12879 u.getOrCreateModemControllerActivityLocked(); 12880 if (totalRxPackets > 0 && entry.getRxPackets() > 0) { 12881 final long rxMs = (entry.getRxPackets() 12882 * deltaInfo.getReceiveTimeMillis()) / totalRxPackets; 12883 activityCounter.getOrCreateRxTimeCounter() 12884 .increment(rxMs, elapsedRealtimeMs); 12885 } 12886 12887 if (totalTxPackets > 0 && entry.getTxPackets() > 0) { 12888 for (int lvl = 0; lvl < MODEM_TX_POWER_LEVEL_COUNT; 12889 lvl++) { 12890 long txMs = entry.getTxPackets() 12891 * deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl); 12892 txMs /= totalTxPackets; 12893 activityCounter.getOrCreateTxTimeCounters()[lvl] 12894 .increment(txMs, elapsedRealtimeMs); 12895 } 12896 } 12897 } 12898 } 12899 } 12900 12901 if (totalAppRadioTimeUs > 0) { 12902 // Whoops, there is some radio time we can't blame on an app! 12903 mMobileRadioActiveUnknownTime.addCountLocked(totalAppRadioTimeUs); 12904 mMobileRadioActiveUnknownCount.addCountLocked(1); 12905 } 12906 12907 // Update the EnergyConsumerStats information. 12908 if (uidEstimatedConsumptionMah != null) { 12909 double totalEstimatedConsumptionMah = 0.0; 12910 if (attributeWithModemActivityInfo) { 12911 // Estimate inactive modem power consumption and combine with previously 12912 // estimated active power consumption for an estimate of total modem 12913 // power consumption. 12914 final long sleepTimeMs = deltaInfo.getSleepTimeMillis(); 12915 final long idleTimeMs = deltaInfo.getIdleTimeMillis(); 12916 final double inactiveConsumptionMah = 12917 mMobileRadioPowerCalculator.calcInactiveStatePowerMah(sleepTimeMs, 12918 idleTimeMs); 12919 totalEstimatedConsumptionMah += inactiveConsumptionMah; 12920 totalEstimatedConsumptionMah += rxTxConsumption.rxConsumptionMah; 12921 totalEstimatedConsumptionMah += rxTxConsumption.txConsumptionMah; 12922 } else { 12923 // Estimate total active radio power consumption since last mark. 12924 totalEstimatedConsumptionMah += 12925 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12926 totalRadioDurationMs); 12927 12928 // Estimate idle power consumption at each signal strength level 12929 final int numSignalStrengthLevels = mPhoneSignalStrengthsTimer.length; 12930 for (int lvl = 0; lvl < numSignalStrengthLevels; lvl++) { 12931 final long strengthLevelDurationMs = 12932 mPhoneSignalStrengthsTimer[lvl].getTimeSinceMarkLocked( 12933 elapsedRealtimeMs * 1000) / 1000; 12934 mPhoneSignalStrengthsTimer[lvl].setMark(elapsedRealtimeMs); 12935 12936 totalEstimatedConsumptionMah += 12937 mMobileRadioPowerCalculator.calcIdlePowerAtSignalStrengthMah( 12938 strengthLevelDurationMs, lvl); 12939 } 12940 12941 // Estimate total active radio power consumption since last mark. 12942 final long scanTimeMs = mPhoneSignalScanningTimer.getTimeSinceMarkLocked( 12943 elapsedRealtimeMs * 1000) / 1000; 12944 mPhoneSignalScanningTimer.setMark(elapsedRealtimeMs); 12945 totalEstimatedConsumptionMah += 12946 mMobileRadioPowerCalculator.calcScanTimePowerMah(scanTimeMs); 12947 } 12948 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 12949 dataConsumedChargeUC, uidEstimatedConsumptionMah, 12950 totalEstimatedConsumptionMah, elapsedRealtimeMs); 12951 } 12952 } 12953 } 12954 } 12955 12956 private static class RxTxConsumption { 12957 public final double rxConsumptionMah; 12958 public final long rxDurationMs; 12959 public final double txConsumptionMah; 12960 public final long txDurationMs; 12961 12962 /** 12963 * Represents the ratio between time spent transmitting and the total active time. 12964 */ 12965 public final double txToTotalRatio; 12966 RxTxConsumption(double rxMah, long rxMs, double txMah, long txMs)12967 RxTxConsumption(double rxMah, long rxMs, double txMah, long txMs) { 12968 rxConsumptionMah = rxMah; 12969 rxDurationMs = rxMs; 12970 txConsumptionMah = txMah; 12971 txDurationMs = txMs; 12972 12973 final long activeDurationMs = txDurationMs + rxDurationMs; 12974 if (activeDurationMs == 0) { 12975 txToTotalRatio = 0.0; 12976 } else { 12977 txToTotalRatio = ((double) txDurationMs) / activeDurationMs; 12978 } 12979 } 12980 } 12981 12982 @GuardedBy("this") 12983 @Nullable incrementPerRatDataLocked(ModemActivityInfo deltaInfo, long elapsedRealtimeMs)12984 private RxTxConsumption incrementPerRatDataLocked(ModemActivityInfo deltaInfo, 12985 long elapsedRealtimeMs) { 12986 double rxConsumptionMah = 0.0; 12987 long rxDurationMs = 0; 12988 double txConsumptionMah = 0.0; 12989 long txDurationMs = 0; 12990 12991 final int infoSize = deltaInfo.getSpecificInfoLength(); 12992 if (infoSize == 1 && deltaInfo.getSpecificInfoRat(0) 12993 == AccessNetworkConstants.AccessNetworkType.UNKNOWN 12994 && deltaInfo.getSpecificInfoFrequencyRange(0) 12995 == ServiceState.FREQUENCY_RANGE_UNKNOWN) { 12996 // Specific info data unavailable. Proportionally smear Rx and Tx times across each RAT. 12997 final int levelCount = CELL_SIGNAL_STRENGTH_LEVEL_COUNT; 12998 long[] perSignalStrengthActiveTimeMs = new long[levelCount]; 12999 long totalActiveTimeMs = 0; 13000 13001 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13002 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13003 if (ratStats == null) continue; 13004 13005 final int freqCount = ratStats.getFrequencyRangeCount(); 13006 for (int freq = 0; freq < freqCount; freq++) { 13007 for (int level = 0; level < levelCount; level++) { 13008 final long durationMs = ratStats.getTimeSinceMark(freq, level, 13009 elapsedRealtimeMs); 13010 perSignalStrengthActiveTimeMs[level] += durationMs; 13011 totalActiveTimeMs += durationMs; 13012 } 13013 } 13014 } 13015 if (totalActiveTimeMs != 0) { 13016 // Smear the provided Tx/Rx durations across each RAT, frequency, and signal 13017 // strength. 13018 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13019 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13020 if (ratStats == null) continue; 13021 13022 final int freqCount = ratStats.getFrequencyRangeCount(); 13023 for (int freq = 0; freq < freqCount; freq++) { 13024 long frequencyDurationMs = 0; 13025 for (int level = 0; level < levelCount; level++) { 13026 final long durationMs = ratStats.getTimeSinceMark(freq, level, 13027 elapsedRealtimeMs); 13028 final long totalLvlDurationMs = 13029 perSignalStrengthActiveTimeMs[level]; 13030 if (totalLvlDurationMs == 0) continue; 13031 final long totalTxLvlDurations = 13032 deltaInfo.getTransmitDurationMillisAtPowerLevel(level); 13033 // Smear HAL provided Tx power level duration based on active modem 13034 // duration in a given state. (Add totalLvlDurationMs / 2 before 13035 // the integer division with totalLvlDurationMs for rounding.) 13036 final long proportionalTxDurationMs = 13037 (durationMs * totalTxLvlDurations 13038 + (totalLvlDurationMs / 2)) / totalLvlDurationMs; 13039 ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs); 13040 frequencyDurationMs += durationMs; 13041 13042 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13043 // Accumulate the power cost of time spent transmitting in a 13044 // particular state. 13045 final double txStatePowerConsumptionMah = 13046 mMobileRadioPowerCalculator.calcTxStatePowerMah(rat, freq, 13047 level, proportionalTxDurationMs); 13048 txConsumptionMah += txStatePowerConsumptionMah; 13049 txDurationMs += proportionalTxDurationMs; 13050 } 13051 } 13052 final long totalRxDuration = deltaInfo.getReceiveTimeMillis(); 13053 // Smear HAL provided Rx power duration based on active modem 13054 // duration in a given state. (Add totalActiveTimeMs / 2 before the 13055 // integer division with totalActiveTimeMs for rounding.) 13056 final long proportionalRxDurationMs = 13057 (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs 13058 / 2)) / totalActiveTimeMs; 13059 ratStats.incrementRxDuration(freq, proportionalRxDurationMs); 13060 13061 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13062 // Accumulate the power cost of time spent receiving in a particular 13063 // state. 13064 final double rxStatePowerConsumptionMah = 13065 mMobileRadioPowerCalculator.calcRxStatePowerMah(rat, freq, 13066 proportionalRxDurationMs); 13067 rxConsumptionMah += rxStatePowerConsumptionMah; 13068 rxDurationMs += proportionalRxDurationMs; 13069 } 13070 } 13071 13072 } 13073 } 13074 } else { 13075 // Specific data available. 13076 for (int index = 0; index < infoSize; index++) { 13077 final int rat = deltaInfo.getSpecificInfoRat(index); 13078 final int freq = deltaInfo.getSpecificInfoFrequencyRange(index); 13079 13080 // Map RadioAccessNetworkType to course grain RadioAccessTechnology. 13081 final int ratBucket = mapRadioAccessNetworkTypeToRadioAccessTechnology(rat); 13082 final RadioAccessTechnologyBatteryStats ratStats = getRatBatteryStatsLocked( 13083 ratBucket); 13084 13085 final long rxTimeMs = deltaInfo.getReceiveTimeMillis(rat, freq); 13086 final int[] txTimesMs = deltaInfo.getTransmitTimeMillis(rat, freq); 13087 13088 ratStats.incrementRxDuration(freq, rxTimeMs); 13089 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13090 // Accumulate the power cost of time spent receiving in a particular state. 13091 final double rxStatePowerConsumptionMah = 13092 mMobileRadioPowerCalculator.calcRxStatePowerMah(ratBucket, freq, 13093 rxTimeMs); 13094 rxConsumptionMah += rxStatePowerConsumptionMah; 13095 rxDurationMs += rxTimeMs; 13096 } 13097 13098 final int numTxLvl = txTimesMs.length; 13099 for (int lvl = 0; lvl < numTxLvl; lvl++) { 13100 final long txTimeMs = txTimesMs[lvl]; 13101 ratStats.incrementTxDuration(freq, lvl, txTimeMs); 13102 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13103 // Accumulate the power cost of time spent transmitting in a particular 13104 // state. 13105 final double txStatePowerConsumptionMah = 13106 mMobileRadioPowerCalculator.calcTxStatePowerMah(ratBucket, freq, 13107 lvl, txTimeMs); 13108 txConsumptionMah += txStatePowerConsumptionMah; 13109 txDurationMs += txTimeMs; 13110 } 13111 } 13112 } 13113 } 13114 13115 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13116 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13117 if (ratStats == null) continue; 13118 ratStats.setMark(elapsedRealtimeMs); 13119 } 13120 13121 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13122 return new RxTxConsumption(rxConsumptionMah, rxDurationMs, txConsumptionMah, 13123 txDurationMs); 13124 } else { 13125 return null; 13126 } 13127 } 13128 13129 /** 13130 * Smear modem Rx/Tx power consumption calculated from {@link ModemActivityInfo} using Rx/Tx 13131 * packets. 13132 * 13133 * @return the combine Rx/Tx smeared power consumption in milliamp-hours. 13134 */ smearModemActivityInfoRxTxConsumptionMah(RxTxConsumption rxTxConsumption, long rxPackets, long txPackets, long totalRxPackets, long totalTxPackets)13135 private double smearModemActivityInfoRxTxConsumptionMah(RxTxConsumption rxTxConsumption, 13136 long rxPackets, long txPackets, long totalRxPackets, long totalTxPackets) { 13137 // Distribute measured mobile radio charge consumption based on 13138 // rx/tx packets and estimated rx/tx charge consumption. 13139 double consumptionMah = 0.0; 13140 if (totalRxPackets != 0) { 13141 // Proportionally distribute receive battery consumption. 13142 consumptionMah += rxTxConsumption.rxConsumptionMah * rxPackets 13143 / totalRxPackets; 13144 } 13145 if (totalTxPackets != 0 || (totalRxPackets != 0 && rxTxConsumption.txToTotalRatio != 0.0)) { 13146 // ModemActivityInfo Tx time represents time spent both transmitting and receiving. 13147 // There is currently no way to distinguish how many Rx packets were received during 13148 // Rx time vs Tx time. 13149 // Assumption: The number of packets received while transmitting is proportional 13150 // to the time spent transmitting over total active time. 13151 final double totalPacketsDuringTxTime = 13152 totalTxPackets + rxTxConsumption.txToTotalRatio * totalRxPackets; 13153 final double packetsDuringTxTime = 13154 txPackets + rxTxConsumption.txToTotalRatio * rxPackets; 13155 consumptionMah += rxTxConsumption.txConsumptionMah * packetsDuringTxTime 13156 / totalPacketsDuringTxTime; 13157 } 13158 return consumptionMah; 13159 } 13160 13161 /** 13162 * Add modem tx power to history 13163 * Device is said to be in high cellular transmit power when it has spent most of the transmit 13164 * time at the highest power level. 13165 * @param activityInfo 13166 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo, long elapsedRealtimeMs, long uptimeMs)13167 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo, 13168 long elapsedRealtimeMs, long uptimeMs) { 13169 if (activityInfo == null) { 13170 return; 13171 } 13172 int levelMaxTimeSpent = 0; 13173 for (int i = 1; i < MODEM_TX_POWER_LEVEL_COUNT; i++) { 13174 if (activityInfo.getTransmitDurationMillisAtPowerLevel(i) 13175 > activityInfo.getTransmitDurationMillisAtPowerLevel(levelMaxTimeSpent)) { 13176 levelMaxTimeSpent = i; 13177 } 13178 } 13179 if (levelMaxTimeSpent == MODEM_TX_POWER_LEVEL_COUNT - 1) { 13180 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 13181 HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG); 13182 } 13183 } 13184 13185 private final class BluetoothActivityInfoCache { 13186 long idleTimeMs; 13187 long rxTimeMs; 13188 long txTimeMs; 13189 long energy; 13190 13191 SparseLongArray uidRxBytes = new SparseLongArray(); 13192 SparseLongArray uidTxBytes = new SparseLongArray(); 13193 set(BluetoothActivityEnergyInfo info)13194 void set(BluetoothActivityEnergyInfo info) { 13195 idleTimeMs = info.getControllerIdleTimeMillis(); 13196 rxTimeMs = info.getControllerRxTimeMillis(); 13197 txTimeMs = info.getControllerTxTimeMillis(); 13198 energy = info.getControllerEnergyUsed(); 13199 if (!info.getUidTraffic().isEmpty()) { 13200 for (UidTraffic traffic : info.getUidTraffic()) { 13201 uidRxBytes.put(traffic.getUid(), traffic.getRxBytes()); 13202 uidTxBytes.put(traffic.getUid(), traffic.getTxBytes()); 13203 } 13204 } 13205 } 13206 reset()13207 void reset() { 13208 idleTimeMs = 0; 13209 rxTimeMs = 0; 13210 txTimeMs = 0; 13211 energy = 0; 13212 uidRxBytes.clear(); 13213 uidTxBytes.clear(); 13214 } 13215 } 13216 13217 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 13218 = new BluetoothActivityInfoCache(); 13219 13220 /** 13221 * Distribute Bluetooth energy info and network traffic to apps. 13222 * 13223 * @param info The accumulated energy information from the bluetooth controller. 13224 */ 13225 @GuardedBy("this") updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)13226 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info, 13227 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 13228 if (mBluetoothPowerStatsCollector.isEnabled()) { 13229 return; 13230 } 13231 13232 if (DEBUG_ENERGY) { 13233 Slog.d(TAG, "Updating bluetooth stats: " + info); 13234 } 13235 13236 if (info == null) { 13237 return; 13238 } 13239 13240 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 13241 mLastBluetoothActivityInfo.set(info); 13242 return; 13243 } 13244 13245 mHasBluetoothReporting = true; 13246 13247 if (info.getControllerRxTimeMillis() < mLastBluetoothActivityInfo.rxTimeMs 13248 || info.getControllerTxTimeMillis() < mLastBluetoothActivityInfo.txTimeMs 13249 || info.getControllerIdleTimeMillis() < mLastBluetoothActivityInfo.idleTimeMs 13250 || info.getControllerEnergyUsed() < mLastBluetoothActivityInfo.energy) { 13251 // A drop in accumulated Bluetooth stats is a sign of a Bluetooth crash. 13252 // Reset the preserved previous snapshot in order to restart accumulating deltas. 13253 mLastBluetoothActivityInfo.reset(); 13254 } 13255 13256 final long rxTimeMs = 13257 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 13258 final long txTimeMs = 13259 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 13260 final long idleTimeMs = 13261 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 13262 13263 if (DEBUG_ENERGY) { 13264 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 13265 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 13266 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 13267 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 13268 } 13269 13270 final SparseDoubleArray uidEstimatedConsumptionMah = 13271 (mGlobalEnergyConsumerStats != null 13272 && mBluetoothPowerCalculator != null && consumedChargeUC > 0) ? 13273 new SparseDoubleArray() : null; 13274 long totalScanTimeMs = 0; 13275 13276 final int uidCount = mUidStats.size(); 13277 for (int i = 0; i < uidCount; i++) { 13278 final Uid u = mUidStats.valueAt(i); 13279 if (u.mBluetoothScanTimer == null) { 13280 continue; 13281 } 13282 13283 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 13284 elapsedRealtimeMs * 1000) / 1000; 13285 } 13286 13287 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 13288 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 13289 13290 if (DEBUG_ENERGY) { 13291 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 13292 + " TX=" + normalizeScanTxTime); 13293 } 13294 13295 long leftOverRxTimeMs = rxTimeMs; 13296 long leftOverTxTimeMs = txTimeMs; 13297 13298 final SparseLongArray rxTimesMs = new SparseLongArray(uidCount); 13299 final SparseLongArray txTimesMs = new SparseLongArray(uidCount); 13300 13301 for (int i = 0; i < uidCount; i++) { 13302 final Uid u = mUidStats.valueAt(i); 13303 if (u.mBluetoothScanTimer == null) { 13304 continue; 13305 } 13306 13307 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 13308 elapsedRealtimeMs * 1000) / 1000; 13309 if (scanTimeSinceMarkMs > 0) { 13310 // Set the new mark so that next time we get new data since this point. 13311 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 13312 13313 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 13314 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 13315 13316 if (normalizeScanRxTime) { 13317 // Scan time is longer than the total rx time in the controller, 13318 // so distribute the scan time proportionately. This means regular traffic 13319 // will not blamed, but scans are more expensive anyways. 13320 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 13321 } 13322 13323 if (normalizeScanTxTime) { 13324 // Scan time is longer than the total tx time in the controller, 13325 // so distribute the scan time proportionately. This means regular traffic 13326 // will not blamed, but scans are more expensive anyways. 13327 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 13328 } 13329 13330 rxTimesMs.incrementValue(u.getUid(), scanTimeRxSinceMarkMs); 13331 txTimesMs.incrementValue(u.getUid(), scanTimeTxSinceMarkMs); 13332 13333 if (uidEstimatedConsumptionMah != null) { 13334 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 13335 mBluetoothPowerCalculator.calculatePowerMah( 13336 scanTimeRxSinceMarkMs, scanTimeTxSinceMarkMs, 0)); 13337 } 13338 13339 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 13340 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 13341 } 13342 } 13343 13344 if (DEBUG_ENERGY) { 13345 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 13346 + leftOverTxTimeMs); 13347 } 13348 13349 // 13350 // Now distribute blame to apps that did bluetooth traffic. 13351 // 13352 13353 long totalTxBytes = 0; 13354 long totalRxBytes = 0; 13355 13356 final List<UidTraffic> uidTraffic = info.getUidTraffic(); 13357 final int numUids = uidTraffic.size(); 13358 for (int i = 0; i < numUids; i++) { 13359 final UidTraffic traffic = uidTraffic.get(i); 13360 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 13361 traffic.getUid()); 13362 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 13363 traffic.getUid()); 13364 13365 // Add to the global counters. 13366 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 13367 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 13368 13369 // Add to the UID counters. 13370 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()), elapsedRealtimeMs, uptimeMs); 13371 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 13372 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 13373 13374 // Calculate the total traffic. 13375 totalRxBytes += rxBytes; 13376 totalTxBytes += txBytes; 13377 } 13378 13379 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 13380 || leftOverTxTimeMs != 0)) { 13381 for (int i = 0; i < numUids; i++) { 13382 final UidTraffic traffic = uidTraffic.get(i); 13383 final int uid = traffic.getUid(); 13384 final long rxBytes = 13385 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 13386 final long txBytes = 13387 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 13388 13389 final Uid u = getUidStatsLocked(mapUid(uid), elapsedRealtimeMs, uptimeMs); 13390 final ControllerActivityCounterImpl counter = 13391 u.getOrCreateBluetoothControllerActivityLocked(); 13392 13393 if (totalRxBytes > 0 && rxBytes > 0) { 13394 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 13395 rxTimesMs.incrementValue(uid, timeRxMs); 13396 } 13397 13398 if (totalTxBytes > 0 && txBytes > 0) { 13399 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 13400 txTimesMs.incrementValue(uid, timeTxMs); 13401 } 13402 } 13403 13404 for (int i = 0; i < txTimesMs.size(); i++) { 13405 final int uid = txTimesMs.keyAt(i); 13406 final long myTxTimeMs = txTimesMs.valueAt(i); 13407 if (DEBUG_ENERGY) { 13408 Slog.d(TAG, " TxTime for UID " + uid + ": " + myTxTimeMs + " ms"); 13409 } 13410 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 13411 .getOrCreateBluetoothControllerActivityLocked() 13412 .getOrCreateTxTimeCounters()[0] 13413 .increment(myTxTimeMs, elapsedRealtimeMs); 13414 if (uidEstimatedConsumptionMah != null) { 13415 uidEstimatedConsumptionMah.incrementValue(uid, 13416 mBluetoothPowerCalculator.calculatePowerMah(0, myTxTimeMs, 0)); 13417 } 13418 } 13419 13420 for (int i = 0; i < rxTimesMs.size(); i++) { 13421 final int uid = rxTimesMs.keyAt(i); 13422 final long myRxTimeMs = rxTimesMs.valueAt(i); 13423 if (DEBUG_ENERGY) { 13424 Slog.d(TAG, " RxTime for UID " + uid + ": " + myRxTimeMs + " ms"); 13425 } 13426 13427 getUidStatsLocked(rxTimesMs.keyAt(i), elapsedRealtimeMs, uptimeMs) 13428 .getOrCreateBluetoothControllerActivityLocked() 13429 .getOrCreateRxTimeCounter() 13430 .increment(myRxTimeMs, elapsedRealtimeMs); 13431 if (uidEstimatedConsumptionMah != null) { 13432 uidEstimatedConsumptionMah.incrementValue(uid, 13433 mBluetoothPowerCalculator.calculatePowerMah(myRxTimeMs, 0, 0)); 13434 } 13435 } 13436 } 13437 13438 mBluetoothActivity.getOrCreateRxTimeCounter().increment(rxTimeMs, elapsedRealtimeMs); 13439 mBluetoothActivity.getOrCreateTxTimeCounters()[0].increment(txTimeMs, elapsedRealtimeMs); 13440 mBluetoothActivity.getOrCreateIdleTimeCounter().increment(idleTimeMs, elapsedRealtimeMs); 13441 13442 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 13443 final double opVolt = mPowerProfile.getAveragePower( 13444 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 13445 double controllerMaMs = 0; 13446 if (opVolt != 0) { 13447 controllerMaMs = (info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 13448 / opVolt; 13449 // We store the power drain as mAms. 13450 mBluetoothActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 13451 } 13452 13453 // Update the EnergyConsumerStats information. 13454 if (uidEstimatedConsumptionMah != null) { 13455 mGlobalEnergyConsumerStats.updateStandardBucket( 13456 EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, consumedChargeUC); 13457 13458 double totalEstimatedMah 13459 = mBluetoothPowerCalculator.calculatePowerMah(rxTimeMs, txTimeMs, idleTimeMs); 13460 totalEstimatedMah = Math.max(totalEstimatedMah, controllerMaMs / MILLISECONDS_IN_HOUR); 13461 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 13462 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedMah, 13463 elapsedRealtimeMs); 13464 } 13465 13466 mLastBluetoothActivityInfo.set(info); 13467 } 13468 /** 13469 * Read Resource Power Manager (RPM) state and voter times. 13470 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 13471 * instead of fetching it anew. 13472 * 13473 * Note: This should be called without synchronizing this BatteryStatsImpl object 13474 */ fillLowPowerStats()13475 public void fillLowPowerStats() { 13476 if (mPlatformIdleStateCallback == null) return; 13477 13478 RpmStats rpmStats = new RpmStats(); 13479 long now = SystemClock.elapsedRealtime(); 13480 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 13481 mPlatformIdleStateCallback.fillLowPowerStats(rpmStats); 13482 synchronized (this) { 13483 mTmpRpmStats = rpmStats; 13484 mLastRpmStatsUpdateTimeMs = now; 13485 } 13486 } 13487 } 13488 13489 /** 13490 * Record Resource Power Manager (RPM) state and voter times. 13491 * TODO(b/185252376): Remove this logging. PowerStatsService logs the same data more 13492 * efficiently. 13493 */ updateRpmStatsLocked(long elapsedRealtimeUs)13494 public void updateRpmStatsLocked(long elapsedRealtimeUs) { 13495 if (mTmpRpmStats == null) return; 13496 13497 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 13498 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 13499 13500 // Update values for this platform state. 13501 final String pName = pstate.getKey(); 13502 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 13503 final int pCount = pstate.getValue().mCount; 13504 getRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 13505 if (SCREEN_OFF_RPM_STATS_ENABLED) { 13506 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 13507 } 13508 13509 // Update values for each voter of this platform state. 13510 for (Map.Entry<String, RpmStats.PowerStateElement> voter 13511 : pstate.getValue().mVoters.entrySet()) { 13512 final String vName = pName + "." + voter.getKey(); 13513 final long vTimeUs = voter.getValue().mTimeMs * 1000; 13514 final int vCount = voter.getValue().mCount; 13515 getRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 13516 if (SCREEN_OFF_RPM_STATS_ENABLED) { 13517 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 13518 } 13519 } 13520 } 13521 13522 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 13523 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 13524 13525 final String subsysName = subsys.getKey(); 13526 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 13527 : subsys.getValue().mStates.entrySet()) { 13528 final String name = subsysName + "." + sstate.getKey(); 13529 final long timeUs = sstate.getValue().mTimeMs * 1000; 13530 final int count = sstate.getValue().mCount; 13531 getRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 13532 if (SCREEN_OFF_RPM_STATS_ENABLED) { 13533 getScreenOffRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 13534 } 13535 } 13536 } 13537 } 13538 13539 /** 13540 * Accumulate Cpu charge consumption and distribute it to the correct state and the apps. 13541 * Only call if device is on battery. 13542 * 13543 * @param clusterChargeUC amount of charge (microcoulombs) consumed by each Cpu Cluster 13544 * @param accumulator collection of calculated uid cpu power consumption to smear 13545 * clusterChargeUC against. 13546 */ 13547 @GuardedBy("this") 13548 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToStandardBucketLocked updateCpuEnergyConsumerStatsLocked(@onNull long[] clusterChargeUC, @NonNull CpuDeltaPowerAccumulator accumulator)13549 private void updateCpuEnergyConsumerStatsLocked(@NonNull long[] clusterChargeUC, 13550 @NonNull CpuDeltaPowerAccumulator accumulator) { 13551 if (DEBUG_ENERGY) { 13552 Slog.d(TAG, "Updating cpu cluster stats: " + Arrays.toString(clusterChargeUC)); 13553 } 13554 if (mGlobalEnergyConsumerStats == null) { 13555 return; 13556 } 13557 13558 final int numClusters = clusterChargeUC.length; 13559 long totalCpuChargeUC = 0; 13560 for (int i = 0; i < numClusters; i++) { 13561 totalCpuChargeUC += clusterChargeUC[i]; 13562 } 13563 if (totalCpuChargeUC <= 0) return; 13564 13565 final long timestampMs = mClock.elapsedRealtime(); 13566 13567 mGlobalEnergyConsumerStats.updateStandardBucket(EnergyConsumerStats.POWER_BUCKET_CPU, 13568 totalCpuChargeUC, timestampMs); 13569 13570 // Calculate the microcoulombs/milliamp-hour charge ratio for each 13571 // cluster to normalize each uid's estimated power usage against actual power usage for 13572 // a given cluster. 13573 final double[] clusterChargeRatio = new double[numClusters]; 13574 for (int cluster = 0; cluster < numClusters; cluster++) { 13575 13576 final double totalClusterChargeMah = accumulator.totalClusterChargesMah[cluster]; 13577 if (totalClusterChargeMah <= 0.0) { 13578 // This cluster did not have any work on it, since last update. 13579 // Avoid dividing by zero. 13580 clusterChargeRatio[cluster] = 0.0; 13581 } else { 13582 clusterChargeRatio[cluster] = 13583 clusterChargeUC[cluster] / accumulator.totalClusterChargesMah[cluster]; 13584 } 13585 } 13586 13587 // Assign and distribute power usage to apps based on their calculated cpu cluster charge. 13588 final long uidChargeArraySize = accumulator.perUidCpuClusterChargesMah.size(); 13589 for (int i = 0; i < uidChargeArraySize; i++) { 13590 final Uid uid = accumulator.perUidCpuClusterChargesMah.keyAt(i); 13591 final double[] uidClusterChargesMah = accumulator.perUidCpuClusterChargesMah.valueAt(i); 13592 13593 // Iterate each cpu cluster and sum the proportional cpu cluster charge to 13594 // get the total cpu charge consumed by a uid. 13595 long uidCpuChargeUC = 0; 13596 for (int cluster = 0; cluster < numClusters; cluster++) { 13597 final double uidClusterChargeMah = uidClusterChargesMah[cluster]; 13598 13599 // Proportionally allocate the cpu cluster charge to a uid using the 13600 // cluster charge/charge ratio. Add 0.5 to round the proportional 13601 // charge double to the nearest long value. 13602 final long uidClusterChargeUC = 13603 (long) (uidClusterChargeMah * clusterChargeRatio[cluster] 13604 + 0.5); 13605 13606 uidCpuChargeUC += uidClusterChargeUC; 13607 } 13608 13609 if (uidCpuChargeUC < 0) { 13610 Slog.wtf(TAG, "Unexpected proportional EnergyConsumer charge " 13611 + "(" + uidCpuChargeUC + ") for uid " + uid.mUid); 13612 continue; 13613 } 13614 13615 uid.addChargeToStandardBucketLocked(uidCpuChargeUC, 13616 EnergyConsumerStats.POWER_BUCKET_CPU, timestampMs); 13617 } 13618 } 13619 13620 /** 13621 * Accumulate Display charge consumption and distribute it to the correct state and the apps. 13622 * 13623 * NOTE: The algorithm used makes the strong assumption that app foreground activity time 13624 * is always 0 when the screen is not "ON" and whenever the rail energy is 0 (if supported). 13625 * To the extent that those assumptions are violated, the algorithm will err. 13626 * 13627 * @param chargesUC amount of charge (microcoulombs) used by each Display since this was last 13628 * called. 13629 * @param screenStates each screen state at the time this data collection was scheduled 13630 */ 13631 @GuardedBy("this") updateDisplayEnergyConsumerStatsLocked(long[] chargesUC, int[] screenStates, long elapsedRealtimeMs)13632 public void updateDisplayEnergyConsumerStatsLocked(long[] chargesUC, int[] screenStates, 13633 long elapsedRealtimeMs) { 13634 if (DEBUG_ENERGY) Slog.d(TAG, "Updating display stats: " + Arrays.toString(chargesUC)); 13635 if (mGlobalEnergyConsumerStats == null) { 13636 return; 13637 } 13638 13639 final int numDisplays; 13640 if (mPerDisplayBatteryStats.length == screenStates.length) { 13641 numDisplays = screenStates.length; 13642 } else { 13643 // if this point is reached, it will be reached every display state change. 13644 // Rate limit the wtf logging to once every 100 display updates. 13645 if (mDisplayMismatchWtfCount++ % 100 == 0) { 13646 Slog.wtf(TAG, "Mismatch between PowerProfile reported display count (" 13647 + mPerDisplayBatteryStats.length 13648 + ") and PowerStatsHal reported display count (" + screenStates.length 13649 + ")"); 13650 } 13651 // Keep the show going, use the shorter of the two. 13652 numDisplays = mPerDisplayBatteryStats.length < screenStates.length 13653 ? mPerDisplayBatteryStats.length : screenStates.length; 13654 } 13655 13656 final int[] oldScreenStates = new int[numDisplays]; 13657 for (int i = 0; i < numDisplays; i++) { 13658 final int screenState = screenStates[i]; 13659 oldScreenStates[i] = mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement; 13660 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 13661 } 13662 13663 if (!mOnBatteryInternal) { 13664 // There's nothing further to update. 13665 return; 13666 } 13667 if (mIgnoreNextExternalStats) { 13668 // Although under ordinary resets we won't get here, and typically a new sync will 13669 // happen right after the reset, strictly speaking we need to set all mark times to now. 13670 final int uidStatsSize = mUidStats.size(); 13671 for (int i = 0; i < uidStatsSize; i++) { 13672 final Uid uid = mUidStats.valueAt(i); 13673 uid.markProcessForegroundTimeUs(elapsedRealtimeMs, false); 13674 } 13675 return; 13676 } 13677 13678 long totalScreenOnChargeUC = 0; 13679 for (int i = 0; i < numDisplays; i++) { 13680 final long chargeUC = chargesUC[i]; 13681 if (chargeUC <= 0) { 13682 // There's nothing further to update. 13683 continue; 13684 } 13685 13686 final @StandardPowerBucket int powerBucket = 13687 EnergyConsumerStats.getDisplayPowerBucket(oldScreenStates[i]); 13688 mGlobalEnergyConsumerStats.updateStandardBucket(powerBucket, chargeUC); 13689 if (powerBucket == EnergyConsumerStats.POWER_BUCKET_SCREEN_ON) { 13690 totalScreenOnChargeUC += chargeUC; 13691 } 13692 } 13693 13694 // Now we blame individual apps, but only if the display was ON. 13695 if (totalScreenOnChargeUC <= 0) { 13696 return; 13697 } 13698 // TODO(b/175726779): Consider unifying the code with the non-rail display power blaming. 13699 13700 // NOTE: fg time is NOT pooled. If two uids are both somehow in fg, then that time is 13701 // 'double counted' and will simply exceed the realtime that elapsed. 13702 // TODO(b/175726779): collect per display uid visibility for display power attribution. 13703 13704 // Collect total time since mark so that we can normalize power. 13705 final SparseDoubleArray fgTimeUsArray = new SparseDoubleArray(); 13706 final long elapsedRealtimeUs = elapsedRealtimeMs * 1000; 13707 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 13708 final int uidStatsSize = mUidStats.size(); 13709 for (int i = 0; i < uidStatsSize; i++) { 13710 final Uid uid = mUidStats.valueAt(i); 13711 final long fgTimeUs = uid.markProcessForegroundTimeUs(elapsedRealtimeMs, true); 13712 if (fgTimeUs == 0) continue; 13713 fgTimeUsArray.put(uid.getUid(), (double) fgTimeUs); 13714 } 13715 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON, 13716 totalScreenOnChargeUC, fgTimeUsArray, 0, elapsedRealtimeMs); 13717 } 13718 13719 /** 13720 * Accumulate GNSS charge consumption and distribute it to the correct state and the apps. 13721 * 13722 * @param chargeUC amount of charge (microcoulombs) used by GNSS since this was last called. 13723 */ 13724 @GuardedBy("this") 13725 public void updateGnssEnergyConsumerStatsLocked(long chargeUC, long elapsedRealtimeMs) { 13726 if (DEBUG_ENERGY) Slog.d(TAG, "Updating gnss stats: " + chargeUC); 13727 if (mGlobalEnergyConsumerStats == null) { 13728 return; 13729 } 13730 13731 if (!mOnBatteryInternal || chargeUC <= 0) { 13732 // There's nothing further to update. 13733 return; 13734 } 13735 if (mIgnoreNextExternalStats) { 13736 // Although under ordinary resets we won't get here, and typically a new sync will 13737 // happen right after the reset, strictly speaking we need to set all mark times to now. 13738 final int uidStatsSize = mUidStats.size(); 13739 for (int i = 0; i < uidStatsSize; i++) { 13740 final Uid uid = mUidStats.valueAt(i); 13741 uid.markGnssTimeUs(elapsedRealtimeMs); 13742 } 13743 return; 13744 } 13745 13746 mGlobalEnergyConsumerStats.updateStandardBucket(EnergyConsumerStats.POWER_BUCKET_GNSS, 13747 chargeUC); 13748 13749 // Collect the per uid time since mark so that we can normalize power. 13750 final SparseDoubleArray gnssTimeUsArray = new SparseDoubleArray(); 13751 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 13752 final int uidStatsSize = mUidStats.size(); 13753 for (int i = 0; i < uidStatsSize; i++) { 13754 final Uid uid = mUidStats.valueAt(i); 13755 final long gnssTimeUs = uid.markGnssTimeUs(elapsedRealtimeMs); 13756 if (gnssTimeUs == 0) continue; 13757 gnssTimeUsArray.put(uid.getUid(), (double) gnssTimeUs); 13758 } 13759 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_GNSS, chargeUC, 13760 gnssTimeUsArray, 0, elapsedRealtimeMs); 13761 } 13762 13763 /** 13764 * Accumulate camera charge consumption and distribute it to the correct state and the apps. 13765 * 13766 * @param chargeUC amount of charge (microcoulombs) used by the camera since this was last 13767 * called. 13768 */ 13769 @GuardedBy("this") 13770 public void updateCameraEnergyConsumerStatsLocked(long chargeUC, long elapsedRealtimeMs) { 13771 if (DEBUG_ENERGY) Slog.d(TAG, "Updating camera stats: " + chargeUC); 13772 if (mGlobalEnergyConsumerStats == null) { 13773 return; 13774 } 13775 13776 if (!mOnBatteryInternal || chargeUC <= 0) { 13777 // There's nothing further to update. 13778 return; 13779 } 13780 13781 if (mIgnoreNextExternalStats) { 13782 // Although under ordinary resets we won't get here, and typically a new sync will 13783 // happen right after the reset, strictly speaking we need to set all mark times to now. 13784 final int uidStatsSize = mUidStats.size(); 13785 for (int i = 0; i < uidStatsSize; i++) { 13786 final Uid uid = mUidStats.valueAt(i); 13787 uid.markCameraTimeUs(elapsedRealtimeMs); 13788 } 13789 return; 13790 } 13791 13792 mGlobalEnergyConsumerStats.updateStandardBucket( 13793 EnergyConsumerStats.POWER_BUCKET_CAMERA, chargeUC); 13794 13795 // Collect the per uid time since mark so that we can normalize power. 13796 final SparseDoubleArray cameraTimeUsArray = new SparseDoubleArray(); 13797 13798 // Note: Iterating over all UIDs may be suboptimal. 13799 final int uidStatsSize = mUidStats.size(); 13800 for (int i = 0; i < uidStatsSize; i++) { 13801 final Uid uid = mUidStats.valueAt(i); 13802 final long cameraTimeUs = uid.markCameraTimeUs(elapsedRealtimeMs); 13803 if (cameraTimeUs == 0) continue; 13804 cameraTimeUsArray.put(uid.getUid(), (double) cameraTimeUs); 13805 } 13806 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_CAMERA, chargeUC, 13807 cameraTimeUsArray, 0, elapsedRealtimeMs); 13808 } 13809 13810 /** 13811 * Accumulate Custom power bucket charge, globally and for each app. 13812 * 13813 * @param totalChargeUC charge (microcoulombs) used for this bucket since this was last called. 13814 * @param uidCharges map of uid->charge (microcoulombs) for this bucket since last called. 13815 * Data inside uidCharges will not be modified (treated immutable). 13816 * Uids not already known to BatteryStats will be ignored. 13817 */ 13818 @GuardedBy("this") 13819 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToCustomBucketLocked 13820 public void updateCustomEnergyConsumerStatsLocked(int customPowerBucket, 13821 long totalChargeUC, @Nullable SparseLongArray uidCharges) { 13822 if (DEBUG_ENERGY) { 13823 Slog.d(TAG, "Updating attributed EnergyConsumer stats for custom bucket " 13824 + customPowerBucket 13825 + " with total charge " + totalChargeUC 13826 + " and uid charges " + uidCharges); 13827 } 13828 if (mGlobalEnergyConsumerStats == null) return; 13829 if (!mOnBatteryInternal || mIgnoreNextExternalStats || totalChargeUC <= 0) return; 13830 13831 mGlobalEnergyConsumerStats.updateCustomBucket(customPowerBucket, totalChargeUC, 13832 mClock.elapsedRealtime()); 13833 13834 if (uidCharges == null) return; 13835 final int numUids = uidCharges.size(); 13836 for (int i = 0; i < numUids; i++) { 13837 final int uidInt = mapUid(uidCharges.keyAt(i)); 13838 final long uidChargeUC = uidCharges.valueAt(i); 13839 if (uidChargeUC == 0) continue; 13840 13841 final Uid uidObj = getAvailableUidStatsLocked(uidInt); 13842 if (uidObj != null) { 13843 uidObj.addChargeToCustomBucketLocked(uidChargeUC, customPowerBucket); 13844 } else { 13845 // Ignore any uid not already known to BatteryStats, rather than creating a new Uid. 13846 // Otherwise we could end up reviving dead Uids. Note that the CPU data is updated 13847 // first, so any uid that has used any CPU should already be known to BatteryStats. 13848 // Recently removed uids (especially common for isolated uids) can reach this path 13849 // and are ignored. 13850 if (!Process.isIsolated(uidInt)) { 13851 Slog.w(TAG, "Received EnergyConsumer charge " + totalChargeUC 13852 + " for custom bucket " + customPowerBucket + " for non-existent uid " 13853 + uidInt); 13854 } 13855 } 13856 } 13857 } 13858 13859 /** 13860 * Attributes energy (for the given bucket) to each uid according to the following formula: 13861 * blamedEnergy[uid] = totalEnergy * ratioNumerators[uid] / ratioDenominator; 13862 * <p>Does nothing if ratioDenominator is 0. 13863 * 13864 * <p>Here, ratioDenominator = max(sumOfAllRatioNumerators, minRatioDenominator), 13865 * so if given minRatioDenominator <= 0, then sumOfAllRatioNumerators will be used implicitly. 13866 * 13867 * <p>Note that ratioNumerators and minRatioDenominator must use the same units, but need not 13868 * use the same units as totalConsumedChargeUC (which must be in microcoulombs). 13869 * 13870 * <p>A consequence of minRatioDenominator is that the sum over all uids might be less than 13871 * totalConsumedChargeUC. This is intentional; the remainder is purposefully unnaccounted rather 13872 * than incorrectly blamed on uids, and implies unknown (non-uid) sources of drain. 13873 * 13874 * <p>All uids in ratioNumerators must exist in mUidStats already. 13875 */ 13876 @GuardedBy("this") 13877 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToStandardBucketLocked 13878 private void distributeEnergyToUidsLocked(@StandardPowerBucket int bucket, 13879 long totalConsumedChargeUC, SparseDoubleArray ratioNumerators, 13880 double minRatioDenominator, long timestampMs) { 13881 13882 // If the sum of all app usage was greater than the total, use that instead: 13883 double sumRatioNumerators = 0; 13884 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 13885 sumRatioNumerators += ratioNumerators.valueAt(i); 13886 } 13887 final double ratioDenominator = Math.max(sumRatioNumerators, minRatioDenominator); 13888 if (ratioDenominator <= 0) return; 13889 13890 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 13891 final Uid uid = getAvailableUidStatsLocked(ratioNumerators.keyAt(i)); 13892 final double ratioNumerator = ratioNumerators.valueAt(i); 13893 final long uidActualUC 13894 = (long) (totalConsumedChargeUC * ratioNumerator / ratioDenominator + 0.5); 13895 uid.addChargeToStandardBucketLocked(uidActualUC, bucket, timestampMs); 13896 } 13897 } 13898 13899 /** 13900 * Read and record Rail Energy data. 13901 */ 13902 public void updateRailStatsLocked() { 13903 if (mEnergyConsumerRetriever == null || !mTmpRailStats.isRailStatsAvailable()) { 13904 return; 13905 } 13906 mEnergyConsumerRetriever.fillRailDataStats(mTmpRailStats); 13907 } 13908 13909 /** Informs that external stats data has been completely flushed. */ 13910 public void informThatAllExternalStatsAreFlushed() { 13911 synchronized (this) { 13912 // Any data from the pre-reset era is flushed, so we can henceforth process future data. 13913 mIgnoreNextExternalStats = false; 13914 } 13915 } 13916 13917 /** 13918 * Read and distribute kernel wake lock use across apps. 13919 */ 13920 public void updateKernelWakelocksLocked(long elapsedRealtimeUs) { 13921 if (mKernelWakelockReader == null) { 13922 return; 13923 } 13924 13925 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 13926 mTmpWakelockStats); 13927 if (wakelockStats == null) { 13928 // Not crashing might make board bringup easier. 13929 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 13930 return; 13931 } 13932 13933 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 13934 String name = ent.getKey(); 13935 KernelWakelockStats.Entry kws = ent.getValue(); 13936 13937 SamplingTimer kwlt = mKernelWakelockStats.get(name); 13938 if (kwlt == null) { 13939 kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 13940 mKernelWakelockStats.put(name, kwlt); 13941 } 13942 13943 kwlt.update(kws.totalTimeUs, kws.activeTimeUs, kws.count, elapsedRealtimeUs); 13944 kwlt.setUpdateVersion(kws.version); 13945 } 13946 13947 int numWakelocksSetStale = 0; 13948 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 13949 // this time. 13950 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 13951 SamplingTimer st = ent.getValue(); 13952 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 13953 st.endSample(elapsedRealtimeUs); 13954 numWakelocksSetStale++; 13955 } 13956 } 13957 13958 if (DEBUG) { 13959 // Record whether we've seen a non-zero time (for debugging b/22716723). 13960 if (wakelockStats.isEmpty()) { 13961 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 13962 } 13963 13964 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 13965 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" 13966 + wakelockStats.kernelWakelockVersion); 13967 } 13968 } 13969 } 13970 13971 // We use an anonymous class to access these variables, 13972 // so they can't live on the stack or they'd have to be 13973 // final MutableLong objects (more allocations). 13974 // Used in updateCpuTimeLocked(). 13975 long mTempTotalCpuUserTimeUs; 13976 long mTempTotalCpuSystemTimeUs; 13977 long[][] mWakeLockAllocationsUs; 13978 13979 /** 13980 * Reads the newest memory stats from the kernel. 13981 */ 13982 public void updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs) { 13983 mKernelMemoryBandwidthStats.updateStats(); 13984 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 13985 final int bandwidthEntryCount = bandwidthEntries.size(); 13986 int index; 13987 for (int i = 0; i < bandwidthEntryCount; i++) { 13988 SamplingTimer timer; 13989 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 13990 timer = mKernelMemoryStats.valueAt(index); 13991 } else { 13992 timer = new SamplingTimer(mClock, mOnBatteryTimeBase); 13993 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 13994 } 13995 timer.update(bandwidthEntries.valueAt(i), 1, elapsedRealtimeUs); 13996 if (DEBUG_MEMORY) { 13997 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 13998 + "mUnpluggedReportedTotalTimeUs %d size %d", bandwidthEntries.keyAt(i), 13999 mKernelMemoryStats.get( 14000 bandwidthEntries.keyAt(i)).mBaseReportedTotalTimeUs, 14001 mKernelMemoryStats.size())); 14002 } 14003 } 14004 } 14005 14006 public boolean isOnBatteryLocked() { 14007 return mOnBatteryTimeBase.isRunning(); 14008 } 14009 14010 public boolean isOnBatteryScreenOffLocked() { 14011 return mOnBatteryScreenOffTimeBase.isRunning(); 14012 } 14013 14014 /** 14015 * Object for calculating and accumulating the estimated cpu power used while reading the 14016 * various cpu kernel files. 14017 */ 14018 @VisibleForTesting 14019 public static class CpuDeltaPowerAccumulator { 14020 // Keeps track of total charge used per cluster. 14021 public final double[] totalClusterChargesMah; 14022 // Keeps track of charge used per cluster per uid. 14023 public final ArrayMap<Uid, double[]> perUidCpuClusterChargesMah; 14024 14025 private final CpuPowerCalculator mCalculator; 14026 private Uid mCachedUid = null; 14027 private double[] mUidClusterCache = null; 14028 14029 CpuDeltaPowerAccumulator(CpuPowerCalculator calculator, int nClusters) { 14030 mCalculator = calculator; 14031 totalClusterChargesMah = new double[nClusters]; 14032 perUidCpuClusterChargesMah = new ArrayMap<>(); 14033 } 14034 14035 /** Add per cpu cluster durations to the currently cached uid. */ 14036 public void addCpuClusterDurationsMs(Uid uid, long[] durationsMs) { 14037 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 14038 for (int cluster = 0; cluster < durationsMs.length; cluster++) { 14039 final double estimatedDeltaMah = mCalculator.calculatePerCpuClusterPowerMah(cluster, 14040 durationsMs[cluster]); 14041 uidChargesMah[cluster] += estimatedDeltaMah; 14042 totalClusterChargesMah[cluster] += estimatedDeltaMah; 14043 } 14044 } 14045 14046 /** Add per speed per cpu cluster durations to the currently cached uid. */ 14047 public void addCpuClusterSpeedDurationsMs(Uid uid, int cluster, int speed, 14048 long durationsMs) { 14049 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 14050 final double estimatedDeltaMah = mCalculator.calculatePerCpuFreqPowerMah(cluster, speed, 14051 durationsMs); 14052 uidChargesMah[cluster] += estimatedDeltaMah; 14053 totalClusterChargesMah[cluster] += estimatedDeltaMah; 14054 } 14055 14056 private double[] getOrCreateUidCpuClusterCharges(Uid uid) { 14057 // Repeated additions on the same uid is very likely. 14058 // Skip a lookup if getting the same uid as the last get. 14059 if (uid == mCachedUid) return mUidClusterCache; 14060 14061 double[] uidChargesMah = perUidCpuClusterChargesMah.get(uid); 14062 if (uidChargesMah == null) { 14063 uidChargesMah = new double[totalClusterChargesMah.length]; 14064 perUidCpuClusterChargesMah.put(uid, uidChargesMah); 14065 } 14066 mCachedUid = uid; 14067 mUidClusterCache = uidChargesMah; 14068 return uidChargesMah; 14069 } 14070 } 14071 14072 /** 14073 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 14074 * and we are on battery with screen off, we give more of the cpu time to those apps holding 14075 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 14076 * It's possible this will be invoked after the internal battery/screen states are updated, so 14077 * passing the appropriate battery/screen states to try attribute the cpu times to correct 14078 * buckets. 14079 */ 14080 @GuardedBy("this") 14081 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff, 14082 long[] cpuClusterChargeUC) { 14083 if (DEBUG_ENERGY_CPU) { 14084 Slog.d(TAG, "!Cpu updating!"); 14085 } 14086 14087 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 14088 // usually holding the wakelock on behalf of an app. 14089 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 14090 ArrayList<StopwatchTimer> partialTimersToConsider = null; 14091 if (onBatteryScreenOff) { 14092 partialTimersToConsider = new ArrayList<>(); 14093 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 14094 final StopwatchTimer timer = mPartialTimers.get(i); 14095 // Since the collection and blaming of wakelocks can be scheduled to run after 14096 // some delay, the mPartialTimers list may have new entries. We can't blame 14097 // the newly added timer for past cpu time, so we only consider timers that 14098 // were present for one round of collection. Once a timer has gone through 14099 // a round of collection, its mInList field is set to true. 14100 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 14101 partialTimersToConsider.add(timer); 14102 } 14103 } 14104 } 14105 markPartialTimersAsEligible(); 14106 14107 // When the battery is not on, we don't attribute the cpu times to any timers but we still 14108 // need to take the snapshots. 14109 if (!onBattery) { 14110 mCpuUidUserSysTimeReader.readDelta(false, null); 14111 mCpuUidFreqTimeReader.readDelta(false, null); 14112 mNumAllUidCpuTimeReads += 2; 14113 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 14114 mCpuUidActiveTimeReader.readDelta(false, null); 14115 mCpuUidClusterTimeReader.readDelta(false, null); 14116 mNumAllUidCpuTimeReads += 2; 14117 } 14118 for (int i = mKernelCpuSpeedReaders.length - 1; i >= 0; --i) { 14119 if (mKernelCpuSpeedReaders[i] != null) { 14120 mKernelCpuSpeedReaders[i].readDelta(); 14121 } 14122 } 14123 if (!Flags.disableSystemServicePowerAttr()) { 14124 mSystemServerCpuThreadReader.readDelta(); 14125 } 14126 return; 14127 } 14128 14129 mUserInfoProvider.refreshUserIds(); 14130 final SparseLongArray updatedUids = mCpuUidFreqTimeReader.allUidTimesAvailable() 14131 ? null : new SparseLongArray(); 14132 14133 final CpuDeltaPowerAccumulator powerAccumulator; 14134 if (mGlobalEnergyConsumerStats != null 14135 && mGlobalEnergyConsumerStats.isStandardBucketSupported( 14136 EnergyConsumerStats.POWER_BUCKET_CPU)) { 14137 if (cpuClusterChargeUC == null) { 14138 Slog.wtf(TAG, 14139 "POWER_BUCKET_CPU supported but no EnergyConsumer Cpu Cluster charge " 14140 + "reported on updateCpuTimeLocked!"); 14141 powerAccumulator = null; 14142 } else { 14143 if (mCpuPowerCalculator == null) { 14144 mCpuPowerCalculator = new CpuPowerCalculator(mCpuScalingPolicies, 14145 mPowerProfile); 14146 } 14147 // Cpu EnergyConsumer is supported, create an object to accumulate the estimated 14148 // charge consumption since the last cpu update 14149 powerAccumulator = new CpuDeltaPowerAccumulator(mCpuPowerCalculator, 14150 mCpuScalingPolicies.getPolicies().length); 14151 } 14152 } else { 14153 powerAccumulator = null; 14154 } 14155 14156 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 14157 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 14158 // freqs, so no need to approximate these values. 14159 if (updatedUids != null) { 14160 updateClusterSpeedTimes(updatedUids, onBattery, powerAccumulator); 14161 } 14162 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff, 14163 powerAccumulator); 14164 mNumAllUidCpuTimeReads += 2; 14165 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 14166 // Cpu Active times do not get any info ony how to attribute Cpu Cluster 14167 // charge, so not need to provide the powerAccumulator 14168 readKernelUidCpuActiveTimesLocked(onBattery); 14169 readKernelUidCpuClusterTimesLocked(onBattery, powerAccumulator); 14170 mNumAllUidCpuTimeReads += 2; 14171 } 14172 14173 if (!Flags.disableSystemServicePowerAttr()) { 14174 updateSystemServerThreadStats(); 14175 } 14176 14177 if (powerAccumulator != null) { 14178 updateCpuEnergyConsumerStatsLocked(cpuClusterChargeUC, powerAccumulator); 14179 } 14180 } 14181 14182 /** 14183 * Estimates the proportion of the System Server CPU activity (per cluster per speed) 14184 * spent on handling incoming binder calls. 14185 */ 14186 @VisibleForTesting 14187 public void updateSystemServerThreadStats() { 14188 // There are some simplifying assumptions made in this algorithm 14189 // 1) We assume that if a thread handles incoming binder calls, all of its activity 14190 // is spent doing that. Most incoming calls are handled by threads allocated 14191 // by the native layer in the binder thread pool, so this assumption is reasonable. 14192 // 2) We use the aggregate CPU time spent in different threads as a proxy for the CPU 14193 // cost. In reality, in multi-core CPUs, the CPU cost may not be linearly 14194 // affected by additional threads. 14195 14196 SystemServerCpuThreadReader.SystemServiceCpuThreadTimes systemServiceCpuThreadTimes = 14197 mSystemServerCpuThreadReader.readDelta(); 14198 if (systemServiceCpuThreadTimes == null) { 14199 return; 14200 } 14201 14202 if (mBinderThreadCpuTimesUs == null) { 14203 mBinderThreadCpuTimesUs = new LongSamplingCounterArray(mOnBatteryTimeBase); 14204 } 14205 mBinderThreadCpuTimesUs.addCountLocked(systemServiceCpuThreadTimes.binderThreadCpuTimesUs); 14206 14207 if (DEBUG_BINDER_STATS) { 14208 Slog.d(TAG, "System server threads per CPU cluster (incoming binder threads)"); 14209 long binderThreadTimeMs = 0; 14210 final long[] binderThreadCpuTimesUs = mBinderThreadCpuTimesUs.getCountsLocked( 14211 BatteryStats.STATS_SINCE_CHARGED); 14212 int index = 0; 14213 int[] policies = mCpuScalingPolicies.getPolicies(); 14214 for (int policy : policies) { 14215 StringBuilder sb = new StringBuilder(); 14216 sb.append("policy").append(policy).append(": ["); 14217 int numSpeeds = mCpuScalingPolicies.getFrequencies(policy).length; 14218 for (int speed = 0; speed < numSpeeds; speed++) { 14219 if (speed != 0) { 14220 sb.append(", "); 14221 } 14222 long binderCountMs = binderThreadCpuTimesUs[index] / 1000; 14223 sb.append(TextUtils.formatSimple("%10d", binderCountMs)); 14224 14225 binderThreadTimeMs += binderCountMs; 14226 index++; 14227 } 14228 Slog.d(TAG, sb.toString()); 14229 } 14230 } 14231 } 14232 14233 /** 14234 * Mark the current partial timers as gone through a collection so that they will be 14235 * considered in the next cpu times distribution to wakelock holders. 14236 */ 14237 @VisibleForTesting 14238 public void markPartialTimersAsEligible() { 14239 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 14240 // No difference, so each timer is now considered for the next collection. 14241 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 14242 mPartialTimers.get(i).mInList = true; 14243 } 14244 } else { 14245 // The lists are different, meaning we added (or removed a timer) since the last 14246 // collection. 14247 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 14248 mLastPartialTimers.get(i).mInList = false; 14249 } 14250 mLastPartialTimers.clear(); 14251 14252 // Mark the current timers as gone through a collection. 14253 final int numPartialTimers = mPartialTimers.size(); 14254 for (int i = 0; i < numPartialTimers; ++i) { 14255 final StopwatchTimer timer = mPartialTimers.get(i); 14256 timer.mInList = true; 14257 mLastPartialTimers.add(timer); 14258 } 14259 } 14260 } 14261 14262 /** 14263 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 14264 * calculate cpu times spent by each uid at different frequencies. Will also add estimated 14265 * power consumptions, if powerAccumulator data structure is provided. 14266 * 14267 * @param updatedUids The uids for which times spent at different frequencies are calculated. 14268 * @param onBattery whether or not this is onBattery 14269 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 14270 */ 14271 @VisibleForTesting 14272 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery, 14273 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 14274 long totalCpuClustersTimeMs = 0; 14275 // Read the time spent for each cluster at various cpu frequencies. 14276 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 14277 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 14278 if (mKernelCpuSpeedReaders[cluster] != null) { 14279 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 14280 if (clusterSpeedTimesMs[cluster] != null) { 14281 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 14282 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 14283 } 14284 } 14285 } 14286 } 14287 if (totalCpuClustersTimeMs != 0) { 14288 // We have cpu times per freq aggregated over all uids but we need the times per uid. 14289 // So, we distribute total time spent by an uid to different cpu freqs based on the 14290 // amount of time cpu was running at that freq. 14291 final int updatedUidsCount = updatedUids.size(); 14292 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14293 final long uptimeMs = mClock.uptimeMillis(); 14294 for (int i = 0; i < updatedUidsCount; ++i) { 14295 final Uid u = getUidStatsLocked(updatedUids.keyAt(i), elapsedRealtimeMs, uptimeMs); 14296 final long appCpuTimeUs = updatedUids.valueAt(i); 14297 // Add the cpu speeds to this UID. 14298 int[] policies = mCpuScalingPolicies.getPolicies(); 14299 if (u.mCpuClusterSpeedTimesUs == null || 14300 u.mCpuClusterSpeedTimesUs.length != policies.length) { 14301 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[policies.length][]; 14302 } 14303 14304 for (int cluster = 0; cluster < policies.length; cluster++) { 14305 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 14306 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 14307 u.mCpuClusterSpeedTimesUs[cluster].length) { 14308 u.mCpuClusterSpeedTimesUs[cluster] 14309 = new LongSamplingCounter[speedsInCluster]; 14310 } 14311 14312 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 14313 for (int speed = 0; speed < speedsInCluster; speed++) { 14314 if (cpuSpeeds[speed] == null) { 14315 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 14316 } 14317 final long deltaSpeedCount = appCpuTimeUs 14318 * clusterSpeedTimesMs[cluster][speed] 14319 / totalCpuClustersTimeMs; 14320 cpuSpeeds[speed].addCountLocked(deltaSpeedCount, onBattery); 14321 14322 if (powerAccumulator != null) { 14323 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14324 speed, deltaSpeedCount); 14325 } 14326 } 14327 } 14328 } 14329 } 14330 } 14331 14332 /** 14333 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 14334 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 14335 * wakelock holders. 14336 * 14337 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 14338 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 14339 */ 14340 @VisibleForTesting 14341 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 14342 @Nullable SparseLongArray updatedUids, boolean onBattery) { 14343 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 14344 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 14345 final long startTimeMs = mClock.uptimeMillis(); 14346 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14347 14348 mCpuUidUserSysTimeReader.readDelta(false, (uid, timesUs) -> { 14349 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 14350 14351 uid = mapUid(uid); 14352 if (Process.isIsolated(uid)) { 14353 // This could happen if the isolated uid mapping was removed before that process 14354 // was actually killed. 14355 if (DEBUG) Slog.d(TAG, "Got readings for an isolated uid: " + uid); 14356 return; 14357 } 14358 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14359 if (DEBUG) Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 14360 return; 14361 } 14362 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 14363 14364 // Accumulate the total system and user time. 14365 mTempTotalCpuUserTimeUs += userTimeUs; 14366 mTempTotalCpuSystemTimeUs += systemTimeUs; 14367 14368 StringBuilder sb = null; 14369 if (DEBUG_ENERGY_CPU) { 14370 sb = new StringBuilder(); 14371 sb.append(" got time for uid=").append(u.mUid).append(": u="); 14372 TimeUtils.formatDuration(userTimeUs / 1000, sb); 14373 sb.append(" s="); 14374 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 14375 sb.append("\n"); 14376 } 14377 14378 if (numWakelocks > 0) { 14379 // We have wakelocks being held, so only give a portion of the 14380 // time to the process. The rest will be distributed among wakelock 14381 // holders. 14382 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 14383 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 14384 } 14385 14386 if (sb != null) { 14387 sb.append(" adding to uid=").append(u.mUid).append(": u="); 14388 TimeUtils.formatDuration(userTimeUs / 1000, sb); 14389 sb.append(" s="); 14390 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 14391 Slog.d(TAG, sb.toString()); 14392 } 14393 14394 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 14395 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 14396 if (updatedUids != null) { 14397 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 14398 } 14399 }); 14400 14401 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14402 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14403 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 14404 } 14405 14406 if (numWakelocks > 0) { 14407 // Distribute a portion of the total cpu time to wakelock holders. 14408 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 14409 mTempTotalCpuSystemTimeUs = 14410 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 14411 14412 for (int i = 0; i < numWakelocks; ++i) { 14413 final StopwatchTimer timer = partialTimers.get(i); 14414 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 14415 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 14416 14417 if (DEBUG_ENERGY_CPU) { 14418 final StringBuilder sb = new StringBuilder(); 14419 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 14420 .append(": u="); 14421 TimeUtils.formatDuration(userTimeUs / 1000, sb); 14422 sb.append(" s="); 14423 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 14424 Slog.d(TAG, sb.toString()); 14425 } 14426 14427 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 14428 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 14429 if (updatedUids != null) { 14430 final int uid = timer.mUid.getUid(); 14431 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 14432 } 14433 14434 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 14435 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 14436 14437 mTempTotalCpuUserTimeUs -= userTimeUs; 14438 mTempTotalCpuSystemTimeUs -= systemTimeUs; 14439 } 14440 } 14441 } 14442 14443 /** 14444 * Take a snapshot of the cpu times spent by each uid in each freq and update the 14445 * corresponding counters. Will also add estimated power consumptions, if powerAccumulator 14446 * data structure is provided. 14447 * 14448 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 14449 * @param onBattery whether or not this is onBattery 14450 * @param onBatteryScreenOff whether or not this is onBattery with the screen off. 14451 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 14452 */ 14453 @VisibleForTesting 14454 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 14455 boolean onBattery, boolean onBatteryScreenOff, 14456 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 14457 final boolean perClusterTimesAvailable = 14458 mCpuUidFreqTimeReader.perClusterTimesAvailable(); 14459 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 14460 final int[] policies = mCpuScalingPolicies.getPolicies(); 14461 final int numClusters = policies.length; 14462 mWakeLockAllocationsUs = null; 14463 final long startTimeMs = mClock.uptimeMillis(); 14464 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14465 // If power is being accumulated for attribution, data needs to be read immediately. 14466 final boolean forceRead = powerAccumulator != null; 14467 mCpuUidFreqTimeReader.readDelta(forceRead, (uid, cpuFreqTimeMs) -> { 14468 uid = mapUid(uid); 14469 if (Process.isIsolated(uid)) { 14470 if (DEBUG) Slog.d(TAG, "Got freq readings for an isolated uid: " + uid); 14471 return; 14472 } 14473 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14474 if (DEBUG) Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 14475 return; 14476 } 14477 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 14478 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 14479 detachIfNotNull(u.mCpuFreqTimeMs); 14480 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 14481 } 14482 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 14483 if (u.mScreenOffCpuFreqTimeMs == null || 14484 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 14485 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 14486 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 14487 mOnBatteryScreenOffTimeBase); 14488 } 14489 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 14490 14491 if (perClusterTimesAvailable) { 14492 if (u.mCpuClusterSpeedTimesUs == null || 14493 u.mCpuClusterSpeedTimesUs.length != numClusters) { 14494 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 14495 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 14496 } 14497 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 14498 mWakeLockAllocationsUs = new long[numClusters][]; 14499 } 14500 14501 int freqIndex = 0; 14502 for (int cluster = 0; cluster < numClusters; cluster++) { 14503 final int[] freqs = mCpuScalingPolicies.getFrequencies(policies[cluster]); 14504 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 14505 u.mCpuClusterSpeedTimesUs[cluster].length != freqs.length) { 14506 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 14507 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[freqs.length]; 14508 } 14509 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 14510 mWakeLockAllocationsUs[cluster] = new long[freqs.length]; 14511 } 14512 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 14513 for (int speed = 0; speed < freqs.length; ++speed) { 14514 if (cpuTimesUs[speed] == null) { 14515 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 14516 } 14517 final long appAllocationUs; 14518 if (mWakeLockAllocationsUs != null) { 14519 appAllocationUs = 14520 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 14521 mWakeLockAllocationsUs[cluster][speed] += 14522 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 14523 } else { 14524 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 14525 } 14526 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 14527 14528 if (powerAccumulator != null) { 14529 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14530 speed, appAllocationUs / 1000); 14531 } 14532 freqIndex++; 14533 } 14534 } 14535 } 14536 }); 14537 14538 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14539 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14540 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 14541 } 14542 14543 if (mWakeLockAllocationsUs != null) { 14544 for (int i = 0; i < numWakelocks; ++i) { 14545 final Uid u = partialTimers.get(i).mUid; 14546 if (u.mCpuClusterSpeedTimesUs == null || 14547 u.mCpuClusterSpeedTimesUs.length != numClusters) { 14548 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 14549 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 14550 } 14551 14552 for (int cluster = 0; cluster < numClusters; ++cluster) { 14553 final int speedsInCluster = 14554 mCpuScalingPolicies.getFrequencies(policies[cluster]).length; 14555 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 14556 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 14557 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 14558 u.mCpuClusterSpeedTimesUs[cluster] 14559 = new LongSamplingCounter[speedsInCluster]; 14560 } 14561 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 14562 for (int speed = 0; speed < speedsInCluster; ++speed) { 14563 if (cpuTimeUs[speed] == null) { 14564 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 14565 } 14566 final long allocationUs = 14567 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 14568 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 14569 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 14570 14571 if (powerAccumulator != null) { 14572 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14573 speed, allocationUs / 1000); 14574 } 14575 } 14576 } 14577 } 14578 } 14579 } 14580 14581 /** 14582 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 14583 * counters. 14584 */ 14585 @VisibleForTesting 14586 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 14587 final long startTimeMs = mClock.uptimeMillis(); 14588 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14589 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { 14590 final int parentUid = mapUid(uid); 14591 if (Process.isIsolated(parentUid)) { 14592 if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); 14593 return; 14594 } 14595 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14596 if (DEBUG) Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 14597 return; 14598 } 14599 final Uid u = getUidStatsLocked(parentUid, elapsedRealtimeMs, startTimeMs); 14600 if (parentUid == uid) { 14601 u.getCpuActiveTimeCounter().update(cpuActiveTimesMs, elapsedRealtimeMs); 14602 } else { 14603 final SparseArray<Uid.ChildUid> childUids = u.mChildUids; 14604 if (childUids == null) { 14605 return; 14606 } 14607 14608 Uid.ChildUid childUid = childUids.get(uid); 14609 if (childUid != null) { 14610 final long delta = 14611 childUid.cpuActiveCounter.update(cpuActiveTimesMs, elapsedRealtimeMs); 14612 u.getCpuActiveTimeCounter().increment(delta, elapsedRealtimeMs); 14613 } 14614 } 14615 }); 14616 14617 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14618 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14619 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 14620 } 14621 } 14622 14623 /** 14624 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 14625 * counters. Will also add estimated power consumptions, if powerAccumulator data structure 14626 * is provided. 14627 * 14628 * @param onBattery whether or not this is onBattery 14629 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 14630 */ 14631 @VisibleForTesting 14632 public void readKernelUidCpuClusterTimesLocked(boolean onBattery, 14633 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 14634 final long startTimeMs = mClock.uptimeMillis(); 14635 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14636 // If power is being accumulated for attribution, data needs to be read immediately. 14637 final boolean forceRead = powerAccumulator != null; 14638 mCpuUidClusterTimeReader.readDelta(forceRead, (uid, cpuClusterTimesMs) -> { 14639 uid = mapUid(uid); 14640 if (Process.isIsolated(uid)) { 14641 if (DEBUG) Slog.w(TAG, "Got cluster times for an isolated uid: " + uid); 14642 return; 14643 } 14644 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14645 if (DEBUG) Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 14646 return; 14647 } 14648 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 14649 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 14650 14651 if (powerAccumulator != null) { 14652 powerAccumulator.addCpuClusterDurationsMs(u, cpuClusterTimesMs); 14653 } 14654 }); 14655 14656 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14657 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14658 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 14659 } 14660 } 14661 14662 boolean setChargingLocked(boolean charging) { 14663 // if the device is no longer charging, remove the callback 14664 // if the device is now charging, it means that this is either called 14665 // 1. directly when level >= 90 14666 // 2. or from within the runnable that we deferred 14667 // For 1. if we have an existing callback, remove it, since we will immediately send a 14668 // ACTION_CHARGING 14669 // For 2. we remove existing callback so we don't send multiple ACTION_CHARGING 14670 mHandler.removeCallbacks(mDeferSetCharging); 14671 if (mCharging != charging) { 14672 mCharging = charging; 14673 mHistory.setChargingState(charging); 14674 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 14675 return true; 14676 } 14677 return false; 14678 } 14679 14680 /** 14681 * Notifies BatteryStatsImpl that the system server is ready. 14682 */ 14683 public void onSystemReady(Context context) { 14684 if (mCpuUidFreqTimeReader != null) { 14685 mCpuUidFreqTimeReader.onSystemReady(); 14686 } 14687 14688 mPowerStatsCollectorInjector.setContext(context); 14689 14690 mCpuPowerStatsCollector.setEnabled( 14691 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)); 14692 mCpuPowerStatsCollector.schedule(); 14693 14694 mMobileRadioPowerStatsCollector.setEnabled( 14695 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)); 14696 mMobileRadioPowerStatsCollector.schedule(); 14697 14698 mWifiPowerStatsCollector.setEnabled( 14699 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_WIFI)); 14700 mWifiPowerStatsCollector.schedule(); 14701 14702 mBluetoothPowerStatsCollector.setEnabled( 14703 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_BLUETOOTH)); 14704 mBluetoothPowerStatsCollector.schedule(); 14705 14706 mSystemReady = true; 14707 } 14708 14709 /** 14710 * Returns a PowerStatsCollector for the specified power component or null if unavailable. 14711 */ 14712 @Nullable 14713 PowerStatsCollector getPowerStatsCollector( 14714 @BatteryConsumer.PowerComponent int powerComponent) { 14715 switch (powerComponent) { 14716 case BatteryConsumer.POWER_COMPONENT_CPU: 14717 return mCpuPowerStatsCollector; 14718 case BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO: 14719 return mMobileRadioPowerStatsCollector; 14720 case BatteryConsumer.POWER_COMPONENT_WIFI: 14721 return mWifiPowerStatsCollector; 14722 case BatteryConsumer.POWER_COMPONENT_BLUETOOTH: 14723 return mBluetoothPowerStatsCollector; 14724 } 14725 return null; 14726 } 14727 14728 14729 /** 14730 * Force recording of all history events regardless of the "charging" state. 14731 */ 14732 @VisibleForTesting 14733 public void forceRecordAllHistory() { 14734 mHistory.forceRecordAllHistory(); 14735 mRecordAllHistory = true; 14736 } 14737 14738 /** 14739 * Might reset battery stats if conditions are met. Assumed the device is currently plugged in. 14740 */ 14741 @VisibleForTesting 14742 @GuardedBy("this") 14743 public void maybeResetWhilePluggedInLocked() { 14744 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14745 if (shouldResetWhilePluggedInLocked(elapsedRealtimeMs)) { 14746 Slog.i(TAG, 14747 "Resetting due to long plug in duration. elapsed time = " + elapsedRealtimeMs 14748 + " ms, last plug in time = " + mBatteryPluggedInRealTimeMs 14749 + " ms, last reset time = " + mRealtimeStartUs / 1000); 14750 resetAllStatsAndHistoryLocked(RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION); 14751 } 14752 14753 scheduleNextResetWhilePluggedInCheck(); 14754 } 14755 14756 @GuardedBy("this") 14757 private void scheduleNextResetWhilePluggedInCheck() { 14758 if (mAlarmManager == null) return; 14759 final long timeoutMs = mClock.currentTimeMillis() 14760 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14761 * DateUtils.HOUR_IN_MILLIS; 14762 Calendar nextAlarm = Calendar.getInstance(); 14763 nextAlarm.setTimeInMillis(timeoutMs); 14764 14765 // Find the 2 AM the same day as the end of the minimum duration. 14766 // This logic does not handle a Daylight Savings transition, or a timezone change 14767 // while the alarm has been set. The need to reset after a long period while plugged 14768 // in is not strict enough to warrant a well architected out solution. 14769 nextAlarm.set(Calendar.MILLISECOND, 0); 14770 nextAlarm.set(Calendar.SECOND, 0); 14771 nextAlarm.set(Calendar.MINUTE, 0); 14772 nextAlarm.set(Calendar.HOUR_OF_DAY, 2); 14773 long possibleNextTimeMs = nextAlarm.getTimeInMillis(); 14774 if (possibleNextTimeMs < timeoutMs) { 14775 // The 2AM on the day of the timeout, move on the next day. 14776 possibleNextTimeMs += DateUtils.DAY_IN_MILLIS; 14777 } 14778 final long nextTimeMs = possibleNextTimeMs; 14779 final AlarmManager am = mAlarmManager; 14780 mHandler.post(() -> am.setWindow(AlarmManager.RTC, nextTimeMs, 14781 DateUtils.HOUR_IN_MILLIS, 14782 TAG, mLongPlugInAlarmHandler, mHandler)); 14783 } 14784 14785 14786 @GuardedBy("this") 14787 private boolean shouldResetWhilePluggedInLocked(long elapsedRealtimeMs) { 14788 if (mNoAutoReset) return false; 14789 if (!mSystemReady) return false; 14790 if (!mHistory.isResetEnabled()) return false; 14791 14792 final long pluggedInThresholdMs = mBatteryPluggedInRealTimeMs 14793 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14794 * DateUtils.HOUR_IN_MILLIS; 14795 if (elapsedRealtimeMs >= pluggedInThresholdMs) { 14796 // The device has been plugged in for a long time. 14797 final long resetThresholdMs = mRealtimeStartUs / 1000 14798 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14799 * DateUtils.HOUR_IN_MILLIS; 14800 if (elapsedRealtimeMs >= resetThresholdMs) { 14801 // And it has been a long time since the last reset. 14802 return true; 14803 } 14804 } 14805 14806 return false; 14807 } 14808 14809 @GuardedBy("this") 14810 private boolean shouldResetOnUnplugLocked(int batteryStatus, int batteryLevel) { 14811 if (mNoAutoReset) return false; 14812 if (!mSystemReady) return false; 14813 if (!mHistory.isResetEnabled()) return false; 14814 if (mBatteryStatsConfig.shouldResetOnUnplugHighBatteryLevel()) { 14815 // Allow resetting due to currently being at high battery level 14816 if (batteryStatus == BatteryManager.BATTERY_STATUS_FULL) return true; 14817 if (batteryLevel >= 90) return true; 14818 } 14819 if (mBatteryStatsConfig.shouldResetOnUnplugAfterSignificantCharge()) { 14820 // Allow resetting after a significant charge (from a very low level to a now very 14821 // high level). 14822 if (mDischargePlugLevel < 20 && batteryLevel >= 80) return true; 14823 } 14824 if (getHighDischargeAmountSinceCharge() >= 200) { 14825 // Reset the stats if battery got partially charged and discharged repeatedly without 14826 // ever reaching the full charge. 14827 // This reset is done in order to prevent stats sessions from going on forever. 14828 // Exceedingly long battery sessions would lead to an overflow of 14829 // data structures such as mWakeupReasonStats. 14830 return true; 14831 } 14832 14833 return false; 14834 } 14835 14836 @GuardedBy("this") 14837 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 14838 final boolean onBattery, final int oldStatus, final int level, final int chargeUah) { 14839 boolean doWrite = false; 14840 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 14841 m.arg1 = onBattery ? 1 : 0; 14842 mHandler.sendMessage(m); 14843 14844 final long uptimeUs = mSecUptime * 1000; 14845 final long realtimeUs = mSecRealtime * 1000; 14846 final int screenState = mScreenState; 14847 if (onBattery) { 14848 boolean reset = false; 14849 if (shouldResetOnUnplugLocked(oldStatus, level)) { 14850 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 14851 + " dischargeLevel=" + mDischargePlugLevel 14852 + " lowAmount=" + getLowDischargeAmountSinceCharge() 14853 + " highAmount=" + getHighDischargeAmountSinceCharge()); 14854 // Before we write, collect a snapshot of the final aggregated 14855 // stats to be reported in the next checkin. Only do this if we have 14856 // a sufficient amount of data to make it interesting. 14857 if (getLowDischargeAmountSinceCharge() >= 20) { 14858 final long startTimeMs = SystemClock.uptimeMillis(); 14859 final Parcel parcel = Parcel.obtain(); 14860 writeSummaryToParcel(parcel, true); 14861 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 14862 BackgroundThread.getHandler().post(new Runnable() { 14863 @Override public void run() { 14864 synchronized (mCheckinFile) { 14865 final long startTimeMs2 = SystemClock.uptimeMillis(); 14866 FileOutputStream stream = null; 14867 try { 14868 stream = mCheckinFile.startWrite(); 14869 stream.write(parcel.marshall()); 14870 stream.flush(); 14871 mCheckinFile.finishWrite(stream); 14872 mFrameworkStatsLogger.writeCommitSysConfigFile( 14873 "batterystats-checkin", 14874 initialTimeMs + SystemClock.uptimeMillis() 14875 - startTimeMs2); 14876 } catch (IOException e) { 14877 Slog.w("BatteryStats", 14878 "Error writing checkin battery statistics", e); 14879 mCheckinFile.failWrite(stream); 14880 } finally { 14881 parcel.recycle(); 14882 } 14883 } 14884 } 14885 }); 14886 } 14887 doWrite = true; 14888 resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_FULL_CHARGE); 14889 if (chargeUah > 0 && level > 0) { 14890 // Only use the reported coulomb charge value if it is supported and reported. 14891 mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0)); 14892 } 14893 reset = true; 14894 mDischargeStepTracker.init(); 14895 } 14896 if (mCharging) { 14897 setChargingLocked(false); 14898 } 14899 mOnBattery = mOnBatteryInternal = true; 14900 mLastDischargeStepLevel = level; 14901 mMinDischargeStepLevel = level; 14902 mDischargeStepTracker.clearTime(); 14903 mDailyDischargeStepTracker.clearTime(); 14904 mInitStepMode = mCurStepMode; 14905 mModStepMode = 0; 14906 pullPendingStateUpdatesLocked(); 14907 if (reset) { 14908 mHistory.startRecordingHistory(mSecRealtime, mSecUptime, reset); 14909 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 14910 } 14911 mBatteryPluggedIn = false; 14912 if (mAlarmManager != null) { 14913 final AlarmManager am = mAlarmManager; 14914 mHandler.post(() -> { 14915 // No longer plugged in. Cancel the long plug in alarm. 14916 am.cancel(mLongPlugInAlarmHandler); 14917 }); 14918 } 14919 mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn); 14920 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 14921 if (Display.isOnState(screenState)) { 14922 mDischargeScreenOnUnplugLevel = level; 14923 mDischargeScreenDozeUnplugLevel = 0; 14924 mDischargeScreenOffUnplugLevel = 0; 14925 } else if (Display.isDozeState(screenState)) { 14926 mDischargeScreenOnUnplugLevel = 0; 14927 mDischargeScreenDozeUnplugLevel = level; 14928 mDischargeScreenOffUnplugLevel = 0; 14929 } else { 14930 mDischargeScreenOnUnplugLevel = 0; 14931 mDischargeScreenDozeUnplugLevel = 0; 14932 mDischargeScreenOffUnplugLevel = level; 14933 } 14934 mDischargeAmountScreenOn = 0; 14935 mDischargeAmountScreenDoze = 0; 14936 mDischargeAmountScreenOff = 0; 14937 updateTimeBasesLocked(true, screenState, uptimeUs, realtimeUs); 14938 } else { 14939 mOnBattery = mOnBatteryInternal = false; 14940 pullPendingStateUpdatesLocked(); 14941 mBatteryPluggedIn = true; 14942 mBatteryPluggedInRealTimeMs = mSecRealtime; 14943 mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn); 14944 mDischargeCurrentLevel = mDischargePlugLevel = level; 14945 if (level < mDischargeUnplugLevel) { 14946 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 14947 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 14948 } 14949 updateDischargeScreenLevelsLocked(screenState, screenState); 14950 updateTimeBasesLocked(false, screenState, uptimeUs, realtimeUs); 14951 mChargeStepTracker.init(); 14952 mLastChargeStepLevel = level; 14953 mMaxChargeStepLevel = level; 14954 mInitStepMode = mCurStepMode; 14955 mModStepMode = 0; 14956 scheduleNextResetWhilePluggedInCheck(); 14957 } 14958 if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) { 14959 if (mStatsFile != null && !mHistory.isReadOnly()) { 14960 writeAsyncLocked(); 14961 } 14962 } 14963 } 14964 14965 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 14966 if (mExternalSync != null) { 14967 mExternalSync.scheduleSync(reason, updateFlags); 14968 } 14969 } 14970 14971 // This should probably be exposed in the API, though it's not critical 14972 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 14973 14974 @GuardedBy("this") 14975 public void setBatteryStateLocked(final int status, final int health, final int plugType, 14976 final int level, /* not final */ int temp, final int voltageMv, final int chargeUah, 14977 final int chargeFullUah, final long chargeTimeToFullSeconds, 14978 final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs) { 14979 14980 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 14981 temp = Math.max(0, temp); 14982 14983 reportChangesToStatsLog(status, plugType, level); 14984 14985 final boolean onBattery = isOnBattery(plugType, status); 14986 if (!mHaveBatteryLevel) { 14987 mHaveBatteryLevel = true; 14988 // We start out assuming that the device is plugged in (not 14989 // on battery). If our first report is now that we are indeed 14990 // plugged in, then twiddle our state to correctly reflect that 14991 // since we won't be going through the full setOnBattery(). 14992 if (onBattery == mOnBattery) { 14993 mHistory.setPluggedInState(!onBattery); 14994 } 14995 mBatteryStatus = status; 14996 mBatteryLevel = level; 14997 mBatteryChargeUah = chargeUah; 14998 14999 // Always start out assuming charging, that will be updated later. 15000 mHistory.setBatteryState(true /* charging */, status, level, chargeUah); 15001 15002 mMaxChargeStepLevel = mMinDischargeStepLevel = 15003 mLastChargeStepLevel = mLastDischargeStepLevel = level; 15004 } else if (mBatteryLevel != level || mOnBattery != onBattery) { 15005 recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs); 15006 } 15007 int oldStatus = mBatteryStatus; 15008 if (onBattery) { 15009 mDischargeCurrentLevel = level; 15010 if (!mHistory.isRecordingHistory()) { 15011 mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 15012 } 15013 } else if (level < 96 && 15014 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 15015 if (!mHistory.isRecordingHistory()) { 15016 mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 15017 } 15018 } 15019 if (mDischargePlugLevel < 0) { 15020 mDischargePlugLevel = level; 15021 } 15022 15023 if (onBattery != mOnBattery) { 15024 mBatteryLevel = level; 15025 mBatteryStatus = status; 15026 mBatteryHealth = health; 15027 mBatteryPlugType = plugType; 15028 mBatteryTemperature = temp; 15029 mBatteryVoltageMv = voltageMv; 15030 mHistory.setBatteryState(status, level, health, plugType, temp, voltageMv, chargeUah); 15031 if (chargeUah < mBatteryChargeUah) { 15032 // Only record discharges 15033 final long chargeDiff = (long) mBatteryChargeUah - chargeUah; 15034 mDischargeCounter.addCountLocked(chargeDiff); 15035 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 15036 if (Display.isDozeState(mScreenState)) { 15037 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 15038 } 15039 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 15040 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 15041 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 15042 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 15043 } 15044 } 15045 mBatteryChargeUah = chargeUah; 15046 setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUah); 15047 } else { 15048 boolean changed = false; 15049 if (mBatteryLevel != level) { 15050 mBatteryLevel = level; 15051 changed = true; 15052 15053 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 15054 // which will pull external stats. 15055 mExternalSync.scheduleSyncDueToBatteryLevelChange( 15056 mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); 15057 } 15058 if (mBatteryStatus != status) { 15059 mBatteryStatus = status; 15060 changed = true; 15061 } 15062 if (mBatteryHealth != health) { 15063 mBatteryHealth = health; 15064 changed = true; 15065 } 15066 if (mBatteryPlugType != plugType) { 15067 mBatteryPlugType = plugType; 15068 changed = true; 15069 } 15070 if (temp >= (mBatteryTemperature + 10) 15071 || temp <= (mBatteryTemperature - 10)) { 15072 mBatteryTemperature = temp; 15073 changed = true; 15074 } 15075 if (voltageMv > (mBatteryVoltageMv + 20) 15076 || voltageMv < (mBatteryVoltageMv - 20)) { 15077 mBatteryVoltageMv = voltageMv; 15078 changed = true; 15079 } 15080 if (chargeUah >= (mBatteryChargeUah + 10) 15081 || chargeUah <= (mBatteryChargeUah - 10)) { 15082 if (chargeUah < mBatteryChargeUah) { 15083 // Only record discharges 15084 final long chargeDiff = (long) mBatteryChargeUah - chargeUah; 15085 mDischargeCounter.addCountLocked(chargeDiff); 15086 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 15087 if (Display.isDozeState(mScreenState)) { 15088 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 15089 } 15090 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 15091 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 15092 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 15093 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 15094 } 15095 } 15096 mBatteryChargeUah = chargeUah; 15097 changed = true; 15098 } 15099 15100 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 15101 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 15102 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 15103 if (onBattery) { 15104 changed |= setChargingLocked(false); 15105 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 15106 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 15107 modeBits, elapsedRealtimeMs); 15108 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 15109 modeBits, elapsedRealtimeMs); 15110 mLastDischargeStepLevel = level; 15111 mMinDischargeStepLevel = level; 15112 mInitStepMode = mCurStepMode; 15113 mModStepMode = 0; 15114 } 15115 } else { 15116 if (level >= mConstants.BATTERY_CHARGING_ENFORCE_LEVEL) { 15117 // If the battery level is at least Constants.BATTERY_CHARGING_ENFORCE_LEVEL, 15118 // always consider the device to be charging even if it happens to go down a 15119 // level. 15120 changed |= setChargingLocked(true); 15121 } else if (!mCharging) { 15122 if (mLastChargeStepLevel < level) { 15123 // We have not reported that we are charging, but the level has gone up, 15124 // but we would like to not have tons of activity from charging-constraint 15125 // jobs, so instead of reporting ACTION_CHARGING immediately, we defer it. 15126 if (!mHandler.hasCallbacks(mDeferSetCharging)) { 15127 mHandler.postDelayed( 15128 mDeferSetCharging, 15129 mConstants.BATTERY_CHARGED_DELAY_MS); 15130 } 15131 } else if (mLastChargeStepLevel > level) { 15132 // if we had deferred a runnable due to charge level increasing, but then 15133 // later the charge level drops (could be due to thermal issues), we don't 15134 // want to trigger the deferred runnable, so remove it here 15135 mHandler.removeCallbacks(mDeferSetCharging); 15136 } 15137 } else { 15138 if (mLastChargeStepLevel > level) { 15139 // We had reported that the device was charging, but here we are with 15140 // power connected and the level going down. Looks like the current 15141 // power supplied isn't enough, so consider the device to now be 15142 // discharging. 15143 changed |= setChargingLocked(false); 15144 } 15145 } 15146 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 15147 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 15148 modeBits, elapsedRealtimeMs); 15149 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 15150 modeBits, elapsedRealtimeMs); 15151 mMaxChargeStepLevel = level; 15152 mInitStepMode = mCurStepMode; 15153 mModStepMode = 0; 15154 } 15155 mLastChargeStepLevel = level; 15156 } 15157 if (changed) { 15158 mHistory.setBatteryState(mBatteryStatus, mBatteryLevel, mBatteryHealth, 15159 mBatteryPlugType, mBatteryTemperature, mBatteryVoltageMv, 15160 mBatteryChargeUah); 15161 mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs); 15162 } 15163 } 15164 if (!onBattery && 15165 (status == BatteryManager.BATTERY_STATUS_FULL || 15166 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) { 15167 // We don't record history while we are plugged in and fully charged 15168 // (or when battery is not present). The next time we are 15169 // unplugged, history will be cleared. 15170 mHistory.setHistoryRecordingEnabled(DEBUG); 15171 } 15172 15173 mLastLearnedBatteryCapacityUah = chargeFullUah; 15174 if (mMinLearnedBatteryCapacityUah == -1) { 15175 mMinLearnedBatteryCapacityUah = chargeFullUah; 15176 } else { 15177 mMinLearnedBatteryCapacityUah = Math.min(mMinLearnedBatteryCapacityUah, chargeFullUah); 15178 } 15179 mMaxLearnedBatteryCapacityUah = Math.max(mMaxLearnedBatteryCapacityUah, chargeFullUah); 15180 15181 mBatteryTimeToFullSeconds = chargeTimeToFullSeconds; 15182 } 15183 15184 public static boolean isOnBattery(int plugType, int status) { 15185 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 15186 } 15187 15188 // Inform StatsLog of setBatteryState changes. 15189 private void reportChangesToStatsLog(final int status, final int plugType, final int level) { 15190 if (!mHaveBatteryLevel || mBatteryStatus != status) { 15191 mFrameworkStatsLogger.chargingStateChanged(status); 15192 } 15193 if (!mHaveBatteryLevel || mBatteryPlugType != plugType) { 15194 mFrameworkStatsLogger.pluggedStateChanged(plugType); 15195 } 15196 if (!mHaveBatteryLevel || mBatteryLevel != level) { 15197 mFrameworkStatsLogger.batteryLevelChanged(level); 15198 } 15199 } 15200 15201 public long getAwakeTimeBattery() { 15202 // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); 15203 // for over a decade, but surely that was a mistake. 15204 return getBatteryUptimeLocked(mClock.uptimeMillis()); 15205 } 15206 15207 public long getAwakeTimePlugged() { 15208 return (mClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 15209 } 15210 15211 @Override 15212 public long computeUptime(long curTimeUs, int which) { 15213 return mUptimeUs + (curTimeUs - mUptimeStartUs); 15214 } 15215 15216 @Override 15217 public long computeRealtime(long curTimeUs, int which) { 15218 return mRealtimeUs + (curTimeUs - mRealtimeStartUs); 15219 } 15220 15221 @Override 15222 public long computeBatteryUptime(long curTimeUs, int which) { 15223 return mOnBatteryTimeBase.computeUptime(curTimeUs, which); 15224 } 15225 15226 @Override 15227 public long computeBatteryRealtime(long curTimeUs, int which) { 15228 return mOnBatteryTimeBase.computeRealtime(curTimeUs, which); 15229 } 15230 15231 @Override 15232 public long computeBatteryScreenOffUptime(long curTimeUs, int which) { 15233 return mOnBatteryScreenOffTimeBase.computeUptime(curTimeUs, which); 15234 } 15235 15236 @Override 15237 public long computeBatteryScreenOffRealtime(long curTimeUs, int which) { 15238 return mOnBatteryScreenOffTimeBase.computeRealtime(curTimeUs, which); 15239 } 15240 15241 @Override 15242 public long computeBatteryTimeRemaining(long curTime) { 15243 if (!mOnBattery) { 15244 return -1; 15245 } 15246 /* Simple implementation just looks at the average discharge per level across the 15247 entire sample period. 15248 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 15249 if (discharge < 2) { 15250 return -1; 15251 } 15252 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 15253 if (duration < 1000*1000) { 15254 return -1; 15255 } 15256 long usPerLevel = duration/discharge; 15257 return usPerLevel * mCurrentBatteryLevel; 15258 */ 15259 if (mDischargeStepTracker.mNumStepDurations < 1) { 15260 return -1; 15261 } 15262 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 15263 if (msPerLevel <= 0) { 15264 return -1; 15265 } 15266 return (msPerLevel * mBatteryLevel) * 1000; 15267 } 15268 15269 @Override 15270 public LevelStepTracker getDischargeLevelStepTracker() { 15271 return mDischargeStepTracker; 15272 } 15273 15274 @Override 15275 public LevelStepTracker getDailyDischargeLevelStepTracker() { 15276 return mDailyDischargeStepTracker; 15277 } 15278 15279 @Override 15280 public long computeChargeTimeRemaining(long curTime) { 15281 if (mOnBattery) { 15282 // Not yet working. 15283 return -1; 15284 } 15285 if (mBatteryTimeToFullSeconds >= 0) { 15286 return mBatteryTimeToFullSeconds * (1000 * 1000); // s to us 15287 } 15288 // Else use algorithmic approach 15289 if (mChargeStepTracker.mNumStepDurations < 1) { 15290 return -1; 15291 } 15292 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 15293 if (msPerLevel <= 0) { 15294 return -1; 15295 } 15296 return (msPerLevel * (100 - mBatteryLevel)) * 1000; 15297 } 15298 15299 /*@hide */ 15300 public CellularBatteryStats getCellularBatteryStats() { 15301 final int which = STATS_SINCE_CHARGED; 15302 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 15303 final ControllerActivityCounter counter = getModemControllerActivity(); 15304 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 15305 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 15306 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 15307 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 15308 final long monitoredRailChargeConsumedMaMs = 15309 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 15310 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 15311 for (int i = 0; i < timeInRatMs.length; i++) { 15312 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTimeUs, which) / 1000; 15313 } 15314 long[] timeInRxSignalStrengthLevelMs = 15315 new long[CELL_SIGNAL_STRENGTH_LEVEL_COUNT]; 15316 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { 15317 timeInRxSignalStrengthLevelMs[i] = 15318 getPhoneSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 15319 } 15320 long[] txTimeMs = new long[Math.min(MODEM_TX_POWER_LEVEL_COUNT, 15321 counter.getTxTimeCounters().length)]; 15322 long totalTxTimeMs = 0; 15323 for (int i = 0; i < txTimeMs.length; i++) { 15324 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which); 15325 totalTxTimeMs += txTimeMs[i]; 15326 } 15327 15328 return new CellularBatteryStats(computeBatteryRealtime(rawRealTimeUs, which) / 1000, 15329 getMobileRadioActiveTime(rawRealTimeUs, which) / 1000, 15330 getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which), 15331 getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which), 15332 getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which), 15333 getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which), 15334 sleepTimeMs, idleTimeMs, rxTimeMs, energyConsumedMaMs, timeInRatMs, 15335 timeInRxSignalStrengthLevelMs, txTimeMs, 15336 monitoredRailChargeConsumedMaMs); 15337 } 15338 15339 /*@hide */ 15340 public WifiBatteryStats getWifiBatteryStats() { 15341 final int which = STATS_SINCE_CHARGED; 15342 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 15343 final ControllerActivityCounter counter = getWifiControllerActivity(); 15344 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 15345 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); 15346 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 15347 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); 15348 final long totalControllerActivityTimeMs 15349 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000; 15350 final long sleepTimeMs 15351 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs); 15352 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 15353 final long monitoredRailChargeConsumedMaMs = 15354 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 15355 long numAppScanRequest = 0; 15356 for (int i = 0; i < mUidStats.size(); i++) { 15357 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); 15358 } 15359 long[] timeInStateMs = new long[NUM_WIFI_STATES]; 15360 for (int i=0; i<NUM_WIFI_STATES; i++) { 15361 timeInStateMs[i] = getWifiStateTime(i, rawRealTimeUs, which) / 1000; 15362 } 15363 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; 15364 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15365 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTimeUs, which) / 1000; 15366 } 15367 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 15368 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15369 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 15370 } 15371 return new WifiBatteryStats( 15372 computeBatteryRealtime(rawRealTimeUs, which) / 1000, 15373 getWifiActiveTime(rawRealTimeUs, which) / 1000, 15374 getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which), 15375 getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which), 15376 getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which), 15377 getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which), 15378 sleepTimeMs, scanTimeMs, idleTimeMs, rxTimeMs, txTimeMs, energyConsumedMaMs, 15379 numAppScanRequest, timeInStateMs, timeSignalStrengthTimeMs, timeInSupplStateMs, 15380 monitoredRailChargeConsumedMaMs); 15381 } 15382 15383 /*@hide */ 15384 public GpsBatteryStats getGpsBatteryStats() { 15385 GpsBatteryStats s = new GpsBatteryStats(); 15386 final int which = STATS_SINCE_CHARGED; 15387 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 15388 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTimeUs, which) / 1000); 15389 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); 15390 long[] time = new long[mGpsSignalQualityTimer.length]; 15391 for (int i=0; i<time.length; i++) { 15392 time[i] = getGpsSignalQualityTime(i, rawRealTimeUs, which) / 1000; 15393 } 15394 s.setTimeInGpsSignalQualityLevel(time); 15395 return s; 15396 } 15397 15398 @Override 15399 public LevelStepTracker getChargeLevelStepTracker() { 15400 return mChargeStepTracker; 15401 } 15402 15403 @Override 15404 public LevelStepTracker getDailyChargeLevelStepTracker() { 15405 return mDailyChargeStepTracker; 15406 } 15407 15408 @Override 15409 public ArrayList<PackageChange> getDailyPackageChanges() { 15410 return mDailyPackageChanges; 15411 } 15412 15413 /** 15414 * @return battery uptime in microseconds 15415 */ 15416 protected long getBatteryUptimeLocked(long uptimeMs) { 15417 return mOnBatteryTimeBase.getUptime(uptimeMs * 1000); 15418 } 15419 15420 @Override 15421 public long getBatteryUptime(long curTimeUs) { 15422 return mOnBatteryTimeBase.getUptime(curTimeUs); 15423 } 15424 15425 @Override 15426 public long getBatteryRealtime(long curTimeUs) { 15427 return mOnBatteryTimeBase.getRealtime(curTimeUs); 15428 } 15429 15430 @Override 15431 public int getDischargeStartLevel() { 15432 synchronized(this) { 15433 return getDischargeStartLevelLocked(); 15434 } 15435 } 15436 15437 public int getDischargeStartLevelLocked() { 15438 return mDischargeUnplugLevel; 15439 } 15440 15441 @Override 15442 public int getDischargeCurrentLevel() { 15443 synchronized(this) { 15444 return getDischargeCurrentLevelLocked(); 15445 } 15446 } 15447 15448 public int getDischargeCurrentLevelLocked() { 15449 return mDischargeCurrentLevel; 15450 } 15451 15452 @Override 15453 public int getLowDischargeAmountSinceCharge() { 15454 synchronized(this) { 15455 int val = mLowDischargeAmountSinceCharge; 15456 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 15457 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 15458 } 15459 return val; 15460 } 15461 } 15462 15463 @Override 15464 public int getHighDischargeAmountSinceCharge() { 15465 synchronized(this) { 15466 int val = mHighDischargeAmountSinceCharge; 15467 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 15468 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 15469 } 15470 return val; 15471 } 15472 } 15473 15474 @Override 15475 public int getDischargeAmount(int which) { 15476 int dischargeAmount = which == STATS_SINCE_CHARGED 15477 ? getHighDischargeAmountSinceCharge() 15478 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 15479 if (dischargeAmount < 0) { 15480 dischargeAmount = 0; 15481 } 15482 return dischargeAmount; 15483 } 15484 15485 @Override 15486 public int getDischargeAmountScreenOn() { 15487 synchronized(this) { 15488 int val = mDischargeAmountScreenOn; 15489 if (mOnBattery && Display.isOnState(mScreenState) 15490 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 15491 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 15492 } 15493 return val; 15494 } 15495 } 15496 15497 @Override 15498 public int getDischargeAmountScreenOnSinceCharge() { 15499 synchronized(this) { 15500 int val = mDischargeAmountScreenOnSinceCharge; 15501 if (mOnBattery && Display.isOnState(mScreenState) 15502 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 15503 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 15504 } 15505 return val; 15506 } 15507 } 15508 15509 @Override 15510 public int getDischargeAmountScreenOff() { 15511 synchronized(this) { 15512 int val = mDischargeAmountScreenOff; 15513 if (mOnBattery && Display.isOffState(mScreenState) 15514 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 15515 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 15516 } 15517 // For backward compatibility, doze discharge is counted into screen off. 15518 return val + getDischargeAmountScreenDoze(); 15519 } 15520 } 15521 15522 @Override 15523 public int getDischargeAmountScreenOffSinceCharge() { 15524 synchronized(this) { 15525 int val = mDischargeAmountScreenOffSinceCharge; 15526 if (mOnBattery && Display.isOffState(mScreenState) 15527 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 15528 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 15529 } 15530 // For backward compatibility, doze discharge is counted into screen off. 15531 return val + getDischargeAmountScreenDozeSinceCharge(); 15532 } 15533 } 15534 15535 @Override 15536 public int getDischargeAmountScreenDoze() { 15537 synchronized(this) { 15538 int val = mDischargeAmountScreenDoze; 15539 if (mOnBattery && Display.isDozeState(mScreenState) 15540 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 15541 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 15542 } 15543 return val; 15544 } 15545 } 15546 15547 @Override 15548 public int getDischargeAmountScreenDozeSinceCharge() { 15549 synchronized(this) { 15550 int val = mDischargeAmountScreenDozeSinceCharge; 15551 if (mOnBattery && Display.isDozeState(mScreenState) 15552 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 15553 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 15554 } 15555 return val; 15556 } 15557 } 15558 15559 15560 /** 15561 * Estimates the time spent by the system server handling incoming binder requests. 15562 */ 15563 @Override 15564 public long[] getSystemServiceTimeAtCpuSpeeds() { 15565 if (mBinderThreadCpuTimesUs == null) { 15566 return null; 15567 } 15568 15569 return mBinderThreadCpuTimesUs.getCountsLocked(BatteryStats.STATS_SINCE_CHARGED); 15570 } 15571 15572 /** 15573 * Retrieve the statistics object for a particular uid, creating if needed. 15574 */ 15575 public Uid getUidStatsLocked(int uid) { 15576 return getUidStatsLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 15577 } 15578 15579 public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 15580 Uid u = mUidStats.get(uid); 15581 if (u == null) { 15582 if (Process.isSdkSandboxUid(uid)) { 15583 Log.wtf(TAG, "Tracking an SDK Sandbox UID"); 15584 } 15585 u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 15586 mUidStats.put(uid, u); 15587 } 15588 return u; 15589 } 15590 15591 /** 15592 * Retrieve the statistics object for a particular uid. Returns null if the object is not 15593 * available. 15594 */ 15595 public Uid getAvailableUidStatsLocked(int uid) { 15596 Uid u = mUidStats.get(uid); 15597 return u; 15598 } 15599 15600 @GuardedBy("this") 15601 public void onCleanupUserLocked(int userId, long elapsedRealtimeMs) { 15602 final int firstUidForUser = UserHandle.getUid(userId, 0); 15603 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 15604 mPendingRemovedUids.add( 15605 new UidToRemove(firstUidForUser, lastUidForUser, elapsedRealtimeMs)); 15606 } 15607 15608 @GuardedBy("this") 15609 public void onUserRemovedLocked(int userId) { 15610 if (mExternalSync != null) { 15611 // Clear out the removed user's UIDs after a short delay. The delay is needed 15612 // because at the point that this method is called, some activities are still 15613 // being wrapped up by those UIDs 15614 mExternalSync.scheduleCleanupDueToRemovedUser(userId); 15615 } 15616 } 15617 15618 /** 15619 * Removes battery stats for UIDs corresponding to a removed user. 15620 */ 15621 @GuardedBy("this") 15622 public void clearRemovedUserUidsLocked(int userId) { 15623 final int firstUidForUser = UserHandle.getUid(userId, 0); 15624 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 15625 mUidStats.put(firstUidForUser, null); 15626 mUidStats.put(lastUidForUser, null); 15627 final int firstIndex = mUidStats.indexOfKey(firstUidForUser); 15628 final int lastIndex = mUidStats.indexOfKey(lastUidForUser); 15629 for (int i = firstIndex; i <= lastIndex; i++) { 15630 final Uid uid = mUidStats.valueAt(i); 15631 if (uid != null) { 15632 uid.detachFromTimeBase(); 15633 } 15634 } 15635 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1); 15636 removeCpuStatsForUidRangeLocked(firstUidForUser, lastUidForUser); 15637 } 15638 15639 /** 15640 * @see #removeUidStatsLocked(int) 15641 */ 15642 @GuardedBy("this") 15643 public void removeUidStatsLocked(int uid, long elapsedRealtimeMs) { 15644 final Uid u = mUidStats.get(uid); 15645 if (u != null) { 15646 u.detachFromTimeBase(); 15647 } 15648 mUidStats.remove(uid); 15649 mPendingRemovedUids.add(new UidToRemove(uid, elapsedRealtimeMs)); 15650 } 15651 15652 /** 15653 * Removes the data for the deleted UIDs from the underlying kernel eBPF tables. 15654 */ 15655 @GuardedBy("this") 15656 private void removeCpuStatsForUidRangeLocked(int startUid, int endUid) { 15657 if (startUid == endUid) { 15658 mCpuUidUserSysTimeReader.removeUid(startUid); 15659 mCpuUidFreqTimeReader.removeUid(startUid); 15660 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 15661 mCpuUidActiveTimeReader.removeUid(startUid); 15662 mCpuUidClusterTimeReader.removeUid(startUid); 15663 } 15664 if (mKernelSingleUidTimeReader != null) { 15665 mKernelSingleUidTimeReader.removeUid(startUid); 15666 } 15667 mNumUidsRemoved++; 15668 } else if (startUid < endUid) { 15669 mCpuUidFreqTimeReader.removeUidsInRange(startUid, endUid); 15670 mCpuUidUserSysTimeReader.removeUidsInRange(startUid, endUid); 15671 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 15672 mCpuUidActiveTimeReader.removeUidsInRange(startUid, endUid); 15673 mCpuUidClusterTimeReader.removeUidsInRange(startUid, endUid); 15674 } 15675 if (mKernelSingleUidTimeReader != null) { 15676 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid); 15677 } 15678 mPowerStatsUidResolver.releaseUidsInRange(startUid, endUid); 15679 // Treat as one. We don't know how many uids there are in between. 15680 mNumUidsRemoved++; 15681 } else { 15682 Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid); 15683 } 15684 } 15685 15686 /** 15687 * Retrieve the statistics object for a particular process, creating 15688 * if needed. 15689 */ 15690 public Uid.Proc getProcessStatsLocked(int uid, String name, 15691 long elapsedRealtimeMs, long uptimeMs) { 15692 uid = mapUid(uid); 15693 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15694 return u.getProcessStatsLocked(name); 15695 } 15696 15697 /** 15698 * Retrieve the statistics object for a particular process, creating 15699 * if needed. 15700 */ 15701 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 15702 return getPackageStatsLocked(uid, pkg, mClock.elapsedRealtime(), mClock.uptimeMillis()); 15703 } 15704 15705 /** 15706 * @see getPackageStatsLocked(int, String) 15707 */ 15708 public Uid.Pkg getPackageStatsLocked(int uid, String pkg, 15709 long elapsedRealtimeMs, long uptimeMs) { 15710 uid = mapUid(uid); 15711 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15712 return u.getPackageStatsLocked(pkg); 15713 } 15714 15715 /** 15716 * Retrieve the statistics object for a particular service, creating 15717 * if needed. 15718 */ 15719 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name, 15720 long elapsedRealtimeMs, long uptimeMs) { 15721 uid = mapUid(uid); 15722 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15723 return u.getServiceStatsLocked(pkg, name); 15724 } 15725 15726 @GuardedBy("this") 15727 public void shutdownLocked() { 15728 mHistory.recordShutdownEvent(mClock.elapsedRealtime(), mClock.uptimeMillis(), 15729 mClock.currentTimeMillis()); 15730 writeSyncLocked(); 15731 mShuttingDown = true; 15732 } 15733 15734 @Override 15735 public boolean isProcessStateDataAvailable() { 15736 synchronized (this) { 15737 return trackPerProcStateCpuTimes(); 15738 } 15739 } 15740 15741 @GuardedBy("this") 15742 private boolean trackPerProcStateCpuTimes() { 15743 return mCpuUidFreqTimeReader.isFastCpuTimesReader(); 15744 } 15745 15746 /** 15747 * Enables or disables the PowerStatsCollector mode. 15748 */ 15749 public void setPowerStatsCollectorEnabled(@BatteryConsumer.PowerComponent int powerComponent, 15750 boolean enabled) { 15751 synchronized (this) { 15752 mPowerStatsCollectorEnabled.put(powerComponent, enabled); 15753 } 15754 } 15755 15756 @GuardedBy("this") 15757 public void systemServicesReady(Context context) { 15758 mConstants.startObserving(context.getContentResolver()); 15759 registerUsbStateReceiver(context); 15760 15761 synchronized (this) { 15762 mAlarmManager = context.getSystemService(AlarmManager.class); 15763 if (mBatteryPluggedIn) { 15764 // Already plugged in. Schedule the long plug in alarm. 15765 scheduleNextResetWhilePluggedInCheck(); 15766 } 15767 } 15768 } 15769 15770 /** 15771 * Initialize the EnergyConsumer stats data structures. 15772 * 15773 * @param supportedStandardBuckets boolean array indicating which {@link StandardPowerBucket}s 15774 * are currently supported. If null, none are supported 15775 * (regardless of customBucketNames). 15776 * @param customBucketNames names of custom (OTHER) EnergyConsumers on this device 15777 */ 15778 @GuardedBy("this") 15779 public void initEnergyConsumerStatsLocked(@Nullable boolean[] supportedStandardBuckets, 15780 String[] customBucketNames) { 15781 final int numDisplays = mPerDisplayBatteryStats.length; 15782 for (int i = 0; i < numDisplays; i++) { 15783 final int screenState = mPerDisplayBatteryStats[i].screenState; 15784 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 15785 } 15786 15787 if (supportedStandardBuckets != null) { 15788 final EnergyConsumerStats.Config config = new EnergyConsumerStats.Config( 15789 supportedStandardBuckets, customBucketNames, 15790 SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS, 15791 getBatteryConsumerProcessStateNames()); 15792 15793 if (mEnergyConsumerStatsConfig != null 15794 && !mEnergyConsumerStatsConfig.isCompatible(config)) { 15795 // Supported power buckets changed since last boot. 15796 // Existing data is no longer reliable. 15797 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 15798 RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE); 15799 } 15800 15801 mEnergyConsumerStatsConfig = config; 15802 mGlobalEnergyConsumerStats = new EnergyConsumerStats(config); 15803 15804 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_BLUETOOTH]) { 15805 mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile); 15806 } 15807 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO]) { 15808 mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile); 15809 } 15810 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_WIFI]) { 15811 mWifiPowerCalculator = new WifiPowerCalculator(mPowerProfile); 15812 } 15813 } else { 15814 if (mEnergyConsumerStatsConfig != null) { 15815 // EnergyConsumer no longer supported, wipe out the existing data. 15816 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 15817 RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE); 15818 } 15819 mEnergyConsumerStatsConfig = null; 15820 mGlobalEnergyConsumerStats = null; 15821 } 15822 } 15823 15824 @GuardedBy("this") 15825 private boolean isMobileRadioEnergyConsumerSupportedLocked() { 15826 if (mGlobalEnergyConsumerStats == null) return false; 15827 return mGlobalEnergyConsumerStats.isStandardBucketSupported( 15828 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 15829 } 15830 15831 @NonNull 15832 private static String[] getBatteryConsumerProcessStateNames() { 15833 String[] procStateNames = new String[BatteryConsumer.PROCESS_STATE_COUNT]; 15834 for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { 15835 procStateNames[procState] = BatteryConsumer.processStateToString(procState); 15836 } 15837 return procStateNames; 15838 } 15839 15840 /** Get the last known Battery voltage (in millivolts), returns -1 if unknown */ 15841 @GuardedBy("this") 15842 public int getBatteryVoltageMvLocked() { 15843 return mBatteryVoltageMv; 15844 } 15845 15846 @VisibleForTesting 15847 public final class Constants extends ContentObserver { 15848 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME 15849 = "track_cpu_active_cluster_time"; 15850 public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME 15851 = "kernel_uid_readers_throttle_time"; 15852 public static final String KEY_UID_REMOVE_DELAY_MS 15853 = "uid_remove_delay_ms"; 15854 public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 15855 = "external_stats_collection_rate_limit_ms"; 15856 public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS 15857 = "battery_level_collection_delay_ms"; 15858 public static final String KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 15859 "procstate_change_collection_delay_ms"; 15860 public static final String KEY_MAX_HISTORY_FILES = "max_history_files"; 15861 public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb"; 15862 public static final String KEY_BATTERY_CHARGED_DELAY_MS = 15863 "battery_charged_delay_ms"; 15864 public static final String KEY_BATTERY_CHARGING_ENFORCE_LEVEL = 15865 "battery_charging_enforce_level"; 15866 public static final String KEY_PER_UID_MODEM_POWER_MODEL = 15867 "per_uid_modem_power_model"; 15868 public static final String KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION = 15869 "phone_on_external_stats_collection"; 15870 public static final String KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 15871 "reset_while_plugged_in_minimum_duration_hours"; 15872 15873 public static final String PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME = 15874 "mobile_radio_active_time"; 15875 public static final String PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME = 15876 "modem_activity_info_rx_tx"; 15877 15878 /** Convert {@link PerUidModemPowerModel} to string */ 15879 public String getPerUidModemModelName(@PerUidModemPowerModel int model) { 15880 switch(model) { 15881 case PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME: 15882 return PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME; 15883 case PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX: 15884 return PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME; 15885 default: 15886 Slog.w(TAG, "Unexpected per uid modem model (" + model + ")"); 15887 return "unknown_" + model; 15888 } 15889 } 15890 15891 /** Convert string to {@link PerUidModemPowerModel} */ 15892 @PerUidModemPowerModel 15893 public int getPerUidModemModel(String name) { 15894 switch(name) { 15895 case PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME: 15896 return PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME; 15897 case PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME: 15898 return PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX; 15899 default: 15900 Slog.w(TAG, "Unexpected per uid modem model name (" + name + ")"); 15901 return DEFAULT_PER_UID_MODEM_MODEL; 15902 } 15903 } 15904 15905 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; 15906 private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000; 15907 private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; 15908 private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; 15909 private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; 15910 private static final long DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 60_000; 15911 private static final int DEFAULT_MAX_HISTORY_FILES = 32; 15912 private static final int DEFAULT_MAX_HISTORY_BUFFER_KB = 128; /*Kilo Bytes*/ 15913 private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64; 15914 private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/ 15915 private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */ 15916 private static final int DEFAULT_BATTERY_CHARGING_ENFORCE_LEVEL = 90; 15917 @PerUidModemPowerModel 15918 private static final int DEFAULT_PER_UID_MODEM_MODEL = 15919 PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX; 15920 private static final boolean DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION = true; 15921 // Little less than 2 days 15922 private static final int DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 47; 15923 15924 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; 15925 /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an 15926 * update when startObserving. */ 15927 public long KERNEL_UID_READERS_THROTTLE_TIME; 15928 public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; 15929 public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 15930 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 15931 public long BATTERY_LEVEL_COLLECTION_DELAY_MS 15932 = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; 15933 public long PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 15934 DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS; 15935 public int MAX_HISTORY_FILES; 15936 public int MAX_HISTORY_BUFFER; /*Bytes*/ 15937 public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS; 15938 public int BATTERY_CHARGING_ENFORCE_LEVEL = DEFAULT_BATTERY_CHARGING_ENFORCE_LEVEL; 15939 public int PER_UID_MODEM_MODEL = DEFAULT_PER_UID_MODEM_MODEL; 15940 public boolean PHONE_ON_EXTERNAL_STATS_COLLECTION = 15941 DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION; 15942 public int RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 15943 DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS; 15944 15945 private ContentResolver mResolver; 15946 private final KeyValueListParser mParser = new KeyValueListParser(','); 15947 15948 public Constants(Handler handler) { 15949 super(handler); 15950 if (isLowRamDevice()) { 15951 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE; 15952 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB * 1024; 15953 } else { 15954 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES; 15955 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_KB * 1024; 15956 } 15957 } 15958 15959 public void startObserving(ContentResolver resolver) { 15960 mResolver = resolver; 15961 mResolver.registerContentObserver( 15962 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS), 15963 false /* notifyForDescendants */, this); 15964 mResolver.registerContentObserver( 15965 Settings.Global.getUriFor(Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY), 15966 false /* notifyForDescendants */, this); 15967 mResolver.registerContentObserver(Settings.Global.getUriFor( 15968 Settings.Global.BATTERY_CHARGING_STATE_ENFORCE_LEVEL), 15969 false /* notifyForDescendants */, this); 15970 updateConstants(); 15971 } 15972 15973 @Override 15974 public void onChange(boolean selfChange, Uri uri) { 15975 if (uri.equals( 15976 Settings.Global.getUriFor( 15977 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY))) { 15978 synchronized (BatteryStatsImpl.this) { 15979 updateBatteryChargedDelayMsLocked(); 15980 } 15981 return; 15982 } else if (uri.equals(Settings.Global.getUriFor( 15983 Settings.Global.BATTERY_CHARGING_STATE_ENFORCE_LEVEL))) { 15984 synchronized (BatteryStatsImpl.this) { 15985 updateBatteryChargingEnforceLevelLocked(); 15986 } 15987 return; 15988 } 15989 updateConstants(); 15990 } 15991 15992 private void updateConstants() { 15993 synchronized (BatteryStatsImpl.this) { 15994 try { 15995 mParser.setString(Settings.Global.getString(mResolver, 15996 Settings.Global.BATTERY_STATS_CONSTANTS)); 15997 } catch (IllegalArgumentException e) { 15998 // Failed to parse the settings string, log this and move on 15999 // with defaults. 16000 Slog.e(TAG, "Bad batterystats settings", e); 16001 } 16002 16003 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( 16004 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); 16005 updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME, 16006 mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME, 16007 DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME)); 16008 updateUidRemoveDelay( 16009 mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS)); 16010 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( 16011 KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, 16012 DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 16013 BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( 16014 KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, 16015 DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); 16016 PROC_STATE_CHANGE_COLLECTION_DELAY_MS = mParser.getLong( 16017 KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS, 16018 DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 16019 MAX_HISTORY_FILES = mParser.getInt(KEY_MAX_HISTORY_FILES, 16020 isLowRamDevice() ? DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE 16021 : DEFAULT_MAX_HISTORY_FILES); 16022 MAX_HISTORY_BUFFER = mParser.getInt(KEY_MAX_HISTORY_BUFFER_KB, 16023 isLowRamDevice() ? DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB 16024 : DEFAULT_MAX_HISTORY_BUFFER_KB) 16025 * 1024; 16026 final String perUidModemModel = mParser.getString(KEY_PER_UID_MODEM_POWER_MODEL, 16027 ""); 16028 PER_UID_MODEM_MODEL = getPerUidModemModel(perUidModemModel); 16029 16030 PHONE_ON_EXTERNAL_STATS_COLLECTION = mParser.getBoolean( 16031 KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION, 16032 DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION); 16033 16034 RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = mParser.getInt( 16035 KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS, 16036 DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); 16037 16038 updateBatteryChargedDelayMsLocked(); 16039 updateBatteryChargingEnforceLevelLocked(); 16040 16041 onChange(); 16042 } 16043 } 16044 16045 /** 16046 * Propagates changes in constant values. 16047 */ 16048 @VisibleForTesting 16049 public void onChange() { 16050 mHistory.setMaxHistoryFiles(MAX_HISTORY_FILES); 16051 mHistory.setMaxHistoryBufferSize(MAX_HISTORY_BUFFER); 16052 } 16053 16054 private void updateBatteryChargedDelayMsLocked() { 16055 // a negative value indicates that we should ignore this override 16056 final int delay = Settings.Global.getInt(mResolver, 16057 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 16058 -1); 16059 16060 BATTERY_CHARGED_DELAY_MS = delay >= 0 ? delay : mParser.getInt( 16061 KEY_BATTERY_CHARGED_DELAY_MS, 16062 DEFAULT_BATTERY_CHARGED_DELAY_MS); 16063 16064 if (mHandler.hasCallbacks(mDeferSetCharging)) { 16065 mHandler.removeCallbacks(mDeferSetCharging); 16066 mHandler.postDelayed(mDeferSetCharging, BATTERY_CHARGED_DELAY_MS); 16067 } 16068 } 16069 16070 private void updateBatteryChargingEnforceLevelLocked() { 16071 int lastChargingEnforceLevel = BATTERY_CHARGING_ENFORCE_LEVEL; 16072 final int level = Settings.Global.getInt(mResolver, 16073 Settings.Global.BATTERY_CHARGING_STATE_ENFORCE_LEVEL, 16074 -1); 16075 16076 BATTERY_CHARGING_ENFORCE_LEVEL = level >= 0 ? level : mParser.getInt( 16077 KEY_BATTERY_CHARGING_ENFORCE_LEVEL, DEFAULT_BATTERY_CHARGING_ENFORCE_LEVEL); 16078 16079 if (BATTERY_CHARGING_ENFORCE_LEVEL <= mLastChargeStepLevel 16080 && mLastChargeStepLevel < lastChargingEnforceLevel) { 16081 setChargingLocked(true); 16082 } 16083 } 16084 16085 private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) { 16086 KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs; 16087 if (oldTimeMs != newTimeMs) { 16088 mCpuUidUserSysTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16089 mCpuUidFreqTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16090 mCpuUidActiveTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16091 mCpuUidClusterTimeReader 16092 .setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16093 } 16094 } 16095 16096 @GuardedBy("BatteryStatsImpl.this") 16097 private void updateUidRemoveDelay(long newTimeMs) { 16098 UID_REMOVE_DELAY_MS = newTimeMs; 16099 clearPendingRemovedUidsLocked(); 16100 } 16101 16102 public void dumpLocked(PrintWriter pw) { 16103 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); 16104 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); 16105 pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("="); 16106 pw.println(KERNEL_UID_READERS_THROTTLE_TIME); 16107 pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); 16108 pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 16109 pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); 16110 pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); 16111 pw.print(KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS); pw.print("="); 16112 pw.println(PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 16113 pw.print(KEY_MAX_HISTORY_FILES); pw.print("="); 16114 pw.println(MAX_HISTORY_FILES); 16115 pw.print(KEY_MAX_HISTORY_BUFFER_KB); pw.print("="); 16116 pw.println(MAX_HISTORY_BUFFER/1024); 16117 pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("="); 16118 pw.println(BATTERY_CHARGED_DELAY_MS); 16119 pw.print(KEY_BATTERY_CHARGING_ENFORCE_LEVEL); pw.print("="); 16120 pw.println(BATTERY_CHARGING_ENFORCE_LEVEL); 16121 pw.print(KEY_PER_UID_MODEM_POWER_MODEL); pw.print("="); 16122 pw.println(getPerUidModemModelName(PER_UID_MODEM_MODEL)); 16123 pw.print(KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION); pw.print("="); 16124 pw.println(PHONE_ON_EXTERNAL_STATS_COLLECTION); 16125 pw.print(KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); pw.print("="); 16126 pw.println(RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); 16127 } 16128 } 16129 16130 public long getExternalStatsCollectionRateLimitMs() { 16131 synchronized (this) { 16132 return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 16133 } 16134 } 16135 16136 @GuardedBy("this") 16137 public void dumpConstantsLocked(PrintWriter pw) { 16138 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16139 iPw.println("BatteryStats constants:"); 16140 iPw.increaseIndent(); 16141 mConstants.dumpLocked(iPw); 16142 iPw.decreaseIndent(); 16143 } 16144 16145 @GuardedBy("this") 16146 public void dumpCpuStatsLocked(PrintWriter pw) { 16147 int size = mUidStats.size(); 16148 pw.println("Per UID CPU user & system time in ms:"); 16149 for (int i = 0; i < size; i++) { 16150 int u = mUidStats.keyAt(i); 16151 Uid uid = mUidStats.get(u); 16152 pw.print(" "); pw.print(u); pw.print(": "); 16153 pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" "); 16154 pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000); 16155 } 16156 16157 pw.println("Per UID CPU active time in ms:"); 16158 for (int i = 0; i < size; i++) { 16159 int u = mUidStats.keyAt(i); 16160 Uid uid = mUidStats.get(u); 16161 if (uid.getCpuActiveTime() > 0) { 16162 pw.print(" "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime()); 16163 } 16164 } 16165 pw.println("Per UID CPU cluster time in ms:"); 16166 for (int i = 0; i < size; i++) { 16167 int u = mUidStats.keyAt(i); 16168 long[] times = mUidStats.get(u).getCpuClusterTimes(); 16169 if (times != null) { 16170 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 16171 } 16172 } 16173 pw.println("Per UID CPU frequency time in ms:"); 16174 for (int i = 0; i < size; i++) { 16175 int u = mUidStats.keyAt(i); 16176 long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED); 16177 if (times != null) { 16178 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 16179 } 16180 } 16181 16182 if (!Flags.disableSystemServicePowerAttr()) { 16183 updateSystemServiceCallStats(); 16184 if (mBinderThreadCpuTimesUs != null) { 16185 pw.println("Per UID System server binder time in ms:"); 16186 long[] systemServiceTimeAtCpuSpeeds = getSystemServiceTimeAtCpuSpeeds(); 16187 for (int i = 0; i < size; i++) { 16188 int u = mUidStats.keyAt(i); 16189 Uid uid = mUidStats.get(u); 16190 double proportionalSystemServiceUsage = uid.getProportionalSystemServiceUsage(); 16191 long timeUs = 0; 16192 for (int j = systemServiceTimeAtCpuSpeeds.length - 1; j >= 0; j--) { 16193 timeUs += systemServiceTimeAtCpuSpeeds[j] * proportionalSystemServiceUsage; 16194 } 16195 16196 pw.print(" "); 16197 pw.print(u); 16198 pw.print(": "); 16199 pw.println(timeUs / 1000); 16200 } 16201 } 16202 } 16203 } 16204 16205 /** 16206 * Dump EnergyConsumer stats 16207 */ 16208 @GuardedBy("this") 16209 public void dumpEnergyConsumerStatsLocked(PrintWriter pw) { 16210 pw.printf("On-battery energy consumer stats (microcoulombs) \n"); 16211 if (mGlobalEnergyConsumerStats == null) { 16212 pw.printf(" Not supported on this device.\n"); 16213 return; 16214 } 16215 16216 dumpEnergyConsumerStatsLocked(pw, "global usage", mGlobalEnergyConsumerStats); 16217 16218 int size = mUidStats.size(); 16219 for (int i = 0; i < size; i++) { 16220 final int u = mUidStats.keyAt(i); 16221 final Uid uid = mUidStats.get(u); 16222 final String name = "uid " + uid.mUid; 16223 dumpEnergyConsumerStatsLocked(pw, name, uid.mUidEnergyConsumerStats); 16224 } 16225 } 16226 16227 /** Dump EnergyConsumer stats for the given uid */ 16228 @GuardedBy("this") 16229 private void dumpEnergyConsumerStatsLocked(PrintWriter pw, String name, 16230 EnergyConsumerStats stats) { 16231 if (stats == null) return; 16232 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16233 iPw.increaseIndent(); 16234 iPw.printf("%s:\n", name); 16235 iPw.increaseIndent(); 16236 stats.dump(iPw); 16237 iPw.decreaseIndent(); 16238 } 16239 16240 /** 16241 * Dump Power Profile 16242 */ 16243 @GuardedBy("this") 16244 public void dumpPowerProfileLocked(PrintWriter pw) { 16245 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16246 iPw.printf("Power Profile: \n"); 16247 iPw.increaseIndent(); 16248 mPowerProfile.dump(iPw); 16249 iPw.decreaseIndent(); 16250 } 16251 16252 /** 16253 * Schedules an immediate (but asynchronous) collection of PowerStats samples. 16254 * Callers will need to wait for the collection to complete on the handler thread. 16255 */ 16256 public void schedulePowerStatsSampleCollection() { 16257 mCpuPowerStatsCollector.forceSchedule(); 16258 mMobileRadioPowerStatsCollector.forceSchedule(); 16259 mWifiPowerStatsCollector.forceSchedule(); 16260 mBluetoothPowerStatsCollector.forceSchedule(); 16261 } 16262 16263 /** 16264 * Schedules an immediate collection of PowerStats samples and awaits the result. 16265 */ 16266 public void collectPowerStatsSamples() { 16267 schedulePowerStatsSampleCollection(); 16268 ConditionVariable done = new ConditionVariable(); 16269 mHandler.post(done::open); 16270 done.block(); 16271 } 16272 16273 /** 16274 * Grabs one sample of PowerStats and prints it. 16275 */ 16276 public void dumpStatsSample(PrintWriter pw) { 16277 mCpuPowerStatsCollector.collectAndDump(pw); 16278 mMobileRadioPowerStatsCollector.collectAndDump(pw); 16279 mWifiPowerStatsCollector.collectAndDump(pw); 16280 mBluetoothPowerStatsCollector.collectAndDump(pw); 16281 } 16282 16283 private final Runnable mWriteAsyncRunnable = () -> { 16284 synchronized (BatteryStatsImpl.this) { 16285 writeSyncLocked(); 16286 } 16287 }; 16288 16289 @GuardedBy("this") 16290 public void writeAsyncLocked() { 16291 BackgroundThread.getHandler().removeCallbacks(mWriteAsyncRunnable); 16292 BackgroundThread.getHandler().post(mWriteAsyncRunnable); 16293 } 16294 16295 @GuardedBy("this") 16296 public void writeSyncLocked() { 16297 BackgroundThread.getHandler().removeCallbacks(mWriteAsyncRunnable); 16298 writeStatsLocked(); 16299 writeHistoryLocked(); 16300 } 16301 16302 @GuardedBy("this") 16303 private void writeStatsLocked() { 16304 if (mStatsFile == null) { 16305 Slog.w(TAG, 16306 "writeStatsLocked: no file associated with this instance"); 16307 return; 16308 } 16309 16310 if (mShuttingDown) { 16311 return; 16312 } 16313 16314 final Parcel p = Parcel.obtain(); 16315 try { 16316 final long start = SystemClock.uptimeMillis(); 16317 writeSummaryToParcel(p, false/*history is in separate file*/); 16318 if (DEBUG) { 16319 Slog.d(TAG, "writeSummaryToParcel duration ms:" 16320 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 16321 } 16322 mLastWriteTimeMs = mClock.elapsedRealtime(); 16323 writeParcelToFileLocked(p, mStatsFile); 16324 } finally { 16325 p.recycle(); 16326 } 16327 } 16328 16329 private void writeHistoryLocked() { 16330 if (mShuttingDown) { 16331 return; 16332 } 16333 16334 mHistory.writeHistory(); 16335 } 16336 16337 private final ReentrantLock mWriteLock = new ReentrantLock(); 16338 private void writeParcelToFileLocked(Parcel p, AtomicFile file) { 16339 mWriteLock.lock(); 16340 FileOutputStream fos = null; 16341 try { 16342 final long startTimeMs = SystemClock.uptimeMillis(); 16343 fos = file.startWrite(); 16344 fos.write(p.marshall()); 16345 fos.flush(); 16346 file.finishWrite(fos); 16347 if (DEBUG) { 16348 Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath() 16349 + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs) 16350 + " bytes:" + p.dataSize()); 16351 } 16352 mFrameworkStatsLogger.writeCommitSysConfigFile( 16353 "batterystats", SystemClock.uptimeMillis() - startTimeMs); 16354 } catch (IOException e) { 16355 Slog.w(TAG, "Error writing battery statistics", e); 16356 file.failWrite(fos); 16357 } finally { 16358 mWriteLock.unlock(); 16359 } 16360 } 16361 16362 @GuardedBy("this") 16363 public void readLocked() { 16364 if (mDailyFile != null) { 16365 readDailyStatsLocked(); 16366 } 16367 16368 if (mStatsFile == null) { 16369 Slog.w(TAG, "readLocked: no file associated with this instance"); 16370 return; 16371 } 16372 16373 mUidStats.clear(); 16374 16375 Parcel stats = Parcel.obtain(); 16376 try { 16377 final long start = SystemClock.uptimeMillis(); 16378 if (mStatsFile.exists()) { 16379 byte[] raw = mStatsFile.readFully(); 16380 stats.unmarshall(raw, 0, raw.length); 16381 stats.setDataPosition(0); 16382 readSummaryFromParcel(stats); 16383 if (DEBUG) { 16384 Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath() 16385 + " bytes:" + raw.length + " took ms:" + (SystemClock.uptimeMillis() 16386 - start)); 16387 } 16388 } 16389 } catch (Exception e) { 16390 Slog.e(TAG, "Error reading battery statistics", e); 16391 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 16392 RESET_REASON_CORRUPT_FILE); 16393 } finally { 16394 stats.recycle(); 16395 } 16396 16397 if (!mHistory.readSummary()) { 16398 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 16399 RESET_REASON_CORRUPT_FILE); 16400 } 16401 16402 mEndPlatformVersion = Build.ID; 16403 16404 mMonotonicEndTime = MonotonicClock.UNDEFINED; 16405 mHistory.continueRecordingHistory(); 16406 16407 recordDailyStatsIfNeededLocked(false, mClock.currentTimeMillis()); 16408 } 16409 16410 @GuardedBy("this") 16411 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 16412 final int version = in.readInt(); 16413 16414 if (version != VERSION) { 16415 Slog.w("BatteryStats", "readFromParcel: version got " + version 16416 + ", expected " + VERSION + "; erasing old stats"); 16417 return; 16418 } 16419 16420 mHistory.readSummaryFromParcel(in); 16421 16422 mStartCount = in.readInt(); 16423 mUptimeUs = in.readLong(); 16424 mRealtimeUs = in.readLong(); 16425 mStartClockTimeMs = in.readLong(); 16426 mMonotonicStartTime = in.readLong(); 16427 mMonotonicEndTime = in.readLong(); 16428 mStartPlatformVersion = in.readString(); 16429 mEndPlatformVersion = in.readString(); 16430 mOnBatteryTimeBase.readSummaryFromParcel(in); 16431 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 16432 mDischargeUnplugLevel = in.readInt(); 16433 mDischargePlugLevel = in.readInt(); 16434 mDischargeCurrentLevel = in.readInt(); 16435 mBatteryLevel = in.readInt(); 16436 mEstimatedBatteryCapacityMah = in.readInt(); 16437 mLastLearnedBatteryCapacityUah = in.readInt(); 16438 mMinLearnedBatteryCapacityUah = in.readInt(); 16439 mMaxLearnedBatteryCapacityUah = in.readInt(); 16440 mLowDischargeAmountSinceCharge = in.readInt(); 16441 mHighDischargeAmountSinceCharge = in.readInt(); 16442 mDischargeAmountScreenOnSinceCharge = in.readInt(); 16443 mDischargeAmountScreenOffSinceCharge = in.readInt(); 16444 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 16445 mDischargeStepTracker.readFromParcel(in); 16446 mChargeStepTracker.readFromParcel(in); 16447 mDailyDischargeStepTracker.readFromParcel(in); 16448 mDailyChargeStepTracker.readFromParcel(in); 16449 mDischargeCounter.readSummaryFromParcelLocked(in); 16450 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 16451 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in); 16452 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in); 16453 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in); 16454 int NPKG = in.readInt(); 16455 if (NPKG > 0) { 16456 mDailyPackageChanges = new ArrayList<>(NPKG); 16457 while (NPKG > 0) { 16458 NPKG--; 16459 PackageChange pc = new PackageChange(); 16460 pc.mPackageName = in.readString(); 16461 pc.mUpdate = in.readInt() != 0; 16462 pc.mVersionCode = in.readLong(); 16463 mDailyPackageChanges.add(pc); 16464 } 16465 } else { 16466 mDailyPackageChanges = null; 16467 } 16468 mDailyStartTimeMs = in.readLong(); 16469 mNextMinDailyDeadlineMs = in.readLong(); 16470 mNextMaxDailyDeadlineMs = in.readLong(); 16471 mBatteryTimeToFullSeconds = in.readLong(); 16472 16473 final EnergyConsumerStats.Config config = EnergyConsumerStats.Config.createFromParcel(in); 16474 final EnergyConsumerStats energyConsumerStats = 16475 EnergyConsumerStats.createAndReadSummaryFromParcel(mEnergyConsumerStatsConfig, in); 16476 if (config != null && Arrays.equals(config.getStateNames(), 16477 getBatteryConsumerProcessStateNames())) { 16478 /** 16479 * WARNING: Supported buckets may have changed across boots. Bucket mismatch is handled 16480 * later when {@link #initEnergyConsumerStatsLocked} is called. 16481 */ 16482 mEnergyConsumerStatsConfig = config; 16483 mGlobalEnergyConsumerStats = energyConsumerStats; 16484 } 16485 16486 mStartCount++; 16487 16488 mScreenState = Display.STATE_UNKNOWN; 16489 mScreenOnTimer.readSummaryFromParcelLocked(in); 16490 mScreenDozeTimer.readSummaryFromParcelLocked(in); 16491 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16492 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 16493 } 16494 final int numDisplays = in.readInt(); 16495 for (int i = 0; i < numDisplays; i++) { 16496 mPerDisplayBatteryStats[i].readSummaryFromParcel(in); 16497 } 16498 mInteractive = false; 16499 mInteractiveTimer.readSummaryFromParcelLocked(in); 16500 mPhoneOn = false; 16501 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 16502 mLongestLightIdleTimeMs = in.readLong(); 16503 mLongestFullIdleTimeMs = in.readLong(); 16504 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 16505 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 16506 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 16507 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 16508 mPhoneOnTimer.readSummaryFromParcelLocked(in); 16509 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 16510 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 16511 } 16512 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 16513 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 16514 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 16515 } 16516 mNrNsaTimer.readSummaryFromParcelLocked(in); 16517 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16518 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 16519 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 16520 } 16521 16522 final int numRat = in.readInt(); 16523 for (int i = 0; i < numRat; i++) { 16524 if (in.readInt() == 0) continue; 16525 getRatBatteryStatsLocked(i).readSummaryFromParcel(in); 16526 } 16527 16528 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 16529 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 16530 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 16531 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 16532 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 16533 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 16534 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in); 16535 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 16536 mWifiOn = false; 16537 mWifiOnTimer.readSummaryFromParcelLocked(in); 16538 mGlobalWifiRunning = false; 16539 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 16540 for (int i=0; i<NUM_WIFI_STATES; i++) { 16541 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 16542 } 16543 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 16544 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 16545 } 16546 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16547 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 16548 } 16549 mWifiActiveTimer.readSummaryFromParcelLocked(in); 16550 mWifiActivity.readSummaryFromParcel(in); 16551 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 16552 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); 16553 } 16554 mBluetoothActivity.readSummaryFromParcel(in); 16555 mModemActivity.readSummaryFromParcel(in); 16556 mHasWifiReporting = in.readInt() != 0; 16557 mHasBluetoothReporting = in.readInt() != 0; 16558 mHasModemReporting = in.readInt() != 0; 16559 16560 mNumConnectivityChange = in.readInt(); 16561 mFlashlightOnNesting = 0; 16562 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 16563 mCameraOnNesting = 0; 16564 mCameraOnTimer.readSummaryFromParcelLocked(in); 16565 mBluetoothScanNesting = 0; 16566 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 16567 16568 int NRPMS = in.readInt(); 16569 if (NRPMS > 10000) { 16570 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 16571 } 16572 for (int irpm = 0; irpm < NRPMS; irpm++) { 16573 if (in.readInt() != 0) { 16574 String rpmName = in.readString(); 16575 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 16576 } 16577 } 16578 int NSORPMS = in.readInt(); 16579 if (NSORPMS > 10000) { 16580 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS); 16581 } 16582 for (int irpm = 0; irpm < NSORPMS; irpm++) { 16583 if (in.readInt() != 0) { 16584 String rpmName = in.readString(); 16585 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 16586 } 16587 } 16588 int NKW = in.readInt(); 16589 if (NKW > 10000) { 16590 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 16591 } 16592 for (int ikw = 0; ikw < NKW; ikw++) { 16593 if (in.readInt() != 0) { 16594 String kwltName = in.readString(); 16595 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 16596 } 16597 } 16598 16599 int NWR = in.readInt(); 16600 if (NWR > 10000) { 16601 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 16602 } 16603 for (int iwr = 0; iwr < NWR; iwr++) { 16604 if (in.readInt() != 0) { 16605 String reasonName = in.readString(); 16606 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 16607 } 16608 } 16609 16610 int NMS = in.readInt(); 16611 for (int ims = 0; ims < NMS; ims++) { 16612 if (in.readInt() != 0) { 16613 long kmstName = in.readLong(); 16614 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 16615 } 16616 } 16617 16618 final int NU = in.readInt(); 16619 if (NU > 10000) { 16620 throw new ParcelFormatException("File corrupt: too many uids " + NU); 16621 } 16622 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 16623 final long uptimeMs = mClock.uptimeMillis(); 16624 for (int iu = 0; iu < NU; iu++) { 16625 int uid = in.readInt(); 16626 Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 16627 mUidStats.put(uid, u); 16628 16629 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 16630 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 16631 16632 u.mWifiRunning = false; 16633 if (in.readInt() != 0) { 16634 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 16635 } 16636 u.mFullWifiLockOut = false; 16637 if (in.readInt() != 0) { 16638 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 16639 } 16640 u.mWifiScanStarted = false; 16641 if (in.readInt() != 0) { 16642 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 16643 } 16644 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 16645 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 16646 if (in.readInt() != 0) { 16647 u.makeWifiBatchedScanBin(i, null); 16648 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 16649 } 16650 } 16651 u.mWifiMulticastWakelockCount = 0; 16652 if (in.readInt() != 0) { 16653 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 16654 } 16655 if (in.readInt() != 0) { 16656 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16657 } 16658 if (in.readInt() != 0) { 16659 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16660 } 16661 if (in.readInt() != 0) { 16662 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16663 } 16664 if (in.readInt() != 0) { 16665 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16666 } 16667 if (in.readInt() != 0) { 16668 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 16669 } 16670 if (in.readInt() != 0) { 16671 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 16672 } 16673 if (in.readInt() != 0) { 16674 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 16675 } 16676 if (in.readInt() != 0) { 16677 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 16678 } 16679 if (in.readInt() != 0) { 16680 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 16681 } 16682 if (in.readInt() != 0) { 16683 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 16684 } 16685 if (in.readInt() != 0) { 16686 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 16687 } 16688 u.mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 16689 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 16690 if (in.readInt() != 0) { 16691 u.makeProcessState(i, null); 16692 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 16693 } 16694 } 16695 if (in.readInt() != 0) { 16696 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 16697 } 16698 16699 if (in.readInt() != 0) { 16700 if (u.mUserActivityCounters == null) { 16701 u.initUserActivityLocked(); 16702 } 16703 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 16704 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 16705 } 16706 } 16707 16708 if (in.readInt() != 0) { 16709 u.ensureNetworkActivityLocked(); 16710 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16711 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 16712 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 16713 } 16714 if (in.readBoolean()) { 16715 u.mMobileRadioActiveTime = TimeMultiStateCounter.readFromParcel(in, 16716 mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 16717 elapsedRealtimeMs); 16718 } 16719 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 16720 } 16721 16722 u.mUserCpuTime.readSummaryFromParcelLocked(in); 16723 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 16724 16725 if (in.readInt() != 0) { 16726 final int numClusters = in.readInt(); 16727 int[] policies = 16728 mCpuScalingPolicies != null ? mCpuScalingPolicies.getPolicies() : null; 16729 if (policies != null && policies.length != numClusters) { 16730 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 16731 } 16732 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 16733 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 16734 for (int cluster = 0; cluster < numClusters; cluster++) { 16735 if (in.readInt() != 0) { 16736 final int NSB = in.readInt(); 16737 if (policies != null 16738 && mCpuScalingPolicies.getFrequencies(policies[cluster]).length 16739 != NSB) { 16740 throw new ParcelFormatException("File corrupt: too many speed bins " + 16741 NSB); 16742 } 16743 16744 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 16745 for (int speed = 0; speed < NSB; speed++) { 16746 if (in.readInt() != 0) { 16747 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 16748 mOnBatteryTimeBase); 16749 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 16750 } 16751 } 16752 } else { 16753 u.mCpuClusterSpeedTimesUs[cluster] = null; 16754 } 16755 } 16756 } else { 16757 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 16758 u.mCpuClusterSpeedTimesUs = null; 16759 } 16760 16761 detachIfNotNull(u.mCpuFreqTimeMs); 16762 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 16763 in, mOnBatteryTimeBase); 16764 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 16765 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 16766 in, mOnBatteryScreenOffTimeBase); 16767 16768 int stateCount = in.readInt(); 16769 if (stateCount != 0) { 16770 u.mCpuActiveTimeMs = TimeMultiStateCounter.readFromParcel(in, 16771 mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 16772 mClock.elapsedRealtime()); 16773 } 16774 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 16775 16776 detachIfNotNull(u.mProcStateTimeMs); 16777 u.mProcStateTimeMs = null; 16778 16779 stateCount = in.readInt(); 16780 if (stateCount != 0) { 16781 detachIfNotNull(u.mProcStateTimeMs); 16782 u.mProcStateTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 16783 mOnBatteryTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 16784 mCpuScalingPolicies.getScalingStepCount(), mClock.elapsedRealtime()); 16785 } 16786 16787 detachIfNotNull(u.mProcStateScreenOffTimeMs); 16788 u.mProcStateScreenOffTimeMs = null; 16789 16790 stateCount = in.readInt(); 16791 if (stateCount != 0) { 16792 detachIfNotNull(u.mProcStateScreenOffTimeMs); 16793 u.mProcStateScreenOffTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 16794 mOnBatteryScreenOffTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 16795 mCpuScalingPolicies.getScalingStepCount(), mClock.elapsedRealtime()); 16796 } 16797 16798 if (in.readInt() != 0) { 16799 detachIfNotNull(u.mMobileRadioApWakeupCount); 16800 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 16801 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 16802 } else { 16803 detachIfNotNull(u.mMobileRadioApWakeupCount); 16804 u.mMobileRadioApWakeupCount = null; 16805 } 16806 16807 if (in.readInt() != 0) { 16808 detachIfNotNull(u.mWifiRadioApWakeupCount); 16809 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 16810 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 16811 } else { 16812 detachIfNotNull(u.mWifiRadioApWakeupCount); 16813 u.mWifiRadioApWakeupCount = null; 16814 } 16815 16816 u.mUidEnergyConsumerStats = EnergyConsumerStats.createAndReadSummaryFromParcel( 16817 mEnergyConsumerStatsConfig, in); 16818 16819 int NW = in.readInt(); 16820 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 16821 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 16822 } 16823 for (int iw = 0; iw < NW; iw++) { 16824 String wlName = in.readString(); 16825 u.readWakeSummaryFromParcelLocked(wlName, in); 16826 } 16827 16828 int NS = in.readInt(); 16829 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 16830 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 16831 } 16832 for (int is = 0; is < NS; is++) { 16833 String name = in.readString(); 16834 u.readSyncSummaryFromParcelLocked(name, in); 16835 } 16836 16837 int NJ = in.readInt(); 16838 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 16839 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 16840 } 16841 for (int ij = 0; ij < NJ; ij++) { 16842 String name = in.readString(); 16843 u.readJobSummaryFromParcelLocked(name, in); 16844 } 16845 16846 u.readJobCompletionsFromParcelLocked(in); 16847 16848 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 16849 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 16850 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 16851 detachIfNotNull(u.mJobsFreshnessBuckets); 16852 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 16853 if (in.readInt() != 0) { 16854 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 16855 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 16856 } 16857 } 16858 16859 int NP = in.readInt(); 16860 if (NP > 1000) { 16861 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 16862 } 16863 for (int is = 0; is < NP; is++) { 16864 int seNumber = in.readInt(); 16865 if (in.readInt() != 0) { 16866 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 16867 } 16868 } 16869 16870 NP = in.readInt(); 16871 if (NP > 10000) { 16872 throw new ParcelFormatException("File corrupt: too many processes " + NP); 16873 } 16874 for (int ip = 0; ip < NP; ip++) { 16875 String procName = in.readString(); 16876 Uid.Proc p = u.getProcessStatsLocked(procName); 16877 p.mUserTimeMs = in.readLong(); 16878 p.mSystemTimeMs = in.readLong(); 16879 p.mForegroundTimeMs = in.readLong(); 16880 p.mStarts = in.readInt(); 16881 p.mNumCrashes = in.readInt(); 16882 p.mNumAnrs = in.readInt(); 16883 p.readExcessivePowerFromParcelLocked(in); 16884 } 16885 16886 NP = in.readInt(); 16887 if (NP > 10000) { 16888 throw new ParcelFormatException("File corrupt: too many packages " + NP); 16889 } 16890 for (int ip = 0; ip < NP; ip++) { 16891 String pkgName = in.readString(); 16892 detachIfNotNull(u.mPackageStats.get(pkgName)); 16893 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 16894 final int NWA = in.readInt(); 16895 if (NWA > 10000) { 16896 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 16897 } 16898 p.mWakeupAlarms.clear(); 16899 for (int iwa = 0; iwa < NWA; iwa++) { 16900 String tag = in.readString(); 16901 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 16902 c.readSummaryFromParcelLocked(in); 16903 p.mWakeupAlarms.put(tag, c); 16904 } 16905 NS = in.readInt(); 16906 if (NS > 10000) { 16907 throw new ParcelFormatException("File corrupt: too many services " + NS); 16908 } 16909 for (int is = 0; is < NS; is++) { 16910 String servName = in.readString(); 16911 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 16912 s.mStartTimeMs = in.readLong(); 16913 s.mStarts = in.readInt(); 16914 s.mLaunches = in.readInt(); 16915 } 16916 } 16917 } 16918 16919 if (!Flags.disableSystemServicePowerAttr()) { 16920 mBinderThreadCpuTimesUs = 16921 LongSamplingCounterArray.readSummaryFromParcelLocked(in, mOnBatteryTimeBase); 16922 } 16923 } 16924 16925 /** 16926 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 16927 * disk. This format does not allow a lossless round-trip. 16928 * 16929 * @param out the Parcel to be written to. 16930 */ 16931 @GuardedBy("this") 16932 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 16933 pullPendingStateUpdatesLocked(); 16934 16935 // Pull the clock time. This may update the time and make a new history entry 16936 // if we had originally pulled a time before the RTC was set. 16937 getStartClockTime(); 16938 16939 final long nowUptime = mClock.uptimeMillis() * 1000; 16940 final long nowRealtime = mClock.elapsedRealtime() * 1000; 16941 16942 out.writeInt(VERSION); 16943 16944 mHistory.writeSummaryToParcel(out, inclHistory); 16945 16946 out.writeInt(mStartCount); 16947 out.writeLong(computeUptime(nowUptime, STATS_SINCE_CHARGED)); 16948 out.writeLong(computeRealtime(nowRealtime, STATS_SINCE_CHARGED)); 16949 out.writeLong(mStartClockTimeMs); 16950 out.writeLong(mMonotonicStartTime); 16951 out.writeLong(mMonotonicClock.monotonicTime()); 16952 out.writeString(mStartPlatformVersion); 16953 out.writeString(mEndPlatformVersion); 16954 mOnBatteryTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 16955 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 16956 out.writeInt(mDischargeUnplugLevel); 16957 out.writeInt(mDischargePlugLevel); 16958 out.writeInt(mDischargeCurrentLevel); 16959 out.writeInt(mBatteryLevel); 16960 out.writeInt(mEstimatedBatteryCapacityMah); 16961 out.writeInt(mLastLearnedBatteryCapacityUah); 16962 out.writeInt(mMinLearnedBatteryCapacityUah); 16963 out.writeInt(mMaxLearnedBatteryCapacityUah); 16964 out.writeInt(getLowDischargeAmountSinceCharge()); 16965 out.writeInt(getHighDischargeAmountSinceCharge()); 16966 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 16967 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 16968 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 16969 mDischargeStepTracker.writeToParcel(out); 16970 mChargeStepTracker.writeToParcel(out); 16971 mDailyDischargeStepTracker.writeToParcel(out); 16972 mDailyChargeStepTracker.writeToParcel(out); 16973 mDischargeCounter.writeSummaryFromParcelLocked(out); 16974 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 16975 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 16976 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 16977 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 16978 if (mDailyPackageChanges != null) { 16979 final int NPKG = mDailyPackageChanges.size(); 16980 out.writeInt(NPKG); 16981 for (int i=0; i<NPKG; i++) { 16982 PackageChange pc = mDailyPackageChanges.get(i); 16983 out.writeString(pc.mPackageName); 16984 out.writeInt(pc.mUpdate ? 1 : 0); 16985 out.writeLong(pc.mVersionCode); 16986 } 16987 } else { 16988 out.writeInt(0); 16989 } 16990 out.writeLong(mDailyStartTimeMs); 16991 out.writeLong(mNextMinDailyDeadlineMs); 16992 out.writeLong(mNextMaxDailyDeadlineMs); 16993 out.writeLong(mBatteryTimeToFullSeconds); 16994 16995 EnergyConsumerStats.Config.writeToParcel(mEnergyConsumerStatsConfig, out); 16996 EnergyConsumerStats.writeSummaryToParcel(mGlobalEnergyConsumerStats, out); 16997 16998 mScreenOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16999 mScreenDozeTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17000 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 17001 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17002 } 17003 final int numDisplays = mPerDisplayBatteryStats.length; 17004 out.writeInt(numDisplays); 17005 for (int i = 0; i < numDisplays; i++) { 17006 mPerDisplayBatteryStats[i].writeSummaryToParcel(out, nowRealtime); 17007 } 17008 mInteractiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17009 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17010 out.writeLong(mLongestLightIdleTimeMs); 17011 out.writeLong(mLongestFullIdleTimeMs); 17012 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17013 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17014 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17015 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17016 mPhoneOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17017 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 17018 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17019 } 17020 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17021 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 17022 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17023 } 17024 mNrNsaTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17025 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 17026 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 17027 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 17028 } 17029 final int numRat = mPerRatBatteryStats.length; 17030 out.writeInt(numRat); 17031 for (int i = 0; i < numRat; i++) { 17032 final RadioAccessTechnologyBatteryStats ratStat = mPerRatBatteryStats[i]; 17033 if (ratStat == null) { 17034 out.writeInt(0); 17035 continue; 17036 } 17037 out.writeInt(1); 17038 ratStat.writeSummaryToParcel(out, nowRealtime); 17039 } 17040 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17041 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17042 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 17043 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 17044 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 17045 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17046 mWifiOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17047 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17048 for (int i=0; i<NUM_WIFI_STATES; i++) { 17049 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17050 } 17051 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 17052 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17053 } 17054 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 17055 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17056 } 17057 mWifiActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17058 mWifiActivity.writeSummaryToParcel(out); 17059 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 17060 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17061 } 17062 mBluetoothActivity.writeSummaryToParcel(out); 17063 mModemActivity.writeSummaryToParcel(out); 17064 out.writeInt(mHasWifiReporting ? 1 : 0); 17065 out.writeInt(mHasBluetoothReporting ? 1 : 0); 17066 out.writeInt(mHasModemReporting ? 1 : 0); 17067 17068 out.writeInt(mNumConnectivityChange); 17069 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17070 mCameraOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17071 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17072 17073 out.writeInt(mRpmStats.size()); 17074 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 17075 Timer rpmt = ent.getValue(); 17076 if (rpmt != null) { 17077 out.writeInt(1); 17078 out.writeString(ent.getKey()); 17079 rpmt.writeSummaryFromParcelLocked(out, nowRealtime); 17080 } else { 17081 out.writeInt(0); 17082 } 17083 } 17084 out.writeInt(mScreenOffRpmStats.size()); 17085 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 17086 Timer rpmt = ent.getValue(); 17087 if (rpmt != null) { 17088 out.writeInt(1); 17089 out.writeString(ent.getKey()); 17090 rpmt.writeSummaryFromParcelLocked(out, nowRealtime); 17091 } else { 17092 out.writeInt(0); 17093 } 17094 } 17095 17096 out.writeInt(mKernelWakelockStats.size()); 17097 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 17098 Timer kwlt = ent.getValue(); 17099 if (kwlt != null) { 17100 out.writeInt(1); 17101 out.writeString(ent.getKey()); 17102 kwlt.writeSummaryFromParcelLocked(out, nowRealtime); 17103 } else { 17104 out.writeInt(0); 17105 } 17106 } 17107 17108 out.writeInt(mWakeupReasonStats.size()); 17109 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 17110 SamplingTimer timer = ent.getValue(); 17111 if (timer != null) { 17112 out.writeInt(1); 17113 out.writeString(ent.getKey()); 17114 timer.writeSummaryFromParcelLocked(out, nowRealtime); 17115 } else { 17116 out.writeInt(0); 17117 } 17118 } 17119 17120 out.writeInt(mKernelMemoryStats.size()); 17121 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 17122 Timer kmt = mKernelMemoryStats.valueAt(i); 17123 if (kmt != null) { 17124 out.writeInt(1); 17125 out.writeLong(mKernelMemoryStats.keyAt(i)); 17126 kmt.writeSummaryFromParcelLocked(out, nowRealtime); 17127 } else { 17128 out.writeInt(0); 17129 } 17130 } 17131 17132 final int NU = mUidStats.size(); 17133 out.writeInt(NU); 17134 for (int iu = 0; iu < NU; iu++) { 17135 out.writeInt(mUidStats.keyAt(iu)); 17136 Uid u = mUidStats.valueAt(iu); 17137 17138 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 17139 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, nowUptime, 17140 nowRealtime); 17141 17142 if (u.mWifiRunningTimer != null) { 17143 out.writeInt(1); 17144 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17145 } else { 17146 out.writeInt(0); 17147 } 17148 if (u.mFullWifiLockTimer != null) { 17149 out.writeInt(1); 17150 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17151 } else { 17152 out.writeInt(0); 17153 } 17154 if (u.mWifiScanTimer != null) { 17155 out.writeInt(1); 17156 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17157 } else { 17158 out.writeInt(0); 17159 } 17160 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 17161 if (u.mWifiBatchedScanTimer[i] != null) { 17162 out.writeInt(1); 17163 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17164 } else { 17165 out.writeInt(0); 17166 } 17167 } 17168 if (u.mWifiMulticastTimer != null) { 17169 out.writeInt(1); 17170 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17171 } else { 17172 out.writeInt(0); 17173 } 17174 if (u.mAudioTurnedOnTimer != null) { 17175 out.writeInt(1); 17176 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17177 } else { 17178 out.writeInt(0); 17179 } 17180 if (u.mVideoTurnedOnTimer != null) { 17181 out.writeInt(1); 17182 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17183 } else { 17184 out.writeInt(0); 17185 } 17186 if (u.mFlashlightTurnedOnTimer != null) { 17187 out.writeInt(1); 17188 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17189 } else { 17190 out.writeInt(0); 17191 } 17192 if (u.mCameraTurnedOnTimer != null) { 17193 out.writeInt(1); 17194 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17195 } else { 17196 out.writeInt(0); 17197 } 17198 if (u.mForegroundActivityTimer != null) { 17199 out.writeInt(1); 17200 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17201 } else { 17202 out.writeInt(0); 17203 } 17204 if (u.mForegroundServiceTimer != null) { 17205 out.writeInt(1); 17206 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17207 } else { 17208 out.writeInt(0); 17209 } 17210 if (u.mAggregatedPartialWakelockTimer != null) { 17211 out.writeInt(1); 17212 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17213 } else { 17214 out.writeInt(0); 17215 } 17216 if (u.mBluetoothScanTimer != null) { 17217 out.writeInt(1); 17218 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17219 } else { 17220 out.writeInt(0); 17221 } 17222 if (u.mBluetoothUnoptimizedScanTimer != null) { 17223 out.writeInt(1); 17224 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17225 } else { 17226 out.writeInt(0); 17227 } 17228 if (u.mBluetoothScanResultCounter != null) { 17229 out.writeInt(1); 17230 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 17231 } else { 17232 out.writeInt(0); 17233 } 17234 if (u.mBluetoothScanResultBgCounter != null) { 17235 out.writeInt(1); 17236 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 17237 } else { 17238 out.writeInt(0); 17239 } 17240 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 17241 if (u.mProcessStateTimer[i] != null) { 17242 out.writeInt(1); 17243 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17244 } else { 17245 out.writeInt(0); 17246 } 17247 } 17248 if (u.mVibratorOnTimer != null) { 17249 out.writeInt(1); 17250 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17251 } else { 17252 out.writeInt(0); 17253 } 17254 17255 if (u.mUserActivityCounters == null) { 17256 out.writeInt(0); 17257 } else { 17258 out.writeInt(1); 17259 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 17260 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 17261 } 17262 } 17263 17264 if (u.mNetworkByteActivityCounters == null) { 17265 out.writeInt(0); 17266 } else { 17267 out.writeInt(1); 17268 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 17269 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 17270 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 17271 } 17272 if (u.mMobileRadioActiveTime != null) { 17273 out.writeBoolean(true); 17274 u.mMobileRadioActiveTime.writeToParcel(out); 17275 } else { 17276 out.writeBoolean(false); 17277 } 17278 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 17279 } 17280 17281 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 17282 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 17283 17284 if (u.mCpuClusterSpeedTimesUs != null) { 17285 out.writeInt(1); 17286 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 17287 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 17288 if (cpuSpeeds != null) { 17289 out.writeInt(1); 17290 out.writeInt(cpuSpeeds.length); 17291 for (LongSamplingCounter c : cpuSpeeds) { 17292 if (c != null) { 17293 out.writeInt(1); 17294 c.writeSummaryFromParcelLocked(out); 17295 } else { 17296 out.writeInt(0); 17297 } 17298 } 17299 } else { 17300 out.writeInt(0); 17301 } 17302 } 17303 } else { 17304 out.writeInt(0); 17305 } 17306 17307 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 17308 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 17309 17310 if (u.mCpuActiveTimeMs != null) { 17311 out.writeInt(u.mCpuActiveTimeMs.getStateCount()); 17312 u.mCpuActiveTimeMs.writeToParcel(out); 17313 } else { 17314 out.writeInt(0); 17315 } 17316 17317 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 17318 17319 if (u.mProcStateTimeMs != null) { 17320 out.writeInt(u.mProcStateTimeMs.getStateCount()); 17321 u.mProcStateTimeMs.writeToParcel(out); 17322 } else { 17323 out.writeInt(0); 17324 } 17325 17326 if (u.mProcStateScreenOffTimeMs != null) { 17327 out.writeInt(u.mProcStateScreenOffTimeMs.getStateCount()); 17328 u.mProcStateScreenOffTimeMs.writeToParcel(out); 17329 } else { 17330 out.writeInt(0); 17331 } 17332 17333 if (u.mMobileRadioApWakeupCount != null) { 17334 out.writeInt(1); 17335 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 17336 } else { 17337 out.writeInt(0); 17338 } 17339 17340 if (u.mWifiRadioApWakeupCount != null) { 17341 out.writeInt(1); 17342 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 17343 } else { 17344 out.writeInt(0); 17345 } 17346 17347 EnergyConsumerStats.writeSummaryToParcel(u.mUidEnergyConsumerStats, out); 17348 17349 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 17350 int NW = wakeStats.size(); 17351 out.writeInt(NW); 17352 for (int iw=0; iw<NW; iw++) { 17353 out.writeString(wakeStats.keyAt(iw)); 17354 Uid.Wakelock wl = wakeStats.valueAt(iw); 17355 if (wl.mTimerFull != null) { 17356 out.writeInt(1); 17357 wl.mTimerFull.writeSummaryFromParcelLocked(out, nowRealtime); 17358 } else { 17359 out.writeInt(0); 17360 } 17361 if (wl.mTimerPartial != null) { 17362 out.writeInt(1); 17363 wl.mTimerPartial.writeSummaryFromParcelLocked(out, nowRealtime); 17364 } else { 17365 out.writeInt(0); 17366 } 17367 if (wl.mTimerWindow != null) { 17368 out.writeInt(1); 17369 wl.mTimerWindow.writeSummaryFromParcelLocked(out, nowRealtime); 17370 } else { 17371 out.writeInt(0); 17372 } 17373 if (wl.mTimerDraw != null) { 17374 out.writeInt(1); 17375 wl.mTimerDraw.writeSummaryFromParcelLocked(out, nowRealtime); 17376 } else { 17377 out.writeInt(0); 17378 } 17379 } 17380 17381 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 17382 int NS = syncStats.size(); 17383 out.writeInt(NS); 17384 for (int is=0; is<NS; is++) { 17385 out.writeString(syncStats.keyAt(is)); 17386 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, nowRealtime); 17387 } 17388 17389 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 17390 int NJ = jobStats.size(); 17391 out.writeInt(NJ); 17392 for (int ij=0; ij<NJ; ij++) { 17393 out.writeString(jobStats.keyAt(ij)); 17394 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, nowRealtime); 17395 } 17396 17397 u.writeJobCompletionsToParcelLocked(out); 17398 17399 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 17400 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 17401 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 17402 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 17403 if (u.mJobsFreshnessBuckets[i] != null) { 17404 out.writeInt(1); 17405 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 17406 } else { 17407 out.writeInt(0); 17408 } 17409 } 17410 17411 int NSE = u.mSensorStats.size(); 17412 out.writeInt(NSE); 17413 for (int ise=0; ise<NSE; ise++) { 17414 out.writeInt(u.mSensorStats.keyAt(ise)); 17415 Uid.Sensor se = u.mSensorStats.valueAt(ise); 17416 if (se.mTimer != null) { 17417 out.writeInt(1); 17418 se.mTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17419 } else { 17420 out.writeInt(0); 17421 } 17422 } 17423 17424 int NP = u.mProcessStats.size(); 17425 out.writeInt(NP); 17426 for (int ip=0; ip<NP; ip++) { 17427 out.writeString(u.mProcessStats.keyAt(ip)); 17428 Uid.Proc ps = u.mProcessStats.valueAt(ip); 17429 out.writeLong(ps.mUserTimeMs); 17430 out.writeLong(ps.mSystemTimeMs); 17431 out.writeLong(ps.mForegroundTimeMs); 17432 out.writeInt(ps.mStarts); 17433 out.writeInt(ps.mNumCrashes); 17434 out.writeInt(ps.mNumAnrs); 17435 ps.writeExcessivePowerToParcelLocked(out); 17436 } 17437 17438 NP = u.mPackageStats.size(); 17439 out.writeInt(NP); 17440 if (NP > 0) { 17441 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 17442 : u.mPackageStats.entrySet()) { 17443 out.writeString(ent.getKey()); 17444 Uid.Pkg ps = ent.getValue(); 17445 final int NWA = ps.mWakeupAlarms.size(); 17446 out.writeInt(NWA); 17447 for (int iwa=0; iwa<NWA; iwa++) { 17448 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 17449 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 17450 } 17451 NS = ps.mServiceStats.size(); 17452 out.writeInt(NS); 17453 for (int is=0; is<NS; is++) { 17454 out.writeString(ps.mServiceStats.keyAt(is)); 17455 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 17456 long time = ss.getStartTimeToNowLocked( 17457 mOnBatteryTimeBase.getUptime(nowUptime) / 1000); 17458 out.writeLong(time); 17459 out.writeInt(ss.mStarts); 17460 out.writeInt(ss.mLaunches); 17461 } 17462 } 17463 } 17464 } 17465 17466 if (!Flags.disableSystemServicePowerAttr()) { 17467 LongSamplingCounterArray.writeSummaryToParcelLocked(out, mBinderThreadCpuTimesUs); 17468 } 17469 } 17470 17471 @GuardedBy("this") 17472 public void prepareForDumpLocked() { 17473 // Need to retrieve current kernel wake lock stats before printing. 17474 pullPendingStateUpdatesLocked(); 17475 17476 // Pull the clock time. This may update the time and make a new history entry 17477 // if we had originally pulled a time before the RTC was set. 17478 getStartClockTime(); 17479 17480 if (!Flags.disableSystemServicePowerAttr()) { 17481 updateSystemServiceCallStats(); 17482 } 17483 } 17484 17485 @GuardedBy("this") 17486 public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart, 17487 BatteryStatsDumpHelper dumpHelper) { 17488 if (DEBUG) { 17489 pw.println("mOnBatteryTimeBase:"); 17490 mOnBatteryTimeBase.dump(pw, " "); 17491 pw.println("mOnBatteryScreenOffTimeBase:"); 17492 mOnBatteryScreenOffTimeBase.dump(pw, " "); 17493 Printer pr = new PrintWriterPrinter(pw); 17494 pr.println("*** Screen on timer:"); 17495 mScreenOnTimer.logState(pr, " "); 17496 pr.println("*** Screen doze timer:"); 17497 mScreenDozeTimer.logState(pr, " "); 17498 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 17499 pr.println("*** Screen brightness #" + i + ":"); 17500 mScreenBrightnessTimer[i].logState(pr, " "); 17501 } 17502 pr.println("*** Interactive timer:"); 17503 mInteractiveTimer.logState(pr, " "); 17504 pr.println("*** Power save mode timer:"); 17505 mPowerSaveModeEnabledTimer.logState(pr, " "); 17506 pr.println("*** Device idle mode light timer:"); 17507 mDeviceIdleModeLightTimer.logState(pr, " "); 17508 pr.println("*** Device idle mode full timer:"); 17509 mDeviceIdleModeFullTimer.logState(pr, " "); 17510 pr.println("*** Device light idling timer:"); 17511 mDeviceLightIdlingTimer.logState(pr, " "); 17512 pr.println("*** Device idling timer:"); 17513 mDeviceIdlingTimer.logState(pr, " "); 17514 pr.println("*** Phone timer:"); 17515 mPhoneOnTimer.logState(pr, " "); 17516 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 17517 pr.println("*** Phone signal strength #" + i + ":"); 17518 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 17519 } 17520 pr.println("*** Signal scanning :"); 17521 mPhoneSignalScanningTimer.logState(pr, " "); 17522 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 17523 pr.println("*** Data connection type #" + i + ":"); 17524 mPhoneDataConnectionsTimer[i].logState(pr, " "); 17525 } 17526 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 17527 pr.println("*** Mobile network active timer:"); 17528 mMobileRadioActiveTimer.logState(pr, " "); 17529 pr.println("*** Mobile network active adjusted timer:"); 17530 mMobileRadioActiveAdjustedTime.logState(pr, " "); 17531 pr.println("*** Wifi Multicast WakeLock Timer:"); 17532 mWifiMulticastWakelockTimer.logState(pr, " "); 17533 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 17534 pr.println("*** Wifi timer:"); 17535 mWifiOnTimer.logState(pr, " "); 17536 pr.println("*** WifiRunning timer:"); 17537 mGlobalWifiRunningTimer.logState(pr, " "); 17538 for (int i=0; i<NUM_WIFI_STATES; i++) { 17539 pr.println("*** Wifi state #" + i + ":"); 17540 mWifiStateTimer[i].logState(pr, " "); 17541 } 17542 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 17543 pr.println("*** Wifi suppl state #" + i + ":"); 17544 mWifiSupplStateTimer[i].logState(pr, " "); 17545 } 17546 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 17547 pr.println("*** Wifi signal strength #" + i + ":"); 17548 mWifiSignalStrengthsTimer[i].logState(pr, " "); 17549 } 17550 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 17551 pr.println("*** GPS signal quality #" + i + ":"); 17552 mGpsSignalQualityTimer[i].logState(pr, " "); 17553 } 17554 pr.println("*** Flashlight timer:"); 17555 mFlashlightOnTimer.logState(pr, " "); 17556 pr.println("*** Camera timer:"); 17557 mCameraOnTimer.logState(pr, " "); 17558 } 17559 super.dump(context, pw, flags, reqUid, histStart, dumpHelper); 17560 17561 synchronized (this) { 17562 pw.print("Per process state tracking available: "); 17563 pw.println(trackPerProcStateCpuTimes()); 17564 pw.print("Total cpu time reads: "); 17565 pw.println(mNumSingleUidCpuTimeReads); 17566 pw.print("Batching Duration (min): "); 17567 pw.println((mClock.uptimeMillis() - mCpuTimeReadsTrackingStartTimeMs) / (60 * 1000)); 17568 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 17569 pw.println(mNumAllUidCpuTimeReads); 17570 pw.print("UIDs removed since the later of device start or stats reset: "); 17571 pw.println(mNumUidsRemoved); 17572 17573 mPowerStatsUidResolver.dump(pw); 17574 17575 pw.println(); 17576 dumpConstantsLocked(pw); 17577 17578 pw.println(); 17579 mCpuPowerStatsCollector.dumpCpuPowerBracketsLocked(pw); 17580 17581 pw.println(); 17582 dumpEnergyConsumerStatsLocked(pw); 17583 } 17584 } 17585 } 17586