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 android.annotation.IntDef; 27 import android.annotation.NonNull; 28 import android.annotation.Nullable; 29 import android.annotation.SuppressLint; 30 import android.app.ActivityManager; 31 import android.app.AlarmManager; 32 import android.app.usage.NetworkStatsManager; 33 import android.bluetooth.BluetoothActivityEnergyInfo; 34 import android.bluetooth.BluetoothAdapter; 35 import android.bluetooth.BluetoothManager; 36 import android.bluetooth.UidTraffic; 37 import android.content.BroadcastReceiver; 38 import android.content.ContentResolver; 39 import android.content.Context; 40 import android.content.Intent; 41 import android.content.IntentFilter; 42 import android.content.pm.PackageManager; 43 import android.database.ContentObserver; 44 import android.hardware.usb.UsbManager; 45 import android.location.GnssSignalQuality; 46 import android.net.NetworkStats; 47 import android.net.Uri; 48 import android.net.wifi.WifiManager; 49 import android.os.BatteryConsumer; 50 import android.os.BatteryManager; 51 import android.os.BatteryStats; 52 import android.os.BatteryUsageStats; 53 import android.os.BatteryUsageStatsQuery; 54 import android.os.Binder; 55 import android.os.BluetoothBatteryStats; 56 import android.os.Build; 57 import android.os.ConditionVariable; 58 import android.os.Handler; 59 import android.os.IBatteryPropertiesRegistrar; 60 import android.os.Looper; 61 import android.os.Message; 62 import android.os.OsProtoEnums; 63 import android.os.Parcel; 64 import android.os.ParcelFormatException; 65 import android.os.Parcelable; 66 import android.os.PowerManager; 67 import android.os.Process; 68 import android.os.RemoteException; 69 import android.os.ServiceManager; 70 import android.os.SystemClock; 71 import android.os.UserHandle; 72 import android.os.WakeLockStats; 73 import android.os.WorkSource; 74 import android.os.WorkSource.WorkChain; 75 import android.os.connectivity.CellularBatteryStats; 76 import android.os.connectivity.GpsBatteryStats; 77 import android.os.connectivity.WifiActivityEnergyInfo; 78 import android.os.connectivity.WifiBatteryStats; 79 import android.power.PowerStatsInternal; 80 import android.provider.Settings; 81 import android.telephony.AccessNetworkConstants; 82 import android.telephony.Annotation.NetworkType; 83 import android.telephony.CellSignalStrength; 84 import android.telephony.CellSignalStrengthLte; 85 import android.telephony.CellSignalStrengthNr; 86 import android.telephony.DataConnectionRealTimeInfo; 87 import android.telephony.ModemActivityInfo; 88 import android.telephony.NetworkRegistrationInfo; 89 import android.telephony.ServiceState; 90 import android.telephony.ServiceState.RegState; 91 import android.telephony.SignalStrength; 92 import android.telephony.TelephonyManager; 93 import android.text.TextUtils; 94 import android.text.format.DateUtils; 95 import android.util.ArrayMap; 96 import android.util.ArraySet; 97 import android.util.AtomicFile; 98 import android.util.IndentingPrintWriter; 99 import android.util.KeyValueListParser; 100 import android.util.Log; 101 import android.util.LongSparseArray; 102 import android.util.LongSparseLongArray; 103 import android.util.MutableInt; 104 import android.util.PrintWriterPrinter; 105 import android.util.Printer; 106 import android.util.Slog; 107 import android.util.SparseArray; 108 import android.util.SparseBooleanArray; 109 import android.util.SparseDoubleArray; 110 import android.util.SparseIntArray; 111 import android.util.SparseLongArray; 112 import android.util.TimeUtils; 113 import android.util.Xml; 114 import android.view.Display; 115 116 import com.android.internal.annotations.GuardedBy; 117 import com.android.internal.annotations.VisibleForTesting; 118 import com.android.internal.os.BackgroundThread; 119 import com.android.internal.os.BatteryStatsHistory; 120 import com.android.internal.os.BatteryStatsHistoryIterator; 121 import com.android.internal.os.BinderCallsStats; 122 import com.android.internal.os.BinderTransactionNameResolver; 123 import com.android.internal.os.Clock; 124 import com.android.internal.os.CpuScalingPolicies; 125 import com.android.internal.os.KernelCpuSpeedReader; 126 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; 127 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; 128 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 129 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; 130 import com.android.internal.os.KernelMemoryBandwidthStats; 131 import com.android.internal.os.KernelSingleUidTimeReader; 132 import com.android.internal.os.LongArrayMultiStateCounter; 133 import com.android.internal.os.LongMultiStateCounter; 134 import com.android.internal.os.MonotonicClock; 135 import com.android.internal.os.PowerProfile; 136 import com.android.internal.os.PowerStats; 137 import com.android.internal.os.RailStats; 138 import com.android.internal.os.RpmStats; 139 import com.android.internal.power.EnergyConsumerStats; 140 import com.android.internal.power.EnergyConsumerStats.StandardPowerBucket; 141 import com.android.internal.util.ArrayUtils; 142 import com.android.internal.util.FrameworkStatsLog; 143 import com.android.internal.util.XmlUtils; 144 import com.android.modules.utils.TypedXmlPullParser; 145 import com.android.modules.utils.TypedXmlSerializer; 146 import com.android.server.LocalServices; 147 import com.android.server.power.feature.PowerManagerFlags; 148 import com.android.server.power.optimization.Flags; 149 import com.android.server.power.stats.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes; 150 import com.android.server.power.stats.format.MobileRadioPowerStatsLayout; 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.TimeUnit; 179 import java.util.concurrent.atomic.AtomicInteger; 180 import java.util.concurrent.locks.ReentrantLock; 181 import java.util.function.LongSupplier; 182 import java.util.function.Supplier; 183 184 /** 185 * All information we are collecting about things that can happen that impact 186 * battery life. All times are represented in microseconds except where indicated 187 * otherwise. 188 */ 189 public class BatteryStatsImpl extends BatteryStats { 190 private static final String TAG = "BatteryStatsImpl"; 191 private static final boolean DEBUG = false; 192 public static final boolean DEBUG_ENERGY = false; 193 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 194 private static final boolean DEBUG_BINDER_STATS = false; 195 private static final boolean DEBUG_MEMORY = false; 196 197 private static final String HISTORY_DIR = "battery-history"; 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 /** 230 * Minimum duration of a battery session. Attempt to automatically start a new 231 * session within this interval are ignored. Explicit resets (e.g. with an adb command) are 232 * not affected by this restriction. 233 */ 234 private static final long MIN_BATTERY_SESSION_DURATION_MILLIS = 60000; 235 236 public static final int RESET_REASON_CORRUPT_FILE = 1; 237 public static final int RESET_REASON_ADB_COMMAND = 2; 238 public static final int RESET_REASON_FULL_CHARGE = 3; 239 public static final int RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE = 4; 240 public static final int RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION = 5; 241 242 @NonNull 243 private final MonotonicClock mMonotonicClock; 244 245 protected Clock mClock; 246 247 private final AtomicFile mStatsFile; 248 public final AtomicFile mCheckinFile; 249 public final AtomicFile mDailyFile; 250 251 static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1; 252 static final int MSG_REPORT_POWER_CHANGE = 2; 253 static final int MSG_REPORT_CHARGING = 3; 254 static final int MSG_REPORT_RESET_STATS = 4; 255 static final long DELAY_UPDATE_WAKELOCKS = 60 * 1000; 256 257 private static final double MILLISECONDS_IN_HOUR = 3600 * 1000; 258 private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L; 259 260 private static final LongCounter ZERO_LONG_COUNTER = new LongCounter() { 261 @Override 262 public long getCountLocked(int which) { 263 return 0; 264 } 265 266 @Override 267 public long getCountForProcessState(int procState) { 268 return 0; 269 } 270 271 @Override 272 public void logState(Printer pw, String prefix) { 273 pw.println(prefix + "mCount=0"); 274 } 275 }; 276 277 private static final LongCounter[] ZERO_LONG_COUNTER_ARRAY = 278 new LongCounter[]{ZERO_LONG_COUNTER}; 279 280 @VisibleForTesting 281 protected CpuScalingPolicies mCpuScalingPolicies; 282 283 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 284 285 @VisibleForTesting 286 protected KernelWakelockReader mKernelWakelockReader; 287 @VisibleForTesting 288 protected KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader; 289 @VisibleForTesting 290 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 291 @VisibleForTesting 292 protected KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader; 293 @VisibleForTesting 294 protected KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader; 295 @VisibleForTesting 296 protected KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader; 297 @VisibleForTesting 298 protected KernelSingleUidTimeReader mKernelSingleUidTimeReader; 299 @VisibleForTesting 300 protected SystemServerCpuThreadReader mSystemServerCpuThreadReader; 301 302 private KernelMemoryBandwidthStats mKernelMemoryBandwidthStats; 303 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); 304 private int[] mCpuPowerBracketMap; 305 private final CpuPowerStatsCollector mCpuPowerStatsCollector; 306 private final WakelockPowerStatsCollector mWakelockPowerStatsCollector; 307 private final ScreenPowerStatsCollector mScreenPowerStatsCollector; 308 private final MobileRadioPowerStatsCollector mMobileRadioPowerStatsCollector; 309 private final WifiPowerStatsCollector mWifiPowerStatsCollector; 310 private final BluetoothPowerStatsCollector mBluetoothPowerStatsCollector; 311 private final CameraPowerStatsCollector mCameraPowerStatsCollector; 312 private final GnssPowerStatsCollector mGnssPowerStatsCollector; 313 private final CustomEnergyConsumerPowerStatsCollector mCustomEnergyConsumerPowerStatsCollector; 314 private final SparseBooleanArray mPowerStatsCollectorEnabled = new SparseBooleanArray(); 315 private boolean mMoveWscLoggingToNotifierEnabled = false; 316 317 static class BatteryStatsSession { 318 private final BatteryStatsHistory mHistory; 319 private final long mMonotonicStartTime; 320 private final long mStartClockTime; 321 private final long mEstimatedBatteryCapacityMah; 322 private final long mBatteryTimeRemainingMs; 323 private final long mChargeTimeRemainingMs; 324 private final String[] mCustomEnergyConsumerNames; 325 private final BatteryStatsImpl mBatteryStats; 326 BatteryStatsSession(BatteryStatsHistory history, long monotonicStartTime, long startClockTime, long batteryTimeRemainingMs, long chargeTimeRemainingMs, long estimatedBatteryCapacityMah, String[] customEnergyConsumerNames, BatteryStatsImpl batteryStats)327 BatteryStatsSession(BatteryStatsHistory history, long monotonicStartTime, 328 long startClockTime, long batteryTimeRemainingMs, long chargeTimeRemainingMs, 329 long estimatedBatteryCapacityMah, String[] customEnergyConsumerNames, 330 BatteryStatsImpl batteryStats) { 331 mHistory = history; 332 mMonotonicStartTime = monotonicStartTime; 333 mStartClockTime = startClockTime; 334 mEstimatedBatteryCapacityMah = estimatedBatteryCapacityMah; 335 mBatteryTimeRemainingMs = batteryTimeRemainingMs; 336 mChargeTimeRemainingMs = chargeTimeRemainingMs; 337 mCustomEnergyConsumerNames = customEnergyConsumerNames; 338 mBatteryStats = batteryStats; 339 } 340 getHistory()341 BatteryStatsHistory getHistory() { 342 return mHistory; 343 } 344 getMonotonicStartTime()345 long getMonotonicStartTime() { 346 return mMonotonicStartTime; 347 } 348 getStartClockTime()349 long getStartClockTime() { 350 return mStartClockTime; 351 } 352 getBatteryTimeRemainingMs()353 long getBatteryTimeRemainingMs() { 354 return mBatteryTimeRemainingMs; 355 } 356 getChargeTimeRemainingMs()357 long getChargeTimeRemainingMs() { 358 return mChargeTimeRemainingMs; 359 } 360 getEstimatedBatteryCapacity()361 double getEstimatedBatteryCapacity() { 362 return mEstimatedBatteryCapacityMah; 363 } 364 getCustomEnergyConsumerNames()365 String[] getCustomEnergyConsumerNames() { 366 return mCustomEnergyConsumerNames; 367 } 368 369 /** @deprecated This method will be removed once PowerCalculators are removed from the 370 * code base. */ 371 @Deprecated getBatteryStats()372 public BatteryStatsImpl getBatteryStats() { 373 return mBatteryStats; 374 } 375 } 376 getBatteryStatsSession()377 BatteryStatsSession getBatteryStatsSession() { 378 synchronized (this) { 379 long elapsedTimeUs = mClock.elapsedRealtime() * 1000; 380 long batteryTimeRemainingUs = computeBatteryTimeRemaining(elapsedTimeUs); 381 long batteryTimeRemainingMs = 382 batteryTimeRemainingUs >= 0 ? batteryTimeRemainingUs / 1000 : -1; 383 long chargeTimeRemainingUs = computeChargeTimeRemaining(elapsedTimeUs); 384 long chargeTimeRemainingMs = 385 chargeTimeRemainingUs >= 0 ? chargeTimeRemainingUs / 1000 : -1; 386 return new BatteryStatsSession(mHistory, getMonotonicStartTime(), getStartClockTime(), 387 batteryTimeRemainingMs, chargeTimeRemainingMs, getEstimatedBatteryCapacity(), 388 getCustomEnergyConsumerNames(), this); 389 } 390 } 391 392 private ScreenPowerStatsCollector.ScreenUsageTimeRetriever mScreenUsageTimeRetriever = 393 new ScreenPowerStatsCollector.ScreenUsageTimeRetriever() { 394 395 @Override 396 public long getScreenOnTimeMs(int display) { 397 synchronized (BatteryStatsImpl.this) { 398 return getDisplayScreenOnTime(display, 399 mClock.elapsedRealtime() * 1000) / 1000; 400 } 401 } 402 403 @Override 404 public long getBrightnessLevelTimeMs(int display, int brightnessLevel) { 405 synchronized (BatteryStatsImpl.this) { 406 return getDisplayScreenBrightnessTime(display, brightnessLevel, 407 mClock.elapsedRealtime() * 1000) / 1000; 408 } 409 } 410 411 @Override 412 public long getScreenDozeTimeMs(int display) { 413 synchronized (BatteryStatsImpl.this) { 414 return getDisplayScreenDozeTime(display, 415 mClock.elapsedRealtime() * 1000) / 1000; 416 } 417 } 418 419 @Override 420 public void retrieveTopActivityTimes(Callback callback) { 421 synchronized (BatteryStatsImpl.this) { 422 long elapsedTimeUs = mClock.elapsedRealtime() * 1000; 423 for (int i = mUidStats.size() - 1; i >= 0; i--) { 424 Uid uid = mUidStats.valueAt(i); 425 long topStateTime = uid.getProcessStateTime(Uid.PROCESS_STATE_TOP, 426 elapsedTimeUs, STATS_SINCE_CHARGED) / 1000; 427 Timer timer = uid.getForegroundActivityTimer(); 428 if (timer == null) { 429 callback.onUidTopActivityTime(uid.mUid, topStateTime); 430 } else { 431 long topActivityTime = timer.getTotalTimeLocked(elapsedTimeUs, 432 STATS_SINCE_CHARGED) / 1000; 433 callback.onUidTopActivityTime(uid.mUid, Math.min(topStateTime, 434 topActivityTime)); 435 } 436 } 437 } 438 } 439 }; 440 private final WifiPowerStatsCollector.WifiStatsRetriever mWifiStatsRetriever = 441 new WifiPowerStatsCollector.WifiStatsRetriever() { 442 @Override 443 public void retrieveWifiScanTimes(Callback callback) { 444 synchronized (BatteryStatsImpl.this) { 445 retrieveWifiScanTimesLocked(callback); 446 } 447 } 448 449 @Override 450 public long getWifiActiveDuration() { 451 synchronized (BatteryStatsImpl.this) { 452 return getGlobalWifiRunningTime(mClock.elapsedRealtime() * 1000, 453 STATS_SINCE_CHARGED) / 1000; 454 } 455 } 456 }; 457 458 private class BluetoothStatsRetrieverImpl implements 459 BluetoothPowerStatsCollector.BluetoothStatsRetriever { 460 private final BluetoothManager mBluetoothManager; 461 BluetoothStatsRetrieverImpl(BluetoothManager bluetoothManager)462 BluetoothStatsRetrieverImpl(BluetoothManager bluetoothManager) { 463 mBluetoothManager = bluetoothManager; 464 } 465 466 @Override retrieveBluetoothScanTimes(Callback callback)467 public void retrieveBluetoothScanTimes(Callback callback) { 468 synchronized (BatteryStatsImpl.this) { 469 retrieveBluetoothScanTimesLocked(callback); 470 } 471 } 472 473 @Override requestControllerActivityEnergyInfo(Executor executor, BluetoothAdapter.OnBluetoothActivityEnergyInfoCallback callback)474 public boolean requestControllerActivityEnergyInfo(Executor executor, 475 BluetoothAdapter.OnBluetoothActivityEnergyInfoCallback callback) { 476 if (mBluetoothManager == null) { 477 return false; 478 } 479 480 BluetoothAdapter adapter = mBluetoothManager.getAdapter(); 481 if (adapter == null) { 482 return false; 483 } 484 485 adapter.requestControllerActivityEnergyInfo(executor, callback); 486 return true; 487 } 488 } 489 490 private final WakelockPowerStatsCollector.WakelockDurationRetriever mWakelockDurationRetriever = 491 new WakelockPowerStatsCollector.WakelockDurationRetriever() { 492 493 @Override 494 public long getWakelockDurationMillis() { 495 synchronized (BatteryStatsImpl.this) { 496 long batteryUptimeUs = getBatteryUptime(mClock.uptimeMillis() * 1000); 497 long screenOnTimeUs = getScreenOnTime(mClock.elapsedRealtime() * 1000, 498 BatteryStats.STATS_SINCE_CHARGED); 499 return Math.max(0, (batteryUptimeUs - screenOnTimeUs) / 1000); 500 } 501 } 502 503 @Override 504 public void retrieveUidWakelockDuration(Callback callback) { 505 synchronized (BatteryStatsImpl.this) { 506 long rawRealtimeUs = mClock.elapsedRealtime() * 1000; 507 for (int i = mUidStats.size() - 1; i >= 0; i--) { 508 Uid u = mUidStats.valueAt(i); 509 long wakeLockTimeUs = 0; 510 ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = 511 u.getWakelockStats(); 512 final int wakelockStatsCount = wakelockStats.size(); 513 for (int j = 0; j < wakelockStatsCount; j++) { 514 final BatteryStats.Uid.Wakelock wakelock = wakelockStats.valueAt(j); 515 BatteryStats.Timer timer = wakelock.getWakeTime( 516 BatteryStats.WAKE_TYPE_PARTIAL); 517 if (timer != null) { 518 wakeLockTimeUs += timer.getTotalTimeLocked(rawRealtimeUs, 519 BatteryStats.STATS_SINCE_CHARGED); 520 } 521 } 522 523 long wakelockTimeMs = wakeLockTimeUs / 1000; 524 if (wakelockTimeMs != 0) { 525 callback.onUidWakelockDuration(u.getUid(), wakelockTimeMs); 526 } 527 } 528 } 529 } 530 }; 531 getKernelMemoryStats()532 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 533 return mKernelMemoryStats; 534 } 535 536 private static final int[] SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS = { 537 EnergyConsumerStats.POWER_BUCKET_CPU, 538 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 539 EnergyConsumerStats.POWER_BUCKET_WIFI, 540 EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 541 }; 542 543 // TimeInState counters need NUM_PROCESS_STATE states in order to accommodate 544 // Uid.PROCESS_STATE_NONEXISTENT, which is outside the range of legitimate proc states. 545 private static final int PROC_STATE_TIME_COUNTER_STATE_COUNT = NUM_PROCESS_STATE + 1; 546 547 @GuardedBy("this") 548 public boolean mPerProcStateCpuTimesAvailable = true; 549 550 @GuardedBy("this") 551 private long mNumSingleUidCpuTimeReads; 552 @GuardedBy("this") 553 private long mCpuTimeReadsTrackingStartTimeMs = SystemClock.uptimeMillis(); 554 @GuardedBy("this") 555 private int mNumUidsRemoved; 556 @GuardedBy("this") 557 private int mNumAllUidCpuTimeReads; 558 559 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ 560 private RpmStats mTmpRpmStats = null; 561 /** The soonest the RPM stats can be updated after it was last updated. */ 562 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; 563 /** Last time that RPM stats were updated by updateRpmStatsLocked. */ 564 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS; 565 566 /** Container for Rail Energy Data stats. */ 567 private RailStats mTmpRailStats; 568 569 /** 570 * Estimate UID modem power usage based on their estimated mobile radio active time. 571 */ 572 public static final int PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME = 1; 573 /** 574 * Estimate UID modem power consumption by proportionally attributing estimated Rx and Tx 575 * power consumption individually. 576 * ModemActivityInfo must be available. 577 */ 578 public static final int PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX = 2; 579 580 @IntDef(flag = true, prefix = "PER_UID_MODEM_MODEL_", value = { 581 PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME, 582 PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX, 583 }) 584 @Retention(RetentionPolicy.SOURCE) 585 public @interface PerUidModemPowerModel { 586 } 587 588 /** 589 * Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader}, 590 * {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader}, 591 * {@link KernelCpuUidFreqTimeReader} and from the Kernel. 592 * 593 * Isolated and invalid UID info must be removed to conserve memory. However, STATSD and 594 * Batterystats both need to access UID cpu time. To resolve this race condition, only 595 * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is 596 * implemented so that STATSD can capture those UID times before they are deleted. 597 */ 598 @GuardedBy("this") 599 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 600 protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>(); 601 602 @NonNull getHistory()603 public BatteryStatsHistory getHistory() { 604 return mHistory; 605 } 606 607 @NonNull copyHistory()608 BatteryStatsHistory copyHistory() { 609 return mHistory.copy(); 610 } 611 612 @VisibleForTesting 613 public final class UidToRemove { 614 private final int mStartUid; 615 private final int mEndUid; 616 private final long mUidRemovalTimestamp; 617 618 /** Remove just one UID */ UidToRemove(int uid, long timestamp)619 public UidToRemove(int uid, long timestamp) { 620 this(uid, uid, timestamp); 621 } 622 623 /** Remove a range of UIDs, startUid must be smaller than endUid. */ UidToRemove(int startUid, int endUid, long timestamp)624 public UidToRemove(int startUid, int endUid, long timestamp) { 625 mStartUid = startUid; 626 mEndUid = endUid; 627 mUidRemovalTimestamp = timestamp; 628 } 629 getUidRemovalTimestamp()630 public long getUidRemovalTimestamp() { 631 return mUidRemovalTimestamp; 632 } 633 634 @GuardedBy("BatteryStatsImpl.this") removeLocked()635 void removeLocked() { 636 removeCpuStatsForUidRangeLocked(mStartUid, mEndUid); 637 } 638 } 639 640 private boolean mSaveBatteryUsageStatsOnReset; 641 private boolean mResetBatteryHistoryOnNewSession; 642 private boolean mAccumulateBatteryUsageStats; 643 private BatteryUsageStatsProvider mBatteryUsageStatsProvider; 644 private PowerStatsStore mPowerStatsStore; 645 646 public interface BatteryCallback { batteryNeedsCpuUpdate()647 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)648 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)649 public void batterySendBroadcast(Intent intent); batteryStatsReset()650 public void batteryStatsReset(); 651 } 652 653 public interface PlatformIdleStateCallback { fillLowPowerStats(RpmStats rpmStats)654 public void fillLowPowerStats(RpmStats rpmStats); 655 } 656 657 /** interface to update rail information for power monitor */ 658 public interface EnergyStatsRetriever { 659 /** Function to fill the map for the rail data stats 660 * Used for power monitoring feature 661 * @param railStats 662 */ fillRailDataStats(RailStats railStats)663 void fillRailDataStats(RailStats railStats); 664 } 665 666 public static abstract class UserInfoProvider { 667 private int[] userIds; getUserIds()668 protected abstract @Nullable int[] getUserIds(); 669 @VisibleForTesting refreshUserIds()670 public final void refreshUserIds() { 671 userIds = getUserIds(); 672 } 673 @VisibleForTesting exists(int userId)674 public boolean exists(int userId) { 675 return userIds != null ? ArrayUtils.contains(userIds, userId) : true; 676 } 677 } 678 679 /** Provide BatteryStatsImpl configuration choices */ 680 public static class BatteryStatsConfig { 681 static final int RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG = 1 << 0; 682 static final int RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG = 1 << 1; 683 684 private final int mFlags; 685 private final Long mDefaultPowerStatsThrottlePeriod; 686 private final Map<String, Long> mPowerStatsThrottlePeriods; 687 private final int mMaxHistorySizeBytes; 688 BatteryStatsConfig(Builder builder)689 private BatteryStatsConfig(Builder builder) { 690 int flags = 0; 691 if (builder.mResetOnUnplugHighBatteryLevel) { 692 flags |= RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG; 693 } 694 if (builder.mResetOnUnplugAfterSignificantCharge) { 695 flags |= RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG; 696 } 697 mFlags = flags; 698 mDefaultPowerStatsThrottlePeriod = builder.mDefaultPowerStatsThrottlePeriod; 699 mPowerStatsThrottlePeriods = builder.mPowerStatsThrottlePeriods; 700 mMaxHistorySizeBytes = builder.mMaxHistorySizeBytes; 701 } 702 703 /** 704 * Returns whether a BatteryStats reset should occur on unplug when the battery level is 705 * high. 706 */ shouldResetOnUnplugHighBatteryLevel()707 public boolean shouldResetOnUnplugHighBatteryLevel() { 708 return (mFlags & RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG) 709 == RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG; 710 } 711 712 /** 713 * Returns whether a BatteryStats reset should occur on unplug if the battery charge a 714 * significant amount since it has been plugged in. 715 */ shouldResetOnUnplugAfterSignificantCharge()716 public boolean shouldResetOnUnplugAfterSignificantCharge() { 717 return (mFlags & RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG) 718 == RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG; 719 } 720 721 /** 722 * Returns the minimum amount of time (in millis) to wait between passes 723 * of power stats collection for the specified power component. 724 */ getPowerStatsThrottlePeriod(String powerComponentName)725 public long getPowerStatsThrottlePeriod(String powerComponentName) { 726 return mPowerStatsThrottlePeriods.getOrDefault(powerComponentName, 727 mDefaultPowerStatsThrottlePeriod); 728 } 729 getMaxHistorySizeBytes()730 public int getMaxHistorySizeBytes() { 731 return mMaxHistorySizeBytes; 732 } 733 734 /** 735 * Builder for BatteryStatsConfig 736 */ 737 public static class Builder { 738 private boolean mResetOnUnplugHighBatteryLevel; 739 private boolean mResetOnUnplugAfterSignificantCharge; 740 private static final long DEFAULT_POWER_STATS_THROTTLE_PERIOD = 741 TimeUnit.HOURS.toMillis(1); 742 private static final long DEFAULT_POWER_STATS_THROTTLE_PERIOD_CPU = 743 TimeUnit.MINUTES.toMillis(1); 744 private static final int DEFAULT_MAX_HISTORY_SIZE = 4 * 1024 * 1024; 745 private long mDefaultPowerStatsThrottlePeriod = DEFAULT_POWER_STATS_THROTTLE_PERIOD; 746 private final Map<String, Long> mPowerStatsThrottlePeriods = new HashMap<>(); 747 private int mMaxHistorySizeBytes = DEFAULT_MAX_HISTORY_SIZE; 748 Builder()749 public Builder() { 750 mResetOnUnplugHighBatteryLevel = true; 751 mResetOnUnplugAfterSignificantCharge = true; 752 setPowerStatsThrottlePeriodMillis(BatteryConsumer.powerComponentIdToString( 753 BatteryConsumer.POWER_COMPONENT_CPU), 754 DEFAULT_POWER_STATS_THROTTLE_PERIOD_CPU); 755 } 756 757 /** 758 * Build the BatteryStatsConfig. 759 */ build()760 public BatteryStatsConfig build() { 761 return new BatteryStatsConfig(this); 762 } 763 764 /** 765 * Set whether a BatteryStats reset should occur on unplug when the battery level is 766 * high. 767 */ setResetOnUnplugHighBatteryLevel(boolean reset)768 public Builder setResetOnUnplugHighBatteryLevel(boolean reset) { 769 mResetOnUnplugHighBatteryLevel = reset; 770 return this; 771 } 772 773 /** 774 * Set whether a BatteryStats reset should occur on unplug if the battery charge a 775 * significant amount since it has been plugged in. 776 */ setResetOnUnplugAfterSignificantCharge(boolean reset)777 public Builder setResetOnUnplugAfterSignificantCharge(boolean reset) { 778 mResetOnUnplugAfterSignificantCharge = reset; 779 return this; 780 } 781 782 /** 783 * Sets the minimum amount of time (in millis) to wait between passes 784 * of power stats collection for the specified power component. 785 */ setPowerStatsThrottlePeriodMillis(String powerComponentName, long periodMs)786 public Builder setPowerStatsThrottlePeriodMillis(String powerComponentName, 787 long periodMs) { 788 mPowerStatsThrottlePeriods.put(powerComponentName, periodMs); 789 return this; 790 } 791 792 /** 793 * Sets the minimum amount of time (in millis) to wait between passes 794 * of power stats collection for any components not configured explicitly. 795 */ setDefaultPowerStatsThrottlePeriodMillis(long periodMs)796 public Builder setDefaultPowerStatsThrottlePeriodMillis(long periodMs) { 797 mDefaultPowerStatsThrottlePeriod = periodMs; 798 return this; 799 } 800 801 /** 802 * Sets the maximum amount of disk space, in bytes, that battery history can 803 * utilize. As this space fills up, the oldest history chunks must be expunged. 804 */ setMaxHistorySizeBytes(int maxHistorySizeBytes)805 public Builder setMaxHistorySizeBytes(int maxHistorySizeBytes) { 806 mMaxHistorySizeBytes = maxHistorySizeBytes; 807 return this; 808 } 809 } 810 } 811 812 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 813 814 private final Runnable mDeferSetCharging = new Runnable() { 815 @Override 816 public void run() { 817 synchronized (BatteryStatsImpl.this) { 818 if (mOnBattery) { 819 // if the device gets unplugged in the time between this runnable being 820 // executed and the lock being taken, we don't want to set charging state 821 return; 822 } 823 boolean changed = setChargingLocked(true); 824 if (changed) { 825 final long uptimeMs = mClock.uptimeMillis(); 826 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 827 mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs); 828 } 829 } 830 } 831 }; 832 833 public final EnergyStatsRetriever mEnergyConsumerRetriever; 834 835 /** 836 * This handler is running on {@link BackgroundThread}. 837 */ 838 final class MyHandler extends Handler { MyHandler(Looper looper)839 public MyHandler(Looper looper) { 840 super(looper, null, true); 841 } 842 843 @Override handleMessage(Message msg)844 public void handleMessage(Message msg) { 845 BatteryCallback cb = mCallback; 846 if (cb == null) { 847 return; 848 } 849 switch (msg.what) { 850 case MSG_REPORT_CPU_UPDATE_NEEDED: 851 cb.batteryNeedsCpuUpdate(); 852 break; 853 case MSG_REPORT_POWER_CHANGE: 854 cb.batteryPowerChanged(msg.arg1 != 0); 855 break; 856 case MSG_REPORT_CHARGING: 857 final String action; 858 synchronized (BatteryStatsImpl.this) { 859 action = mCharging ? BatteryManager.ACTION_CHARGING 860 : BatteryManager.ACTION_DISCHARGING; 861 } 862 Intent intent = new Intent(action); 863 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 864 cb.batterySendBroadcast(intent); 865 break; 866 case MSG_REPORT_RESET_STATS: 867 cb.batteryStatsReset(); 868 } 869 } 870 } 871 postBatteryNeedsCpuUpdateMsg()872 public void postBatteryNeedsCpuUpdateMsg() { 873 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); 874 } 875 876 /** 877 * Update per-freq cpu times for the supplied UID. 878 */ 879 @GuardedBy("this") 880 @SuppressWarnings("GuardedBy") // errorprone false positive on getProcStateTimeCounter 881 @VisibleForTesting updateProcStateCpuTimesLocked(int uid, long elapsedRealtimeMs, long uptimeMs)882 public void updateProcStateCpuTimesLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 883 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 884 return; 885 } 886 887 ensureKernelSingleUidTimeReaderLocked(); 888 889 final Uid u = getUidStatsLocked(uid); 890 891 mNumSingleUidCpuTimeReads++; 892 893 LongArrayMultiStateCounter onBatteryCounter = 894 u.getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 895 LongArrayMultiStateCounter onBatteryScreenOffCounter = 896 u.getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 897 898 899 mKernelSingleUidTimeReader.addDelta(uid, onBatteryCounter, elapsedRealtimeMs); 900 mKernelSingleUidTimeReader.addDelta(uid, onBatteryScreenOffCounter, elapsedRealtimeMs); 901 902 if (u.mChildUids != null) { 903 long[] delta = getCpuTimeInFreqContainer(); 904 int childUidCount = u.mChildUids.size(); 905 for (int j = childUidCount - 1; j >= 0; --j) { 906 LongArrayMultiStateCounter cpuTimeInFreqCounter = 907 u.mChildUids.valueAt(j).cpuTimeInFreqCounter; 908 if (cpuTimeInFreqCounter != null) { 909 mKernelSingleUidTimeReader.addDelta(u.mChildUids.keyAt(j), 910 cpuTimeInFreqCounter, elapsedRealtimeMs, delta); 911 onBatteryCounter.addCounts(delta); 912 onBatteryScreenOffCounter.addCounts(delta); 913 } 914 } 915 } 916 } 917 918 /** 919 * Removes kernel CPU stats for removed UIDs, in the order they were added to the 920 * mPendingRemovedUids queue. 921 */ 922 @GuardedBy("this") 923 @SuppressWarnings("GuardedBy") // errorprone false positive on removeLocked clearPendingRemovedUidsLocked()924 public void clearPendingRemovedUidsLocked() { 925 long cutOffTimeMs = mClock.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; 926 while (!mPendingRemovedUids.isEmpty() 927 && mPendingRemovedUids.peek().getUidRemovalTimestamp() < cutOffTimeMs) { 928 mPendingRemovedUids.poll().removeLocked(); 929 } 930 } 931 932 /** 933 * When the battery/screen state changes, we don't attribute the cpu times to any process 934 * but we still need to take snapshots of all uids to get correct deltas later on. 935 */ 936 @SuppressWarnings("GuardedBy") // errorprone false positive on getProcStateTimeCounter updateCpuTimesForAllUids()937 public void updateCpuTimesForAllUids() { 938 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 939 mCpuPowerStatsCollector.schedule(); 940 return; 941 } 942 943 synchronized (BatteryStatsImpl.this) { 944 if (!trackPerProcStateCpuTimes()) { 945 return; 946 } 947 948 ensureKernelSingleUidTimeReaderLocked(); 949 950 // TODO(b/197162116): just get a list of UIDs 951 final SparseArray<long[]> allUidCpuFreqTimesMs = 952 mCpuUidFreqTimeReader.getAllUidCpuFreqTimeMs(); 953 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) { 954 final int uid = allUidCpuFreqTimesMs.keyAt(i); 955 final int parentUid = mapUid(uid); 956 final Uid u = getAvailableUidStatsLocked(parentUid); 957 if (u == null) { 958 continue; 959 } 960 961 final int procState = u.mProcessState; 962 if (procState == Uid.PROCESS_STATE_NONEXISTENT) { 963 continue; 964 } 965 966 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 967 final long uptimeMs = mClock.uptimeMillis(); 968 final LongArrayMultiStateCounter onBatteryCounter = 969 u.getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 970 final LongArrayMultiStateCounter onBatteryScreenOffCounter = 971 u.getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 972 973 if (uid == parentUid || Process.isSdkSandboxUid(uid)) { 974 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryCounter, 975 elapsedRealtimeMs); 976 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryScreenOffCounter, 977 elapsedRealtimeMs); 978 } else { 979 Uid.ChildUid childUid = u.getChildUid(uid); 980 if (childUid != null) { 981 final LongArrayMultiStateCounter counter = childUid.cpuTimeInFreqCounter; 982 if (counter != null) { 983 final long[] deltaContainer = getCpuTimeInFreqContainer(); 984 mKernelSingleUidTimeReader.addDelta(uid, counter, elapsedRealtimeMs, 985 deltaContainer); 986 onBatteryCounter.addCounts(deltaContainer); 987 onBatteryScreenOffCounter.addCounts(deltaContainer); 988 } 989 } 990 } 991 } 992 } 993 } 994 995 @GuardedBy("this") ensureKernelSingleUidTimeReaderLocked()996 private void ensureKernelSingleUidTimeReaderLocked() { 997 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU) 998 || mKernelSingleUidTimeReader != null) { 999 return; 1000 } 1001 1002 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader( 1003 mCpuScalingPolicies.getScalingStepCount()); 1004 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.perClusterTimesAvailable() 1005 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable(); 1006 } 1007 1008 public interface ExternalStatsSync { 1009 int UPDATE_CPU = 0x01; 1010 int UPDATE_WIFI = 0x02; 1011 int UPDATE_RADIO = 0x04; 1012 int UPDATE_BT = 0x08; 1013 int UPDATE_RPM = 0x10; 1014 int UPDATE_DISPLAY = 0x20; 1015 int UPDATE_CAMERA = 0x40; 1016 int RESET = 0x80; 1017 1018 int UPDATE_ALL = 1019 UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM | UPDATE_DISPLAY 1020 | UPDATE_CAMERA; 1021 1022 int UPDATE_ON_PROC_STATE_CHANGE = UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT; 1023 1024 int UPDATE_ON_RESET = UPDATE_ALL | RESET; 1025 1026 @IntDef(flag = true, prefix = "UPDATE_", value = { 1027 UPDATE_CPU, 1028 UPDATE_WIFI, 1029 UPDATE_RADIO, 1030 UPDATE_BT, 1031 UPDATE_RPM, 1032 UPDATE_DISPLAY, 1033 UPDATE_CAMERA, 1034 UPDATE_ALL, 1035 }) 1036 @Retention(RetentionPolicy.SOURCE) 1037 public @interface ExternalUpdateFlag { 1038 } 1039 1040 /** 1041 * Schedules a sync of kernel metrics in accordance with the specified flags. 1042 */ scheduleSync(String reason, @ExternalUpdateFlag int flags)1043 void scheduleSync(String reason, @ExternalUpdateFlag int flags); 1044 1045 /** 1046 * Schedules a CPU stats sync after a UID removal. 1047 */ scheduleCpuSyncDueToRemovedUid(int uid)1048 void scheduleCpuSyncDueToRemovedUid(int uid); 1049 1050 /** 1051 * Schedule a sync because of a screen state change. 1052 */ scheduleSyncDueToScreenStateChange(@xternalUpdateFlag int flags, boolean onBattery, boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates)1053 void scheduleSyncDueToScreenStateChange(@ExternalUpdateFlag int flags, boolean onBattery, 1054 boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates); 1055 1056 /** 1057 * Schedules a sync after a wakelock state change 1058 */ scheduleCpuSyncDueToWakelockChange(long delayMillis)1059 void scheduleCpuSyncDueToWakelockChange(long delayMillis); 1060 1061 /** 1062 * Canceles any pending sync due to a wakelock state change 1063 */ cancelCpuSyncDueToWakelockChange()1064 void cancelCpuSyncDueToWakelockChange(); 1065 1066 /** Schedule removal of UIDs corresponding to a removed user */ scheduleCleanupDueToRemovedUser(int userId)1067 void scheduleCleanupDueToRemovedUser(int userId); 1068 /** Schedule a sync because of a process state change */ scheduleSyncDueToProcessStateChange(int flags, long delayMillis)1069 void scheduleSyncDueToProcessStateChange(int flags, long delayMillis); 1070 } 1071 1072 public Handler mHandler; 1073 private ExternalStatsSync mExternalSync = null; 1074 @VisibleForTesting 1075 protected UserInfoProvider mUserInfoProvider = null; 1076 1077 private BatteryCallback mCallback; 1078 1079 /** 1080 * Mapping child uids to their parent uid. 1081 */ 1082 @VisibleForTesting 1083 protected final PowerStatsUidResolver mPowerStatsUidResolver; 1084 1085 /** 1086 * The statistics we have collected organized by uids. 1087 */ 1088 private final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 1089 1090 // A set of pools of currently active timers. When a timer is queried, we will divide the 1091 // elapsed time by the number of active timers to arrive at that timer's share of the time. 1092 // In order to do this, we must refresh each timer whenever the number of active timers 1093 // changes. 1094 @VisibleForTesting 1095 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 1096 private final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 1097 private final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 1098 private final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 1099 private final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 1100 private final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 1101 private final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 1102 private final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 1103 private final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 1104 private final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = 1105 new SparseArray<>(); 1106 private final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 1107 private final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 1108 private final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 1109 private final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 1110 private final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 1111 1112 // Last partial timers we use for distributing CPU usage. 1113 @VisibleForTesting 1114 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 1115 1116 // These are the objects that will want to do something when the device 1117 // is unplugged from power. 1118 protected final TimeBase mOnBatteryTimeBase = new TimeBase(true); 1119 1120 // These are the objects that will want to do something when the device 1121 // is unplugged from power *and* the screen is off or doze. 1122 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true); 1123 1124 private boolean mSystemReady; 1125 private boolean mShuttingDown; 1126 1127 private final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 1128 private final BatteryHistoryStepDetailsProvider mStepDetailsProvider = 1129 new BatteryHistoryStepDetailsProvider(this); 1130 1131 private boolean mHaveBatteryLevel = false; 1132 private boolean mBatteryPluggedIn; 1133 private long mBatteryPluggedInRealTimeMs = 0; 1134 private int mBatteryStatus; 1135 private int mBatteryLevel; 1136 private int mBatteryPlugType; 1137 private int mBatteryChargeUah; 1138 private int mBatteryHealth; 1139 private int mBatteryTemperature; 1140 private int mBatteryVoltageMv; 1141 1142 @Nullable 1143 private final BatteryHistoryDirectory mBatteryHistoryDirectory; 1144 @NonNull 1145 private final BatteryStatsHistory mHistory; 1146 1147 int mStartCount; 1148 1149 /** 1150 * Set to true when a reset occurs, informing us that the next time BatteryExternalStatsWorker 1151 * gives us data, we mustn't process it since this data includes pre-reset-period data. 1152 */ 1153 @GuardedBy("this") 1154 boolean mIgnoreNextExternalStats = false; 1155 1156 long mStartClockTimeMs; 1157 String mStartPlatformVersion; 1158 String mEndPlatformVersion; 1159 1160 long mUptimeUs; 1161 long mUptimeStartUs; 1162 long mRealtimeUs; 1163 long mRealtimeStartUs; 1164 long mMonotonicStartTime; 1165 long mMonotonicEndTime = MonotonicClock.UNDEFINED; 1166 1167 int mWakeLockNesting; 1168 boolean mWakeLockImportant; 1169 public boolean mRecordAllHistory; 1170 boolean mNoAutoReset; 1171 1172 /** 1173 * Overall screen state. For multidisplay devices, this represents the current highest screen 1174 * state of the displays. 1175 */ 1176 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 1177 protected int mScreenState = Display.STATE_UNKNOWN; 1178 /** 1179 * Overall screen on timer. For multidisplay devices, this represents the time spent with at 1180 * least one display in the screen on state. 1181 */ 1182 StopwatchTimer mScreenOnTimer; 1183 /** 1184 * Overall screen doze timer. For multidisplay devices, this represents the time spent with 1185 * screen doze being the highest screen state. 1186 */ 1187 StopwatchTimer mScreenDozeTimer; 1188 /** 1189 * Overall screen brightness bin. For multidisplay devices, this represents the current 1190 * brightest screen. 1191 */ 1192 int mScreenBrightnessBin = -1; 1193 /** 1194 * Overall screen brightness timers. For multidisplay devices, the {@link mScreenBrightnessBin} 1195 * timer will be active at any given time 1196 */ 1197 final StopwatchTimer[] mScreenBrightnessTimer = 1198 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 1199 1200 boolean mPretendScreenOff; 1201 1202 private static class DisplayBatteryStats { 1203 /** 1204 * Per display screen state. 1205 */ 1206 public int screenState = Display.STATE_UNKNOWN; 1207 /** 1208 * Per display screen on timers. 1209 */ 1210 public StopwatchTimer screenOnTimer; 1211 /** 1212 * Per display screen doze timers. 1213 */ 1214 public StopwatchTimer screenDozeTimer; 1215 /** 1216 * Per display screen brightness bins. 1217 */ 1218 public int screenBrightnessBin = -1; 1219 /** 1220 * Per display screen brightness timers. 1221 */ 1222 public StopwatchTimer[] screenBrightnessTimers = 1223 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 1224 /** 1225 * Per display screen state the last time {@link #updateDisplayEnergyConsumerStatsLocked} 1226 * was called. 1227 */ 1228 public int screenStateAtLastEnergyMeasurement = Display.STATE_UNKNOWN; 1229 DisplayBatteryStats(Clock clock, TimeBase timeBase)1230 DisplayBatteryStats(Clock clock, TimeBase timeBase) { 1231 screenOnTimer = new StopwatchTimer(clock, null, -1, null, 1232 timeBase); 1233 screenDozeTimer = new StopwatchTimer(clock, null, -1, null, 1234 timeBase); 1235 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1236 screenBrightnessTimers[i] = new StopwatchTimer(clock, null, -100 - i, null, 1237 timeBase); 1238 } 1239 } 1240 1241 /** 1242 * Reset display timers. 1243 */ reset(long elapsedRealtimeUs)1244 public void reset(long elapsedRealtimeUs) { 1245 screenOnTimer.reset(false, elapsedRealtimeUs); 1246 screenDozeTimer.reset(false, elapsedRealtimeUs); 1247 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1248 screenBrightnessTimers[i].reset(false, elapsedRealtimeUs); 1249 } 1250 } 1251 1252 /** 1253 * Write data to summary parcel 1254 */ writeSummaryToParcel(Parcel out, long elapsedRealtimeUs)1255 public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { 1256 screenOnTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1257 screenDozeTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1258 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1259 screenBrightnessTimers[i].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1260 } 1261 } 1262 1263 /** 1264 * Read data from summary parcel 1265 */ readSummaryFromParcel(Parcel in)1266 public void readSummaryFromParcel(Parcel in) { 1267 screenOnTimer.readSummaryFromParcelLocked(in); 1268 screenDozeTimer.readSummaryFromParcelLocked(in); 1269 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 1270 screenBrightnessTimers[i].readSummaryFromParcelLocked(in); 1271 } 1272 } 1273 } 1274 1275 DisplayBatteryStats[] mPerDisplayBatteryStats; 1276 1277 private int mDisplayMismatchWtfCount = 0; 1278 1279 boolean mInteractive; 1280 StopwatchTimer mInteractiveTimer; 1281 1282 boolean mPowerSaveModeEnabled; 1283 StopwatchTimer mPowerSaveModeEnabledTimer; 1284 1285 boolean mDeviceIdling; 1286 StopwatchTimer mDeviceIdlingTimer; 1287 1288 boolean mDeviceLightIdling; 1289 StopwatchTimer mDeviceLightIdlingTimer; 1290 1291 int mDeviceIdleMode; 1292 long mLastIdleTimeStartMs; 1293 long mLongestLightIdleTimeMs; 1294 long mLongestFullIdleTimeMs; 1295 StopwatchTimer mDeviceIdleModeLightTimer; 1296 StopwatchTimer mDeviceIdleModeFullTimer; 1297 1298 boolean mPhoneOn; 1299 StopwatchTimer mPhoneOnTimer; 1300 1301 int mAudioOnNesting; 1302 StopwatchTimer mAudioOnTimer; 1303 1304 int mVideoOnNesting; 1305 StopwatchTimer mVideoOnTimer; 1306 1307 int mFlashlightOnNesting; 1308 StopwatchTimer mFlashlightOnTimer; 1309 1310 int mCameraOnNesting; 1311 StopwatchTimer mCameraOnTimer; 1312 1313 private static final int USB_DATA_UNKNOWN = 0; 1314 private static final int USB_DATA_DISCONNECTED = 1; 1315 private static final int USB_DATA_CONNECTED = 2; 1316 int mUsbDataState = USB_DATA_UNKNOWN; 1317 1318 int mGpsSignalQualityBin = -1; 1319 final StopwatchTimer[] mGpsSignalQualityTimer = 1320 new StopwatchTimer[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS]; 1321 1322 int mPhoneSignalStrengthBin = -1; 1323 int mPhoneSignalStrengthBinRaw = -1; 1324 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 1325 new StopwatchTimer[CELL_SIGNAL_STRENGTH_LEVEL_COUNT]; 1326 1327 StopwatchTimer mPhoneSignalScanningTimer; 1328 1329 int mPhoneDataConnectionType = -1; 1330 final StopwatchTimer[] mPhoneDataConnectionsTimer = 1331 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 1332 1333 int mNrState = -1; 1334 StopwatchTimer mNrNsaTimer; 1335 1336 @RadioAccessTechnology 1337 int mActiveRat = RADIO_ACCESS_TECHNOLOGY_OTHER; 1338 1339 private static class RadioAccessTechnologyBatteryStats { 1340 /** 1341 * This RAT is currently being used. 1342 */ 1343 private boolean mActive = false; 1344 /** 1345 * Current active frequency range for this RAT. 1346 */ 1347 @ServiceState.FrequencyRange 1348 private int mFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN; 1349 /** 1350 * Current signal strength for this RAT. 1351 */ 1352 private int mSignalStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1353 /** 1354 * Timers for each combination of frequency range and signal strength. 1355 */ 1356 public final StopwatchTimer[][] perStateTimers; 1357 /** 1358 * Counters tracking the time (in milliseconds) spent transmitting data in a given state. 1359 */ 1360 @Nullable 1361 private LongSamplingCounter[][] mPerStateTxDurationMs = null; 1362 /** 1363 * Counters tracking the time (in milliseconds) spent receiving data in at given frequency. 1364 */ 1365 @Nullable 1366 private LongSamplingCounter[] mPerFrequencyRxDurationMs = null; 1367 RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase)1368 RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase) { 1369 perStateTimers = 1370 new StopwatchTimer[freqCount][CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 1371 for (int i = 0; i < freqCount; i++) { 1372 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1373 perStateTimers[i][j] = new StopwatchTimer(clock, null, -1, null, timeBase); 1374 } 1375 } 1376 } 1377 1378 /** 1379 * Note this RAT is currently being used. 1380 */ noteActive(boolean active, long elapsedRealtimeMs)1381 public void noteActive(boolean active, long elapsedRealtimeMs) { 1382 if (mActive == active) return; 1383 mActive = active; 1384 if (mActive) { 1385 perStateTimers[mFrequencyRange][mSignalStrength].startRunningLocked( 1386 elapsedRealtimeMs); 1387 } else { 1388 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked( 1389 elapsedRealtimeMs); 1390 } 1391 } 1392 1393 /** 1394 * Note current frequency range has changed. 1395 */ noteFrequencyRange(@erviceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs)1396 public void noteFrequencyRange(@ServiceState.FrequencyRange int frequencyRange, 1397 long elapsedRealtimeMs) { 1398 if (mFrequencyRange == frequencyRange) return; 1399 1400 if (!mActive) { 1401 // RAT not in use, note the frequency change and move on. 1402 mFrequencyRange = frequencyRange; 1403 return; 1404 } 1405 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked(elapsedRealtimeMs); 1406 perStateTimers[frequencyRange][mSignalStrength].startRunningLocked(elapsedRealtimeMs); 1407 mFrequencyRange = frequencyRange; 1408 } 1409 1410 /** 1411 * Note current signal strength has changed. 1412 */ noteSignalStrength(int signalStrength, long elapsedRealtimeMs)1413 public void noteSignalStrength(int signalStrength, long elapsedRealtimeMs) { 1414 if (mSignalStrength == signalStrength) return; 1415 1416 if (!mActive) { 1417 // RAT not in use, note the signal strength change and move on. 1418 mSignalStrength = signalStrength; 1419 return; 1420 } 1421 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked(elapsedRealtimeMs); 1422 perStateTimers[mFrequencyRange][signalStrength].startRunningLocked(elapsedRealtimeMs); 1423 mSignalStrength = signalStrength; 1424 } 1425 1426 /** 1427 * Returns the duration in milliseconds spent in a given state since the last mark. 1428 */ getTimeSinceMark(@erviceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)1429 public long getTimeSinceMark(@ServiceState.FrequencyRange int frequencyRange, 1430 int signalStrength, long elapsedRealtimeMs) { 1431 return perStateTimers[frequencyRange][signalStrength].getTimeSinceMarkLocked( 1432 elapsedRealtimeMs * 1000) / 1000; 1433 } 1434 1435 /** 1436 * Set mark for all timers. 1437 */ setMark(long elapsedRealtimeMs)1438 public void setMark(long elapsedRealtimeMs) { 1439 final int size = perStateTimers.length; 1440 for (int i = 0; i < size; i++) { 1441 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1442 perStateTimers[i][j].setMark(elapsedRealtimeMs); 1443 } 1444 } 1445 } 1446 1447 /** 1448 * Returns numbers of frequencies tracked for this RAT. 1449 */ getFrequencyRangeCount()1450 public int getFrequencyRangeCount() { 1451 return perStateTimers.length; 1452 } 1453 1454 /** 1455 * Add TX time for a given state. 1456 */ incrementTxDuration(@erviceState.FrequencyRange int frequencyRange, int signalStrength, long durationMs)1457 public void incrementTxDuration(@ServiceState.FrequencyRange int frequencyRange, 1458 int signalStrength, long durationMs) { 1459 getTxDurationCounter(frequencyRange, signalStrength, true).addCountLocked(durationMs); 1460 } 1461 1462 /** 1463 * Add TX time for a given frequency. 1464 */ incrementRxDuration(@erviceState.FrequencyRange int frequencyRange, long durationMs)1465 public void incrementRxDuration(@ServiceState.FrequencyRange int frequencyRange, 1466 long durationMs) { 1467 getRxDurationCounter(frequencyRange, true).addCountLocked(durationMs); 1468 } 1469 1470 /** 1471 * Reset radio access technology timers and counts. 1472 */ reset(long elapsedRealtimeUs)1473 public void reset(long elapsedRealtimeUs) { 1474 final int size = perStateTimers.length; 1475 for (int i = 0; i < size; i++) { 1476 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1477 perStateTimers[i][j].reset(false, elapsedRealtimeUs); 1478 if (mPerStateTxDurationMs == null) continue; 1479 mPerStateTxDurationMs[i][j].reset(false, elapsedRealtimeUs); 1480 } 1481 if (mPerFrequencyRxDurationMs == null) continue; 1482 mPerFrequencyRxDurationMs[i].reset(false, elapsedRealtimeUs); 1483 } 1484 } 1485 1486 /** 1487 * Write data to summary parcel 1488 */ writeSummaryToParcel(Parcel out, long elapsedRealtimeUs)1489 public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { 1490 final int freqCount = perStateTimers.length; 1491 out.writeInt(freqCount); 1492 out.writeInt(CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS); 1493 for (int i = 0; i < freqCount; i++) { 1494 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1495 perStateTimers[i][j].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1496 } 1497 } 1498 1499 if (mPerStateTxDurationMs == null) { 1500 out.writeInt(0); 1501 } else { 1502 out.writeInt(1); 1503 for (int i = 0; i < freqCount; i++) { 1504 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1505 mPerStateTxDurationMs[i][j].writeSummaryFromParcelLocked(out); 1506 } 1507 } 1508 } 1509 1510 if (mPerFrequencyRxDurationMs == null) { 1511 out.writeInt(0); 1512 } else { 1513 out.writeInt(1); 1514 for (int i = 0; i < freqCount; i++) { 1515 mPerFrequencyRxDurationMs[i].writeSummaryFromParcelLocked(out); 1516 } 1517 } 1518 } 1519 1520 /** 1521 * Read data from summary parcel 1522 */ readSummaryFromParcel(Parcel in)1523 public void readSummaryFromParcel(Parcel in) { 1524 final int oldFreqCount = in.readInt(); 1525 final int oldSignalStrengthCount = in.readInt(); 1526 final int currFreqCount = perStateTimers.length; 1527 final int currSignalStrengthCount = CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; 1528 1529 for (int freq = 0; freq < oldFreqCount; freq++) { 1530 for (int strength = 0; strength < oldSignalStrengthCount; strength++) { 1531 if (freq >= currFreqCount || strength >= currSignalStrengthCount) { 1532 // Mismatch with the summary parcel. Consume the data but don't use it. 1533 final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, 1534 new TimeBase()); 1535 // Consume perStateTimers data. 1536 temp.readSummaryFromParcelLocked(in); 1537 } else { 1538 perStateTimers[freq][strength].readSummaryFromParcelLocked(in); 1539 } 1540 } 1541 } 1542 1543 if (in.readInt() == 1) { 1544 for (int freq = 0; freq < oldFreqCount; freq++) { 1545 for (int strength = 0; strength < oldSignalStrengthCount; strength++) { 1546 if (freq >= currFreqCount || strength >= currSignalStrengthCount) { 1547 // Mismatch with the summary parcel. Consume the data but don't use it. 1548 final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, 1549 new TimeBase()); 1550 // Consume mPerStateTxDurationMs data. 1551 temp.readSummaryFromParcelLocked(in); 1552 } 1553 getTxDurationCounter(freq, strength, true).readSummaryFromParcelLocked(in); 1554 } 1555 } 1556 } 1557 1558 if (in.readInt() == 1) { 1559 for (int freq = 0; freq < oldFreqCount; freq++) { 1560 if (freq >= currFreqCount) { 1561 // Mismatch with the summary parcel. Consume the data but don't use it. 1562 final StopwatchTimer 1563 temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); 1564 // Consume mPerFrequencyRxDurationMs data. 1565 temp.readSummaryFromParcelLocked(in); 1566 continue; 1567 } 1568 getRxDurationCounter(freq, true).readSummaryFromParcelLocked(in); 1569 } 1570 } 1571 } 1572 getTxDurationCounter( @erviceState.FrequencyRange int frequencyRange, int signalStrength, boolean make)1573 private LongSamplingCounter getTxDurationCounter( 1574 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, boolean make) { 1575 if (mPerStateTxDurationMs == null) { 1576 if (!make) return null; 1577 1578 final int freqCount = getFrequencyRangeCount(); 1579 final int signalStrengthCount = perStateTimers[0].length; 1580 final TimeBase timeBase = perStateTimers[0][0].mTimeBase; 1581 mPerStateTxDurationMs = new LongSamplingCounter[freqCount][signalStrengthCount]; 1582 for (int freq = 0; freq < freqCount; freq++) { 1583 for (int strength = 0; strength < signalStrengthCount; strength++) { 1584 mPerStateTxDurationMs[freq][strength] = new LongSamplingCounter(timeBase); 1585 } 1586 } 1587 } 1588 if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { 1589 Slog.w(TAG, "Unexpected frequency range (" + frequencyRange 1590 + ") requested in getTxDurationCounter"); 1591 return null; 1592 } 1593 if (signalStrength < 0 || signalStrength >= perStateTimers[0].length) { 1594 Slog.w(TAG, "Unexpected signal strength (" + signalStrength 1595 + ") requested in getTxDurationCounter"); 1596 return null; 1597 } 1598 return mPerStateTxDurationMs[frequencyRange][signalStrength]; 1599 } 1600 getRxDurationCounter( @erviceState.FrequencyRange int frequencyRange, boolean make)1601 private LongSamplingCounter getRxDurationCounter( 1602 @ServiceState.FrequencyRange int frequencyRange, boolean make) { 1603 if (mPerFrequencyRxDurationMs == null) { 1604 if (!make) return null; 1605 1606 final int freqCount = getFrequencyRangeCount(); 1607 final TimeBase timeBase = perStateTimers[0][0].mTimeBase; 1608 mPerFrequencyRxDurationMs = new LongSamplingCounter[freqCount]; 1609 for (int freq = 0; freq < freqCount; freq++) { 1610 mPerFrequencyRxDurationMs[freq] = new LongSamplingCounter(timeBase); 1611 } 1612 } 1613 if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { 1614 Slog.w(TAG, "Unexpected frequency range (" + frequencyRange 1615 + ") requested in getRxDurationCounter"); 1616 return null; 1617 } 1618 return mPerFrequencyRxDurationMs[frequencyRange]; 1619 } 1620 } 1621 1622 /** 1623 * Number of frequency ranges, keep in sync with {@link ServiceState.FrequencyRange} 1624 */ 1625 private static final int NR_FREQUENCY_COUNT = 5; 1626 1627 RadioAccessTechnologyBatteryStats[] mPerRatBatteryStats = 1628 new RadioAccessTechnologyBatteryStats[RADIO_ACCESS_TECHNOLOGY_COUNT]; 1629 1630 @GuardedBy("this") getRatBatteryStatsLocked( @adioAccessTechnology int rat)1631 private RadioAccessTechnologyBatteryStats getRatBatteryStatsLocked( 1632 @RadioAccessTechnology int rat) { 1633 RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 1634 if (stats == null) { 1635 final int freqCount = rat == RADIO_ACCESS_TECHNOLOGY_NR ? NR_FREQUENCY_COUNT : 1; 1636 stats = new RadioAccessTechnologyBatteryStats(freqCount, mClock, mOnBatteryTimeBase); 1637 mPerRatBatteryStats[rat] = stats; 1638 } 1639 return stats; 1640 } 1641 1642 final LongSamplingCounter[] mNetworkByteActivityCounters = 1643 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 1644 1645 final LongSamplingCounter[] mNetworkPacketActivityCounters = 1646 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 1647 1648 /** 1649 * The WiFi Overall wakelock timer 1650 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 1651 * since addition of per UID timers would not result in an accurate value due to overlapp of 1652 * per uid wakelock timers 1653 */ 1654 StopwatchTimer mWifiMulticastWakelockTimer; 1655 1656 /** 1657 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 1658 */ 1659 ControllerActivityCounterImpl mWifiActivity; 1660 1661 /** 1662 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 1663 */ 1664 ControllerActivityCounterImpl mBluetoothActivity; 1665 1666 /** 1667 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 1668 */ 1669 ControllerActivityCounterImpl mModemActivity; 1670 1671 /** 1672 * Whether the device supports WiFi controller energy reporting. This is set to true on 1673 * the first WiFi energy report. See {@link #mWifiActivity}. 1674 */ 1675 boolean mHasWifiReporting = false; 1676 1677 /** 1678 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 1679 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 1680 */ 1681 boolean mHasBluetoothReporting = false; 1682 1683 /** 1684 * Whether the device supports Modem controller energy reporting. This is set to true on 1685 * the first Modem energy report. See {@link #mModemActivity}. 1686 */ 1687 boolean mHasModemReporting = false; 1688 1689 boolean mWifiOn; 1690 StopwatchTimer mWifiOnTimer; 1691 1692 boolean mGlobalWifiRunning; 1693 StopwatchTimer mGlobalWifiRunningTimer; 1694 1695 int mWifiState = -1; 1696 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 1697 1698 int mWifiSupplState = -1; 1699 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 1700 1701 int mWifiSignalStrengthBin = -1; 1702 final StopwatchTimer[] mWifiSignalStrengthsTimer = 1703 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 1704 1705 StopwatchTimer mWifiActiveTimer; 1706 1707 int mBluetoothScanNesting; 1708 StopwatchTimer mBluetoothScanTimer; 1709 1710 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1711 long mMobileRadioActiveStartTimeMs; 1712 StopwatchTimer mMobileRadioActiveTimer; 1713 StopwatchTimer mMobileRadioActivePerAppTimer; 1714 LongSamplingCounter mMobileRadioActiveAdjustedTime; 1715 LongSamplingCounter mMobileRadioActiveUnknownTime; 1716 LongSamplingCounter mMobileRadioActiveUnknownCount; 1717 1718 /** 1719 * The soonest the Mobile Radio stats can be updated due to a mobile radio power state change 1720 * after it was last updated. 1721 */ 1722 @VisibleForTesting 1723 protected static final long MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS = 1000 * 60 * 10; 1724 1725 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1726 1727 @GuardedBy("this") 1728 @VisibleForTesting 1729 protected @Nullable EnergyConsumerStats.Config mEnergyConsumerStatsConfig; 1730 1731 /** 1732 * Accumulated global (generally, device-wide total) charge consumption of various consumers 1733 * while on battery. 1734 * Its '<b>custom</b> power buckets' correspond to the 1735 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 1736 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 1737 * 1738 * If energy consumer data is completely unavailable this will be null. 1739 */ 1740 @GuardedBy("this") 1741 @VisibleForTesting 1742 @Nullable 1743 protected EnergyConsumerStats mGlobalEnergyConsumerStats; 1744 /** Bluetooth Power calculator for attributing bluetooth EnergyConsumer to uids */ 1745 @Nullable BluetoothPowerCalculator mBluetoothPowerCalculator = null; 1746 /** Cpu Power calculator for attributing cpu EnergyConsumer to uids */ 1747 @Nullable CpuPowerCalculator mCpuPowerCalculator = null; 1748 /** Mobile Radio Power calculator for attributing radio EnergyConsumer to uids */ 1749 @Nullable MobileRadioPowerCalculator mMobileRadioPowerCalculator = null; 1750 /** Wifi Power calculator for attributing wifi EnergyConsumer to uids */ 1751 @Nullable WifiPowerCalculator mWifiPowerCalculator = null; 1752 1753 /** 1754 * These provide time bases that discount the time the device is plugged 1755 * in to power. 1756 */ 1757 boolean mOnBattery; 1758 @VisibleForTesting 1759 protected boolean mOnBatteryInternal; 1760 1761 /** 1762 * External reporting of whether the device is actually charging. 1763 */ 1764 boolean mCharging = true; 1765 1766 /* 1767 * These keep track of battery levels (1-100) at the last unplug event. 1768 */ 1769 int mDischargeUnplugLevel; 1770 int mDischargePlugLevel; 1771 int mDischargeCurrentLevel; 1772 int mLowDischargeAmountSinceCharge; 1773 int mHighDischargeAmountSinceCharge; 1774 int mDischargeScreenOnUnplugLevel; 1775 int mDischargeScreenOffUnplugLevel; 1776 int mDischargeScreenDozeUnplugLevel; 1777 int mDischargeAmountScreenOn; 1778 int mDischargeAmountScreenOnSinceCharge; 1779 int mDischargeAmountScreenOff; 1780 int mDischargeAmountScreenOffSinceCharge; 1781 int mDischargeAmountScreenDoze; 1782 int mDischargeAmountScreenDozeSinceCharge; 1783 1784 private LongSamplingCounter mDischargeScreenOffCounter; 1785 private LongSamplingCounter mDischargeScreenDozeCounter; 1786 private LongSamplingCounter mDischargeCounter; 1787 private LongSamplingCounter mDischargeLightDozeCounter; 1788 private LongSamplingCounter mDischargeDeepDozeCounter; 1789 1790 static final int MAX_LEVEL_STEPS = 200; 1791 1792 int mInitStepMode = 0; 1793 int mCurStepMode = 0; 1794 int mModStepMode = 0; 1795 1796 int mLastDischargeStepLevel; 1797 int mMinDischargeStepLevel; 1798 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1799 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1800 ArrayList<PackageChange> mDailyPackageChanges; 1801 1802 int mLastChargeStepLevel; 1803 int mMaxChargeStepLevel; 1804 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1805 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1806 1807 static final int MAX_DAILY_ITEMS = 10; 1808 1809 long mDailyStartTimeMs = 0; 1810 long mNextMinDailyDeadlineMs = 0; 1811 long mNextMaxDailyDeadlineMs = 0; 1812 1813 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 1814 1815 long mLastWriteTimeMs = 0; // Milliseconds 1816 1817 private int mPhoneServiceState = -1; 1818 private int mPhoneServiceStateRaw = -1; 1819 private int mPhoneSimStateRaw = -1; 1820 1821 private int mNumConnectivityChange; 1822 1823 private int mEstimatedBatteryCapacityMah = -1; 1824 1825 private int mLastLearnedBatteryCapacityUah = -1; 1826 private int mMinLearnedBatteryCapacityUah = -1; 1827 private int mMaxLearnedBatteryCapacityUah = -1; 1828 1829 private long mBatteryTimeToFullSeconds = -1; 1830 1831 private long[] mTmpCpuTimeInFreq; 1832 1833 /** 1834 * Times spent by the system server threads handling incoming binder requests. 1835 */ 1836 private LongSamplingCounterArray mBinderThreadCpuTimesUs; 1837 1838 private final PowerProfile mPowerProfile; 1839 1840 @VisibleForTesting 1841 @GuardedBy("this") 1842 protected final Constants mConstants; 1843 1844 @VisibleForTesting 1845 protected final BatteryStatsConfig mBatteryStatsConfig; 1846 1847 @GuardedBy("this") 1848 private AlarmManager mAlarmManager = null; 1849 1850 private final AlarmManager.OnAlarmListener mLongPlugInAlarmHandler = () -> 1851 mHandler.post(() -> { 1852 synchronized (BatteryStatsImpl.this) { 1853 maybeResetWhilePluggedInLocked(); 1854 } 1855 }); 1856 1857 /* 1858 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 1859 * recording their times when on-battery (regardless of screen state). 1860 */ 1861 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 1862 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 1863 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 1864 1865 @Override getRpmStats()1866 public Map<String, ? extends Timer> getRpmStats() { 1867 return mRpmStats; 1868 } 1869 1870 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 1871 @Override getScreenOffRpmStats()1872 public Map<String, ? extends Timer> getScreenOffRpmStats() { 1873 return mScreenOffRpmStats; 1874 } 1875 1876 /* 1877 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 1878 */ 1879 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 1880 getKernelWakelockStats()1881 public Map<String, ? extends Timer> getKernelWakelockStats() { 1882 return mKernelWakelockStats; 1883 } 1884 1885 @Override getWakeLockStats()1886 public WakeLockStats getWakeLockStats() { 1887 final long realtimeMs = mClock.elapsedRealtime(); 1888 List<WakeLockStats.WakeLock> uidWakeLockStats = new ArrayList<>(); 1889 List<WakeLockStats.WakeLock> uidAggregatedWakeLockStats = new ArrayList<>(); 1890 for (int i = mUidStats.size() - 1; i >= 0; i--) { 1891 final Uid uid = mUidStats.valueAt(i); 1892 1893 // Converts unaggregated wakelocks. 1894 final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = 1895 uid.mWakelockStats.getMap(); 1896 for (int j = wakelockStats.size() - 1; j >= 0; j--) { 1897 final String name = wakelockStats.keyAt(j); 1898 final Uid.Wakelock wakelock = (Uid.Wakelock) wakelockStats.valueAt(j); 1899 final WakeLockStats.WakeLock wakeLockItem = 1900 createWakeLock(uid, name, /* isAggregated= */ false, wakelock.mTimerPartial, 1901 realtimeMs); 1902 if (wakeLockItem != null) { 1903 uidWakeLockStats.add(wakeLockItem); 1904 } 1905 } 1906 1907 // Converts aggregated wakelocks. 1908 final WakeLockStats.WakeLock aggregatedWakeLockItem = 1909 createWakeLock( 1910 uid, 1911 WakeLockStats.WakeLock.NAME_AGGREGATED, 1912 /* isAggregated= */ true, 1913 uid.mAggregatedPartialWakelockTimer, 1914 realtimeMs); 1915 if (aggregatedWakeLockItem != null) { 1916 uidAggregatedWakeLockStats.add(aggregatedWakeLockItem); 1917 } 1918 } 1919 return new WakeLockStats(uidWakeLockStats, uidAggregatedWakeLockStats); 1920 } 1921 1922 // Returns a valid {@code WakeLockStats.WakeLock} or null. createWakeLock( Uid uid, String name, boolean isAggregated, DualTimer timer, final long realtimeMs)1923 private WakeLockStats.WakeLock createWakeLock( 1924 Uid uid, String name, boolean isAggregated, DualTimer timer, final long realtimeMs) { 1925 if (timer == null) { 1926 return null; 1927 } 1928 // Uses the primary timer for total wakelock data and used the sub timer for background 1929 // wakelock data. 1930 final WakeLockStats.WakeLockData totalWakeLockData = createWakeLockData(timer, realtimeMs); 1931 final WakeLockStats.WakeLockData backgroundWakeLockData = 1932 createWakeLockData(timer.getSubTimer(), realtimeMs); 1933 1934 return WakeLockStats.WakeLock.isDataValid(totalWakeLockData, backgroundWakeLockData) 1935 ? new WakeLockStats.WakeLock( 1936 uid.getUid(), 1937 name, 1938 isAggregated, 1939 totalWakeLockData, 1940 backgroundWakeLockData) : null; 1941 } 1942 1943 @NonNull createWakeLockData( DurationTimer timer, final long realtimeMs)1944 private WakeLockStats.WakeLockData createWakeLockData( 1945 DurationTimer timer, final long realtimeMs) { 1946 if (timer == null) { 1947 return WakeLockStats.WakeLockData.EMPTY; 1948 } 1949 final long totalTimeLockHeldMs = 1950 timer.getTotalTimeLocked(realtimeMs * 1000, STATS_SINCE_CHARGED) / 1000; 1951 if (totalTimeLockHeldMs == 0) { 1952 return WakeLockStats.WakeLockData.EMPTY; 1953 } 1954 return new WakeLockStats.WakeLockData( 1955 timer.getCountLocked(STATS_SINCE_CHARGED), 1956 totalTimeLockHeldMs, 1957 timer.isRunningLocked() ? timer.getCurrentDurationMsLocked(realtimeMs) : 0); 1958 } 1959 1960 @Override 1961 @GuardedBy("this") getBluetoothBatteryStats()1962 public BluetoothBatteryStats getBluetoothBatteryStats() { 1963 final long elapsedRealtimeUs = mClock.elapsedRealtime() * 1000; 1964 ArrayList<BluetoothBatteryStats.UidStats> uidStats = new ArrayList<>(); 1965 for (int i = mUidStats.size() - 1; i >= 0; i--) { 1966 final Uid uid = mUidStats.valueAt(i); 1967 final Timer scanTimer = uid.getBluetoothScanTimer(); 1968 final long scanTimeMs = 1969 scanTimer != null ? scanTimer.getTotalTimeLocked( 1970 elapsedRealtimeUs, STATS_SINCE_CHARGED) / 1000 : 0; 1971 1972 final Timer unoptimizedScanTimer = uid.getBluetoothUnoptimizedScanTimer(); 1973 final long unoptimizedScanTimeMs = 1974 unoptimizedScanTimer != null ? unoptimizedScanTimer.getTotalTimeLocked( 1975 elapsedRealtimeUs, STATS_SINCE_CHARGED) / 1000 : 0; 1976 1977 final Counter scanResultCounter = uid.getBluetoothScanResultCounter(); 1978 final int scanResultCount = 1979 scanResultCounter != null ? scanResultCounter.getCountLocked( 1980 STATS_SINCE_CHARGED) : 0; 1981 1982 final ControllerActivityCounter counter = uid.getBluetoothControllerActivity(); 1983 final long rxTimeMs = counter != null ? counter.getRxTimeCounter().getCountLocked( 1984 STATS_SINCE_CHARGED) : 0; 1985 final long txTimeMs = counter != null ? counter.getTxTimeCounters()[0].getCountLocked( 1986 STATS_SINCE_CHARGED) : 0; 1987 1988 if (scanTimeMs != 0 || unoptimizedScanTimeMs != 0 || scanResultCount != 0 1989 || rxTimeMs != 0 || txTimeMs != 0) { 1990 uidStats.add(new BluetoothBatteryStats.UidStats(uid.getUid(), 1991 scanTimeMs, 1992 unoptimizedScanTimeMs, 1993 scanResultCount, 1994 rxTimeMs, 1995 txTimeMs)); 1996 } 1997 } 1998 1999 return new BluetoothBatteryStats(uidStats); 2000 } 2001 2002 String mLastWakeupReason = null; 2003 long mLastWakeupUptimeMs = 0; 2004 long mLastWakeupElapsedTimeMs = 0; 2005 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 2006 getWakeupReasonStats()2007 public Map<String, ? extends Timer> getWakeupReasonStats() { 2008 return mWakeupReasonStats; 2009 } 2010 2011 @Override getUahDischarge(int which)2012 public long getUahDischarge(int which) { 2013 return mDischargeCounter.getCountLocked(which); 2014 } 2015 2016 @Override getUahDischargeScreenOff(int which)2017 public long getUahDischargeScreenOff(int which) { 2018 return mDischargeScreenOffCounter.getCountLocked(which); 2019 } 2020 2021 @Override getUahDischargeScreenDoze(int which)2022 public long getUahDischargeScreenDoze(int which) { 2023 return mDischargeScreenDozeCounter.getCountLocked(which); 2024 } 2025 2026 @Override getUahDischargeLightDoze(int which)2027 public long getUahDischargeLightDoze(int which) { 2028 return mDischargeLightDozeCounter.getCountLocked(which); 2029 } 2030 2031 @Override getUahDischargeDeepDoze(int which)2032 public long getUahDischargeDeepDoze(int which) { 2033 return mDischargeDeepDozeCounter.getCountLocked(which); 2034 } 2035 2036 @Override getEstimatedBatteryCapacity()2037 public int getEstimatedBatteryCapacity() { 2038 return mEstimatedBatteryCapacityMah; 2039 } 2040 2041 @Override getLearnedBatteryCapacity()2042 public int getLearnedBatteryCapacity() { 2043 return mLastLearnedBatteryCapacityUah; 2044 } 2045 2046 @Override getMinLearnedBatteryCapacity()2047 public int getMinLearnedBatteryCapacity() { 2048 return mMinLearnedBatteryCapacityUah; 2049 } 2050 2051 @Override getMaxLearnedBatteryCapacity()2052 public int getMaxLearnedBatteryCapacity() { 2053 return mMaxLearnedBatteryCapacityUah; 2054 } 2055 2056 public static class FrameworkStatsLogger { uidProcessStateChanged(int uid, int state)2057 public void uidProcessStateChanged(int uid, int state) { 2058 // TODO(b/155216561): It is possible for isolated uids to be in a higher 2059 // state than its parent uid. We should track the highest state within the union of host 2060 // and isolated uids rather than only the parent uid. 2061 FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, 2062 ActivityManager.processStateAmToProto(state)); 2063 } 2064 wakelockStateChanged(int uid, WorkChain wc, String name, int procState, boolean acquired, int powerManagerWakeLockLevel)2065 public void wakelockStateChanged(int uid, WorkChain wc, String name, 2066 int procState, boolean acquired, int powerManagerWakeLockLevel) { 2067 int event = acquired 2068 ? FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE 2069 : FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE; 2070 if (wc != null) { 2071 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 2072 wc.getTags(), powerManagerWakeLockLevel, name, event, procState); 2073 } else { 2074 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, uid, 2075 null, powerManagerWakeLockLevel, name, event, procState); 2076 } 2077 } 2078 kernelWakeupReported(long deltaUptimeUs, String lastWakeupReason, long lastWakeupElapsedTimeMs)2079 public void kernelWakeupReported(long deltaUptimeUs, String lastWakeupReason, 2080 long lastWakeupElapsedTimeMs) { 2081 FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, lastWakeupReason, 2082 /* duration_usec */ deltaUptimeUs, lastWakeupElapsedTimeMs); 2083 } 2084 gpsScanStateChanged(int uid, WorkChain workChain, boolean stateOn)2085 public void gpsScanStateChanged(int uid, WorkChain workChain, boolean stateOn) { 2086 int event = stateOn 2087 ? FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON 2088 : FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF; 2089 if (workChain != null) { 2090 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 2091 workChain.getUids(), workChain.getTags(), event); 2092 } else { 2093 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 2094 uid, null, event); 2095 } 2096 } 2097 batterySaverModeChanged(boolean enabled)2098 public void batterySaverModeChanged(boolean enabled) { 2099 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 2100 enabled 2101 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 2102 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 2103 } 2104 deviceIdlingModeStateChanged(int mode)2105 public void deviceIdlingModeStateChanged(int mode) { 2106 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, mode); 2107 } 2108 deviceIdleModeStateChanged(int mode)2109 public void deviceIdleModeStateChanged(int mode) { 2110 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 2111 } 2112 chargingStateChanged(int status)2113 public void chargingStateChanged(int status) { 2114 FrameworkStatsLog.write(FrameworkStatsLog.CHARGING_STATE_CHANGED, status); 2115 } 2116 pluggedStateChanged(int plugType)2117 public void pluggedStateChanged(int plugType) { 2118 FrameworkStatsLog.write(FrameworkStatsLog.PLUGGED_STATE_CHANGED, plugType); 2119 } 2120 batteryLevelChanged(int level)2121 public void batteryLevelChanged(int level) { 2122 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_LEVEL_CHANGED, level); 2123 } 2124 phoneServiceStateChanged(int state, int simState, int strengthBin)2125 public void phoneServiceStateChanged(int state, int simState, int strengthBin) { 2126 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 2127 simState, strengthBin); 2128 } 2129 phoneSignalStrengthChanged(int strengthBin)2130 public void phoneSignalStrengthChanged(int strengthBin) { 2131 FrameworkStatsLog.write( 2132 FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 2133 } 2134 2135 /** 2136 * Records a statsd event when the batterystats config file is written to disk. 2137 */ writeCommitSysConfigFile(String fileName, long durationMs)2138 public void writeCommitSysConfigFile(String fileName, long durationMs) { 2139 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(fileName, 2140 durationMs); 2141 } 2142 } 2143 2144 private final FrameworkStatsLogger mFrameworkStatsLogger; 2145 initKernelStatsReaders()2146 private void initKernelStatsReaders() { 2147 if (!isKernelStatsAvailable()) { 2148 return; 2149 } 2150 2151 mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(true, mClock); 2152 mCpuUidFreqTimeReader = new KernelCpuUidFreqTimeReader(true, mClock); 2153 mCpuUidActiveTimeReader = new KernelCpuUidActiveTimeReader(true, mClock); 2154 mCpuUidClusterTimeReader = new KernelCpuUidClusterTimeReader(true, mClock); 2155 mKernelWakelockReader = new KernelWakelockReader(); 2156 if (!Flags.disableSystemServicePowerAttr()) { 2157 mSystemServerCpuThreadReader = SystemServerCpuThreadReader.create(); 2158 } 2159 mKernelMemoryBandwidthStats = new KernelMemoryBandwidthStats(); 2160 mTmpRailStats = new RailStats(); 2161 } 2162 2163 private class PowerStatsCollectorInjector implements CpuPowerStatsCollector.Injector, 2164 ScreenPowerStatsCollector.Injector, MobileRadioPowerStatsCollector.Injector, 2165 WifiPowerStatsCollector.Injector, BluetoothPowerStatsCollector.Injector, 2166 EnergyConsumerPowerStatsCollector.Injector, WakelockPowerStatsCollector.Injector { 2167 private PackageManager mPackageManager; 2168 private PowerStatsCollector.ConsumedEnergyRetriever mConsumedEnergyRetriever; 2169 private NetworkStatsManager mNetworkStatsManager; 2170 private TelephonyManager mTelephonyManager; 2171 private WifiManager mWifiManager; 2172 private BluetoothPowerStatsCollector.BluetoothStatsRetriever mBluetoothStatsRetriever; 2173 2174 @SuppressLint("WifiManagerPotentialLeak") setContext(Context context)2175 void setContext(Context context) { 2176 mPackageManager = context.getPackageManager(); 2177 mConsumedEnergyRetriever = new PowerStatsCollector.ConsumedEnergyRetrieverImpl( 2178 LocalServices.getService(PowerStatsInternal.class), () -> mBatteryVoltageMv); 2179 mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class); 2180 mTelephonyManager = 2181 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 2182 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 2183 mBluetoothStatsRetriever = new BluetoothStatsRetrieverImpl( 2184 context.getSystemService(BluetoothManager.class)); 2185 } 2186 2187 @Override getHandler()2188 public Handler getHandler() { 2189 return mHandler; 2190 } 2191 2192 @Override getClock()2193 public Clock getClock() { 2194 return mClock; 2195 } 2196 2197 @Override getPowerStatsCollectionThrottlePeriod(String powerComponentName)2198 public long getPowerStatsCollectionThrottlePeriod(String powerComponentName) { 2199 return mBatteryStatsConfig.getPowerStatsThrottlePeriod(powerComponentName); 2200 } 2201 2202 @Override getUidResolver()2203 public PowerStatsUidResolver getUidResolver() { 2204 return mPowerStatsUidResolver; 2205 } 2206 2207 @Override getCpuScalingPolicies()2208 public CpuScalingPolicies getCpuScalingPolicies() { 2209 return mCpuScalingPolicies; 2210 } 2211 2212 @Override getPowerProfile()2213 public PowerProfile getPowerProfile() { 2214 return mPowerProfile; 2215 } 2216 2217 @Override getKernelCpuStatsReader()2218 public CpuPowerStatsCollector.KernelCpuStatsReader getKernelCpuStatsReader() { 2219 return new CpuPowerStatsCollector.KernelCpuStatsReader(); 2220 } 2221 2222 @Override getPackageManager()2223 public PackageManager getPackageManager() { 2224 return mPackageManager; 2225 } 2226 2227 @Override getConsumedEnergyRetriever()2228 public PowerStatsCollector.ConsumedEnergyRetriever getConsumedEnergyRetriever() { 2229 return mConsumedEnergyRetriever; 2230 } 2231 2232 @Override getScreenUsageTimeRetriever()2233 public ScreenPowerStatsCollector.ScreenUsageTimeRetriever getScreenUsageTimeRetriever() { 2234 return mScreenUsageTimeRetriever; 2235 } 2236 2237 @Override getDisplayCount()2238 public int getDisplayCount() { 2239 return BatteryStatsImpl.this.getDisplayCount(); 2240 } 2241 2242 @Override getMobileNetworkStatsSupplier()2243 public Supplier<NetworkStats> getMobileNetworkStatsSupplier() { 2244 return () -> readMobileNetworkStatsLocked(mNetworkStatsManager); 2245 } 2246 2247 @Override getWifiNetworkStatsSupplier()2248 public Supplier<NetworkStats> getWifiNetworkStatsSupplier() { 2249 return () -> readWifiNetworkStatsLocked(mNetworkStatsManager); 2250 } 2251 2252 @Override getWifiStatsRetriever()2253 public WifiPowerStatsCollector.WifiStatsRetriever getWifiStatsRetriever() { 2254 return mWifiStatsRetriever; 2255 } 2256 2257 @Override getTelephonyManager()2258 public TelephonyManager getTelephonyManager() { 2259 return mTelephonyManager; 2260 } 2261 2262 @Override getWifiManager()2263 public WifiManager getWifiManager() { 2264 return mWifiManager; 2265 } 2266 2267 @Override getBluetoothStatsRetriever()2268 public BluetoothPowerStatsCollector.BluetoothStatsRetriever getBluetoothStatsRetriever() { 2269 return mBluetoothStatsRetriever; 2270 } 2271 2272 @Override getCallDurationSupplier()2273 public LongSupplier getCallDurationSupplier() { 2274 return () -> mPhoneOnTimer.getTotalTimeLocked(mClock.elapsedRealtime() * 1000, 2275 STATS_SINCE_CHARGED) / 1000; 2276 } 2277 2278 @Override getPhoneSignalScanDurationSupplier()2279 public LongSupplier getPhoneSignalScanDurationSupplier() { 2280 return () -> mPhoneSignalScanningTimer.getTotalTimeLocked( 2281 mClock.elapsedRealtime() * 1000, STATS_SINCE_CHARGED) / 1000; 2282 } 2283 2284 @Override 2285 public WakelockPowerStatsCollector.WakelockDurationRetriever getWakelockDurationRetriever()2286 getWakelockDurationRetriever() { 2287 return mWakelockDurationRetriever; 2288 } 2289 2290 @Override networkStatsDelta(NetworkStats stats, NetworkStats oldStats)2291 public NetworkStats networkStatsDelta(NetworkStats stats, NetworkStats oldStats) { 2292 return BatteryStatsImpl.this.networkStatsDelta(stats, oldStats); 2293 } 2294 } 2295 2296 private final PowerStatsCollectorInjector mPowerStatsCollectorInjector = 2297 new PowerStatsCollectorInjector(); 2298 2299 /** 2300 * TimeBase observer. 2301 */ 2302 public interface TimeBaseObs { onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2303 void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2304 void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); 2305 2306 /** 2307 * Reset the observer's state, returns true if the timer/counter is inactive 2308 * so it can be destroyed. 2309 * @param detachIfReset detach if true, no-op if false. 2310 * @return Returns true if the timer/counter is inactive and can be destroyed. 2311 */ reset(boolean detachIfReset)2312 default boolean reset(boolean detachIfReset) { 2313 return reset(detachIfReset, SystemClock.elapsedRealtime() * 1000); 2314 } 2315 2316 /** 2317 * @see #reset(boolean) 2318 * @param detachIfReset detach if true, no-op if false. 2319 * @param elapsedRealtimeUs the timestamp when this reset is actually reequested 2320 * @return Returns true if the timer/counter is inactive and can be destroyed. 2321 */ reset(boolean detachIfReset, long elapsedRealtimeUs)2322 boolean reset(boolean detachIfReset, long elapsedRealtimeUs); 2323 2324 /** 2325 * Detach the observer from TimeBase. 2326 */ detach()2327 void detach(); 2328 } 2329 2330 // methods are protected not private to be VisibleForTesting 2331 public static class TimeBase { 2332 protected final Collection<TimeBaseObs> mObservers; 2333 2334 // All below time metrics are in microseconds. 2335 protected long mUptimeUs; 2336 protected long mRealtimeUs; 2337 2338 protected boolean mRunning; 2339 2340 protected long mPastUptimeUs; 2341 protected long mUptimeStartUs; 2342 protected long mPastRealtimeUs; 2343 protected long mRealtimeStartUs; 2344 protected long mUnpluggedUptimeUs; 2345 protected long mUnpluggedRealtimeUs; 2346 dump(PrintWriter pw, String prefix)2347 public void dump(PrintWriter pw, String prefix) { 2348 StringBuilder sb = new StringBuilder(128); 2349 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 2350 sb.setLength(0); 2351 sb.append(prefix); 2352 sb.append("mUptime="); 2353 formatTimeMs(sb, mUptimeUs / 1000); 2354 pw.println(sb.toString()); 2355 sb.setLength(0); 2356 sb.append(prefix); 2357 sb.append("mRealtime="); 2358 formatTimeMs(sb, mRealtimeUs / 1000); 2359 pw.println(sb.toString()); 2360 sb.setLength(0); 2361 sb.append(prefix); 2362 sb.append("mPastUptime="); 2363 formatTimeMs(sb, mPastUptimeUs / 1000); sb.append("mUptimeStart="); 2364 formatTimeMs(sb, mUptimeStartUs / 1000); 2365 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptimeUs / 1000); 2366 pw.println(sb.toString()); 2367 sb.setLength(0); 2368 sb.append(prefix); 2369 sb.append("mPastRealtime="); 2370 formatTimeMs(sb, mPastRealtimeUs / 1000); sb.append("mRealtimeStart="); 2371 formatTimeMs(sb, mRealtimeStartUs / 1000); 2372 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtimeUs / 1000); 2373 pw.println(sb.toString()); 2374 } 2375 /** 2376 * The mObservers of TimeBase in BatteryStatsImpl object can contain up to 20k entries. 2377 * The mObservers of TimeBase in BatteryStatsImpl.Uid object only contains a few or tens of 2378 * entries. 2379 * mObservers must have good performance on add(), remove(), also be memory efficient. 2380 * This is why we provide isLongList parameter for long and short list user cases. 2381 * @param isLongList If true, use HashSet for mObservers list. 2382 * If false, use ArrayList for mObservers list. 2383 */ TimeBase(boolean isLongList)2384 public TimeBase(boolean isLongList) { 2385 mObservers = isLongList ? new HashSet<>() : new ArrayList<>(); 2386 } 2387 TimeBase()2388 public TimeBase() { 2389 this(false); 2390 } 2391 add(TimeBaseObs observer)2392 public void add(TimeBaseObs observer) { 2393 mObservers.add(observer); 2394 } 2395 remove(TimeBaseObs observer)2396 public void remove(TimeBaseObs observer) { 2397 mObservers.remove(observer); 2398 } 2399 hasObserver(TimeBaseObs observer)2400 public boolean hasObserver(TimeBaseObs observer) { 2401 return mObservers.contains(observer); 2402 } 2403 init(long uptimeUs, long elapsedRealtimeUs)2404 public void init(long uptimeUs, long elapsedRealtimeUs) { 2405 mRealtimeUs = 0; 2406 mUptimeUs = 0; 2407 mPastUptimeUs = 0; 2408 mPastRealtimeUs = 0; 2409 mUptimeStartUs = uptimeUs; 2410 mRealtimeStartUs = elapsedRealtimeUs; 2411 mUnpluggedUptimeUs = getUptime(mUptimeStartUs); 2412 mUnpluggedRealtimeUs = getRealtime(mRealtimeStartUs); 2413 } 2414 reset(long uptimeUs, long elapsedRealtimeUs)2415 public void reset(long uptimeUs, long elapsedRealtimeUs) { 2416 if (!mRunning) { 2417 mPastUptimeUs = 0; 2418 mPastRealtimeUs = 0; 2419 } else { 2420 mUptimeStartUs = uptimeUs; 2421 mRealtimeStartUs = elapsedRealtimeUs; 2422 // TODO: Since mUptimeStartUs was just reset and we are running, getUptime will 2423 // just return mPastUptimeUs. Also, are we sure we don't want to reset that? 2424 mUnpluggedUptimeUs = getUptime(uptimeUs); 2425 // TODO: likewise. 2426 mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 2427 } 2428 } 2429 computeUptime(long curTimeUs, int which)2430 public long computeUptime(long curTimeUs, int which) { 2431 return mUptimeUs + getUptime(curTimeUs); 2432 } 2433 computeRealtime(long curTimeUs, int which)2434 public long computeRealtime(long curTimeUs, int which) { 2435 return mRealtimeUs + getRealtime(curTimeUs); 2436 } 2437 getUptime(long curTimeUs)2438 public long getUptime(long curTimeUs) { 2439 long time = mPastUptimeUs; 2440 if (mRunning) { 2441 time += curTimeUs - mUptimeStartUs; 2442 } 2443 return time; 2444 } 2445 getRealtime(long curTimeUs)2446 public long getRealtime(long curTimeUs) { 2447 long time = mPastRealtimeUs; 2448 if (mRunning) { 2449 time += curTimeUs - mRealtimeStartUs; 2450 } 2451 return time; 2452 } 2453 getUptimeStart()2454 public long getUptimeStart() { 2455 return mUptimeStartUs; 2456 } 2457 getRealtimeStart()2458 public long getRealtimeStart() { 2459 return mRealtimeStartUs; 2460 } 2461 isRunning()2462 public boolean isRunning() { 2463 return mRunning; 2464 } 2465 setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs)2466 public boolean setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs) { 2467 if (mRunning != running) { 2468 mRunning = running; 2469 if (running) { 2470 mUptimeStartUs = uptimeUs; 2471 mRealtimeStartUs = elapsedRealtimeUs; 2472 long batteryUptimeUs = mUnpluggedUptimeUs = getUptime(uptimeUs); 2473 long batteryRealtimeUs = mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 2474 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 2475 // Iterator object, here is an exception because mObservers' type is Collection 2476 // instead of list. 2477 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 2478 while (iter.hasNext()) { 2479 iter.next().onTimeStarted( 2480 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 2481 } 2482 } else { 2483 mPastUptimeUs += uptimeUs - mUptimeStartUs; 2484 mPastRealtimeUs += elapsedRealtimeUs - mRealtimeStartUs; 2485 long batteryUptimeUs = getUptime(uptimeUs); 2486 long batteryRealtimeUs = getRealtime(elapsedRealtimeUs); 2487 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 2488 // Iterator object, here is an exception because mObservers' type is Collection 2489 // instead of list. 2490 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 2491 while (iter.hasNext()) { 2492 iter.next().onTimeStopped( 2493 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 2494 } 2495 } 2496 return true; 2497 } 2498 return false; 2499 } 2500 readSummaryFromParcel(Parcel in)2501 public void readSummaryFromParcel(Parcel in) { 2502 mUptimeUs = in.readLong(); 2503 mRealtimeUs = in.readLong(); 2504 } 2505 writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)2506 public void writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 2507 out.writeLong(computeUptime(uptimeUs, STATS_SINCE_CHARGED)); 2508 out.writeLong(computeRealtime(elapsedRealtimeUs, STATS_SINCE_CHARGED)); 2509 } 2510 readFromParcel(Parcel in)2511 public void readFromParcel(Parcel in) { 2512 mRunning = false; 2513 mUptimeUs = in.readLong(); 2514 mPastUptimeUs = in.readLong(); 2515 mUptimeStartUs = in.readLong(); 2516 mRealtimeUs = in.readLong(); 2517 mPastRealtimeUs = in.readLong(); 2518 mRealtimeStartUs = in.readLong(); 2519 mUnpluggedUptimeUs = in.readLong(); 2520 mUnpluggedRealtimeUs = in.readLong(); 2521 } 2522 writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)2523 public void writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 2524 final long runningUptime = getUptime(uptimeUs); 2525 final long runningRealtime = getRealtime(elapsedRealtimeUs); 2526 out.writeLong(mUptimeUs); 2527 out.writeLong(runningUptime); 2528 out.writeLong(mUptimeStartUs); 2529 out.writeLong(mRealtimeUs); 2530 out.writeLong(runningRealtime); 2531 out.writeLong(mRealtimeStartUs); 2532 out.writeLong(mUnpluggedUptimeUs); 2533 out.writeLong(mUnpluggedRealtimeUs); 2534 } 2535 } 2536 2537 /** 2538 * State for keeping track of counting information. 2539 */ 2540 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 2541 final AtomicInteger mCount = new AtomicInteger(); 2542 final TimeBase mTimeBase; 2543 Counter(TimeBase timeBase, Parcel in)2544 public Counter(TimeBase timeBase, Parcel in) { 2545 mTimeBase = timeBase; 2546 mCount.set(in.readInt()); 2547 timeBase.add(this); 2548 } 2549 Counter(TimeBase timeBase)2550 public Counter(TimeBase timeBase) { 2551 mTimeBase = timeBase; 2552 timeBase.add(this); 2553 } 2554 writeToParcel(Parcel out)2555 public void writeToParcel(Parcel out) { 2556 out.writeInt(mCount.get()); 2557 } 2558 2559 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2560 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2561 } 2562 2563 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2564 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2565 } 2566 2567 @Override getCountLocked(int which)2568 public int getCountLocked(int which) { 2569 return mCount.get(); 2570 } 2571 logState(Printer pw, String prefix)2572 public void logState(Printer pw, String prefix) { 2573 pw.println(prefix + "mCount=" + mCount.get()); 2574 } 2575 2576 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()2577 public void stepAtomic() { 2578 if (mTimeBase.isRunning()) { 2579 mCount.incrementAndGet(); 2580 } 2581 } 2582 addAtomic(int delta)2583 void addAtomic(int delta) { 2584 if (mTimeBase.isRunning()) { 2585 mCount.addAndGet(delta); 2586 } 2587 } 2588 2589 /** 2590 * Clear state of this counter. 2591 */ 2592 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2593 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2594 mCount.set(0); 2595 if (detachIfReset) { 2596 detach(); 2597 } 2598 return true; 2599 } 2600 2601 @Override detach()2602 public void detach() { 2603 mTimeBase.remove(this); 2604 } 2605 2606 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)2607 public void writeSummaryFromParcelLocked(Parcel out) { 2608 out.writeInt(mCount.get()); 2609 } 2610 2611 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)2612 public void readSummaryFromParcelLocked(Parcel in) { 2613 mCount.set(in.readInt()); 2614 } 2615 } 2616 2617 @VisibleForTesting 2618 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 2619 final TimeBase mTimeBase; 2620 public long[] mCounts; 2621 LongSamplingCounterArray(TimeBase timeBase, Parcel in)2622 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 2623 mTimeBase = timeBase; 2624 mCounts = in.createLongArray(); 2625 timeBase.add(this); 2626 } 2627 LongSamplingCounterArray(TimeBase timeBase)2628 public LongSamplingCounterArray(TimeBase timeBase) { 2629 mTimeBase = timeBase; 2630 timeBase.add(this); 2631 } 2632 writeToParcel(Parcel out)2633 private void writeToParcel(Parcel out) { 2634 out.writeLongArray(mCounts); 2635 } 2636 2637 @Override onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs)2638 public void onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs) { 2639 } 2640 2641 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2642 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2643 } 2644 2645 @Override getCountsLocked(int which)2646 public long[] getCountsLocked(int which) { 2647 return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); 2648 } 2649 2650 @Override logState(Printer pw, String prefix)2651 public void logState(Printer pw, String prefix) { 2652 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); 2653 } 2654 addCountLocked(long[] counts)2655 public void addCountLocked(long[] counts) { 2656 addCountLocked(counts, mTimeBase.isRunning()); 2657 } 2658 addCountLocked(long[] counts, boolean isRunning)2659 public void addCountLocked(long[] counts, boolean isRunning) { 2660 if (counts == null) { 2661 return; 2662 } 2663 if (isRunning) { 2664 if (mCounts == null) { 2665 mCounts = new long[counts.length]; 2666 } 2667 for (int i = 0; i < counts.length; ++i) { 2668 mCounts[i] += counts[i]; 2669 } 2670 } 2671 } 2672 getSize()2673 public int getSize() { 2674 return mCounts == null ? 0 : mCounts.length; 2675 } 2676 2677 /** 2678 * Clear state of this counter. 2679 */ 2680 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2681 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2682 if (mCounts != null) { 2683 Arrays.fill(mCounts, 0); 2684 } 2685 if (detachIfReset) { 2686 detach(); 2687 } 2688 return true; 2689 } 2690 2691 @Override detach()2692 public void detach() { 2693 mTimeBase.remove(this); 2694 } 2695 writeSummaryToParcelLocked(Parcel out)2696 private void writeSummaryToParcelLocked(Parcel out) { 2697 out.writeLongArray(mCounts); 2698 } 2699 readSummaryFromParcelLocked(Parcel in)2700 private void readSummaryFromParcelLocked(Parcel in) { 2701 mCounts = in.createLongArray(); 2702 } 2703 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)2704 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 2705 if (counterArray != null) { 2706 out.writeInt(1); 2707 counterArray.writeToParcel(out); 2708 } else { 2709 out.writeInt(0); 2710 } 2711 } 2712 readFromParcel(Parcel in, TimeBase timeBase)2713 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 2714 if (in.readInt() != 0) { 2715 return new LongSamplingCounterArray(timeBase, in); 2716 } else { 2717 return null; 2718 } 2719 } 2720 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)2721 public static void writeSummaryToParcelLocked(Parcel out, 2722 LongSamplingCounterArray counterArray) { 2723 if (counterArray != null) { 2724 out.writeInt(1); 2725 counterArray.writeSummaryToParcelLocked(out); 2726 } else { 2727 out.writeInt(0); 2728 } 2729 } 2730 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)2731 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 2732 TimeBase timeBase) { 2733 if (in.readInt() != 0) { 2734 final LongSamplingCounterArray counterArray 2735 = new LongSamplingCounterArray(timeBase); 2736 counterArray.readSummaryFromParcelLocked(in); 2737 return counterArray; 2738 } else { 2739 return null; 2740 } 2741 } 2742 } 2743 2744 private static class TimeMultiStateCounter extends LongCounter implements TimeBaseObs { 2745 private final TimeBase mTimeBase; 2746 private final LongMultiStateCounter mCounter; 2747 TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs)2748 private TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs) { 2749 this(timeBase, new LongMultiStateCounter(stateCount), timestampMs); 2750 } 2751 TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter, long timestampMs)2752 private TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter, 2753 long timestampMs) { 2754 mTimeBase = timeBase; 2755 mCounter = counter; 2756 mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); 2757 timeBase.add(this); 2758 } 2759 2760 @Nullable readFromParcel(Parcel in, TimeBase timeBase, int stateCount, long timestampMs)2761 private static TimeMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase, 2762 int stateCount, long timestampMs) { 2763 LongMultiStateCounter counter = LongMultiStateCounter.CREATOR.createFromParcel(in); 2764 if (counter.getStateCount() != stateCount) { 2765 return null; 2766 } 2767 return new TimeMultiStateCounter(timeBase, counter, timestampMs); 2768 } 2769 writeToParcel(Parcel out)2770 private void writeToParcel(Parcel out) { 2771 mCounter.writeToParcel(out, 0); 2772 } 2773 2774 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2775 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2776 mCounter.setEnabled(true, elapsedRealtimeUs / 1000); 2777 } 2778 2779 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2780 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2781 mCounter.setEnabled(false, elapsedRealtimeUs / 1000); 2782 } 2783 getStateCount()2784 public int getStateCount() { 2785 return mCounter.getStateCount(); 2786 } 2787 setState(@atteryConsumer.ProcessState int processState, long elapsedRealtimeMs)2788 private void setState(@BatteryConsumer.ProcessState int processState, 2789 long elapsedRealtimeMs) { 2790 mCounter.setState(processState, elapsedRealtimeMs); 2791 } 2792 update(long value, long timestampMs)2793 private long update(long value, long timestampMs) { 2794 return mCounter.updateValue(value, timestampMs); 2795 } 2796 increment(long increment, long timestampMs)2797 private void increment(long increment, long timestampMs) { 2798 mCounter.incrementValue(increment, timestampMs); 2799 } 2800 2801 /** 2802 * Returns accumulated count for the specified state. 2803 */ getCountForProcessState(@atteryConsumer.ProcessState int procState)2804 public long getCountForProcessState(@BatteryConsumer.ProcessState int procState) { 2805 return mCounter.getCount(procState); 2806 } 2807 getTotalCountLocked()2808 public long getTotalCountLocked() { 2809 return mCounter.getTotalCount(); 2810 } 2811 2812 @Override getCountLocked(int statsType)2813 public long getCountLocked(int statsType) { 2814 return getTotalCountLocked(); 2815 } 2816 2817 @Override logState(Printer pw, String prefix)2818 public void logState(Printer pw, String prefix) { 2819 pw.println(prefix + "mCounter=" + mCounter); 2820 } 2821 2822 /** 2823 * Clears state of this counter. 2824 */ 2825 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2826 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2827 mCounter.reset(); 2828 if (detachIfReset) { 2829 detach(); 2830 } 2831 return true; 2832 } 2833 2834 @Override detach()2835 public void detach() { 2836 mTimeBase.remove(this); 2837 } 2838 } 2839 2840 private static class TimeInFreqMultiStateCounter implements TimeBaseObs { 2841 private final TimeBase mTimeBase; 2842 private final LongArrayMultiStateCounter mCounter; 2843 TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount, long timestampMs)2844 private TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount, 2845 long timestampMs) { 2846 this(timeBase, new LongArrayMultiStateCounter(stateCount, cpuFreqCount), timestampMs); 2847 } 2848 TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter, long timestampMs)2849 private TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter, 2850 long timestampMs) { 2851 mTimeBase = timeBase; 2852 mCounter = counter; 2853 mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); 2854 timeBase.add(this); 2855 } 2856 writeToParcel(Parcel out)2857 private void writeToParcel(Parcel out) { 2858 mCounter.writeToParcel(out, 0); 2859 } 2860 2861 @Nullable readFromParcel(Parcel in, TimeBase timeBase, int stateCount, int cpuFreqCount, long timestampMs)2862 private static TimeInFreqMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase, 2863 int stateCount, int cpuFreqCount, long timestampMs) { 2864 // Read the object from the Parcel, whether it's usable or not 2865 LongArrayMultiStateCounter counter = 2866 LongArrayMultiStateCounter.CREATOR.createFromParcel(in); 2867 if (counter.getStateCount() != stateCount 2868 || counter.getArrayLength() != cpuFreqCount) { 2869 return null; 2870 } 2871 return new TimeInFreqMultiStateCounter(timeBase, counter, timestampMs); 2872 } 2873 2874 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2875 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2876 mCounter.setEnabled(true, elapsedRealtimeUs / 1000); 2877 } 2878 2879 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2880 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2881 mCounter.setEnabled(false, elapsedRealtimeUs / 1000); 2882 } 2883 getCounter()2884 public LongArrayMultiStateCounter getCounter() { 2885 return mCounter; 2886 } 2887 getStateCount()2888 public int getStateCount() { 2889 return mCounter.getStateCount(); 2890 } 2891 setTrackingEnabled(boolean enabled, long timestampMs)2892 public void setTrackingEnabled(boolean enabled, long timestampMs) { 2893 mCounter.setEnabled(enabled && mTimeBase.isRunning(), timestampMs); 2894 } 2895 setState(int uidRunningState, long elapsedRealtimeMs)2896 private void setState(int uidRunningState, long elapsedRealtimeMs) { 2897 mCounter.setState(uidRunningState, elapsedRealtimeMs); 2898 } 2899 2900 /** 2901 * Returns accumulated counts for the specified state, or false if all counts are zero. 2902 */ getCountsLocked(long[] counts, int procState)2903 public boolean getCountsLocked(long[] counts, int procState) { 2904 if (counts.length != mCounter.getArrayLength()) { 2905 return false; 2906 } 2907 2908 return mCounter.getCounts(counts, procState); 2909 } 2910 2911 /** 2912 * Clears state of this counter. 2913 */ 2914 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2915 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2916 mCounter.reset(); 2917 if (detachIfReset) { 2918 detach(); 2919 } 2920 return true; 2921 } 2922 2923 @Override detach()2924 public void detach() { 2925 mTimeBase.remove(this); 2926 } 2927 } 2928 2929 @VisibleForTesting 2930 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 2931 final TimeBase mTimeBase; 2932 private long mCount; 2933 LongSamplingCounter(TimeBase timeBase, Parcel in)2934 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 2935 mTimeBase = timeBase; 2936 mCount = in.readLong(); 2937 timeBase.add(this); 2938 } 2939 LongSamplingCounter(TimeBase timeBase)2940 public LongSamplingCounter(TimeBase timeBase) { 2941 mTimeBase = timeBase; 2942 timeBase.add(this); 2943 } 2944 writeToParcel(Parcel out)2945 public void writeToParcel(Parcel out) { 2946 out.writeLong(mCount); 2947 } 2948 2949 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2950 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2951 } 2952 2953 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2954 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2955 } 2956 getCountLocked(int which)2957 public long getCountLocked(int which) { 2958 return mCount; 2959 } 2960 2961 @Override getCountForProcessState(int procState)2962 public long getCountForProcessState(int procState) { 2963 if (procState == BatteryConsumer.PROCESS_STATE_ANY) { 2964 return getCountLocked(STATS_SINCE_CHARGED); 2965 } 2966 return 0; 2967 } 2968 2969 @Override logState(Printer pw, String prefix)2970 public void logState(Printer pw, String prefix) { 2971 pw.println(prefix + "mCount=" + mCount); 2972 } 2973 addCountLocked(long count)2974 public void addCountLocked(long count) { 2975 addCountLocked(count, mTimeBase.isRunning()); 2976 } 2977 addCountLocked(long count, boolean isRunning)2978 public void addCountLocked(long count, boolean isRunning) { 2979 if (isRunning) { 2980 mCount += count; 2981 } 2982 } 2983 2984 /** 2985 * Clear state of this counter. 2986 */ 2987 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2988 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2989 mCount = 0; 2990 if (detachIfReset) { 2991 detach(); 2992 } 2993 return true; 2994 } 2995 2996 @Override detach()2997 public void detach() { 2998 mTimeBase.remove(this); 2999 } 3000 writeSummaryFromParcelLocked(Parcel out)3001 public void writeSummaryFromParcelLocked(Parcel out) { 3002 out.writeLong(mCount); 3003 } 3004 readSummaryFromParcelLocked(Parcel in)3005 public void readSummaryFromParcelLocked(Parcel in) { 3006 mCount = in.readLong(); 3007 } 3008 } 3009 3010 /** 3011 * State for keeping track of timing information. 3012 */ 3013 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 3014 protected final Clock mClock; 3015 protected final int mType; 3016 protected final TimeBase mTimeBase; 3017 3018 protected int mCount; 3019 3020 // Times are in microseconds for better accuracy when dividing by the 3021 // lock count, and are in "battery realtime" units. 3022 3023 /** 3024 * The total time we have accumulated since the start of the original 3025 * boot, to the last time something interesting happened in the 3026 * current run. 3027 */ 3028 protected long mTotalTimeUs; 3029 3030 /** 3031 * The total time this timer has been running until the latest mark has been set. 3032 * Subtract this from mTotalTimeUs to get the time spent running since the mark was set. 3033 */ 3034 protected long mTimeBeforeMarkUs; 3035 3036 /** 3037 * Constructs from a parcel. 3038 * @param type 3039 * @param timeBase 3040 * @param in 3041 */ Timer(Clock clock, int type, TimeBase timeBase, Parcel in)3042 public Timer(Clock clock, int type, TimeBase timeBase, Parcel in) { 3043 mClock = clock; 3044 mType = type; 3045 mTimeBase = timeBase; 3046 3047 mCount = in.readInt(); 3048 mTotalTimeUs = in.readLong(); 3049 mTimeBeforeMarkUs = in.readLong(); 3050 timeBase.add(this); 3051 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTimeUs); 3052 } 3053 Timer(Clock clock, int type, TimeBase timeBase)3054 public Timer(Clock clock, int type, TimeBase timeBase) { 3055 mClock = clock; 3056 mType = type; 3057 mTimeBase = timeBase; 3058 timeBase.add(this); 3059 } 3060 writeToParcel(Parcel out, long elapsedRealtimeUs)3061 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3062 if (DEBUG) { 3063 Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 3064 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 3065 elapsedRealtimeUs)); 3066 } 3067 out.writeInt(computeCurrentCountLocked()); 3068 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 3069 elapsedRealtimeUs)); 3070 out.writeLong(mTimeBeforeMarkUs); 3071 } 3072 computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)3073 protected abstract long computeRunTimeLocked(long curBatteryRealtime, 3074 long elapsedRealtimeUs); 3075 computeCurrentCountLocked()3076 protected abstract int computeCurrentCountLocked(); 3077 3078 /** 3079 * Clear state of this timer. Returns true if the timer is inactive 3080 * so can be completely dropped. 3081 */ 3082 @Override reset(boolean detachIfReset)3083 public boolean reset(boolean detachIfReset) { 3084 return reset(detachIfReset, mClock.elapsedRealtime() * 1000); 3085 } 3086 3087 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )3088 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 3089 mTotalTimeUs = mTimeBeforeMarkUs = 0; 3090 mCount = 0; 3091 if (detachIfReset) { 3092 detach(); 3093 } 3094 return true; 3095 } 3096 3097 @Override detach()3098 public void detach() { 3099 mTimeBase.remove(this); 3100 } 3101 3102 @Override onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, long baseRealtimeUs)3103 public void onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, 3104 long baseRealtimeUs) { 3105 } 3106 3107 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3108 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3109 if (DEBUG && mType < 0) { 3110 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtimeUs 3111 + " old mTotalTime=" + mTotalTimeUs); 3112 } 3113 mTotalTimeUs = computeRunTimeLocked(baseRealtimeUs, elapsedRealtimeUs); 3114 mCount = computeCurrentCountLocked(); 3115 if (DEBUG && mType < 0) { 3116 Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTimeUs); 3117 } 3118 } 3119 3120 /** 3121 * Writes a possibly null Timer to a Parcel. 3122 * 3123 * @param out the Parcel to be written to. 3124 * @param timer a Timer, or null. 3125 */ writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)3126 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 3127 if (timer == null) { 3128 out.writeInt(0); // indicates null 3129 return; 3130 } 3131 out.writeInt(1); // indicates non-null 3132 timer.writeToParcel(out, elapsedRealtimeUs); 3133 } 3134 3135 @Override getTotalTimeLocked(long elapsedRealtimeUs, int which)3136 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 3137 return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 3138 elapsedRealtimeUs); 3139 } 3140 3141 @Override getCountLocked(int which)3142 public int getCountLocked(int which) { 3143 return computeCurrentCountLocked(); 3144 } 3145 3146 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)3147 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 3148 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 3149 elapsedRealtimeUs); 3150 return val - mTimeBeforeMarkUs; 3151 } 3152 3153 @Override logState(Printer pw, String prefix)3154 public void logState(Printer pw, String prefix) { 3155 pw.println(prefix + "mCount=" + mCount); 3156 pw.println(prefix + "mTotalTime=" + mTotalTimeUs); 3157 } 3158 3159 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)3160 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 3161 long runTimeUs = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 3162 elapsedRealtimeUs); 3163 out.writeLong(runTimeUs); 3164 out.writeInt(computeCurrentCountLocked()); 3165 } 3166 readSummaryFromParcelLocked(Parcel in)3167 public void readSummaryFromParcelLocked(Parcel in) { 3168 // Multiply by 1000 for backwards compatibility 3169 mTotalTimeUs = in.readLong(); 3170 mCount = in.readInt(); 3171 // When reading the summary, we set the mark to be the latest information. 3172 mTimeBeforeMarkUs = mTotalTimeUs; 3173 } 3174 } 3175 3176 /** 3177 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 3178 * method. The state of the timer according to its {@link TimeBase} will determine how much 3179 * of the value is recorded. 3180 * 3181 * If the value being recorded resets, {@link #endSample()} can be called in order to 3182 * account for the change. If the value passed in to {@link #update(long, int)} decreased 3183 * between calls, the {@link #endSample()} is automatically called and the new value is 3184 * expected to increase monotonically from that point on. 3185 */ 3186 public static class SamplingTimer extends Timer { 3187 3188 /** 3189 * The most recent reported count from /proc/wakelocks. 3190 */ 3191 int mCurrentReportedCount; 3192 3193 /** 3194 * The reported count from /proc/wakelocks when unplug() was last 3195 * called. 3196 */ 3197 int mBaseReportedCount; 3198 3199 /** 3200 * The most recent reported total_time from /proc/wakelocks. 3201 */ 3202 long mCurrentReportedTotalTimeUs; 3203 3204 /** 3205 * The reported total_time from /proc/wakelocks when unplug() was last 3206 * called. 3207 */ 3208 long mBaseReportedTotalTimeUs; 3209 3210 /** 3211 * Whether we are currently in a discharge cycle. 3212 */ 3213 boolean mTimeBaseRunning; 3214 3215 /** 3216 * Whether we are currently recording reported values. 3217 */ 3218 boolean mTrackingReportedValues; 3219 3220 /* 3221 * A sequence counter, incremented once for each update of the stats. 3222 */ 3223 int mUpdateVersion; 3224 3225 @VisibleForTesting SamplingTimer(Clock clock, TimeBase timeBase, Parcel in)3226 public SamplingTimer(Clock clock, TimeBase timeBase, Parcel in) { 3227 super(clock, 0, timeBase, in); 3228 mCurrentReportedCount = in.readInt(); 3229 mBaseReportedCount = in.readInt(); 3230 mCurrentReportedTotalTimeUs = in.readLong(); 3231 mBaseReportedTotalTimeUs = in.readLong(); 3232 mTrackingReportedValues = in.readInt() == 1; 3233 mTimeBaseRunning = timeBase.isRunning(); 3234 } 3235 3236 @VisibleForTesting SamplingTimer(Clock clock, TimeBase timeBase)3237 public SamplingTimer(Clock clock, TimeBase timeBase) { 3238 super(clock, 0, timeBase); 3239 mTrackingReportedValues = false; 3240 mTimeBaseRunning = timeBase.isRunning(); 3241 } 3242 3243 /** 3244 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 3245 * be less than the values used for a previous invocation. 3246 */ endSample()3247 public void endSample() { 3248 endSample(mClock.elapsedRealtime() * 1000); 3249 } 3250 3251 /** 3252 * @see #endSample() 3253 */ endSample(long elapsedRealtimeUs)3254 public void endSample(long elapsedRealtimeUs) { 3255 mTotalTimeUs = computeRunTimeLocked(0 /* unused by us */, elapsedRealtimeUs); 3256 mCount = computeCurrentCountLocked(); 3257 mBaseReportedTotalTimeUs = mCurrentReportedTotalTimeUs = 0; 3258 mBaseReportedCount = mCurrentReportedCount = 0; 3259 mTrackingReportedValues = false; 3260 } 3261 setUpdateVersion(int version)3262 public void setUpdateVersion(int version) { 3263 mUpdateVersion = version; 3264 } 3265 getUpdateVersion()3266 public int getUpdateVersion() { 3267 return mUpdateVersion; 3268 } 3269 3270 /** 3271 * Updates the current recorded values. These are meant to be monotonically increasing 3272 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 3273 * 3274 * If the values being recorded have been reset, the monotonically increasing requirement 3275 * will be broken. In this case, {@link #endSample()} is automatically called and 3276 * the total value of totalTimeUs and count are recorded, starting a new monotonically 3277 * increasing sample. 3278 * 3279 * @param totalTimeUs total time of sample in microseconds. 3280 * @param count total number of times the event being sampled occurred. 3281 */ update(long totalTimeUs, int count, long elapsedRealtimeUs)3282 public void update(long totalTimeUs, int count, long elapsedRealtimeUs) { 3283 update(totalTimeUs, 0, count, elapsedRealtimeUs); 3284 } 3285 3286 /** 3287 * Updates the current recorded values. See {@link #update(long, int, long)} 3288 * 3289 * @param activeTimeUs Time that the currently active wake lock has been held. 3290 */ update(long totalTimeUs, long activeTimeUs, int count, long elapsedRealtimeUs)3291 public void update(long totalTimeUs, long activeTimeUs, int count, 3292 long elapsedRealtimeUs) { 3293 if (mTimeBaseRunning && !mTrackingReportedValues) { 3294 // Updating the reported value for the first time. If the wake lock is currently 3295 // active, mark the time it was acquired as the base timestamp. 3296 mBaseReportedTotalTimeUs = totalTimeUs - activeTimeUs; 3297 mBaseReportedCount = activeTimeUs == 0 ? count : count - 1; 3298 } 3299 3300 mTrackingReportedValues = true; 3301 3302 if (totalTimeUs < mCurrentReportedTotalTimeUs || count < mCurrentReportedCount) { 3303 endSample(elapsedRealtimeUs); 3304 } 3305 3306 mCurrentReportedTotalTimeUs = totalTimeUs; 3307 mCurrentReportedCount = count; 3308 } 3309 3310 /** 3311 * Adds deltaTime and deltaCount to the current sample. 3312 * 3313 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 3314 * @param deltaCount additional number of times the event being sampled occurred. 3315 */ add(long deltaTimeUs, int deltaCount)3316 public void add(long deltaTimeUs, int deltaCount) { 3317 add(deltaTimeUs, deltaCount, mClock.elapsedRealtime() * 1000); 3318 } 3319 3320 /** 3321 * @see #add(long, int) 3322 */ add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs)3323 public void add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs) { 3324 update(mCurrentReportedTotalTimeUs + deltaTimeUs, mCurrentReportedCount + deltaCount, 3325 elapsedRealtimeUs); 3326 } 3327 3328 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3329 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3330 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3331 if (mTrackingReportedValues) { 3332 mBaseReportedTotalTimeUs = mCurrentReportedTotalTimeUs; 3333 mBaseReportedCount = mCurrentReportedCount; 3334 } 3335 mTimeBaseRunning = true; 3336 } 3337 3338 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3339 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3340 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3341 mTimeBaseRunning = false; 3342 } 3343 3344 @Override logState(Printer pw, String prefix)3345 public void logState(Printer pw, String prefix) { 3346 super.logState(pw, prefix); 3347 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 3348 + " mBaseReportedCount=" + mBaseReportedCount 3349 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTimeUs 3350 + " mBaseReportedTotalTimeUs=" + mBaseReportedTotalTimeUs); 3351 } 3352 3353 @Override computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)3354 protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) { 3355 return mTotalTimeUs + (mTimeBaseRunning && mTrackingReportedValues 3356 ? mCurrentReportedTotalTimeUs - mBaseReportedTotalTimeUs : 0); 3357 } 3358 3359 @Override computeCurrentCountLocked()3360 protected int computeCurrentCountLocked() { 3361 return mCount + (mTimeBaseRunning && mTrackingReportedValues 3362 ? mCurrentReportedCount - mBaseReportedCount : 0); 3363 } 3364 3365 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3366 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3367 super.writeToParcel(out, elapsedRealtimeUs); 3368 out.writeInt(mCurrentReportedCount); 3369 out.writeInt(mBaseReportedCount); 3370 out.writeLong(mCurrentReportedTotalTimeUs); 3371 out.writeLong(mBaseReportedTotalTimeUs); 3372 out.writeInt(mTrackingReportedValues ? 1 : 0); 3373 } 3374 3375 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3376 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3377 super.reset(detachIfReset, elapsedRealtimeUs); 3378 mTrackingReportedValues = false; 3379 mBaseReportedTotalTimeUs = 0; 3380 mBaseReportedCount = 0; 3381 return true; 3382 } 3383 } 3384 3385 /** 3386 * A timer that increments in batches. It does not run for durations, but just jumps 3387 * for a pre-determined amount. 3388 */ 3389 public static class BatchTimer extends Timer { 3390 final Uid mUid; 3391 3392 /** 3393 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 3394 */ 3395 long mLastAddedTimeUs; 3396 3397 /** 3398 * The last duration that we added to the timer. This is in microseconds. 3399 */ 3400 long mLastAddedDurationUs; 3401 3402 /** 3403 * Whether we are currently in a discharge cycle. 3404 */ 3405 boolean mInDischarge; 3406 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase, Parcel in)3407 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase, Parcel in) { 3408 super(clock, type, timeBase, in); 3409 mUid = uid; 3410 mLastAddedTimeUs = in.readLong(); 3411 mLastAddedDurationUs = in.readLong(); 3412 mInDischarge = timeBase.isRunning(); 3413 } 3414 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase)3415 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase) { 3416 super(clock, type, timeBase); 3417 mUid = uid; 3418 mInDischarge = timeBase.isRunning(); 3419 } 3420 3421 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3422 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3423 super.writeToParcel(out, elapsedRealtimeUs); 3424 out.writeLong(mLastAddedTimeUs); 3425 out.writeLong(mLastAddedDurationUs); 3426 } 3427 3428 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3429 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3430 recomputeLastDuration(elapsedRealtimeUs, false); 3431 mInDischarge = false; 3432 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3433 } 3434 3435 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3436 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3437 recomputeLastDuration(elapsedRealtimeUs, false); 3438 mInDischarge = true; 3439 // If we are still within the last added duration, then re-added whatever remains. 3440 if (mLastAddedTimeUs == elapsedRealtimeUs) { 3441 mTotalTimeUs += mLastAddedDurationUs; 3442 } 3443 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3444 } 3445 3446 @Override logState(Printer pw, String prefix)3447 public void logState(Printer pw, String prefix) { 3448 super.logState(pw, prefix); 3449 pw.println(prefix + "mLastAddedTime=" + mLastAddedTimeUs 3450 + " mLastAddedDuration=" + mLastAddedDurationUs); 3451 } 3452 computeOverage(long curTimeUs)3453 private long computeOverage(long curTimeUs) { 3454 if (mLastAddedTimeUs > 0) { 3455 return mLastAddedDurationUs - curTimeUs; 3456 } 3457 return 0; 3458 } 3459 recomputeLastDuration(long curTimeUs, boolean abort)3460 private void recomputeLastDuration(long curTimeUs, boolean abort) { 3461 final long overage = computeOverage(curTimeUs); 3462 if (overage > 0) { 3463 // Aborting before the duration ran out -- roll back the remaining 3464 // duration. Only do this if currently discharging; otherwise we didn't 3465 // actually add the time. 3466 if (mInDischarge) { 3467 mTotalTimeUs -= overage; 3468 } 3469 if (abort) { 3470 mLastAddedTimeUs = 0; 3471 } else { 3472 mLastAddedTimeUs = curTimeUs; 3473 mLastAddedDurationUs -= overage; 3474 } 3475 } 3476 } 3477 addDuration(long durationMs, long elapsedRealtimeMs)3478 public void addDuration(long durationMs, long elapsedRealtimeMs) { 3479 final long nowUs = elapsedRealtimeMs * 1000; 3480 recomputeLastDuration(nowUs, true); 3481 mLastAddedTimeUs = nowUs; 3482 mLastAddedDurationUs = durationMs * 1000; 3483 if (mInDischarge) { 3484 mTotalTimeUs += mLastAddedDurationUs; 3485 mCount++; 3486 } 3487 } 3488 abortLastDuration(long elapsedRealtimeMs)3489 public void abortLastDuration(long elapsedRealtimeMs) { 3490 final long nowUs = elapsedRealtimeMs * 1000; 3491 recomputeLastDuration(nowUs, true); 3492 } 3493 3494 @Override computeCurrentCountLocked()3495 protected int computeCurrentCountLocked() { 3496 return mCount; 3497 } 3498 3499 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)3500 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 3501 final long overage = computeOverage(elapsedRealtimeUs); 3502 if (overage > 0) { 3503 return mTotalTimeUs = overage; 3504 } 3505 return mTotalTimeUs; 3506 } 3507 3508 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3509 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3510 recomputeLastDuration(elapsedRealtimeUs, true); 3511 boolean stillActive = mLastAddedTimeUs == elapsedRealtimeUs; 3512 super.reset(!stillActive && detachIfReset, elapsedRealtimeUs); 3513 return !stillActive; 3514 } 3515 } 3516 3517 3518 /** 3519 * A StopwatchTimer that also tracks the total and max individual 3520 * time spent active according to the given timebase. Whereas 3521 * StopwatchTimer apportions the time amongst all in the pool, 3522 * the total and max durations are not apportioned. 3523 */ 3524 public static class DurationTimer extends StopwatchTimer { 3525 /** 3526 * The time (in ms) that the timer was last acquired or the time base 3527 * last (re-)started. Increasing the nesting depth does not reset this time. 3528 * 3529 * -1 if the timer is currently not running or the time base is not running. 3530 * 3531 * If written to a parcel, the start time is reset, as is mNesting in the base class 3532 * StopwatchTimer. 3533 */ 3534 long mStartTimeMs = -1; 3535 3536 /** 3537 * The longest time period (in ms) that the timer has been active. Not pooled. 3538 */ 3539 long mMaxDurationMs; 3540 3541 /** 3542 * The time (in ms) that that the timer has been active since most recent 3543 * stopRunningLocked() or reset(). Not pooled. 3544 */ 3545 long mCurrentDurationMs; 3546 3547 /** 3548 * The total time (in ms) that that the timer has been active since most recent reset() 3549 * prior to the current startRunningLocked. This is the sum of all past currentDurations 3550 * (but not including the present currentDuration) since reset. Not pooled. 3551 */ 3552 long mTotalDurationMs; 3553 DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)3554 public DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3555 TimeBase timeBase, Parcel in) { 3556 super(clock, uid, type, timerPool, timeBase, in); 3557 mMaxDurationMs = in.readLong(); 3558 mTotalDurationMs = in.readLong(); 3559 mCurrentDurationMs = in.readLong(); 3560 } 3561 DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)3562 public DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3563 TimeBase timeBase) { 3564 super(clock, uid, type, timerPool, timeBase); 3565 } 3566 3567 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3568 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3569 super.writeToParcel(out, elapsedRealtimeUs); 3570 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 3571 out.writeLong(mTotalDurationMs); 3572 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 3573 } 3574 3575 /** 3576 * Write the summary to the parcel. 3577 * 3578 * Since the time base is probably meaningless after we come back, reading 3579 * from this will have the effect of stopping the timer. So here all we write 3580 * is the max and total durations. 3581 */ 3582 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)3583 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 3584 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3585 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 3586 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 3587 } 3588 3589 /** 3590 * Read the summary parcel. 3591 * 3592 * Has the side effect of stopping the timer. 3593 */ 3594 @Override readSummaryFromParcelLocked(Parcel in)3595 public void readSummaryFromParcelLocked(Parcel in) { 3596 super.readSummaryFromParcelLocked(in); 3597 mMaxDurationMs = in.readLong(); 3598 mTotalDurationMs = in.readLong(); 3599 mStartTimeMs = -1; 3600 mCurrentDurationMs = 0; 3601 } 3602 3603 /** 3604 * The TimeBase time started (again). 3605 * 3606 * If the timer is also running, store the start time. 3607 */ onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3608 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3609 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3610 if (mNesting > 0) { 3611 mStartTimeMs = baseRealtimeUs / 1000; 3612 } 3613 } 3614 3615 /** 3616 * The TimeBase stopped running. 3617 * 3618 * If the timer is running, add the duration into mCurrentDurationMs. 3619 */ 3620 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3621 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3622 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3623 if (mNesting > 0) { 3624 // baseRealtimeUs has already been converted to the timebase's realtime. 3625 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 3626 } 3627 mStartTimeMs = -1; 3628 } 3629 3630 @Override logState(Printer pw, String prefix)3631 public void logState(Printer pw, String prefix) { 3632 super.logState(pw, prefix); 3633 } 3634 3635 @Override startRunningLocked(long elapsedRealtimeMs)3636 public void startRunningLocked(long elapsedRealtimeMs) { 3637 super.startRunningLocked(elapsedRealtimeMs); 3638 if (mNesting == 1 && mTimeBase.isRunning()) { 3639 // Just started 3640 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 3641 } 3642 } 3643 3644 /** 3645 * Decrements the mNesting ref-count on this timer. 3646 * 3647 * If it actually stopped (mNesting went to 0), then possibly update 3648 * mMaxDuration if the current duration was the longest ever. 3649 */ 3650 @Override stopRunningLocked(long elapsedRealtimeMs)3651 public void stopRunningLocked(long elapsedRealtimeMs) { 3652 if (mNesting == 1) { 3653 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 3654 mTotalDurationMs += durationMs; 3655 if (durationMs > mMaxDurationMs) { 3656 mMaxDurationMs = durationMs; 3657 } 3658 mStartTimeMs = -1; 3659 mCurrentDurationMs = 0; 3660 } 3661 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 3662 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 3663 super.stopRunningLocked(elapsedRealtimeMs); 3664 } 3665 3666 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3667 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3668 boolean result = super.reset(detachIfReset, elapsedRealtimeUs); 3669 mMaxDurationMs = 0; 3670 mTotalDurationMs = 0; 3671 mCurrentDurationMs = 0; 3672 if (mNesting > 0) { 3673 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeUs) / 1000; 3674 } else { 3675 mStartTimeMs = -1; 3676 } 3677 return result; 3678 } 3679 3680 /** 3681 * Returns the max duration that this timer has ever seen. 3682 * 3683 * Note that this time is NOT split between the timers in the timer group that 3684 * this timer is attached to. It is the TOTAL time. 3685 */ 3686 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)3687 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 3688 if (mNesting > 0) { 3689 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 3690 if (durationMs > mMaxDurationMs) { 3691 return durationMs; 3692 } 3693 } 3694 return mMaxDurationMs; 3695 } 3696 3697 /** 3698 * Returns the time since the timer was started. 3699 * Returns 0 if the timer is not currently running. 3700 * 3701 * Note that this time is NOT split between the timers in the timer group that 3702 * this timer is attached to. It is the TOTAL time. 3703 * 3704 * Note that if running timer is parceled and unparceled, this method will return 3705 * current duration value at the time of parceling even though timer may not be 3706 * currently running. 3707 */ 3708 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)3709 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 3710 long durationMs = mCurrentDurationMs; 3711 if (mNesting > 0 && mTimeBase.isRunning()) { 3712 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) 3713 - mStartTimeMs; 3714 } 3715 return durationMs; 3716 } 3717 3718 /** 3719 * Returns the total cumulative duration that this timer has been on since reset(). 3720 * If mTimerPool == null, this should be the same 3721 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 3722 * 3723 * Note that this time is NOT split between the timers in the timer group that 3724 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 3725 * the result will not be equivalent to getTotalTimeLocked. 3726 */ 3727 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)3728 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 3729 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 3730 } 3731 } 3732 3733 /** 3734 * State for keeping track of timing information. 3735 */ 3736 public static class StopwatchTimer extends Timer { 3737 final Uid mUid; 3738 final ArrayList<StopwatchTimer> mTimerPool; 3739 3740 int mNesting; 3741 3742 /** 3743 * The last time at which we updated the timer. If mNesting is > 0, 3744 * subtract this from the current battery time to find the amount of 3745 * time we have been running since we last computed an update. 3746 */ 3747 long mUpdateTimeUs; 3748 3749 /** 3750 * The total time at which the timer was acquired, to determine if it 3751 * was actually held for an interesting duration. If time base was not running when timer 3752 * was acquired, will be -1. 3753 */ 3754 long mAcquireTimeUs = -1; 3755 3756 long mTimeoutUs; 3757 3758 /** 3759 * For partial wake locks, keep track of whether we are in the list 3760 * to consume CPU cycles. 3761 */ 3762 @VisibleForTesting 3763 public boolean mInList; 3764 StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)3765 public StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3766 TimeBase timeBase, Parcel in) { 3767 super(clock, type, timeBase, in); 3768 mUid = uid; 3769 mTimerPool = timerPool; 3770 mUpdateTimeUs = in.readLong(); 3771 } 3772 StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)3773 public StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3774 TimeBase timeBase) { 3775 super(clock, type, timeBase); 3776 mUid = uid; 3777 mTimerPool = timerPool; 3778 } 3779 setTimeout(long timeoutUs)3780 public void setTimeout(long timeoutUs) { 3781 mTimeoutUs = timeoutUs; 3782 } 3783 writeToParcel(Parcel out, long elapsedRealtimeUs)3784 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3785 super.writeToParcel(out, elapsedRealtimeUs); 3786 out.writeLong(mUpdateTimeUs); 3787 } 3788 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3789 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3790 if (mNesting > 0) { 3791 if (DEBUG && mType < 0) { 3792 Log.v(TAG, "old mUpdateTime=" + mUpdateTimeUs); 3793 } 3794 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3795 mUpdateTimeUs = baseRealtimeUs; 3796 if (DEBUG && mType < 0) { 3797 Log.v(TAG, "new mUpdateTime=" + mUpdateTimeUs); 3798 } 3799 } 3800 } 3801 logState(Printer pw, String prefix)3802 public void logState(Printer pw, String prefix) { 3803 super.logState(pw, prefix); 3804 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTimeUs 3805 + " mAcquireTime=" + mAcquireTimeUs); 3806 } 3807 startRunningLocked(long elapsedRealtimeMs)3808 public void startRunningLocked(long elapsedRealtimeMs) { 3809 if (mNesting++ == 0) { 3810 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3811 mUpdateTimeUs = batteryRealtimeUs; 3812 if (mTimerPool != null) { 3813 // Accumulate time to all currently active timers before adding 3814 // this new one to the pool. 3815 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 3816 // Add this timer to the active pool 3817 mTimerPool.add(this); 3818 } 3819 if (mTimeBase.isRunning()) { 3820 // Increment the count 3821 mCount++; 3822 mAcquireTimeUs = mTotalTimeUs; 3823 } else { 3824 mAcquireTimeUs = -1; 3825 } 3826 if (DEBUG && mType < 0) { 3827 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTimeUs 3828 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 3829 + " mAcquireTime=" + mAcquireTimeUs); 3830 } 3831 } 3832 } 3833 isRunningLocked()3834 public boolean isRunningLocked() { 3835 return mNesting > 0; 3836 } 3837 stopRunningLocked(long elapsedRealtimeMs)3838 public void stopRunningLocked(long elapsedRealtimeMs) { 3839 // Ignore attempt to stop a timer that isn't running 3840 if (mNesting == 0) { 3841 return; 3842 } 3843 if (--mNesting == 0) { 3844 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3845 if (mTimerPool != null) { 3846 // Accumulate time to all active counters, scaled by the total 3847 // active in the pool, before taking this one out of the pool. 3848 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 3849 // Remove this timer from the active pool 3850 mTimerPool.remove(this); 3851 } else { 3852 mNesting = 1; 3853 mTotalTimeUs = computeRunTimeLocked(batteryRealtimeUs, 3854 elapsedRealtimeMs * 1000); 3855 mNesting = 0; 3856 } 3857 3858 if (DEBUG && mType < 0) { 3859 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTimeUs 3860 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 3861 + " mAcquireTime=" + mAcquireTimeUs); 3862 } 3863 3864 if (mAcquireTimeUs >= 0 && mTotalTimeUs == mAcquireTimeUs) { 3865 // If there was no change in the time, then discard this 3866 // count. A somewhat cheezy strategy, but hey. 3867 mCount--; 3868 } 3869 } 3870 } 3871 stopAllRunningLocked(long elapsedRealtimeMs)3872 public void stopAllRunningLocked(long elapsedRealtimeMs) { 3873 if (mNesting > 0) { 3874 mNesting = 1; 3875 stopRunningLocked(elapsedRealtimeMs); 3876 } 3877 } 3878 3879 // Update the total time for all other running Timers with the same type as this Timer 3880 // due to a change in timer count refreshTimersLocked(long batteryRealtimeUs, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)3881 private static long refreshTimersLocked(long batteryRealtimeUs, 3882 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 3883 long selfTimeUs = 0; 3884 final int N = pool.size(); 3885 for (int i=N-1; i>= 0; i--) { 3886 final StopwatchTimer t = pool.get(i); 3887 long heldTimeUs = batteryRealtimeUs - t.mUpdateTimeUs; 3888 if (heldTimeUs > 0) { 3889 final long myTimeUs = heldTimeUs / N; 3890 if (t == self) { 3891 selfTimeUs = myTimeUs; 3892 } 3893 t.mTotalTimeUs += myTimeUs; 3894 } 3895 t.mUpdateTimeUs = batteryRealtimeUs; 3896 } 3897 return selfTimeUs; 3898 } 3899 3900 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)3901 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 3902 if (mTimeoutUs > 0 && curBatteryRealtimeUs > mUpdateTimeUs + mTimeoutUs) { 3903 curBatteryRealtimeUs = mUpdateTimeUs + mTimeoutUs; 3904 } 3905 return mTotalTimeUs + (mNesting > 0 3906 ? (curBatteryRealtimeUs - mUpdateTimeUs) 3907 / (mTimerPool != null && mTimerPool.size() > 0 ? mTimerPool.size() : 1) 3908 : 0); 3909 } 3910 3911 @Override computeCurrentCountLocked()3912 protected int computeCurrentCountLocked() { 3913 return mCount; 3914 } 3915 3916 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3917 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3918 boolean canDetach = mNesting <= 0; 3919 super.reset(canDetach && detachIfReset, elapsedRealtimeUs); 3920 if (mNesting > 0) { 3921 mUpdateTimeUs = mTimeBase.getRealtime(elapsedRealtimeUs); 3922 } 3923 // To ensure mCount isn't decreased to -1 if timer is stopped later. 3924 mAcquireTimeUs = -1; 3925 return canDetach; 3926 } 3927 3928 @Override detach()3929 public void detach() { 3930 super.detach(); 3931 if (mTimerPool != null) { 3932 mTimerPool.remove(this); 3933 } 3934 } 3935 3936 @Override readSummaryFromParcelLocked(Parcel in)3937 public void readSummaryFromParcelLocked(Parcel in) { 3938 super.readSummaryFromParcelLocked(in); 3939 mNesting = 0; 3940 } 3941 3942 /** 3943 * Set the mark so that we can query later for the total time the timer has 3944 * accumulated since this point. The timer can be running or not. 3945 * 3946 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 3947 */ setMark(long elapsedRealtimeMs)3948 public void setMark(long elapsedRealtimeMs) { 3949 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3950 if (mNesting > 0) { 3951 // We are running. 3952 if (mTimerPool != null) { 3953 refreshTimersLocked(batteryRealtimeUs, mTimerPool, this); 3954 } else { 3955 mTotalTimeUs += batteryRealtimeUs - mUpdateTimeUs; 3956 mUpdateTimeUs = batteryRealtimeUs; 3957 } 3958 } 3959 mTimeBeforeMarkUs = mTotalTimeUs; 3960 } 3961 } 3962 3963 /** 3964 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 3965 * TimeBase is effectively a subset of the other. 3966 */ 3967 public static class DualTimer extends DurationTimer { 3968 // This class both is a DurationTimer and also holds a second DurationTimer. 3969 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 3970 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 3971 // STATS_SINCE_CHARGED). 3972 // mSubTimer typically tracks only part of the total time, such as background time, as 3973 // determined by a subTimeBase. It is NOT pooled. 3974 private final DurationTimer mSubTimer; 3975 3976 /** 3977 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 3978 * The main timer (this) is based on the given timeBase and timerPool. 3979 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 3980 * the main timer is. 3981 */ DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)3982 public DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3983 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 3984 super(clock, uid, type, timerPool, timeBase, in); 3985 mSubTimer = new DurationTimer(clock, uid, type, null, subTimeBase, in); 3986 } 3987 3988 /** 3989 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 3990 * The main timer (this) is based on the given timeBase and timerPool. 3991 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 3992 * the main timer is. 3993 */ DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)3994 public DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3995 TimeBase timeBase, TimeBase subTimeBase) { 3996 super(clock, uid, type, timerPool, timeBase); 3997 mSubTimer = new DurationTimer(clock, uid, type, null, subTimeBase); 3998 } 3999 4000 /** Get the secondary timer. */ 4001 @Override getSubTimer()4002 public DurationTimer getSubTimer() { 4003 return mSubTimer; 4004 } 4005 4006 @Override startRunningLocked(long elapsedRealtimeMs)4007 public void startRunningLocked(long elapsedRealtimeMs) { 4008 super.startRunningLocked(elapsedRealtimeMs); 4009 mSubTimer.startRunningLocked(elapsedRealtimeMs); 4010 } 4011 4012 @Override stopRunningLocked(long elapsedRealtimeMs)4013 public void stopRunningLocked(long elapsedRealtimeMs) { 4014 super.stopRunningLocked(elapsedRealtimeMs); 4015 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 4016 } 4017 4018 @Override stopAllRunningLocked(long elapsedRealtimeMs)4019 public void stopAllRunningLocked(long elapsedRealtimeMs) { 4020 super.stopAllRunningLocked(elapsedRealtimeMs); 4021 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 4022 } 4023 4024 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)4025 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 4026 boolean active = false; 4027 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 4028 active |= !mSubTimer.reset(false, elapsedRealtimeUs); 4029 active |= !super.reset(detachIfReset, elapsedRealtimeUs); 4030 return !active; 4031 } 4032 4033 @Override detach()4034 public void detach() { 4035 mSubTimer.detach(); 4036 super.detach(); 4037 } 4038 4039 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)4040 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 4041 super.writeToParcel(out, elapsedRealtimeUs); 4042 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 4043 } 4044 4045 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)4046 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 4047 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 4048 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 4049 } 4050 4051 @Override readSummaryFromParcelLocked(Parcel in)4052 public void readSummaryFromParcelLocked(Parcel in) { 4053 super.readSummaryFromParcelLocked(in); 4054 mSubTimer.readSummaryFromParcelLocked(in); 4055 } 4056 } 4057 4058 4059 public abstract class OverflowArrayMap<T> { 4060 private static final String OVERFLOW_NAME = "*overflow*"; 4061 4062 final int mUid; 4063 final ArrayMap<String, T> mMap = new ArrayMap<>(); 4064 T mCurOverflow; 4065 ArrayMap<String, MutableInt> mActiveOverflow; 4066 long mLastOverflowTimeMs; 4067 long mLastOverflowFinishTimeMs; 4068 long mLastClearTimeMs; 4069 long mLastCleanupTimeMs; 4070 OverflowArrayMap(int uid)4071 public OverflowArrayMap(int uid) { 4072 mUid = uid; 4073 } 4074 getMap()4075 public ArrayMap<String, T> getMap() { 4076 return mMap; 4077 } 4078 clear()4079 public void clear() { 4080 mLastClearTimeMs = SystemClock.elapsedRealtime(); 4081 mMap.clear(); 4082 mCurOverflow = null; 4083 mActiveOverflow = null; 4084 } 4085 add(String name, T obj)4086 public void add(String name, T obj) { 4087 if (name == null) { 4088 name = ""; 4089 } 4090 mMap.put(name, obj); 4091 if (OVERFLOW_NAME.equals(name)) { 4092 mCurOverflow = obj; 4093 } 4094 } 4095 cleanup(long elapsedRealtimeMs)4096 public void cleanup(long elapsedRealtimeMs) { 4097 mLastCleanupTimeMs = elapsedRealtimeMs; 4098 if (mActiveOverflow != null) { 4099 if (mActiveOverflow.size() == 0) { 4100 mActiveOverflow = null; 4101 } 4102 } 4103 if (mActiveOverflow == null) { 4104 // There is no currently active overflow, so we should no longer have 4105 // an overflow entry. 4106 if (mMap.containsKey(OVERFLOW_NAME)) { 4107 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 4108 + mMap.get(OVERFLOW_NAME)); 4109 mMap.remove(OVERFLOW_NAME); 4110 } 4111 mCurOverflow = null; 4112 } else { 4113 // There is currently active overflow, so we should still have an overflow entry. 4114 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 4115 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 4116 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 4117 } 4118 } 4119 } 4120 startObject(String name, long elapsedRealtimeMs)4121 public T startObject(String name, long elapsedRealtimeMs) { 4122 if (name == null) { 4123 name = ""; 4124 } 4125 T obj = mMap.get(name); 4126 if (obj != null) { 4127 return obj; 4128 } 4129 4130 // No object exists for the given name, but do we currently have it 4131 // running as part of the overflow? 4132 if (mActiveOverflow != null) { 4133 MutableInt over = mActiveOverflow.get(name); 4134 if (over != null) { 4135 // We are already actively counting this name in the overflow object. 4136 obj = mCurOverflow; 4137 if (obj == null) { 4138 // Shouldn't be here, but we'll try to recover. 4139 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 4140 obj = mCurOverflow = instantiateObject(); 4141 mMap.put(OVERFLOW_NAME, obj); 4142 } 4143 over.value++; 4144 return obj; 4145 } 4146 } 4147 4148 // No object exists for given name nor in the overflow; we need to make 4149 // a new one. 4150 final int N = mMap.size(); 4151 if (N >= MAX_WAKELOCKS_PER_UID) { 4152 // Went over the limit on number of objects to track; this one goes 4153 // in to the overflow. 4154 obj = mCurOverflow; 4155 if (obj == null) { 4156 // Need to start overflow now... 4157 obj = mCurOverflow = instantiateObject(); 4158 mMap.put(OVERFLOW_NAME, obj); 4159 } 4160 if (mActiveOverflow == null) { 4161 mActiveOverflow = new ArrayMap<>(); 4162 } 4163 mActiveOverflow.put(name, new MutableInt(1)); 4164 mLastOverflowTimeMs = elapsedRealtimeMs; 4165 return obj; 4166 } 4167 4168 // Normal case where we just need to make a new object. 4169 obj = instantiateObject(); 4170 mMap.put(name, obj); 4171 return obj; 4172 } 4173 stopObject(String name, long elapsedRealtimeMs)4174 public T stopObject(String name, long elapsedRealtimeMs) { 4175 if (name == null) { 4176 name = ""; 4177 } 4178 T obj = mMap.get(name); 4179 if (obj != null) { 4180 return obj; 4181 } 4182 4183 // No object exists for the given name, but do we currently have it 4184 // running as part of the overflow? 4185 if (mActiveOverflow != null) { 4186 MutableInt over = mActiveOverflow.get(name); 4187 if (over != null) { 4188 // We are already actively counting this name in the overflow object. 4189 obj = mCurOverflow; 4190 if (obj != null) { 4191 over.value--; 4192 if (over.value <= 0) { 4193 mActiveOverflow.remove(name); 4194 mLastOverflowFinishTimeMs = elapsedRealtimeMs; 4195 } 4196 return obj; 4197 } 4198 } 4199 } 4200 4201 // Huh, they are stopping an active operation but we can't find one! 4202 // That's not good. 4203 StringBuilder sb = new StringBuilder(); 4204 sb.append("Unable to find object for "); 4205 sb.append(name); 4206 sb.append(" in uid "); 4207 sb.append(mUid); 4208 sb.append(" mapsize="); 4209 sb.append(mMap.size()); 4210 sb.append(" activeoverflow="); 4211 sb.append(mActiveOverflow); 4212 sb.append(" curoverflow="); 4213 sb.append(mCurOverflow); 4214 long now = elapsedRealtimeMs; 4215 if (mLastOverflowTimeMs != 0) { 4216 sb.append(" lastOverflowTime="); 4217 TimeUtils.formatDuration(mLastOverflowTimeMs - now, sb); 4218 } 4219 if (mLastOverflowFinishTimeMs != 0) { 4220 sb.append(" lastOverflowFinishTime="); 4221 TimeUtils.formatDuration(mLastOverflowFinishTimeMs - now, sb); 4222 } 4223 if (mLastClearTimeMs != 0) { 4224 sb.append(" lastClearTime="); 4225 TimeUtils.formatDuration(mLastClearTimeMs - now, sb); 4226 } 4227 if (mLastCleanupTimeMs != 0) { 4228 sb.append(" lastCleanupTime="); 4229 TimeUtils.formatDuration(mLastCleanupTimeMs - now, sb); 4230 } 4231 Slog.wtf(TAG, sb.toString()); 4232 return null; 4233 } 4234 instantiateObject()4235 public abstract T instantiateObject(); 4236 } 4237 4238 @SuppressWarnings("ParcelableCreator") 4239 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 4240 implements Parcelable { 4241 private final Clock mClock; 4242 private final TimeBase mTimeBase; 4243 private int mNumTxStates; 4244 private int mProcessState; 4245 private TimeMultiStateCounter mIdleTimeMillis; 4246 private final LongSamplingCounter mScanTimeMillis; 4247 private final LongSamplingCounter mSleepTimeMillis; 4248 private TimeMultiStateCounter mRxTimeMillis; 4249 private TimeMultiStateCounter[] mTxTimeMillis; 4250 private final LongSamplingCounter mPowerDrainMaMs; 4251 private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs; 4252 ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates)4253 public ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates) { 4254 mClock = clock; 4255 mTimeBase = timeBase; 4256 mNumTxStates = numTxStates; 4257 mScanTimeMillis = new LongSamplingCounter(timeBase); 4258 mSleepTimeMillis = new LongSamplingCounter(timeBase); 4259 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 4260 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase); 4261 } 4262 readSummaryFromParcel(Parcel in)4263 public void readSummaryFromParcel(Parcel in) { 4264 mIdleTimeMillis = readTimeMultiStateCounter(in, mTimeBase); 4265 mScanTimeMillis.readSummaryFromParcelLocked(in); 4266 mSleepTimeMillis.readSummaryFromParcelLocked(in); 4267 mRxTimeMillis = readTimeMultiStateCounter(in, mTimeBase); 4268 mTxTimeMillis = readTimeMultiStateCounters(in, mTimeBase, mNumTxStates); 4269 4270 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 4271 mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in); 4272 } 4273 4274 @Override describeContents()4275 public int describeContents() { 4276 return 0; 4277 } 4278 writeSummaryToParcel(Parcel dest)4279 public void writeSummaryToParcel(Parcel dest) { 4280 writeTimeMultiStateCounter(dest, mIdleTimeMillis); 4281 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 4282 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 4283 writeTimeMultiStateCounter(dest, mRxTimeMillis); 4284 writeTimeMultiStateCounters(dest, mTxTimeMillis); 4285 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 4286 mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest); 4287 } 4288 4289 @Override writeToParcel(Parcel dest, int flags)4290 public void writeToParcel(Parcel dest, int flags) { 4291 writeTimeMultiStateCounter(dest, mIdleTimeMillis); 4292 mScanTimeMillis.writeToParcel(dest); 4293 mSleepTimeMillis.writeToParcel(dest); 4294 writeTimeMultiStateCounter(dest, mRxTimeMillis); 4295 writeTimeMultiStateCounters(dest, mTxTimeMillis); 4296 mPowerDrainMaMs.writeToParcel(dest); 4297 mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); 4298 } 4299 readTimeMultiStateCounter(Parcel in, TimeBase timeBase)4300 private TimeMultiStateCounter readTimeMultiStateCounter(Parcel in, TimeBase timeBase) { 4301 if (in.readBoolean()) { 4302 return TimeMultiStateCounter.readFromParcel(in, timeBase, 4303 BatteryConsumer.PROCESS_STATE_COUNT, mClock.elapsedRealtime()); 4304 } 4305 return null; 4306 } 4307 writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter)4308 private void writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter) { 4309 if (counter != null) { 4310 dest.writeBoolean(true); 4311 counter.writeToParcel(dest); 4312 } else { 4313 dest.writeBoolean(false); 4314 } 4315 } 4316 readTimeMultiStateCounters(Parcel in, TimeBase timeBase, int expectedNumCounters)4317 private TimeMultiStateCounter[] readTimeMultiStateCounters(Parcel in, TimeBase timeBase, 4318 int expectedNumCounters) { 4319 if (in.readBoolean()) { 4320 final int numCounters = in.readInt(); 4321 boolean valid = (numCounters == expectedNumCounters); 4322 // Need to read counters out of the Parcel, even if all or some of them are 4323 // invalid. 4324 TimeMultiStateCounter[] counters = new TimeMultiStateCounter[numCounters]; 4325 for (int i = 0; i < numCounters; i++) { 4326 final TimeMultiStateCounter counter = TimeMultiStateCounter.readFromParcel(in, 4327 timeBase, BatteryConsumer.PROCESS_STATE_COUNT, 4328 mClock.elapsedRealtime()); 4329 if (counter != null) { 4330 counters[i] = counter; 4331 } else { 4332 valid = false; 4333 } 4334 } 4335 if (valid) { 4336 return counters; 4337 } 4338 } 4339 return null; 4340 } 4341 writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters)4342 private void writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters) { 4343 if (counters != null) { 4344 dest.writeBoolean(true); 4345 dest.writeInt(counters.length); 4346 for (TimeMultiStateCounter counter : counters) { 4347 counter.writeToParcel(dest); 4348 } 4349 } else { 4350 dest.writeBoolean(false); 4351 } 4352 } 4353 reset(boolean detachIfReset, long elapsedRealtimeUs)4354 public void reset(boolean detachIfReset, long elapsedRealtimeUs) { 4355 resetIfNotNull(mIdleTimeMillis, detachIfReset, elapsedRealtimeUs); 4356 mScanTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 4357 mSleepTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 4358 resetIfNotNull(mRxTimeMillis, detachIfReset, elapsedRealtimeUs); 4359 resetIfNotNull(mTxTimeMillis, detachIfReset, elapsedRealtimeUs); 4360 mPowerDrainMaMs.reset(detachIfReset, elapsedRealtimeUs); 4361 mMonitoredRailChargeConsumedMaMs.reset(detachIfReset, elapsedRealtimeUs); 4362 } 4363 detach()4364 public void detach() { 4365 detachIfNotNull(mIdleTimeMillis); 4366 mScanTimeMillis.detach(); 4367 mSleepTimeMillis.detach(); 4368 detachIfNotNull(mRxTimeMillis); 4369 detachIfNotNull(mTxTimeMillis); 4370 mPowerDrainMaMs.detach(); 4371 mMonitoredRailChargeConsumedMaMs.detach(); 4372 } 4373 4374 /** 4375 * @return a LongSamplingCounter, measuring time spent in the idle state in 4376 * milliseconds. 4377 */ 4378 @Override getIdleTimeCounter()4379 public LongCounter getIdleTimeCounter() { 4380 if (mIdleTimeMillis == null) { 4381 return ZERO_LONG_COUNTER; 4382 } 4383 return mIdleTimeMillis; 4384 } 4385 getOrCreateIdleTimeCounter()4386 private TimeMultiStateCounter getOrCreateIdleTimeCounter() { 4387 if (mIdleTimeMillis == null) { 4388 mIdleTimeMillis = createTimeMultiStateCounter(); 4389 } 4390 return mIdleTimeMillis; 4391 } 4392 4393 /** 4394 * @return a LongSamplingCounter, measuring time spent in the scan state in 4395 * milliseconds. 4396 */ 4397 @Override getScanTimeCounter()4398 public LongSamplingCounter getScanTimeCounter() { 4399 return mScanTimeMillis; 4400 } 4401 4402 /** 4403 * @return a LongSamplingCounter, measuring time spent in the sleep state in 4404 * milliseconds. 4405 */ 4406 @Override getSleepTimeCounter()4407 public LongSamplingCounter getSleepTimeCounter() { 4408 return mSleepTimeMillis; 4409 } 4410 4411 /** 4412 * @return a LongSamplingCounter, measuring time spent in the receive state in 4413 * milliseconds. 4414 */ 4415 @Override getRxTimeCounter()4416 public LongCounter getRxTimeCounter() { 4417 if (mRxTimeMillis == null) { 4418 return ZERO_LONG_COUNTER; 4419 } 4420 return mRxTimeMillis; 4421 } 4422 getOrCreateRxTimeCounter()4423 private TimeMultiStateCounter getOrCreateRxTimeCounter() { 4424 if (mRxTimeMillis == null) { 4425 mRxTimeMillis = createTimeMultiStateCounter(); 4426 } 4427 return mRxTimeMillis; 4428 } 4429 4430 /** 4431 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 4432 * milliseconds. 4433 */ 4434 @Override getTxTimeCounters()4435 public LongCounter[] getTxTimeCounters() { 4436 if (mTxTimeMillis == null) { 4437 return ZERO_LONG_COUNTER_ARRAY; 4438 } 4439 return mTxTimeMillis; 4440 } 4441 getOrCreateTxTimeCounters()4442 private TimeMultiStateCounter[] getOrCreateTxTimeCounters() { 4443 if (mTxTimeMillis == null) { 4444 mTxTimeMillis = new TimeMultiStateCounter[mNumTxStates]; 4445 for (int i = 0; i < mNumTxStates; i++) { 4446 mTxTimeMillis[i] = createTimeMultiStateCounter(); 4447 } 4448 } 4449 return mTxTimeMillis; 4450 } 4451 createTimeMultiStateCounter()4452 private TimeMultiStateCounter createTimeMultiStateCounter() { 4453 final long timestampMs = mClock.elapsedRealtime(); 4454 TimeMultiStateCounter counter = new TimeMultiStateCounter(mTimeBase, 4455 BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 4456 counter.setState(mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 4457 timestampMs); 4458 counter.update(0, timestampMs); 4459 return counter; 4460 } 4461 4462 /** 4463 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 4464 */ 4465 @Override getPowerCounter()4466 public LongSamplingCounter getPowerCounter() { 4467 return mPowerDrainMaMs; 4468 } 4469 4470 /** 4471 * @return a LongSamplingCounter, measuring actual monitored rail energy consumed 4472 * milli-ampere milli-seconds (mAmS). 4473 */ 4474 @Override getMonitoredRailChargeConsumedMaMs()4475 public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() { 4476 return mMonitoredRailChargeConsumedMaMs; 4477 } 4478 setState(int processState, long elapsedTimeMs)4479 private void setState(int processState, long elapsedTimeMs) { 4480 mProcessState = processState; 4481 if (mIdleTimeMillis != null) { 4482 mIdleTimeMillis.setState(processState, elapsedTimeMs); 4483 } 4484 if (mRxTimeMillis != null) { 4485 mRxTimeMillis.setState(processState, elapsedTimeMs); 4486 } 4487 if (mTxTimeMillis != null) { 4488 for (int i = 0; i < mTxTimeMillis.length; i++) { 4489 mTxTimeMillis[i].setState(processState, elapsedTimeMs); 4490 } 4491 } 4492 } 4493 } 4494 4495 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)4496 public SamplingTimer getRpmTimerLocked(String name) { 4497 SamplingTimer rpmt = mRpmStats.get(name); 4498 if (rpmt == null) { 4499 rpmt = new SamplingTimer(mClock, mOnBatteryTimeBase); 4500 mRpmStats.put(name, rpmt); 4501 } 4502 return rpmt; 4503 } 4504 4505 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)4506 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 4507 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 4508 if (rpmt == null) { 4509 rpmt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 4510 mScreenOffRpmStats.put(name, rpmt); 4511 } 4512 return rpmt; 4513 } 4514 4515 /* 4516 * Get the wakeup reason counter, and create a new one if one 4517 * doesn't already exist. 4518 */ getWakeupReasonTimerLocked(String name)4519 public SamplingTimer getWakeupReasonTimerLocked(String name) { 4520 SamplingTimer timer = mWakeupReasonStats.get(name); 4521 if (timer == null) { 4522 timer = new SamplingTimer(mClock, mOnBatteryTimeBase); 4523 mWakeupReasonStats.put(name, timer); 4524 } 4525 return timer; 4526 } 4527 4528 /* 4529 * Get the KernelWakelockTimer associated with name, and create a new one if one 4530 * doesn't already exist. 4531 */ getKernelWakelockTimerLocked(String name)4532 public SamplingTimer getKernelWakelockTimerLocked(String name) { 4533 SamplingTimer kwlt = mKernelWakelockStats.get(name); 4534 if (kwlt == null) { 4535 kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 4536 mKernelWakelockStats.put(name, kwlt); 4537 } 4538 return kwlt; 4539 } 4540 getKernelMemoryTimerLocked(long bucket)4541 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 4542 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 4543 if (kmt == null) { 4544 kmt = new SamplingTimer(mClock, mOnBatteryTimeBase); 4545 mKernelMemoryStats.put(bucket, kmt); 4546 } 4547 return kmt; 4548 } 4549 4550 @GuardedBy("this") 4551 @Override commitCurrentHistoryBatchLocked()4552 public void commitCurrentHistoryBatchLocked() { 4553 mHistory.commitCurrentHistoryBatchLocked(); 4554 } 4555 4556 @GuardedBy("this") createFakeHistoryEvents(long numEvents)4557 public void createFakeHistoryEvents(long numEvents) { 4558 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 4559 final long uptimeMs = mClock.uptimeMillis(); 4560 for(long i = 0; i < numEvents; i++) { 4561 noteLongPartialWakelockStart("name1", "historyName1", 1000, 4562 elapsedRealtimeMs, uptimeMs); 4563 noteLongPartialWakelockFinish("name1", "historyName1", 1000, 4564 elapsedRealtimeMs, uptimeMs); 4565 } 4566 } 4567 4568 @GuardedBy("this") recordHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)4569 public void recordHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 4570 String name, int uid) { 4571 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid); 4572 } 4573 4574 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, long realtimeUs)4575 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, 4576 long realtimeUs) { 4577 final boolean screenOff = !Display.isOnState(screenState); 4578 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 4579 final boolean updateOnBatteryScreenOffTimeBase = 4580 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 4581 4582 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 4583 if (updateOnBatteryScreenOffTimeBase) { 4584 updateKernelWakelocksLocked(realtimeUs); 4585 updateBatteryPropertiesLocked(); 4586 } 4587 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 4588 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 4589 // improved, remove the surrounding if{}. 4590 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 4591 // if either OnBattery or OnBatteryScreenOfftimebase changes. 4592 updateRpmStatsLocked(realtimeUs); 4593 } 4594 if (DEBUG_ENERGY_CPU) { 4595 Slog.d(TAG, "Updating cpu time because screen is now " 4596 + Display.stateToString(screenState) 4597 + " and battery is " + (unplugged ? "on" : "off")); 4598 } 4599 4600 mOnBatteryTimeBase.setRunning(unplugged, uptimeUs, realtimeUs); 4601 if (updateOnBatteryTimeBase) { 4602 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4603 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptimeUs, realtimeUs); 4604 } 4605 } 4606 if (updateOnBatteryScreenOffTimeBase) { 4607 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, 4608 uptimeUs, realtimeUs); 4609 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4610 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptimeUs, realtimeUs); 4611 } 4612 } 4613 } 4614 } 4615 4616 @GuardedBy("this") updateBatteryPropertiesLocked()4617 protected void updateBatteryPropertiesLocked() { 4618 try { 4619 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 4620 ServiceManager.getService("batteryproperties")); 4621 if (registrar != null) { 4622 registrar.scheduleUpdate(); 4623 } 4624 } catch (RemoteException e) { 4625 // Ignore. 4626 } 4627 } 4628 onIsolatedUidAdded(int isolatedUid, int parentUid)4629 private void onIsolatedUidAdded(int isolatedUid, int parentUid) { 4630 long realtime = mClock.elapsedRealtime(); 4631 long uptime = mClock.uptimeMillis(); 4632 synchronized (this) { 4633 getUidStatsLocked(parentUid, realtime, uptime).addIsolatedUid(isolatedUid); 4634 } 4635 } 4636 onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid)4637 private void onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid) { 4638 long realtime = mClock.elapsedRealtime(); 4639 mPowerStatsUidResolver.retainIsolatedUid(isolatedUid); 4640 synchronized (this) { 4641 mPendingRemovedUids.add(new UidToRemove(isolatedUid, realtime)); 4642 } 4643 if (mExternalSync != null) { 4644 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 4645 } 4646 } 4647 onAfterIsolatedUidRemoved(int isolatedUid, int parentUid)4648 private void onAfterIsolatedUidRemoved(int isolatedUid, int parentUid) { 4649 long realtime = mClock.elapsedRealtime(); 4650 long uptime = mClock.uptimeMillis(); 4651 synchronized (this) { 4652 getUidStatsLocked(parentUid, realtime, uptime).removeIsolatedUid(isolatedUid); 4653 } 4654 } 4655 4656 /** 4657 * Isolated uid should only be removed after all wakelocks associated with the uid are stopped 4658 * and the cpu time-in-state has been read one last time for the uid. 4659 */ 4660 @GuardedBy("this") releaseIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs)4661 public void releaseIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs) { 4662 mPowerStatsUidResolver.releaseIsolatedUid(isolatedUid); 4663 } 4664 mapUid(int uid)4665 private int mapUid(int uid) { 4666 if (Process.isSdkSandboxUid(uid)) { 4667 return Process.getAppUidForSdkSandboxUid(uid); 4668 } 4669 return mPowerStatsUidResolver.mapUid(uid); 4670 } 4671 mapIsolatedUid(int uid)4672 private int mapIsolatedUid(int uid) { 4673 return mPowerStatsUidResolver.mapUid(uid); 4674 } 4675 4676 @GuardedBy("this") noteEventLocked(int code, String name, int uid, long elapsedRealtimeMs, long uptimeMs)4677 public void noteEventLocked(int code, String name, int uid, 4678 long elapsedRealtimeMs, long uptimeMs) { 4679 uid = mapUid(uid); 4680 if (!mActiveEvents.updateState(code, name, uid, 0)) { 4681 return; 4682 } 4683 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid); 4684 } 4685 4686 @GuardedBy("this") noteCurrentTimeChangedLocked(long currentTimeMs, long elapsedRealtimeMs, long uptimeMs)4687 public void noteCurrentTimeChangedLocked(long currentTimeMs, 4688 long elapsedRealtimeMs, long uptimeMs) { 4689 mHistory.recordCurrentTimeChange(elapsedRealtimeMs, uptimeMs, currentTimeMs); 4690 adjustStartClockTime(currentTimeMs); 4691 } 4692 adjustStartClockTime(long currentTimeMs)4693 private void adjustStartClockTime(long currentTimeMs) { 4694 mStartClockTimeMs = 4695 currentTimeMs - (mClock.elapsedRealtime() - (mRealtimeStartUs / 1000)); 4696 } 4697 4698 @GuardedBy("this") noteProcessStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4699 public void noteProcessStartLocked(String name, int uid, 4700 long elapsedRealtimeMs, long uptimeMs) { 4701 uid = mapUid(uid); 4702 if (isOnBattery()) { 4703 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4704 u.getProcessStatsLocked(name).incStartsLocked(); 4705 } 4706 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 4707 return; 4708 } 4709 if (!mRecordAllHistory) { 4710 return; 4711 } 4712 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid); 4713 } 4714 4715 @GuardedBy("this") noteProcessCrashLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4716 public void noteProcessCrashLocked(String name, int uid, 4717 long elapsedRealtimeMs, long uptimeMs) { 4718 uid = mapUid(uid); 4719 if (isOnBattery()) { 4720 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4721 u.getProcessStatsLocked(name).incNumCrashesLocked(); 4722 } 4723 } 4724 4725 @GuardedBy("this") noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4726 public void noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4727 uid = mapUid(uid); 4728 if (isOnBattery()) { 4729 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4730 u.getProcessStatsLocked(name).incNumAnrsLocked(); 4731 } 4732 } 4733 4734 @GuardedBy("this") noteUidProcessStateLocked(int uid, int state)4735 public void noteUidProcessStateLocked(int uid, int state) { 4736 noteUidProcessStateLocked(uid, state, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4737 } 4738 4739 @GuardedBy("this") 4740 @SuppressWarnings("GuardedBy") // errorprone false positive on u.updateUidProcessStateLocked noteUidProcessStateLocked(int uid, int state, long elapsedRealtimeMs, long uptimeMs)4741 public void noteUidProcessStateLocked(int uid, int state, 4742 long elapsedRealtimeMs, long uptimeMs) { 4743 int parentUid = mapUid(uid); 4744 if (uid != parentUid) { 4745 if (Process.isIsolated(uid)) { 4746 // Isolated UIDs process state is already rolled up into parent, so no need to track 4747 // Otherwise the parent's process state will get downgraded incorrectly 4748 return; 4749 } 4750 } 4751 mFrameworkStatsLogger.uidProcessStateChanged(uid, state); 4752 getUidStatsLocked(parentUid, elapsedRealtimeMs, uptimeMs) 4753 .updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs); 4754 } 4755 4756 @GuardedBy("this") noteProcessFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4757 public void noteProcessFinishLocked(String name, int uid, 4758 long elapsedRealtimeMs, long uptimeMs) { 4759 uid = mapUid(uid); 4760 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4761 return; 4762 } 4763 if (!mRecordAllHistory) { 4764 return; 4765 } 4766 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH, name, uid); 4767 } 4768 4769 @GuardedBy("this") noteSyncStartLocked(String name, int uid)4770 public void noteSyncStartLocked(String name, int uid) { 4771 noteSyncStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4772 } 4773 4774 @GuardedBy("this") noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4775 public void noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4776 uid = mapUid(uid); 4777 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4778 .noteStartSyncLocked(name, elapsedRealtimeMs); 4779 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4780 return; 4781 } 4782 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid); 4783 } 4784 4785 @GuardedBy("this") noteSyncFinishLocked(String name, int uid)4786 public void noteSyncFinishLocked(String name, int uid) { 4787 noteSyncFinishLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4788 } 4789 4790 @GuardedBy("this") noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4791 public void noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4792 uid = mapUid(uid); 4793 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4794 .noteStopSyncLocked(name, elapsedRealtimeMs); 4795 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4796 return; 4797 } 4798 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH, name, uid); 4799 } 4800 4801 @GuardedBy("this") noteJobStartLocked(String name, int uid)4802 public void noteJobStartLocked(String name, int uid) { 4803 noteJobStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4804 } 4805 4806 @GuardedBy("this") noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4807 public void noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4808 uid = mapUid(uid); 4809 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4810 .noteStartJobLocked(name, elapsedRealtimeMs); 4811 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4812 return; 4813 } 4814 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid); 4815 } 4816 4817 @GuardedBy("this") noteJobFinishLocked(String name, int uid, int stopReason)4818 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4819 noteJobFinishLocked(name, uid, stopReason, 4820 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4821 } 4822 4823 @GuardedBy("this") noteJobFinishLocked(String name, int uid, int stopReason, long elapsedRealtimeMs, long uptimeMs)4824 public void noteJobFinishLocked(String name, int uid, int stopReason, 4825 long elapsedRealtimeMs, long uptimeMs) { 4826 uid = mapUid(uid); 4827 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4828 .noteStopJobLocked(name, elapsedRealtimeMs, stopReason); 4829 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4830 return; 4831 } 4832 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid); 4833 } 4834 4835 @GuardedBy("this") noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, long elapsedRealtimeMs, long uptimeMs)4836 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, 4837 long elapsedRealtimeMs, long uptimeMs) { 4838 uid = mapUid(uid); 4839 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4840 .noteJobsDeferredLocked(numDeferred, sinceLast); 4841 } 4842 4843 @GuardedBy("this") noteAlarmStartLocked(String name, WorkSource workSource, int uid)4844 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4845 noteAlarmStartLocked(name, workSource, uid, 4846 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4847 } 4848 4849 @GuardedBy("this") noteAlarmStartLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4850 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid, 4851 long elapsedRealtimeMs, long uptimeMs) { 4852 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid, 4853 elapsedRealtimeMs, uptimeMs); 4854 } 4855 4856 @GuardedBy("this") noteAlarmFinishLocked(String name, WorkSource workSource, int uid)4857 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 4858 noteAlarmFinishLocked(name, workSource, uid, 4859 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4860 } 4861 4862 @GuardedBy("this") noteAlarmFinishLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4863 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid, 4864 long elapsedRealtimeMs, long uptimeMs) { 4865 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid, 4866 elapsedRealtimeMs, uptimeMs); 4867 } 4868 4869 @GuardedBy("this") noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4870 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4871 int uid, long elapsedRealtimeMs, long uptimeMs) { 4872 if (!mRecordAllHistory) { 4873 return; 4874 } 4875 4876 if (workSource != null) { 4877 for (int i = 0; i < workSource.size(); ++i) { 4878 uid = mapUid(workSource.getUid(i)); 4879 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4880 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4881 } 4882 } 4883 4884 List<WorkChain> workChains = workSource.getWorkChains(); 4885 if (workChains != null) { 4886 for (int i = 0; i < workChains.size(); ++i) { 4887 uid = mapUid(workChains.get(i).getAttributionUid()); 4888 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4889 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4890 } 4891 } 4892 } 4893 } else { 4894 uid = mapUid(uid); 4895 4896 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4897 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4898 } 4899 } 4900 } 4901 4902 @GuardedBy("this") noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)4903 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4904 String tag) { 4905 noteWakupAlarmLocked(packageName, uid, workSource, tag, 4906 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4907 } 4908 4909 @GuardedBy("this") noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag, long elapsedRealtimeMs, long uptimeMs)4910 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4911 String tag, long elapsedRealtimeMs, long uptimeMs) { 4912 if (workSource != null) { 4913 for (int i = 0; i < workSource.size(); ++i) { 4914 uid = workSource.getUid(i); 4915 final String workSourceName = workSource.getPackageName(i); 4916 4917 if (isOnBattery()) { 4918 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 4919 workSourceName != null ? workSourceName : packageName, 4920 elapsedRealtimeMs, uptimeMs); 4921 pkg.noteWakeupAlarmLocked(tag); 4922 } 4923 } 4924 4925 List<WorkChain> workChains = workSource.getWorkChains(); 4926 if (workChains != null) { 4927 for (int i = 0; i < workChains.size(); ++i) { 4928 final WorkChain wc = workChains.get(i); 4929 uid = wc.getAttributionUid(); 4930 4931 if (isOnBattery()) { 4932 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4933 elapsedRealtimeMs, uptimeMs); 4934 pkg.noteWakeupAlarmLocked(tag); 4935 } 4936 } 4937 } 4938 } else { 4939 if (isOnBattery()) { 4940 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4941 elapsedRealtimeMs, uptimeMs); 4942 pkg.noteWakeupAlarmLocked(tag); 4943 } 4944 } 4945 } 4946 requestWakelockCpuUpdate()4947 private void requestWakelockCpuUpdate() { 4948 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 4949 } 4950 requestImmediateCpuUpdate()4951 private void requestImmediateCpuUpdate() { 4952 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 4953 } 4954 4955 @GuardedBy("this") setRecordAllHistoryLocked(boolean enabled)4956 public void setRecordAllHistoryLocked(boolean enabled) { 4957 mRecordAllHistory = enabled; 4958 if (!enabled) { 4959 // Clear out any existing state. 4960 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 4961 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 4962 // Record the currently running processes as stopping, now that we are no 4963 // longer tracking them. 4964 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4965 HistoryItem.EVENT_PROC); 4966 if (active != null) { 4967 long mSecRealtime = mClock.elapsedRealtime(); 4968 final long mSecUptime = mClock.uptimeMillis(); 4969 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4970 SparseIntArray uids = ent.getValue(); 4971 for (int j=0; j<uids.size(); j++) { 4972 mHistory.recordEvent(mSecRealtime, mSecUptime, 4973 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 4974 } 4975 } 4976 } 4977 } else { 4978 // Record the currently running processes as starting, now that we are tracking them. 4979 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4980 HistoryItem.EVENT_PROC); 4981 if (active != null) { 4982 long mSecRealtime = mClock.elapsedRealtime(); 4983 final long mSecUptime = mClock.uptimeMillis(); 4984 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4985 SparseIntArray uids = ent.getValue(); 4986 for (int j=0; j<uids.size(); j++) { 4987 mHistory.recordEvent(mSecRealtime, mSecUptime, HistoryItem.EVENT_PROC_START, 4988 ent.getKey(), uids.keyAt(j)); 4989 } 4990 } 4991 } 4992 } 4993 } 4994 setNoAutoReset(boolean enabled)4995 public void setNoAutoReset(boolean enabled) { 4996 mNoAutoReset = enabled; 4997 } 4998 4999 @GuardedBy("this") setPretendScreenOff(boolean pretendScreenOff)5000 public void setPretendScreenOff(boolean pretendScreenOff) { 5001 if (mPretendScreenOff != pretendScreenOff) { 5002 mPretendScreenOff = pretendScreenOff; 5003 final int primaryScreenState = mPerDisplayBatteryStats[0].screenState; 5004 noteScreenStateLocked(0, primaryScreenState); 5005 } 5006 } 5007 5008 @GuardedBy("this") noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging)5009 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5010 int type, boolean unimportantForLogging) { 5011 noteStartWakeLocked(uid, pid, wc, name, historyName, type, unimportantForLogging, 5012 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5013 } 5014 5015 @GuardedBy("this") noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)5016 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5017 int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs) { 5018 final int mappedUid = mapUid(uid); 5019 if (type == WAKE_TYPE_PARTIAL) { 5020 // Only care about partial wake locks, since full wake locks 5021 // will be canceled when the user puts the screen to sleep. 5022 if (historyName == null) { 5023 historyName = name; 5024 } 5025 if (mRecordAllHistory) { 5026 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 5027 mappedUid, 0)) { 5028 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, 5029 HistoryItem.EVENT_WAKE_LOCK_START, historyName, mappedUid); 5030 } 5031 } 5032 if (mWakeLockNesting == 0) { 5033 mWakeLockImportant = !unimportantForLogging; 5034 mHistory.recordWakelockStartEvent(elapsedRealtimeMs, uptimeMs, historyName, 5035 mappedUid); 5036 } else if (!mWakeLockImportant && !unimportantForLogging) { 5037 if (mHistory.maybeUpdateWakelockTag(elapsedRealtimeMs, uptimeMs, historyName, 5038 mappedUid)) { 5039 mWakeLockImportant = true; 5040 } 5041 } 5042 mWakeLockNesting++; 5043 } 5044 if (mappedUid >= 0) { 5045 if (mappedUid != uid) { 5046 // Prevent the isolated uid mapping from being removed while the wakelock is 5047 // being held. 5048 mPowerStatsUidResolver.retainIsolatedUid(uid); 5049 } 5050 if (mOnBatteryScreenOffTimeBase.isRunning()) { 5051 // We only update the cpu time when a wake lock is acquired if the screen is off. 5052 // If the screen is on, we don't distribute the power amongst partial wakelocks. 5053 if (DEBUG_ENERGY_CPU) { 5054 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 5055 } 5056 requestWakelockCpuUpdate(); 5057 } 5058 5059 Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs); 5060 uidStats.noteStartWakeLocked(pid, name, type, elapsedRealtimeMs); 5061 if (!mMoveWscLoggingToNotifierEnabled) { 5062 mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name, 5063 uidStats.mProcessState, true /* acquired */, 5064 getPowerManagerWakeLockLevel(type)); 5065 } 5066 if (mPowerManagerFlags.isFrameworkWakelockInfoEnabled()) { 5067 mFrameworkEvents.noteStartWakeLock( 5068 mapIsolatedUid(uid), name, getPowerManagerWakeLockLevel(type), uptimeMs); 5069 } 5070 } 5071 } 5072 5073 @GuardedBy("this") noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type)5074 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5075 int type) { 5076 noteStopWakeLocked(uid, pid, wc, name, historyName, type, 5077 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5078 } 5079 5080 @GuardedBy("this") noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)5081 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5082 int type, long elapsedRealtimeMs, long uptimeMs) { 5083 final int mappedUid = mapUid(uid); 5084 if (type == WAKE_TYPE_PARTIAL) { 5085 mWakeLockNesting--; 5086 if (historyName == null) { 5087 historyName = name; 5088 } 5089 if (mRecordAllHistory) { 5090 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 5091 mappedUid, 0)) { 5092 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, 5093 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, mappedUid); 5094 } 5095 } 5096 if (mWakeLockNesting == 0) { 5097 mHistory.recordWakelockStopEvent(elapsedRealtimeMs, uptimeMs, historyName, 5098 mappedUid); 5099 } 5100 } 5101 if (mappedUid >= 0) { 5102 if (mOnBatteryScreenOffTimeBase.isRunning()) { 5103 if (DEBUG_ENERGY_CPU) { 5104 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 5105 } 5106 requestWakelockCpuUpdate(); 5107 } 5108 5109 Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs); 5110 uidStats.noteStopWakeLocked(pid, name, type, elapsedRealtimeMs); 5111 5112 if (!mMoveWscLoggingToNotifierEnabled) { 5113 mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name, 5114 uidStats.mProcessState, false/* acquired */, 5115 getPowerManagerWakeLockLevel(type)); 5116 } 5117 if (mPowerManagerFlags.isFrameworkWakelockInfoEnabled()) { 5118 mFrameworkEvents.noteStopWakeLock( 5119 mapIsolatedUid(uid), name, getPowerManagerWakeLockLevel(type), uptimeMs); 5120 } 5121 5122 if (mappedUid != uid) { 5123 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 5124 releaseIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 5125 } 5126 } 5127 } 5128 5129 /** 5130 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 5131 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 5132 * These are estimations, since batterystats loses some of the original data. 5133 * TODO: Delete this. Instead, FrameworkStatsLog.write should be called from 5134 * PowerManager's Notifier. 5135 */ getPowerManagerWakeLockLevel(int batteryStatsWakelockType)5136 private int getPowerManagerWakeLockLevel(int batteryStatsWakelockType) { 5137 switch (batteryStatsWakelockType) { 5138 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 5139 case BatteryStats.WAKE_TYPE_PARTIAL: 5140 return PowerManager.PARTIAL_WAKE_LOCK; 5141 5142 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 5143 case BatteryStats.WAKE_TYPE_FULL: 5144 return PowerManager.FULL_WAKE_LOCK; 5145 5146 case BatteryStats.WAKE_TYPE_DRAW: 5147 return PowerManager.DRAW_WAKE_LOCK; 5148 5149 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 5150 case BatteryStats.WAKE_TYPE_WINDOW: 5151 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 5152 return -1; 5153 5154 default: 5155 Slog.e(TAG, "Illegal wakelock type in batterystats: " + batteryStatsWakelockType); 5156 return -1; 5157 } 5158 } 5159 5160 @GuardedBy("this") noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)5161 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 5162 String historyName, int type, boolean unimportantForLogging, 5163 long elapsedRealtimeMs, long uptimeMs) { 5164 final int N = ws.size(); 5165 for (int i=0; i<N; i++) { 5166 noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type, 5167 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 5168 } 5169 5170 List<WorkChain> wcs = ws.getWorkChains(); 5171 if (wcs != null) { 5172 for (int i = 0; i < wcs.size(); ++i) { 5173 final WorkChain wc = wcs.get(i); 5174 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 5175 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 5176 } 5177 } 5178 } 5179 5180 @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)5181 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 5182 String historyName, int type, WorkSource newWs, int newPid, String newName, 5183 String newHistoryName, int newType, boolean newUnimportantForLogging, 5184 long elapsedRealtimeMs, long uptimeMs) { 5185 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 5186 5187 // For correct semantics, we start the need worksources first, so that we won't 5188 // make inappropriate history items as if all wake locks went away and new ones 5189 // appeared. This is okay because tracking of wake locks allows nesting. 5190 // 5191 // First the starts : 5192 final int NN = newWs.size(); 5193 for (int i=0; i<NN; i++) { 5194 noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType, 5195 newUnimportantForLogging, elapsedRealtimeMs, uptimeMs); 5196 } 5197 if (wcs != null) { 5198 List<WorkChain> newChains = wcs[0]; 5199 if (newChains != null) { 5200 for (int i = 0; i < newChains.size(); ++i) { 5201 final WorkChain newChain = newChains.get(i); 5202 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 5203 newHistoryName, newType, newUnimportantForLogging, elapsedRealtimeMs, 5204 uptimeMs); 5205 } 5206 } 5207 } 5208 5209 // Then the stops : 5210 final int NO = ws.size(); 5211 for (int i=0; i<NO; i++) { 5212 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 5213 uptimeMs); 5214 } 5215 if (wcs != null) { 5216 List<WorkChain> goneChains = wcs[1]; 5217 if (goneChains != null) { 5218 for (int i = 0; i < goneChains.size(); ++i) { 5219 final WorkChain goneChain = goneChains.get(i); 5220 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 5221 historyName, type, elapsedRealtimeMs, uptimeMs); 5222 } 5223 } 5224 } 5225 } 5226 5227 @GuardedBy("this") noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)5228 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 5229 String historyName, int type, long elapsedRealtimeMs, long uptimeMs) { 5230 final int N = ws.size(); 5231 for (int i=0; i<N; i++) { 5232 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 5233 uptimeMs); 5234 } 5235 5236 List<WorkChain> wcs = ws.getWorkChains(); 5237 if (wcs != null) { 5238 for (int i = 0; i < wcs.size(); ++i) { 5239 final WorkChain wc = wcs.get(i); 5240 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 5241 elapsedRealtimeMs, uptimeMs); 5242 } 5243 } 5244 } 5245 5246 @GuardedBy("this") noteLongPartialWakelockStart(String name, String historyName, int uid)5247 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 5248 noteLongPartialWakelockStart(name, historyName, uid, 5249 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5250 } 5251 5252 @GuardedBy("this") noteLongPartialWakelockStart(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5253 public void noteLongPartialWakelockStart(String name, String historyName, int uid, 5254 long elapsedRealtimeMs, long uptimeMs) { 5255 noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 5256 } 5257 5258 @GuardedBy("this") noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)5259 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 5260 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 5261 final int N = workSource.size(); 5262 for (int i = 0; i < N; ++i) { 5263 final int uid = mapUid(workSource.getUid(i)); 5264 noteLongPartialWakeLockStartInternal(name, historyName, uid, 5265 elapsedRealtimeMs, uptimeMs); 5266 } 5267 5268 final List<WorkChain> workChains = workSource.getWorkChains(); 5269 if (workChains != null) { 5270 for (int i = 0; i < workChains.size(); ++i) { 5271 final WorkChain workChain = workChains.get(i); 5272 final int uid = workChain.getAttributionUid(); 5273 noteLongPartialWakeLockStartInternal(name, historyName, uid, 5274 elapsedRealtimeMs, uptimeMs); 5275 } 5276 } 5277 } 5278 5279 @GuardedBy("this") noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5280 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, 5281 long elapsedRealtimeMs, long uptimeMs) { 5282 final int mappedUid = mapUid(uid); 5283 if (historyName == null) { 5284 historyName = name; 5285 } 5286 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, 5287 mappedUid, 0)) { 5288 return; 5289 } 5290 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 5291 historyName, mappedUid); 5292 if (mappedUid != uid) { 5293 // Prevent the isolated uid mapping from being removed while the wakelock is 5294 // being held. 5295 mPowerStatsUidResolver.retainIsolatedUid(uid); 5296 } 5297 } 5298 5299 @GuardedBy("this") noteLongPartialWakelockFinish(String name, String historyName, int uid)5300 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 5301 noteLongPartialWakelockFinish(name, historyName, uid, 5302 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5303 } 5304 5305 @GuardedBy("this") noteLongPartialWakelockFinish(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5306 public void noteLongPartialWakelockFinish(String name, String historyName, int uid, 5307 long elapsedRealtimeMs, long uptimeMs) { 5308 noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 5309 } 5310 5311 @GuardedBy("this") noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)5312 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 5313 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 5314 final int N = workSource.size(); 5315 for (int i = 0; i < N; ++i) { 5316 final int uid = mapUid(workSource.getUid(i)); 5317 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 5318 elapsedRealtimeMs, uptimeMs); 5319 } 5320 5321 final List<WorkChain> workChains = workSource.getWorkChains(); 5322 if (workChains != null) { 5323 for (int i = 0; i < workChains.size(); ++i) { 5324 final WorkChain workChain = workChains.get(i); 5325 final int uid = workChain.getAttributionUid(); 5326 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 5327 elapsedRealtimeMs, uptimeMs); 5328 } 5329 } 5330 } 5331 5332 @GuardedBy("this") noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5333 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, 5334 long elapsedRealtimeMs, long uptimeMs) { 5335 final int mappedUid = mapUid(uid); 5336 if (historyName == null) { 5337 historyName = name; 5338 } 5339 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, 5340 mappedUid, 0)) { 5341 return; 5342 } 5343 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 5344 historyName, mappedUid); 5345 if (mappedUid != uid) { 5346 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 5347 releaseIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 5348 } 5349 } 5350 5351 @GuardedBy("this") noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs)5352 public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) { 5353 if (mLastWakeupReason != null) { 5354 long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs; 5355 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 5356 timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds 5357 mFrameworkStatsLogger.kernelWakeupReported(deltaUptimeMs * 1000, mLastWakeupReason, 5358 mLastWakeupElapsedTimeMs); 5359 } 5360 mHistory.recordWakeupEvent(elapsedRealtimeMs, uptimeMs, reason); 5361 mLastWakeupReason = reason; 5362 mLastWakeupUptimeMs = uptimeMs; 5363 mLastWakeupElapsedTimeMs = elapsedRealtimeMs; 5364 } 5365 5366 @GuardedBy("this") startAddingCpuStatsLocked()5367 public boolean startAddingCpuStatsLocked() { 5368 mExternalSync.cancelCpuSyncDueToWakelockChange(); 5369 return mOnBatteryInternal; 5370 } 5371 5372 @GuardedBy("this") addCpuStatsLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs)5373 public void addCpuStatsLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, 5374 int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, 5375 int statSoftIrqTimeMs, int statIdleTimeMs) { 5376 mStepDetailsProvider.addCpuStats(totalUTimeMs, totalSTimeMs, statUserTimeMs, 5377 statSystemTimeMs, statIOWaitTimeMs, statIrqTimeMs, 5378 statSoftIrqTimeMs, statIdleTimeMs); 5379 } 5380 5381 /** 5382 * Called after {@link #addCpuStatsLocked} has been invoked for all active apps. 5383 */ 5384 @GuardedBy("this") finishAddingCpuStatsLocked()5385 public void finishAddingCpuStatsLocked() { 5386 mStepDetailsProvider.finishAddingCpuLocked(); 5387 } 5388 noteProcessDiedLocked(int uid, int pid)5389 public void noteProcessDiedLocked(int uid, int pid) { 5390 uid = mapUid(uid); 5391 Uid u = mUidStats.get(uid); 5392 if (u != null) { 5393 u.mPids.remove(pid); 5394 } 5395 } 5396 reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs)5397 public void reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs) { 5398 uid = mapUid(uid); 5399 Uid u = mUidStats.get(uid); 5400 if (u != null) { 5401 u.reportExcessiveCpuLocked(proc, overTimeMs, usedTimeMs); 5402 } 5403 } 5404 5405 @GuardedBy("this") noteStartSensorLocked(int uid, int sensor)5406 public void noteStartSensorLocked(int uid, int sensor) { 5407 noteStartSensorLocked(uid, sensor, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5408 } 5409 5410 @GuardedBy("this") noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)5411 public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 5412 uid = mapUid(uid); 5413 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5414 HistoryItem.STATE_SENSOR_ON_FLAG, uid, "sensor:0x" + Integer.toHexString(sensor)); 5415 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5416 .noteStartSensor(sensor, elapsedRealtimeMs); 5417 } 5418 5419 @GuardedBy("this") noteStopSensorLocked(int uid, int sensor)5420 public void noteStopSensorLocked(int uid, int sensor) { 5421 noteStopSensorLocked(uid, sensor, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5422 } 5423 5424 @GuardedBy("this") noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)5425 public void noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 5426 uid = mapUid(uid); 5427 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5428 HistoryItem.STATE_SENSOR_ON_FLAG, uid, "sensor:0x" + Integer.toHexString(sensor)); 5429 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5430 .noteStopSensor(sensor, elapsedRealtimeMs); 5431 } 5432 5433 int mGpsNesting; 5434 5435 @GuardedBy("this") noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)5436 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 5437 noteGpsChangedLocked(oldWs, newWs, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5438 } 5439 5440 @GuardedBy("this") noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)5441 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, 5442 long elapsedRealtimeMs, long uptimeMs) { 5443 for (int i = 0; i < newWs.size(); ++i) { 5444 noteStartGpsLocked(newWs.getUid(i), null, elapsedRealtimeMs, uptimeMs); 5445 } 5446 5447 for (int i = 0; i < oldWs.size(); ++i) { 5448 noteStopGpsLocked((oldWs.getUid(i)), null, elapsedRealtimeMs, uptimeMs); 5449 } 5450 5451 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 5452 if (wcs != null) { 5453 if (wcs[0] != null) { 5454 final List<WorkChain> newChains = wcs[0]; 5455 for (int i = 0; i < newChains.size(); ++i) { 5456 noteStartGpsLocked(-1, newChains.get(i), elapsedRealtimeMs, uptimeMs); 5457 } 5458 } 5459 5460 if (wcs[1] != null) { 5461 final List<WorkChain> goneChains = wcs[1]; 5462 for (int i = 0; i < goneChains.size(); ++i) { 5463 noteStopGpsLocked(-1, goneChains.get(i), elapsedRealtimeMs, uptimeMs); 5464 } 5465 } 5466 } 5467 } 5468 5469 @GuardedBy("this") noteStartGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)5470 private void noteStartGpsLocked(int uid, WorkChain workChain, 5471 long elapsedRealtimeMs, long uptimeMs) { 5472 if (workChain != null) { 5473 uid = workChain.getAttributionUid(); 5474 } 5475 final int mappedUid = mapUid(uid); 5476 if (mGpsNesting == 0) { 5477 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5478 HistoryItem.STATE_GPS_ON_FLAG, uid, "gnss"); 5479 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS)) { 5480 mGnssPowerStatsCollector.schedule(); 5481 } 5482 } 5483 mGpsNesting++; 5484 5485 mFrameworkStatsLogger.gpsScanStateChanged(mapIsolatedUid(uid), workChain, /* on */true); 5486 5487 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs).noteStartGps(elapsedRealtimeMs); 5488 } 5489 5490 @GuardedBy("this") noteStopGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)5491 private void noteStopGpsLocked(int uid, WorkChain workChain, 5492 long elapsedRealtimeMs, long uptimeMs) { 5493 if (workChain != null) { 5494 uid = workChain.getAttributionUid(); 5495 } 5496 final int mappedUid = mapUid(uid); 5497 mGpsNesting--; 5498 if (mGpsNesting == 0) { 5499 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5500 HistoryItem.STATE_GPS_ON_FLAG, uid, "gnss"); 5501 mHistory.recordGpsSignalQualityEvent(elapsedRealtimeMs, uptimeMs, 5502 HistoryItem.GNSS_SIGNAL_QUALITY_NONE); 5503 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 5504 mGpsSignalQualityBin = -1; 5505 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS)) { 5506 mGnssPowerStatsCollector.schedule(); 5507 } 5508 } 5509 5510 mFrameworkStatsLogger.gpsScanStateChanged(mapIsolatedUid(uid), workChain, /* on */ false); 5511 5512 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs).noteStopGps(elapsedRealtimeMs); 5513 } 5514 5515 @GuardedBy("this") noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs)5516 public void noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs) { 5517 if (mGpsNesting == 0) { 5518 return; 5519 } 5520 if (signalLevel < 0 || signalLevel >= mGpsSignalQualityTimer.length) { 5521 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 5522 return; 5523 } 5524 if (mGpsSignalQualityBin != signalLevel) { 5525 if (mGpsSignalQualityBin >= 0) { 5526 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtimeMs); 5527 } 5528 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 5529 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs); 5530 } 5531 mHistory.recordGpsSignalQualityEvent(elapsedRealtimeMs, uptimeMs, signalLevel); 5532 mGpsSignalQualityBin = signalLevel; 5533 } 5534 } 5535 getScreenStateTag( int display, int state, @Display.StateReason int reason)5536 private static String getScreenStateTag( 5537 int display, int state, @Display.StateReason int reason) { 5538 return String.format( 5539 "display=%d state=%s reason=%s", 5540 display, Display.stateToString(state), Display.stateReasonToString(reason)); 5541 } 5542 5543 @GuardedBy("this") noteScreenStateLocked(int display, int state)5544 public void noteScreenStateLocked(int display, int state) { 5545 noteScreenStateLocked(display, state, Display.STATE_REASON_UNKNOWN, 5546 mClock.elapsedRealtime(), mClock.uptimeMillis(), mClock.currentTimeMillis()); 5547 } 5548 5549 @GuardedBy("this") noteScreenStateLocked(int display, int displayState, @Display.StateReason int displayStateReason, long elapsedRealtimeMs, long uptimeMs, long currentTimeMs)5550 public void noteScreenStateLocked(int display, int displayState, 5551 @Display.StateReason int displayStateReason, long elapsedRealtimeMs, long uptimeMs, 5552 long currentTimeMs) { 5553 if (Flags.batteryStatsScreenStateEvent()) { 5554 mHistory.recordEvent( 5555 elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_DISPLAY_STATE_CHANGED, 5556 getScreenStateTag(display, displayState, displayStateReason), 5557 Process.INVALID_UID); 5558 } 5559 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 5560 // original 4 are mapped to one of the originals. 5561 if (displayState > MAX_TRACKED_SCREEN_STATE) { 5562 if (Display.isOnState(displayState)) { 5563 displayState = Display.STATE_ON; 5564 } else if (Display.isDozeState(displayState)) { 5565 if (Display.isSuspendedState(displayState)) { 5566 displayState = Display.STATE_DOZE_SUSPEND; 5567 } else { 5568 displayState = Display.STATE_DOZE; 5569 } 5570 } else if (Display.isOffState(displayState)) { 5571 displayState = Display.STATE_OFF; 5572 } else { 5573 Slog.wtf(TAG, "Unknown screen state (not mapped): " + displayState); 5574 displayState = Display.STATE_UNKNOWN; 5575 } 5576 } 5577 // As of this point, displayState should be mapped to one of: 5578 // - Display.STATE_ON, 5579 // - Display.STATE_DOZE 5580 // - Display.STATE_DOZE_SUSPEND 5581 // - Display.STATE_OFF 5582 // - Display.STATE_UNKNOWN 5583 5584 int state; 5585 int overallBin = mScreenBrightnessBin; 5586 int externalUpdateFlag = 0; 5587 boolean shouldScheduleSync = false; 5588 final int numDisplay = mPerDisplayBatteryStats.length; 5589 if (display < 0 || display >= numDisplay) { 5590 Slog.wtf(TAG, "Unexpected note screen state for display " + display + " (only " 5591 + mPerDisplayBatteryStats.length + " displays exist...)"); 5592 return; 5593 } 5594 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5595 final int oldDisplayState = displayStats.screenState; 5596 5597 if (oldDisplayState == displayState) { 5598 // Nothing changed 5599 state = mScreenState; 5600 } else { 5601 displayStats.screenState = displayState; 5602 5603 // Stop timer for previous display state. 5604 switch (oldDisplayState) { 5605 case Display.STATE_ON: 5606 displayStats.screenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5607 final int bin = displayStats.screenBrightnessBin; 5608 if (bin >= 0) { 5609 displayStats.screenBrightnessTimers[bin].stopRunningLocked( 5610 elapsedRealtimeMs); 5611 } 5612 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5613 shouldScheduleSync = true; 5614 break; 5615 case Display.STATE_DOZE: 5616 // Transition from doze to doze suspend can be ignored. 5617 if (displayState == Display.STATE_DOZE_SUSPEND) break; 5618 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5619 shouldScheduleSync = true; 5620 break; 5621 case Display.STATE_DOZE_SUSPEND: 5622 // Transition from doze suspend to doze can be ignored. 5623 if (displayState == Display.STATE_DOZE) break; 5624 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5625 shouldScheduleSync = true; 5626 break; 5627 case Display.STATE_OFF: 5628 shouldScheduleSync = true; 5629 break; 5630 case Display.STATE_UNKNOWN: 5631 // Not tracked by timers. 5632 break; 5633 default: 5634 Slog.wtf(TAG, 5635 "Attempted to stop timer for unexpected display state " + display); 5636 } 5637 5638 // Start timer for new display state. 5639 switch (displayState) { 5640 case Display.STATE_ON: 5641 displayStats.screenOnTimer.startRunningLocked(elapsedRealtimeMs); 5642 final int bin = displayStats.screenBrightnessBin; 5643 if (bin >= 0) { 5644 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5645 elapsedRealtimeMs); 5646 } 5647 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5648 shouldScheduleSync = true; 5649 break; 5650 case Display.STATE_DOZE: 5651 // Transition from doze suspend to doze can be ignored. 5652 if (oldDisplayState == Display.STATE_DOZE_SUSPEND) break; 5653 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5654 shouldScheduleSync = true; 5655 break; 5656 case Display.STATE_DOZE_SUSPEND: 5657 // Transition from doze to doze suspend can be ignored. 5658 if (oldDisplayState == Display.STATE_DOZE) break; 5659 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5660 shouldScheduleSync = true; 5661 break; 5662 case Display.STATE_OFF: 5663 shouldScheduleSync = true; 5664 break; 5665 case Display.STATE_UNKNOWN: 5666 // Not tracked by timers. 5667 break; 5668 default: 5669 Slog.wtf(TAG, 5670 "Attempted to start timer for unexpected display state " + displayState 5671 + " for display " + display); 5672 } 5673 5674 if (shouldScheduleSync 5675 && mGlobalEnergyConsumerStats != null 5676 && mGlobalEnergyConsumerStats.isStandardBucketSupported( 5677 EnergyConsumerStats.POWER_BUCKET_SCREEN_ON)) { 5678 // Display energy consumption stats is available. Prepare to schedule an 5679 // external sync. 5680 externalUpdateFlag |= ExternalStatsSync.UPDATE_DISPLAY; 5681 } 5682 5683 // Reevaluate most important display screen state. 5684 state = Display.STATE_UNKNOWN; 5685 for (int i = 0; i < numDisplay; i++) { 5686 final int tempState = mPerDisplayBatteryStats[i].screenState; 5687 if (tempState == Display.STATE_ON 5688 || state == Display.STATE_ON) { 5689 state = Display.STATE_ON; 5690 } else if (tempState == Display.STATE_DOZE 5691 || state == Display.STATE_DOZE) { 5692 state = Display.STATE_DOZE; 5693 } else if (tempState == Display.STATE_DOZE_SUSPEND 5694 || state == Display.STATE_DOZE_SUSPEND) { 5695 state = Display.STATE_DOZE_SUSPEND; 5696 } else if (tempState == Display.STATE_OFF 5697 || state == Display.STATE_OFF) { 5698 state = Display.STATE_OFF; 5699 } 5700 } 5701 } 5702 5703 final boolean batteryRunning = mOnBatteryTimeBase.isRunning(); 5704 final boolean batteryScreenOffRunning = mOnBatteryScreenOffTimeBase.isRunning(); 5705 5706 state = mPretendScreenOff ? Display.STATE_OFF : state; 5707 if (mScreenState != state) { 5708 recordDailyStatsIfNeededLocked(true, currentTimeMs); 5709 final int oldState = mScreenState; 5710 mScreenState = state; 5711 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 5712 + ", newState=" + Display.stateToString(state)); 5713 5714 if (state != Display.STATE_UNKNOWN) { 5715 int stepState = state-1; 5716 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 5717 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 5718 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 5719 } else { 5720 Slog.wtf(TAG, "Unexpected screen state: " + state); 5721 } 5722 } 5723 5724 int startStates = 0; 5725 int stopStates = 0; 5726 if (Display.isDozeState(state) && !Display.isDozeState(oldState)) { 5727 startStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 5728 mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5729 } else if (Display.isDozeState(oldState) && !Display.isDozeState(state)) { 5730 stopStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 5731 mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5732 } 5733 if (Display.isOnState(state)) { 5734 startStates |= HistoryItem.STATE_SCREEN_ON_FLAG; 5735 mScreenOnTimer.startRunningLocked(elapsedRealtimeMs); 5736 if (mScreenBrightnessBin >= 0) { 5737 mScreenBrightnessTimer[mScreenBrightnessBin] 5738 .startRunningLocked(elapsedRealtimeMs); 5739 } 5740 } else if (Display.isOnState(oldState)) { 5741 stopStates |= HistoryItem.STATE_SCREEN_ON_FLAG; 5742 mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5743 if (mScreenBrightnessBin >= 0) { 5744 mScreenBrightnessTimer[mScreenBrightnessBin] 5745 .stopRunningLocked(elapsedRealtimeMs); 5746 } 5747 } 5748 if (startStates != 0 || stopStates != 0) { 5749 mHistory.recordStateChangeEvent(elapsedRealtimeMs, uptimeMs, startStates, 5750 stopStates); 5751 } 5752 5753 // Per screen state Cpu stats needed. Prepare to schedule an external sync. 5754 externalUpdateFlag |= ExternalStatsSync.UPDATE_CPU; 5755 shouldScheduleSync = true; 5756 5757 if (Display.isOnState(state)) { 5758 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 5759 uptimeMs * 1000, elapsedRealtimeMs * 1000); 5760 // Fake a wake lock, so we consider the device waked as long as the screen is on. 5761 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 5762 elapsedRealtimeMs, uptimeMs); 5763 } else if (Display.isOnState(oldState)) { 5764 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 5765 elapsedRealtimeMs, uptimeMs); 5766 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 5767 uptimeMs * 1000, elapsedRealtimeMs * 1000); 5768 } 5769 // Update discharge amounts. 5770 if (mOnBatteryInternal) { 5771 updateDischargeScreenLevelsLocked(oldState, state); 5772 } 5773 } 5774 5775 // Changing display states might have changed the screen used to determine the overall 5776 // brightness. 5777 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 5778 5779 if (shouldScheduleSync) { 5780 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_SCREEN)) { 5781 mScreenPowerStatsCollector.onScreenStateChange(); 5782 } else { 5783 final int numDisplays = mPerDisplayBatteryStats.length; 5784 final int[] displayStates = new int[numDisplays]; 5785 for (int i = 0; i < numDisplays; i++) { 5786 displayStates[i] = mPerDisplayBatteryStats[i].screenState; 5787 } 5788 mExternalSync.scheduleSyncDueToScreenStateChange(externalUpdateFlag, 5789 batteryRunning, batteryScreenOffRunning, state, displayStates); 5790 } 5791 } 5792 } 5793 5794 /** 5795 * Note screen brightness change for a display. 5796 */ 5797 @GuardedBy("this") noteScreenBrightnessLocked(int display, int brightness)5798 public void noteScreenBrightnessLocked(int display, int brightness) { 5799 noteScreenBrightnessLocked(display, brightness, mClock.elapsedRealtime(), 5800 mClock.uptimeMillis()); 5801 } 5802 5803 5804 /** 5805 * Note screen brightness change for a display. 5806 */ 5807 @GuardedBy("this") noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, long uptimeMs)5808 public void noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, 5809 long uptimeMs) { 5810 // Bin the brightness. 5811 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 5812 if (bin < 0) bin = 0; 5813 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 5814 5815 final int overallBin; 5816 5817 final int numDisplays = mPerDisplayBatteryStats.length; 5818 if (display < 0 || display >= numDisplays) { 5819 Slog.wtf(TAG, "Unexpected note screen brightness for display " + display + " (only " 5820 + mPerDisplayBatteryStats.length + " displays exist...)"); 5821 return; 5822 } 5823 5824 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5825 final int oldBin = displayStats.screenBrightnessBin; 5826 if (oldBin == bin) { 5827 // Nothing changed 5828 overallBin = mScreenBrightnessBin; 5829 } else { 5830 displayStats.screenBrightnessBin = bin; 5831 if (displayStats.screenState == Display.STATE_ON) { 5832 if (oldBin >= 0) { 5833 displayStats.screenBrightnessTimers[oldBin].stopRunningLocked( 5834 elapsedRealtimeMs); 5835 } 5836 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5837 elapsedRealtimeMs); 5838 } 5839 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5840 } 5841 5842 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 5843 } 5844 5845 @GuardedBy("this") evaluateOverallScreenBrightnessBinLocked()5846 private int evaluateOverallScreenBrightnessBinLocked() { 5847 int overallBin = -1; 5848 final int numDisplays = getDisplayCount(); 5849 for (int display = 0; display < numDisplays; display++) { 5850 final int displayBrightnessBin; 5851 if (mPerDisplayBatteryStats[display].screenState == Display.STATE_ON) { 5852 displayBrightnessBin = mPerDisplayBatteryStats[display].screenBrightnessBin; 5853 } else { 5854 displayBrightnessBin = -1; 5855 } 5856 if (displayBrightnessBin > overallBin) { 5857 overallBin = displayBrightnessBin; 5858 } 5859 } 5860 return overallBin; 5861 } 5862 5863 @GuardedBy("this") maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, long uptimeMs)5864 private void maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, 5865 long uptimeMs) { 5866 if (mScreenBrightnessBin != overallBin) { 5867 if (overallBin >= 0) { 5868 mHistory.recordScreenBrightnessEvent(elapsedRealtimeMs, uptimeMs, overallBin); 5869 } 5870 if (mScreenState == Display.STATE_ON) { 5871 if (mScreenBrightnessBin >= 0) { 5872 mScreenBrightnessTimer[mScreenBrightnessBin] 5873 .stopRunningLocked(elapsedRealtimeMs); 5874 } 5875 if (overallBin >= 0) { 5876 mScreenBrightnessTimer[overallBin] 5877 .startRunningLocked(elapsedRealtimeMs); 5878 } 5879 } 5880 mScreenBrightnessBin = overallBin; 5881 } 5882 } 5883 5884 @GuardedBy("this") noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event, long elapsedRealtimeMs, long uptimeMs)5885 public void noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event, 5886 long elapsedRealtimeMs, long uptimeMs) { 5887 if (mOnBatteryInternal) { 5888 uid = mapUid(uid); 5889 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteUserActivityLocked(event); 5890 } 5891 } 5892 5893 @GuardedBy("this") noteWakeUpLocked(String reason, int reasonUid, long elapsedRealtimeMs, long uptimeMs)5894 public void noteWakeUpLocked(String reason, int reasonUid, 5895 long elapsedRealtimeMs, long uptimeMs) { 5896 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP, reason, 5897 reasonUid); 5898 } 5899 5900 @GuardedBy("this") noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs)5901 public void noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs) { 5902 if (mInteractive != interactive) { 5903 mInteractive = interactive; 5904 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 5905 if (interactive) { 5906 mInteractiveTimer.startRunningLocked(elapsedRealtimeMs); 5907 } else { 5908 mInteractiveTimer.stopRunningLocked(elapsedRealtimeMs); 5909 } 5910 } 5911 } 5912 5913 @GuardedBy("this") noteConnectivityChangedLocked(int type, String extra, long elapsedRealtimeMs, long uptimeMs)5914 public void noteConnectivityChangedLocked(int type, String extra, 5915 long elapsedRealtimeMs, long uptimeMs) { 5916 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 5917 extra, type); 5918 mNumConnectivityChange++; 5919 } 5920 5921 @GuardedBy("this") noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5922 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 5923 final long uptimeMillis, int uid) { 5924 uid = mapUid(uid); 5925 mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5926 uid); 5927 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked(); 5928 } 5929 5930 /** 5931 * Updates the radio power state and returns true if an external stats collection should occur. 5932 */ 5933 @GuardedBy("this") noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)5934 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 5935 return noteMobileRadioPowerStateLocked(powerState, timestampNs, uid, 5936 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5937 } 5938 5939 @GuardedBy("this") noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)5940 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, 5941 long elapsedRealtimeMs, long uptimeMs) { 5942 if (mMobileRadioPowerState != powerState) { 5943 long realElapsedRealtimeMs; 5944 final boolean active = isActiveRadioPowerState(powerState); 5945 if (active) { 5946 if (uid > 0) { 5947 noteMobileRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 5948 } 5949 5950 mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 5951 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5952 HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG); 5953 } else { 5954 realElapsedRealtimeMs = timestampNs / (1000*1000); 5955 long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs; 5956 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 5957 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 5958 + " is before start time " + lastUpdateTimeMs); 5959 realElapsedRealtimeMs = elapsedRealtimeMs; 5960 } else if (realElapsedRealtimeMs < elapsedRealtimeMs) { 5961 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs 5962 - realElapsedRealtimeMs); 5963 } 5964 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5965 HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG); 5966 } 5967 mMobileRadioPowerState = powerState; 5968 5969 // Inform current RatBatteryStats that the modem active state might have changed. 5970 getRatBatteryStatsLocked(mActiveRat).noteActive(active, elapsedRealtimeMs); 5971 5972 if (active) { 5973 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtimeMs); 5974 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtimeMs); 5975 } else { 5976 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 5977 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 5978 5979 if (mMobileRadioPowerStatsCollector.isEnabled()) { 5980 mMobileRadioPowerStatsCollector.schedule(); 5981 } else { 5982 // Check if modem Activity info has been collected recently, don't bother 5983 // triggering another update. 5984 if (mLastModemActivityInfo == null 5985 || elapsedRealtimeMs >= mLastModemActivityInfo.getTimestampMillis() 5986 + MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS) { 5987 mExternalSync.scheduleSync("modem-data", 5988 BatteryExternalStatsWorker.UPDATE_RADIO); 5989 return true; 5990 } 5991 } 5992 } 5993 } 5994 return false; 5995 } 5996 isActiveRadioPowerState(int powerState)5997 private static boolean isActiveRadioPowerState(int powerState) { 5998 return powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5999 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 6000 } 6001 6002 /** 6003 * Toggles the power save mode state. 6004 */ 6005 @GuardedBy("this") notePowerSaveModeLockedInit(boolean enabled, long elapsedRealtimeMs, long uptimeMs)6006 public void notePowerSaveModeLockedInit(boolean enabled, long elapsedRealtimeMs, 6007 long uptimeMs) { 6008 if (mPowerSaveModeEnabled != enabled) { 6009 notePowerSaveModeLocked(enabled, elapsedRealtimeMs, uptimeMs); 6010 } else { 6011 // Log an initial value for BATTERY_SAVER_MODE_STATE_CHANGED in order to 6012 // allow the atom to read all future state changes. 6013 mFrameworkStatsLogger.batterySaverModeChanged(enabled); 6014 } 6015 } 6016 6017 @GuardedBy("this") notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs)6018 public void notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs) { 6019 if (mPowerSaveModeEnabled != enabled) { 6020 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 6021 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 6022 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 6023 mPowerSaveModeEnabled = enabled; 6024 if (enabled) { 6025 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6026 HistoryItem.STATE2_POWER_SAVE_FLAG); 6027 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs); 6028 } else { 6029 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6030 HistoryItem.STATE2_POWER_SAVE_FLAG); 6031 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs); 6032 } 6033 mFrameworkStatsLogger.batterySaverModeChanged(enabled); 6034 } 6035 } 6036 6037 @GuardedBy("this") noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, long elapsedRealtimeMs, long uptimeMs)6038 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, 6039 long elapsedRealtimeMs, long uptimeMs) { 6040 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 6041 if (mDeviceIdling && !nowIdling && activeReason == null) { 6042 // We don't go out of general idling mode until explicitly taken out of 6043 // device idle through going active or significant motion. 6044 nowIdling = true; 6045 } 6046 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 6047 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 6048 // We don't go out of general light idling mode until explicitly taken out of 6049 // device idle through going active or significant motion. 6050 nowLightIdling = true; 6051 } 6052 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 6053 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE, 6054 activeReason, activeUid); 6055 } 6056 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 6057 int statsmode; 6058 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 6059 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 6060 else statsmode = DEVICE_IDLE_MODE_OFF; 6061 mFrameworkStatsLogger.deviceIdlingModeStateChanged(statsmode); 6062 } 6063 if (mDeviceIdling != nowIdling) { 6064 mDeviceIdling = nowIdling; 6065 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 6066 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 6067 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 6068 if (nowIdling) { 6069 mDeviceIdlingTimer.startRunningLocked(elapsedRealtimeMs); 6070 } else { 6071 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 6072 } 6073 } 6074 if (mDeviceLightIdling != nowLightIdling) { 6075 mDeviceLightIdling = nowLightIdling; 6076 if (nowLightIdling) { 6077 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtimeMs); 6078 } else { 6079 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 6080 } 6081 } 6082 if (mDeviceIdleMode != mode) { 6083 mHistory.recordDeviceIdleEvent(elapsedRealtimeMs, uptimeMs, mode); 6084 long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs; 6085 mLastIdleTimeStartMs = elapsedRealtimeMs; 6086 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 6087 if (lastDuration > mLongestLightIdleTimeMs) { 6088 mLongestLightIdleTimeMs = lastDuration; 6089 } 6090 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtimeMs); 6091 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 6092 if (lastDuration > mLongestFullIdleTimeMs) { 6093 mLongestFullIdleTimeMs = lastDuration; 6094 } 6095 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtimeMs); 6096 } 6097 if (mode == DEVICE_IDLE_MODE_LIGHT) { 6098 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtimeMs); 6099 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 6100 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtimeMs); 6101 } 6102 mDeviceIdleMode = mode; 6103 mFrameworkStatsLogger.deviceIdleModeStateChanged(mode); 6104 } 6105 } 6106 6107 @GuardedBy("this") notePackageInstalledLocked(String pkgName, long versionCode, long elapsedRealtimeMs, long uptimeMs)6108 public void notePackageInstalledLocked(String pkgName, long versionCode, 6109 long elapsedRealtimeMs, long uptimeMs) { 6110 // XXX need to figure out what to do with long version codes. 6111 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED, 6112 pkgName, (int)versionCode); 6113 PackageChange pc = new PackageChange(); 6114 pc.mPackageName = pkgName; 6115 pc.mUpdate = true; 6116 pc.mVersionCode = versionCode; 6117 addPackageChange(pc); 6118 } 6119 6120 @GuardedBy("this") notePackageUninstalledLocked(String pkgName, long elapsedRealtimeMs, long uptimeMs)6121 public void notePackageUninstalledLocked(String pkgName, 6122 long elapsedRealtimeMs, long uptimeMs) { 6123 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_UNINSTALLED, 6124 pkgName, 0); 6125 PackageChange pc = new PackageChange(); 6126 pc.mPackageName = pkgName; 6127 pc.mUpdate = true; 6128 addPackageChange(pc); 6129 } 6130 addPackageChange(PackageChange pc)6131 private void addPackageChange(PackageChange pc) { 6132 if (mDailyPackageChanges == null) { 6133 mDailyPackageChanges = new ArrayList<>(); 6134 } 6135 mDailyPackageChanges.add(pc); 6136 } 6137 6138 @GuardedBy("this") stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs)6139 void stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs) { 6140 for (int i = 0; i < mGpsSignalQualityTimer.length; i++) { 6141 if (i == except) { 6142 continue; 6143 } 6144 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 6145 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtimeMs); 6146 } 6147 } 6148 } 6149 6150 @GuardedBy("this") notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs)6151 public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) { 6152 if (!mPhoneOn) { 6153 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6154 HistoryItem.STATE2_PHONE_IN_CALL_FLAG); 6155 mPhoneOn = true; 6156 mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs); 6157 if (mConstants.PHONE_ON_EXTERNAL_STATS_COLLECTION) { 6158 scheduleSyncExternalStatsLocked("phone-on", ExternalStatsSync.UPDATE_RADIO); 6159 mMobileRadioPowerStatsCollector.schedule(); 6160 } 6161 } 6162 } 6163 6164 @GuardedBy("this") notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs)6165 public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) { 6166 if (mPhoneOn) { 6167 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6168 HistoryItem.STATE2_PHONE_IN_CALL_FLAG); 6169 mPhoneOn = false; 6170 mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs); 6171 scheduleSyncExternalStatsLocked("phone-off", ExternalStatsSync.UPDATE_RADIO); 6172 mMobileRadioPowerStatsCollector.schedule(); 6173 } 6174 } 6175 6176 @GuardedBy("this") registerUsbStateReceiver(Context context)6177 private void registerUsbStateReceiver(Context context) { 6178 final IntentFilter usbStateFilter = new IntentFilter(); 6179 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 6180 context.registerReceiver(new BroadcastReceiver() { 6181 @Override 6182 public void onReceive(Context context, Intent intent) { 6183 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 6184 synchronized (BatteryStatsImpl.this) { 6185 noteUsbConnectionStateLocked(state, mClock.elapsedRealtime(), 6186 mClock.uptimeMillis()); 6187 } 6188 } 6189 }, usbStateFilter); 6190 synchronized (this) { 6191 if (mUsbDataState == USB_DATA_UNKNOWN) { 6192 final Intent usbState = context.registerReceiver(null, usbStateFilter); 6193 final boolean initState = usbState != null && usbState.getBooleanExtra( 6194 UsbManager.USB_CONNECTED, false); 6195 noteUsbConnectionStateLocked(initState, mClock.elapsedRealtime(), 6196 mClock.uptimeMillis()); 6197 } 6198 } 6199 } 6200 6201 @GuardedBy("this") noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, long uptimeMs)6202 private void noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, 6203 long uptimeMs) { 6204 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 6205 if (mUsbDataState != newState) { 6206 mUsbDataState = newState; 6207 if (connected) { 6208 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6209 HistoryItem.STATE2_USB_DATA_LINK_FLAG); 6210 } else { 6211 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6212 HistoryItem.STATE2_USB_DATA_LINK_FLAG); 6213 } 6214 } 6215 } 6216 6217 @GuardedBy("this") stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)6218 void stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 6219 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 6220 if (i == except) { 6221 continue; 6222 } 6223 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 6224 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 6225 } 6226 } 6227 } 6228 6229 @GuardedBy("this") updateAllPhoneStateLocked(int state, int simState, int strengthBin, long elapsedRealtimeMs, long uptimeMs)6230 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin, 6231 long elapsedRealtimeMs, long uptimeMs) { 6232 boolean scanning = false; 6233 boolean newHistory = false; 6234 int addStateFlag = 0; 6235 int removeStateFlag = 0; 6236 int newState = -1; 6237 int newSignalStrength = -1; 6238 6239 mPhoneServiceStateRaw = state; 6240 mPhoneSimStateRaw = simState; 6241 mPhoneSignalStrengthBinRaw = strengthBin; 6242 6243 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 6244 // In this case we will always be STATE_OUT_OF_SERVICE, so need 6245 // to infer that we are scanning from other data. 6246 if (state == ServiceState.STATE_OUT_OF_SERVICE 6247 && strengthBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 6248 state = ServiceState.STATE_IN_SERVICE; 6249 } 6250 } 6251 6252 // If the phone is powered off, stop all timers. 6253 if (state == ServiceState.STATE_POWER_OFF) { 6254 strengthBin = -1; 6255 6256 // If we are in service, make sure the correct signal string timer is running. 6257 } else if (state == ServiceState.STATE_IN_SERVICE) { 6258 // Bin will be changed below. 6259 6260 // If we're out of service, we are in the lowest signal strength 6261 // bin and have the scanning bit set. 6262 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 6263 scanning = true; 6264 strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 6265 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 6266 addStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG; 6267 newHistory = true; 6268 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtimeMs); 6269 mFrameworkStatsLogger.phoneServiceStateChanged(state, simState, strengthBin); 6270 } 6271 } 6272 6273 if (!scanning) { 6274 // If we are no longer scanning, then stop the scanning timer. 6275 if (mPhoneSignalScanningTimer.isRunningLocked()) { 6276 removeStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG; 6277 newHistory = true; 6278 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs); 6279 mFrameworkStatsLogger.phoneServiceStateChanged(state, simState, strengthBin); 6280 } 6281 } 6282 6283 if (mPhoneServiceState != state) { 6284 newState = state; 6285 newHistory = true; 6286 mPhoneServiceState = state; 6287 } 6288 6289 if (mPhoneSignalStrengthBin != strengthBin) { 6290 if (mPhoneSignalStrengthBin >= 0) { 6291 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 6292 elapsedRealtimeMs); 6293 } 6294 if (strengthBin >= 0) { 6295 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 6296 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 6297 } 6298 newSignalStrength = strengthBin; 6299 newHistory = true; 6300 mFrameworkStatsLogger.phoneSignalStrengthChanged(strengthBin); 6301 } else { 6302 stopAllPhoneSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 6303 } 6304 mPhoneSignalStrengthBin = strengthBin; 6305 } 6306 6307 if (newHistory) { 6308 mHistory.recordPhoneStateChangeEvent(elapsedRealtimeMs, uptimeMs, 6309 addStateFlag, removeStateFlag, newState, newSignalStrength); 6310 } 6311 } 6312 6313 @GuardedBy("this") notePhoneStateLocked(int state, int simState, long elapsedRealtimeMs, long uptimeMs)6314 public void notePhoneStateLocked(int state, int simState, 6315 long elapsedRealtimeMs, long uptimeMs) { 6316 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw, 6317 elapsedRealtimeMs, uptimeMs); 6318 } 6319 6320 @GuardedBy("this") notePhoneSignalStrengthLocked(SignalStrength signalStrength, long elapsedRealtimeMs, long uptimeMs)6321 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength, 6322 long elapsedRealtimeMs, long uptimeMs) { 6323 final int overallSignalStrength = signalStrength.getLevel(); 6324 final SparseIntArray perRatSignalStrength = new SparseIntArray( 6325 BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT); 6326 6327 // Extract signal strength level for each RAT. 6328 final List<CellSignalStrength> cellSignalStrengths = 6329 signalStrength.getCellSignalStrengths(); 6330 final int size = cellSignalStrengths.size(); 6331 for (int i = 0; i < size; i++) { 6332 CellSignalStrength cellSignalStrength = cellSignalStrengths.get(i); 6333 // Map each CellSignalStrength to a BatteryStats.RadioAccessTechnology 6334 final int ratType; 6335 final int level; 6336 if (cellSignalStrength instanceof CellSignalStrengthNr) { 6337 ratType = RADIO_ACCESS_TECHNOLOGY_NR; 6338 level = cellSignalStrength.getLevel(); 6339 } else if (cellSignalStrength instanceof CellSignalStrengthLte) { 6340 ratType = RADIO_ACCESS_TECHNOLOGY_LTE; 6341 level = cellSignalStrength.getLevel(); 6342 } else { 6343 ratType = RADIO_ACCESS_TECHNOLOGY_OTHER; 6344 level = cellSignalStrength.getLevel(); 6345 } 6346 6347 // According to SignalStrength#getCellSignalStrengths(), multiple of the same 6348 // cellSignalStrength can be present. Just take the highest level one for each RAT. 6349 if (perRatSignalStrength.get(ratType, -1) < level) { 6350 perRatSignalStrength.put(ratType, level); 6351 } 6352 } 6353 6354 notePhoneSignalStrengthLocked(overallSignalStrength, perRatSignalStrength, 6355 elapsedRealtimeMs, uptimeMs); 6356 } 6357 6358 /** 6359 * Note phone signal strength change, including per RAT signal strength. 6360 * 6361 * @param signalStrength overall signal strength {@see SignalStrength#getLevel()} 6362 * @param perRatSignalStrength signal strength of available RATs 6363 */ 6364 @GuardedBy("this") notePhoneSignalStrengthLocked(int signalStrength, SparseIntArray perRatSignalStrength)6365 public void notePhoneSignalStrengthLocked(int signalStrength, 6366 SparseIntArray perRatSignalStrength) { 6367 notePhoneSignalStrengthLocked(signalStrength, perRatSignalStrength, 6368 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6369 } 6370 6371 /** 6372 * Note phone signal strength change, including per RAT signal strength. 6373 * 6374 * @param signalStrength overall signal strength {@see SignalStrength#getLevel()} 6375 * @param perRatSignalStrength signal strength of available RATs 6376 */ 6377 @GuardedBy("this") notePhoneSignalStrengthLocked(int signalStrength, SparseIntArray perRatSignalStrength, long elapsedRealtimeMs, long uptimeMs)6378 public void notePhoneSignalStrengthLocked(int signalStrength, 6379 SparseIntArray perRatSignalStrength, 6380 long elapsedRealtimeMs, long uptimeMs) { 6381 // Note each RAT's signal strength. 6382 final int size = perRatSignalStrength.size(); 6383 for (int i = 0; i < size; i++) { 6384 final int rat = perRatSignalStrength.keyAt(i); 6385 final int ratSignalStrength = perRatSignalStrength.valueAt(i); 6386 getRatBatteryStatsLocked(rat).noteSignalStrength(ratSignalStrength, elapsedRealtimeMs); 6387 } 6388 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, signalStrength, 6389 elapsedRealtimeMs, uptimeMs); 6390 } 6391 6392 @GuardedBy("this") notePhoneDataConnectionStateLocked(@etworkType int dataType, boolean hasData, @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, @ServiceState.FrequencyRange int nrFrequency)6393 public void notePhoneDataConnectionStateLocked(@NetworkType int dataType, boolean hasData, 6394 @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, 6395 @ServiceState.FrequencyRange int nrFrequency) { 6396 notePhoneDataConnectionStateLocked(dataType, hasData, serviceType, nrState, nrFrequency, 6397 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6398 } 6399 6400 @GuardedBy("this") notePhoneDataConnectionStateLocked(@etworkType int dataType, boolean hasData, @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, @ServiceState.FrequencyRange int nrFrequency, long elapsedRealtimeMs, long uptimeMs)6401 public void notePhoneDataConnectionStateLocked(@NetworkType int dataType, boolean hasData, 6402 @RegState int serviceType, @NetworkRegistrationInfo.NRState int nrState, 6403 @ServiceState.FrequencyRange int nrFrequency, long elapsedRealtimeMs, long uptimeMs) { 6404 // BatteryStats uses 0 to represent no network type. 6405 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 6406 // Unknown is included in DATA_CONNECTION_OTHER. 6407 int bin = DATA_CONNECTION_OUT_OF_SERVICE; 6408 if (hasData) { 6409 if (dataType > 0 && dataType <= NUM_ALL_NETWORK_TYPES) { 6410 bin = dataType; 6411 } else { 6412 switch (serviceType) { 6413 case ServiceState.STATE_OUT_OF_SERVICE: 6414 bin = DATA_CONNECTION_OUT_OF_SERVICE; 6415 break; 6416 case ServiceState.STATE_EMERGENCY_ONLY: 6417 bin = DATA_CONNECTION_EMERGENCY_SERVICE; 6418 break; 6419 default: 6420 bin = DATA_CONNECTION_OTHER; 6421 break; 6422 } 6423 } 6424 } 6425 6426 6427 6428 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 6429 if (mPhoneDataConnectionType != bin) { 6430 mHistory.recordDataConnectionTypeChangeEvent(elapsedRealtimeMs, uptimeMs, bin); 6431 if (mPhoneDataConnectionType >= 0) { 6432 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 6433 elapsedRealtimeMs); 6434 } 6435 mPhoneDataConnectionType = bin; 6436 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtimeMs); 6437 } 6438 6439 if (mNrState != nrState) { 6440 mHistory.recordNrStateChangeEvent(elapsedRealtimeMs, uptimeMs, nrState); 6441 mNrState = nrState; 6442 } 6443 6444 final boolean newNrNsaActive = isNrNsa(bin, nrState); 6445 final boolean nrNsaActive = mNrNsaTimer.isRunningLocked(); 6446 if (newNrNsaActive != nrNsaActive) { 6447 if (newNrNsaActive) { 6448 mNrNsaTimer.startRunningLocked(elapsedRealtimeMs); 6449 } else { 6450 mNrNsaTimer.stopRunningLocked(elapsedRealtimeMs); 6451 } 6452 } 6453 6454 final int newRat = mapNetworkTypeToRadioAccessTechnology(bin, nrState); 6455 if (newRat == RADIO_ACCESS_TECHNOLOGY_NR) { 6456 // Note possible frequency change for the NR RAT. 6457 getRatBatteryStatsLocked(newRat).noteFrequencyRange(nrFrequency, elapsedRealtimeMs); 6458 } 6459 if (mActiveRat != newRat) { 6460 getRatBatteryStatsLocked(mActiveRat).noteActive(false, elapsedRealtimeMs); 6461 mActiveRat = newRat; 6462 } 6463 final boolean modemActive = mMobileRadioActiveTimer.isRunningLocked(); 6464 getRatBatteryStatsLocked(newRat).noteActive(modemActive, elapsedRealtimeMs); 6465 } 6466 6467 /** 6468 * Non-standalone (NSA) mode for 5G NR will have an LTE network type. If NR state is 6469 * connected while on an LTE network, the device is in NR NSA mode. 6470 */ isNrNsa(@etworkType int dataType, @NetworkRegistrationInfo.NRState int nrState)6471 private static boolean isNrNsa(@NetworkType int dataType, 6472 @NetworkRegistrationInfo.NRState int nrState) { 6473 return dataType == TelephonyManager.NETWORK_TYPE_LTE 6474 && nrState == NetworkRegistrationInfo.NR_STATE_CONNECTED; 6475 } 6476 6477 @RadioAccessTechnology mapNetworkTypeToRadioAccessTechnology(@etworkType int dataType, @NetworkRegistrationInfo.NRState int nrState)6478 private static int mapNetworkTypeToRadioAccessTechnology(@NetworkType int dataType, 6479 @NetworkRegistrationInfo.NRState int nrState) { 6480 if (isNrNsa(dataType, nrState)) { 6481 // Treat an NR NSA connection as RADIO_ACCESS_TECHNOLOGY_NR 6482 return RADIO_ACCESS_TECHNOLOGY_NR; 6483 } 6484 6485 switch (dataType) { 6486 case TelephonyManager.NETWORK_TYPE_NR: 6487 return RADIO_ACCESS_TECHNOLOGY_NR; 6488 case TelephonyManager.NETWORK_TYPE_LTE: 6489 return RADIO_ACCESS_TECHNOLOGY_LTE; 6490 case TelephonyManager.NETWORK_TYPE_UNKNOWN: //fallthrough 6491 case TelephonyManager.NETWORK_TYPE_GPRS: //fallthrough 6492 case TelephonyManager.NETWORK_TYPE_EDGE: //fallthrough 6493 case TelephonyManager.NETWORK_TYPE_UMTS: //fallthrough 6494 case TelephonyManager.NETWORK_TYPE_CDMA: //fallthrough 6495 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fallthrough 6496 case TelephonyManager.NETWORK_TYPE_EVDO_A: //fallthrough 6497 case TelephonyManager.NETWORK_TYPE_1xRTT: //fallthrough 6498 case TelephonyManager.NETWORK_TYPE_HSDPA: //fallthrough 6499 case TelephonyManager.NETWORK_TYPE_HSUPA: //fallthrough 6500 case TelephonyManager.NETWORK_TYPE_HSPA: //fallthrough 6501 case TelephonyManager.NETWORK_TYPE_IDEN: //fallthrough 6502 case TelephonyManager.NETWORK_TYPE_EVDO_B: //fallthrough 6503 case TelephonyManager.NETWORK_TYPE_EHRPD: //fallthrough 6504 case TelephonyManager.NETWORK_TYPE_HSPAP: //fallthrough 6505 case TelephonyManager.NETWORK_TYPE_GSM: //fallthrough 6506 case TelephonyManager.NETWORK_TYPE_TD_SCDMA: //fallthrough 6507 case TelephonyManager.NETWORK_TYPE_IWLAN: //fallthrough 6508 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6509 default: 6510 Slog.w(TAG, "Unhandled NetworkType (" + dataType + "), mapping to OTHER"); 6511 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6512 } 6513 } 6514 6515 @GuardedBy("this") noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs)6516 public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) { 6517 if (!mWifiOn) { 6518 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6519 HistoryItem.STATE2_WIFI_ON_FLAG); 6520 mWifiOn = true; 6521 mWifiOnTimer.startRunningLocked(elapsedRealtimeMs); 6522 if (mWifiPowerStatsCollector.isEnabled()) { 6523 mWifiPowerStatsCollector.schedule(); 6524 } else { 6525 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 6526 } 6527 } 6528 } 6529 6530 @GuardedBy("this") noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs)6531 public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) { 6532 if (mWifiOn) { 6533 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6534 HistoryItem.STATE2_WIFI_ON_FLAG); 6535 mWifiOn = false; 6536 mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs); 6537 if (mWifiPowerStatsCollector.isEnabled()) { 6538 mWifiPowerStatsCollector.schedule(); 6539 } else { 6540 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 6541 } 6542 } 6543 } 6544 6545 @GuardedBy("this") noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6546 public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6547 uid = mapUid(uid); 6548 if (mAudioOnNesting == 0) { 6549 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6550 HistoryItem.STATE_AUDIO_ON_FLAG, uid, "audio"); 6551 mAudioOnTimer.startRunningLocked(elapsedRealtimeMs); 6552 } 6553 mAudioOnNesting++; 6554 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_AUDIO)) { 6555 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6556 .noteAudioTurnedOnLocked(elapsedRealtimeMs); 6557 } 6558 } 6559 6560 @GuardedBy("this") noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6561 public void noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6562 if (mAudioOnNesting == 0) { 6563 return; 6564 } 6565 uid = mapUid(uid); 6566 if (--mAudioOnNesting == 0) { 6567 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6568 HistoryItem.STATE_AUDIO_ON_FLAG, uid, "audio"); 6569 mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs); 6570 } 6571 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_AUDIO)) { 6572 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6573 .noteAudioTurnedOffLocked(elapsedRealtimeMs); 6574 } 6575 } 6576 6577 @GuardedBy("this") noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6578 public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6579 uid = mapUid(uid); 6580 if (mVideoOnNesting == 0) { 6581 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6582 HistoryItem.STATE2_VIDEO_ON_FLAG, uid, "video"); 6583 mVideoOnTimer.startRunningLocked(elapsedRealtimeMs); 6584 } 6585 mVideoOnNesting++; 6586 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_VIDEO)) { 6587 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6588 .noteVideoTurnedOnLocked(elapsedRealtimeMs); 6589 } 6590 } 6591 6592 @GuardedBy("this") noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6593 public void noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6594 if (mVideoOnNesting == 0) { 6595 return; 6596 } 6597 uid = mapUid(uid); 6598 if (--mVideoOnNesting == 0) { 6599 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6600 HistoryItem.STATE2_VIDEO_ON_FLAG, uid, "video"); 6601 mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs); 6602 } 6603 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_VIDEO)) { 6604 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6605 .noteVideoTurnedOffLocked(elapsedRealtimeMs); 6606 } 6607 } 6608 6609 @GuardedBy("this") noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs)6610 public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) { 6611 if (mAudioOnNesting > 0) { 6612 mAudioOnNesting = 0; 6613 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6614 HistoryItem.STATE_AUDIO_ON_FLAG); 6615 mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6616 for (int i=0; i<mUidStats.size(); i++) { 6617 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6618 uid.noteResetAudioLocked(elapsedRealtimeMs); 6619 } 6620 } 6621 } 6622 6623 @GuardedBy("this") noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs)6624 public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) { 6625 if (mVideoOnNesting > 0) { 6626 mVideoOnNesting = 0; 6627 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6628 HistoryItem.STATE2_VIDEO_ON_FLAG); 6629 mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6630 for (int i=0; i<mUidStats.size(); i++) { 6631 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6632 uid.noteResetVideoLocked(elapsedRealtimeMs); 6633 } 6634 } 6635 } 6636 6637 @GuardedBy("this") noteActivityResumedLocked(int uid)6638 public void noteActivityResumedLocked(int uid) { 6639 noteActivityResumedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6640 } 6641 6642 @GuardedBy("this") noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6643 public void noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6644 uid = mapUid(uid); 6645 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6646 .noteActivityResumedLocked(elapsedRealtimeMs); 6647 } 6648 6649 @GuardedBy("this") noteActivityPausedLocked(int uid)6650 public void noteActivityPausedLocked(int uid) { 6651 noteActivityPausedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6652 } 6653 6654 @GuardedBy("this") noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6655 public void noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6656 uid = mapUid(uid); 6657 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6658 .noteActivityPausedLocked(elapsedRealtimeMs); 6659 } 6660 6661 @GuardedBy("this") noteVibratorOnLocked(int uid, long durationMillis, long elapsedRealtimeMs, long uptimeMs)6662 public void noteVibratorOnLocked(int uid, long durationMillis, 6663 long elapsedRealtimeMs, long uptimeMs) { 6664 uid = mapUid(uid); 6665 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6666 .noteVibratorOnLocked(durationMillis, elapsedRealtimeMs); 6667 } 6668 6669 @GuardedBy("this") noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6670 public void noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6671 uid = mapUid(uid); 6672 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6673 .noteVibratorOffLocked(elapsedRealtimeMs); 6674 } 6675 6676 @GuardedBy("this") noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6677 public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6678 uid = mapUid(uid); 6679 if (mFlashlightOnNesting++ == 0) { 6680 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6681 HistoryItem.STATE2_FLASHLIGHT_FLAG, uid, "flashlight"); 6682 mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs); 6683 } 6684 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) { 6685 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6686 .noteFlashlightTurnedOnLocked(elapsedRealtimeMs); 6687 } 6688 } 6689 6690 @GuardedBy("this") noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6691 public void noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6692 if (mFlashlightOnNesting == 0) { 6693 return; 6694 } 6695 uid = mapUid(uid); 6696 if (--mFlashlightOnNesting == 0) { 6697 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6698 HistoryItem.STATE2_FLASHLIGHT_FLAG, uid, "flashlight"); 6699 mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs); 6700 } 6701 if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) { 6702 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6703 .noteFlashlightTurnedOffLocked(elapsedRealtimeMs); 6704 } 6705 } 6706 6707 @GuardedBy("this") noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6708 public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6709 uid = mapUid(uid); 6710 if (mCameraOnNesting++ == 0) { 6711 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6712 HistoryItem.STATE2_CAMERA_FLAG, uid, "camera"); 6713 mCameraOnTimer.startRunningLocked(elapsedRealtimeMs); 6714 } 6715 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6716 .noteCameraTurnedOnLocked(elapsedRealtimeMs); 6717 6718 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CAMERA)) { 6719 mCameraPowerStatsCollector.schedule(); 6720 } else { 6721 scheduleSyncExternalStatsLocked("camera-on", ExternalStatsSync.UPDATE_CAMERA); 6722 } 6723 } 6724 6725 @GuardedBy("this") noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6726 public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6727 if (mCameraOnNesting == 0) { 6728 return; 6729 } 6730 uid = mapUid(uid); 6731 if (--mCameraOnNesting == 0) { 6732 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6733 HistoryItem.STATE2_CAMERA_FLAG, uid, "camera"); 6734 mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs); 6735 } 6736 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6737 .noteCameraTurnedOffLocked(elapsedRealtimeMs); 6738 6739 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CAMERA)) { 6740 mCameraPowerStatsCollector.schedule(); 6741 } else { 6742 scheduleSyncExternalStatsLocked("camera-off", ExternalStatsSync.UPDATE_CAMERA); 6743 } 6744 } 6745 6746 @GuardedBy("this") noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs)6747 public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) { 6748 if (mCameraOnNesting > 0) { 6749 mCameraOnNesting = 0; 6750 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6751 HistoryItem.STATE2_CAMERA_FLAG); 6752 mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6753 for (int i=0; i<mUidStats.size(); i++) { 6754 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6755 uid.noteResetCameraLocked(elapsedRealtimeMs); 6756 } 6757 } 6758 6759 scheduleSyncExternalStatsLocked("camera-reset", ExternalStatsSync.UPDATE_CAMERA); 6760 } 6761 6762 @GuardedBy("this") noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs)6763 public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) { 6764 if (mFlashlightOnNesting > 0) { 6765 mFlashlightOnNesting = 0; 6766 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6767 HistoryItem.STATE2_FLASHLIGHT_FLAG); 6768 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6769 for (int i=0; i<mUidStats.size(); i++) { 6770 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6771 uid.noteResetFlashlightLocked(elapsedRealtimeMs); 6772 } 6773 } 6774 } 6775 6776 @GuardedBy("this") noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6777 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 6778 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 6779 if (workChain != null) { 6780 uid = workChain.getAttributionUid(); 6781 } 6782 uid = mapUid(uid); 6783 if (mBluetoothScanNesting == 0) { 6784 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6785 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6786 mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs); 6787 } 6788 mBluetoothScanNesting++; 6789 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6790 .noteBluetoothScanStartedLocked(elapsedRealtimeMs, isUnoptimized); 6791 } 6792 6793 @GuardedBy("this") noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)6794 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 6795 noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized, 6796 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6797 } 6798 6799 @GuardedBy("this") noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6800 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 6801 long elapsedRealtimeMs, long uptimeMs) { 6802 final int N = ws.size(); 6803 for (int i = 0; i < N; i++) { 6804 noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized, 6805 elapsedRealtimeMs, uptimeMs); 6806 } 6807 6808 final List<WorkChain> workChains = ws.getWorkChains(); 6809 if (workChains != null) { 6810 for (int i = 0; i < workChains.size(); ++i) { 6811 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized, 6812 elapsedRealtimeMs, uptimeMs); 6813 } 6814 } 6815 } 6816 6817 @GuardedBy("this") noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6818 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 6819 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 6820 if (workChain != null) { 6821 uid = workChain.getAttributionUid(); 6822 } 6823 uid = mapUid(uid); 6824 mBluetoothScanNesting--; 6825 if (mBluetoothScanNesting == 0) { 6826 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6827 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6828 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 6829 } 6830 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6831 .noteBluetoothScanStoppedLocked(elapsedRealtimeMs, isUnoptimized); 6832 } 6833 6834 @GuardedBy("this") noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)6835 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 6836 noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized, 6837 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6838 } 6839 6840 @GuardedBy("this") noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6841 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 6842 long elapsedRealtimeMs, long uptimeMs) { 6843 final int N = ws.size(); 6844 for (int i = 0; i < N; i++) { 6845 noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized, 6846 elapsedRealtimeMs, uptimeMs); 6847 } 6848 6849 final List<WorkChain> workChains = ws.getWorkChains(); 6850 if (workChains != null) { 6851 for (int i = 0; i < workChains.size(); ++i) { 6852 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized, 6853 elapsedRealtimeMs, uptimeMs); 6854 } 6855 } 6856 } 6857 6858 @GuardedBy("this") noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs)6859 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) { 6860 if (mBluetoothScanNesting > 0) { 6861 mBluetoothScanNesting = 0; 6862 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6863 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6864 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 6865 for (int i=0; i<mUidStats.size(); i++) { 6866 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6867 uid.noteResetBluetoothScanLocked(elapsedRealtimeMs); 6868 } 6869 } 6870 } 6871 6872 @GuardedBy("this") noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)6873 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 6874 noteBluetoothScanResultsFromSourceLocked(ws, numNewResults, 6875 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6876 } 6877 6878 @GuardedBy("this") noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, long elapsedRealtimeMs, long uptimeMs)6879 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, 6880 long elapsedRealtimeMs, long uptimeMs) { 6881 final int N = ws.size(); 6882 for (int i = 0; i < N; i++) { 6883 int uid = mapUid(ws.getUid(i)); 6884 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6885 .noteBluetoothScanResultsLocked(numNewResults); 6886 } 6887 6888 final List<WorkChain> workChains = ws.getWorkChains(); 6889 if (workChains != null) { 6890 for (int i = 0; i < workChains.size(); ++i) { 6891 final WorkChain wc = workChains.get(i); 6892 int uid = mapUid(wc.getAttributionUid()); 6893 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6894 .noteBluetoothScanResultsLocked(numNewResults); 6895 } 6896 } 6897 } 6898 retrieveBluetoothScanTimesLocked( BluetoothPowerStatsCollector.BluetoothStatsRetriever.Callback callback)6899 private void retrieveBluetoothScanTimesLocked( 6900 BluetoothPowerStatsCollector.BluetoothStatsRetriever.Callback callback) { 6901 long elapsedTimeUs = mClock.elapsedRealtime() * 1000; 6902 for (int i = mUidStats.size() - 1; i >= 0; i--) { 6903 Uid uidStats = mUidStats.valueAt(i); 6904 if (uidStats.mBluetoothScanTimer == null) { 6905 continue; 6906 } 6907 6908 long scanTimeUs = mBluetoothScanTimer.getTotalTimeLocked(elapsedTimeUs, 6909 STATS_SINCE_CHARGED); 6910 if (scanTimeUs != 0) { 6911 int uid = mUidStats.keyAt(i); 6912 callback.onBluetoothScanTime(uid, (scanTimeUs + 500) / 1000); 6913 } 6914 } 6915 } 6916 6917 @GuardedBy("this") noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)6918 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 6919 final long uptimeMillis, int uid) { 6920 uid = mapUid(uid); 6921 mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 6922 uid); 6923 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked(); 6924 } 6925 6926 @GuardedBy("this") noteWifiRadioPowerState(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)6927 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid, 6928 long elapsedRealtimeMs, long uptimeMs) { 6929 if (mWifiRadioPowerState != powerState) { 6930 final boolean active = 6931 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 6932 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 6933 if (active) { 6934 if (uid > 0) { 6935 noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 6936 } 6937 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6938 HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG); 6939 mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs); 6940 } else { 6941 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6942 HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG); 6943 mWifiActiveTimer.stopRunningLocked(timestampNs / (1000 * 1000)); 6944 } 6945 mWifiRadioPowerState = powerState; 6946 } 6947 } 6948 6949 @GuardedBy("this") noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6950 public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6951 if (!mGlobalWifiRunning) { 6952 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6953 HistoryItem.STATE2_WIFI_RUNNING_FLAG); 6954 mGlobalWifiRunning = true; 6955 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 6956 int N = ws.size(); 6957 for (int i=0; i<N; i++) { 6958 int uid = mapUid(ws.getUid(i)); 6959 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6960 .noteWifiRunningLocked(elapsedRealtimeMs); 6961 } 6962 6963 List<WorkChain> workChains = ws.getWorkChains(); 6964 if (workChains != null) { 6965 for (int i = 0; i < workChains.size(); ++i) { 6966 int uid = mapUid(workChains.get(i).getAttributionUid()); 6967 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6968 .noteWifiRunningLocked(elapsedRealtimeMs); 6969 } 6970 } 6971 if (mWifiPowerStatsCollector.isEnabled()) { 6972 mWifiPowerStatsCollector.schedule(); 6973 } else { 6974 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 6975 } 6976 } else { 6977 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 6978 } 6979 } 6980 6981 @GuardedBy("this") noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)6982 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, 6983 long elapsedRealtimeMs, long uptimeMs) { 6984 if (mGlobalWifiRunning) { 6985 int N = oldWs.size(); 6986 for (int i=0; i<N; i++) { 6987 int uid = mapUid(oldWs.getUid(i)); 6988 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6989 .noteWifiStoppedLocked(elapsedRealtimeMs); 6990 } 6991 6992 List<WorkChain> workChains = oldWs.getWorkChains(); 6993 if (workChains != null) { 6994 for (int i = 0; i < workChains.size(); ++i) { 6995 int uid = mapUid(workChains.get(i).getAttributionUid()); 6996 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6997 .noteWifiStoppedLocked(elapsedRealtimeMs); 6998 } 6999 } 7000 7001 N = newWs.size(); 7002 for (int i=0; i<N; i++) { 7003 int uid = mapUid(newWs.getUid(i)); 7004 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7005 .noteWifiRunningLocked(elapsedRealtimeMs); 7006 } 7007 7008 workChains = newWs.getWorkChains(); 7009 if (workChains != null) { 7010 for (int i = 0; i < workChains.size(); ++i) { 7011 int uid = mapUid(workChains.get(i).getAttributionUid()); 7012 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7013 .noteWifiRunningLocked(elapsedRealtimeMs); 7014 } 7015 } 7016 } else { 7017 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 7018 } 7019 } 7020 7021 @GuardedBy("this") noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7022 public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 7023 if (mGlobalWifiRunning) { 7024 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 7025 HistoryItem.STATE2_WIFI_RUNNING_FLAG); 7026 mGlobalWifiRunning = false; 7027 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 7028 int N = ws.size(); 7029 for (int i=0; i<N; i++) { 7030 int uid = mapUid(ws.getUid(i)); 7031 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7032 .noteWifiStoppedLocked(elapsedRealtimeMs); 7033 } 7034 7035 List<WorkChain> workChains = ws.getWorkChains(); 7036 if (workChains != null) { 7037 for (int i = 0; i < workChains.size(); ++i) { 7038 int uid = mapUid(workChains.get(i).getAttributionUid()); 7039 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7040 .noteWifiStoppedLocked(elapsedRealtimeMs); 7041 } 7042 } 7043 7044 if (mWifiPowerStatsCollector.isEnabled()) { 7045 mWifiPowerStatsCollector.schedule(); 7046 } else { 7047 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 7048 } 7049 } else { 7050 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 7051 } 7052 } 7053 7054 @GuardedBy("this") noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs)7055 public void noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs) { 7056 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 7057 if (mWifiState != wifiState) { 7058 if (mWifiState >= 0) { 7059 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtimeMs); 7060 } 7061 mWifiState = wifiState; 7062 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtimeMs); 7063 if (mWifiPowerStatsCollector.isEnabled()) { 7064 mWifiPowerStatsCollector.schedule(); 7065 } else { 7066 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 7067 } 7068 } 7069 } 7070 7071 @GuardedBy("this") noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, long elapsedRealtimeMs, long uptimeMs)7072 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, 7073 long elapsedRealtimeMs, long uptimeMs) { 7074 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 7075 if (mWifiSupplState != supplState) { 7076 if (mWifiSupplState >= 0) { 7077 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtimeMs); 7078 } 7079 mWifiSupplState = supplState; 7080 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs); 7081 mHistory.recordWifiSupplicantStateChangeEvent(elapsedRealtimeMs, uptimeMs, supplState); 7082 } 7083 } 7084 7085 @GuardedBy("this") stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)7086 void stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 7087 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 7088 if (i == except) { 7089 continue; 7090 } 7091 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 7092 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 7093 } 7094 } 7095 } 7096 7097 @GuardedBy("this") noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs)7098 public void noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs) { 7099 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 7100 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 7101 if (mWifiSignalStrengthBin != strengthBin) { 7102 if (mWifiSignalStrengthBin >= 0) { 7103 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 7104 elapsedRealtimeMs); 7105 } 7106 if (strengthBin >= 0) { 7107 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 7108 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 7109 } 7110 mHistory.recordWifiSignalStrengthChangeEvent(elapsedRealtimeMs, uptimeMs, 7111 strengthBin); 7112 } else { 7113 stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 7114 } 7115 mWifiSignalStrengthBin = strengthBin; 7116 } 7117 } 7118 7119 private int mWifiFullLockNesting = 0; 7120 7121 @GuardedBy("this") noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7122 public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7123 if (mWifiFullLockNesting == 0) { 7124 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 7125 HistoryItem.STATE_WIFI_FULL_LOCK_FLAG); 7126 } 7127 mWifiFullLockNesting++; 7128 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7129 .noteFullWifiLockAcquiredLocked(elapsedRealtimeMs); 7130 } 7131 7132 @GuardedBy("this") noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7133 public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7134 mWifiFullLockNesting--; 7135 if (mWifiFullLockNesting == 0) { 7136 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 7137 HistoryItem.STATE_WIFI_FULL_LOCK_FLAG); 7138 } 7139 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7140 .noteFullWifiLockReleasedLocked(elapsedRealtimeMs); 7141 } 7142 7143 int mWifiScanNesting = 0; 7144 7145 @GuardedBy("this") noteWifiScanStartedLocked(int uid)7146 public void noteWifiScanStartedLocked(int uid) { 7147 noteWifiScanStartedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7148 } 7149 7150 @GuardedBy("this") noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7151 public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7152 if (mWifiScanNesting == 0) { 7153 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 7154 HistoryItem.STATE_WIFI_SCAN_FLAG); 7155 } 7156 mWifiScanNesting++; 7157 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7158 .noteWifiScanStartedLocked(elapsedRealtimeMs); 7159 } 7160 7161 @GuardedBy("this") noteWifiScanStoppedLocked(int uid)7162 public void noteWifiScanStoppedLocked(int uid) { 7163 noteWifiScanStoppedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7164 } 7165 7166 @GuardedBy("this") noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7167 public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7168 mWifiScanNesting--; 7169 if (mWifiScanNesting == 0) { 7170 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 7171 HistoryItem.STATE_WIFI_SCAN_FLAG); 7172 } 7173 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7174 .noteWifiScanStoppedLocked(elapsedRealtimeMs); 7175 } 7176 noteWifiBatchedScanStartedLocked(int uid, int csph, long elapsedRealtimeMs, long uptimeMs)7177 public void noteWifiBatchedScanStartedLocked(int uid, int csph, 7178 long elapsedRealtimeMs, long uptimeMs) { 7179 uid = mapUid(uid); 7180 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7181 .noteWifiBatchedScanStartedLocked(csph, elapsedRealtimeMs); 7182 } 7183 noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7184 public void noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7185 uid = mapUid(uid); 7186 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7187 .noteWifiBatchedScanStoppedLocked(elapsedRealtimeMs); 7188 } 7189 retrieveWifiScanTimesLocked( WifiPowerStatsCollector.WifiStatsRetriever.Callback callback)7190 private void retrieveWifiScanTimesLocked( 7191 WifiPowerStatsCollector.WifiStatsRetriever.Callback callback) { 7192 long elapsedTimeUs = mClock.elapsedRealtime() * 1000; 7193 for (int i = mUidStats.size() - 1; i >= 0; i--) { 7194 int uid = mUidStats.keyAt(i); 7195 Uid uidStats = mUidStats.valueAt(i); 7196 long scanTimeUs = uidStats.getWifiScanTime(elapsedTimeUs, STATS_SINCE_CHARGED); 7197 long batchScanTimeUs = 0; 7198 for (int bucket = 0; bucket < NUM_WIFI_BATCHED_SCAN_BINS; bucket++) { 7199 batchScanTimeUs += uidStats.getWifiBatchedScanTime(bucket, elapsedTimeUs, 7200 STATS_SINCE_CHARGED); 7201 } 7202 if (scanTimeUs != 0 || batchScanTimeUs != 0) { 7203 callback.onWifiScanTime(uid, (scanTimeUs + 500) / 1000, 7204 (batchScanTimeUs + 500) / 1000); 7205 } 7206 } 7207 } 7208 7209 private int mWifiMulticastNesting = 0; 7210 7211 @GuardedBy("this") noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7212 public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7213 uid = mapUid(uid); 7214 if (mWifiMulticastNesting == 0) { 7215 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 7216 HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG); 7217 // Start Wifi Multicast overall timer 7218 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 7219 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs); 7220 } 7221 } 7222 mWifiMulticastNesting++; 7223 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7224 .noteWifiMulticastEnabledLocked(elapsedRealtimeMs); 7225 } 7226 7227 @GuardedBy("this") noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7228 public void noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7229 uid = mapUid(uid); 7230 mWifiMulticastNesting--; 7231 if (mWifiMulticastNesting == 0) { 7232 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 7233 HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG); 7234 7235 // Stop Wifi Multicast overall timer 7236 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 7237 if (DEBUG) Slog.v(TAG, "Multicast Overall Timer Stopped"); 7238 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 7239 } 7240 } 7241 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7242 .noteWifiMulticastDisabledLocked(elapsedRealtimeMs); 7243 } 7244 7245 @GuardedBy("this") noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7246 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, 7247 long elapsedRealtimeMs, long uptimeMs) { 7248 int N = ws.size(); 7249 for (int i=0; i<N; i++) { 7250 final int uid = mapUid(ws.getUid(i)); 7251 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 7252 } 7253 7254 final List<WorkChain> workChains = ws.getWorkChains(); 7255 if (workChains != null) { 7256 for (int i = 0; i < workChains.size(); ++i) { 7257 final WorkChain workChain = workChains.get(i); 7258 final int uid = mapUid(workChain.getAttributionUid()); 7259 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 7260 } 7261 } 7262 } 7263 7264 @GuardedBy("this") noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7265 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, 7266 long elapsedRealtimeMs, long uptimeMs) { 7267 int N = ws.size(); 7268 for (int i=0; i<N; i++) { 7269 final int uid = mapUid(ws.getUid(i)); 7270 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 7271 } 7272 7273 final List<WorkChain> workChains = ws.getWorkChains(); 7274 if (workChains != null) { 7275 for (int i = 0; i < workChains.size(); ++i) { 7276 final WorkChain workChain = workChains.get(i); 7277 final int uid = mapUid(workChain.getAttributionUid()); 7278 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 7279 } 7280 } 7281 } 7282 7283 @GuardedBy("this") noteWifiScanStartedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7284 public void noteWifiScanStartedFromSourceLocked(WorkSource ws, 7285 long elapsedRealtimeMs, long uptimeMs) { 7286 int N = ws.size(); 7287 for (int i=0; i<N; i++) { 7288 final int uid = mapUid(ws.getUid(i)); 7289 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 7290 } 7291 7292 final List<WorkChain> workChains = ws.getWorkChains(); 7293 if (workChains != null) { 7294 for (int i = 0; i < workChains.size(); ++i) { 7295 final WorkChain workChain = workChains.get(i); 7296 final int uid = mapUid(workChain.getAttributionUid()); 7297 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 7298 } 7299 } 7300 } 7301 7302 @GuardedBy("this") noteWifiScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7303 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws, 7304 long elapsedRealtimeMs, long uptimeMs) { 7305 int N = ws.size(); 7306 for (int i=0; i<N; i++) { 7307 final int uid = mapUid(ws.getUid(i)); 7308 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 7309 } 7310 7311 final List<WorkChain> workChains = ws.getWorkChains(); 7312 if (workChains != null) { 7313 for (int i = 0; i < workChains.size(); ++i) { 7314 final WorkChain workChain = workChains.get(i); 7315 final int uid = mapUid(workChain.getAttributionUid()); 7316 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 7317 } 7318 } 7319 } 7320 7321 @GuardedBy("this") noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, long elapsedRealtimeMs, long uptimeMs)7322 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, 7323 long elapsedRealtimeMs, long uptimeMs) { 7324 int N = ws.size(); 7325 for (int i=0; i<N; i++) { 7326 noteWifiBatchedScanStartedLocked(ws.getUid(i), csph, elapsedRealtimeMs, uptimeMs); 7327 } 7328 7329 final List<WorkChain> workChains = ws.getWorkChains(); 7330 if (workChains != null) { 7331 for (int i = 0; i < workChains.size(); ++i) { 7332 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph, 7333 elapsedRealtimeMs, uptimeMs); 7334 } 7335 } 7336 } 7337 7338 @GuardedBy("this") noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7339 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, 7340 long elapsedRealtimeMs, long uptimeMs) { 7341 int N = ws.size(); 7342 for (int i=0; i<N; i++) { 7343 noteWifiBatchedScanStoppedLocked(ws.getUid(i), elapsedRealtimeMs, uptimeMs); 7344 } 7345 7346 final List<WorkChain> workChains = ws.getWorkChains(); 7347 if (workChains != null) { 7348 for (int i = 0; i < workChains.size(); ++i) { 7349 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid(), 7350 elapsedRealtimeMs, uptimeMs); 7351 } 7352 } 7353 } 7354 includeInStringArray(String[] array, String str)7355 private static String[] includeInStringArray(String[] array, String str) { 7356 if (ArrayUtils.indexOf(array, str) >= 0) { 7357 return array; 7358 } 7359 String[] newArray = new String[array.length+1]; 7360 System.arraycopy(array, 0, newArray, 0, array.length); 7361 newArray[array.length] = str; 7362 return newArray; 7363 } 7364 excludeFromStringArray(String[] array, String str)7365 private static String[] excludeFromStringArray(String[] array, String str) { 7366 int index = ArrayUtils.indexOf(array, str); 7367 if (index >= 0) { 7368 String[] newArray = new String[array.length-1]; 7369 if (index > 0) { 7370 System.arraycopy(array, 0, newArray, 0, index); 7371 } 7372 if (index < array.length-1) { 7373 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 7374 } 7375 return newArray; 7376 } 7377 return array; 7378 } 7379 7380 /** @hide */ noteNetworkInterfaceForTransports(String iface, int[] transportTypes)7381 public void noteNetworkInterfaceForTransports(String iface, int[] transportTypes) { 7382 if (TextUtils.isEmpty(iface)) return; 7383 final int displayTransport = getDisplayTransport(transportTypes); 7384 7385 synchronized (mModemNetworkLock) { 7386 if (displayTransport == TRANSPORT_CELLULAR) { 7387 mModemIfaces = includeInStringArray(mModemIfaces, iface); 7388 if (DEBUG) { 7389 Slog.d(TAG, "Note mobile iface " + iface + ": " 7390 + Arrays.toString(mModemIfaces)); 7391 } 7392 } else { 7393 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 7394 if (DEBUG) { 7395 Slog.d(TAG, "Note non-mobile iface " + iface + ": " 7396 + Arrays.toString(mModemIfaces)); 7397 } 7398 } 7399 } 7400 7401 synchronized (mWifiNetworkLock) { 7402 if (displayTransport == TRANSPORT_WIFI) { 7403 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 7404 if (DEBUG) { 7405 Slog.d(TAG, "Note wifi iface " + iface + ": " + Arrays.toString(mWifiIfaces)); 7406 } 7407 } else { 7408 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 7409 if (DEBUG) { 7410 Slog.d(TAG, "Note non-wifi iface " + iface + ": " 7411 + Arrays.toString(mWifiIfaces)); 7412 } 7413 } 7414 } 7415 } 7416 7417 /** 7418 * Records timing data related to an incoming Binder call in order to attribute 7419 * the power consumption to the calling app. 7420 */ noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)7421 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 7422 Collection<BinderCallsStats.CallStat> callStats) { 7423 noteBinderCallStats(workSourceUid, incrementalCallCount, callStats, 7424 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7425 } 7426 noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats, long elapsedRealtimeMs, long uptimeMs)7427 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 7428 Collection<BinderCallsStats.CallStat> callStats, 7429 long elapsedRealtimeMs, long uptimeMs) { 7430 synchronized (this) { 7431 getUidStatsLocked(workSourceUid, elapsedRealtimeMs, uptimeMs) 7432 .noteBinderCallStatsLocked(incrementalCallCount, callStats); 7433 } 7434 } 7435 7436 /** 7437 * Takes note of native IDs of threads taking incoming binder calls. The CPU time 7438 * of these threads is attributed to the apps making those binder calls. 7439 */ noteBinderThreadNativeIds(int[] binderThreadNativeTids)7440 public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) { 7441 mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids); 7442 } 7443 7444 /** 7445 * Estimates the proportion of system server CPU activity handling incoming binder calls 7446 * that can be attributed to each app 7447 */ 7448 @VisibleForTesting updateSystemServiceCallStats()7449 public void updateSystemServiceCallStats() { 7450 // Start off by computing the average duration of recorded binder calls, 7451 // regardless of which binder or transaction. We will use this as a fallback 7452 // for calls that were not sampled at all. 7453 int totalRecordedCallCount = 0; 7454 long totalRecordedCallTimeMicros = 0; 7455 for (int i = 0; i < mUidStats.size(); i++) { 7456 Uid uid = mUidStats.valueAt(i); 7457 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 7458 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 7459 BinderCallStats stats = binderCallStats.valueAt(j); 7460 totalRecordedCallCount += stats.recordedCallCount; 7461 totalRecordedCallTimeMicros += stats.recordedCpuTimeMicros; 7462 } 7463 } 7464 7465 long totalSystemServiceTimeMicros = 0; 7466 7467 // For every UID, use recorded durations of sampled binder calls to estimate 7468 // the total time the system server spent handling requests from this UID. 7469 for (int i = 0; i < mUidStats.size(); i++) { 7470 Uid uid = mUidStats.valueAt(i); 7471 7472 long totalTimeForUidUs = 0; 7473 int totalCallCountForUid = 0; 7474 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 7475 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 7476 BinderCallStats stats = binderCallStats.valueAt(j); 7477 totalCallCountForUid += stats.callCount; 7478 if (stats.recordedCallCount > 0) { 7479 totalTimeForUidUs += 7480 stats.callCount * stats.recordedCpuTimeMicros / stats.recordedCallCount; 7481 } else if (totalRecordedCallCount > 0) { 7482 totalTimeForUidUs += 7483 stats.callCount * totalRecordedCallTimeMicros / totalRecordedCallCount; 7484 } 7485 } 7486 7487 if (totalCallCountForUid < uid.mBinderCallCount && totalRecordedCallCount > 0) { 7488 // Estimate remaining calls, which were not tracked because of binder call 7489 // stats sampling 7490 totalTimeForUidUs += 7491 (uid.mBinderCallCount - totalCallCountForUid) * totalRecordedCallTimeMicros 7492 / totalRecordedCallCount; 7493 } 7494 7495 uid.mSystemServiceTimeUs = totalTimeForUidUs; 7496 totalSystemServiceTimeMicros += totalTimeForUidUs; 7497 } 7498 7499 for (int i = 0; i < mUidStats.size(); i++) { 7500 Uid uid = mUidStats.valueAt(i); 7501 if (totalSystemServiceTimeMicros > 0) { 7502 uid.mProportionalSystemServiceUsage = 7503 (double) uid.mSystemServiceTimeUs / totalSystemServiceTimeMicros; 7504 } else { 7505 uid.mProportionalSystemServiceUsage = 0; 7506 } 7507 } 7508 } 7509 getWifiIfaces()7510 public String[] getWifiIfaces() { 7511 synchronized (mWifiNetworkLock) { 7512 return mWifiIfaces; 7513 } 7514 } 7515 getMobileIfaces()7516 public String[] getMobileIfaces() { 7517 synchronized (mModemNetworkLock) { 7518 return mModemIfaces; 7519 } 7520 } 7521 getScreenOnTime(long elapsedRealtimeUs, int which)7522 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 7523 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7524 } 7525 getScreenOnCount(int which)7526 @Override public int getScreenOnCount(int which) { 7527 return mScreenOnTimer.getCountLocked(which); 7528 } 7529 getScreenDozeTime(long elapsedRealtimeUs, int which)7530 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 7531 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7532 } 7533 getScreenDozeCount(int which)7534 @Override public int getScreenDozeCount(int which) { 7535 return mScreenDozeTimer.getCountLocked(which); 7536 } 7537 getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)7538 @Override public long getScreenBrightnessTime(int brightnessBin, 7539 long elapsedRealtimeUs, int which) { 7540 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 7541 elapsedRealtimeUs, which); 7542 } 7543 getScreenBrightnessTimer(int brightnessBin)7544 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 7545 return mScreenBrightnessTimer[brightnessBin]; 7546 } 7547 7548 @Override getDisplayCount()7549 public int getDisplayCount() { 7550 return mPerDisplayBatteryStats.length; 7551 } 7552 7553 @Override getDisplayScreenOnTime(int display, long elapsedRealtimeUs)7554 public long getDisplayScreenOnTime(int display, long elapsedRealtimeUs) { 7555 return mPerDisplayBatteryStats[display].screenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, 7556 STATS_SINCE_CHARGED); 7557 } 7558 7559 @Override getDisplayScreenDozeTime(int display, long elapsedRealtimeUs)7560 public long getDisplayScreenDozeTime(int display, long elapsedRealtimeUs) { 7561 return mPerDisplayBatteryStats[display].screenDozeTimer.getTotalTimeLocked( 7562 elapsedRealtimeUs, STATS_SINCE_CHARGED); 7563 } 7564 7565 @Override getDisplayScreenBrightnessTime(int display, int brightnessBin, long elapsedRealtimeUs)7566 public long getDisplayScreenBrightnessTime(int display, int brightnessBin, 7567 long elapsedRealtimeUs) { 7568 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 7569 return displayStats.screenBrightnessTimers[brightnessBin].getTotalTimeLocked( 7570 elapsedRealtimeUs, STATS_SINCE_CHARGED); 7571 } 7572 getInteractiveTime(long elapsedRealtimeUs, int which)7573 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 7574 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7575 } 7576 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)7577 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 7578 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7579 } 7580 getPowerSaveModeEnabledCount(int which)7581 @Override public int getPowerSaveModeEnabledCount(int which) { 7582 return mPowerSaveModeEnabledTimer.getCountLocked(which); 7583 } 7584 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)7585 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 7586 int which) { 7587 switch (mode) { 7588 case DEVICE_IDLE_MODE_LIGHT: 7589 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7590 case DEVICE_IDLE_MODE_DEEP: 7591 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7592 } 7593 return 0; 7594 } 7595 getDeviceIdleModeCount(int mode, int which)7596 @Override public int getDeviceIdleModeCount(int mode, int which) { 7597 switch (mode) { 7598 case DEVICE_IDLE_MODE_LIGHT: 7599 return mDeviceIdleModeLightTimer.getCountLocked(which); 7600 case DEVICE_IDLE_MODE_DEEP: 7601 return mDeviceIdleModeFullTimer.getCountLocked(which); 7602 } 7603 return 0; 7604 } 7605 getLongestDeviceIdleModeTime(int mode)7606 @Override public long getLongestDeviceIdleModeTime(int mode) { 7607 switch (mode) { 7608 case DEVICE_IDLE_MODE_LIGHT: 7609 return mLongestLightIdleTimeMs; 7610 case DEVICE_IDLE_MODE_DEEP: 7611 return mLongestFullIdleTimeMs; 7612 } 7613 return 0; 7614 } 7615 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)7616 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 7617 switch (mode) { 7618 case DEVICE_IDLE_MODE_LIGHT: 7619 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7620 case DEVICE_IDLE_MODE_DEEP: 7621 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7622 } 7623 return 0; 7624 } 7625 getDeviceIdlingCount(int mode, int which)7626 @Override public int getDeviceIdlingCount(int mode, int which) { 7627 switch (mode) { 7628 case DEVICE_IDLE_MODE_LIGHT: 7629 return mDeviceLightIdlingTimer.getCountLocked(which); 7630 case DEVICE_IDLE_MODE_DEEP: 7631 return mDeviceIdlingTimer.getCountLocked(which); 7632 } 7633 return 0; 7634 } 7635 getNumConnectivityChange(int which)7636 @Override public int getNumConnectivityChange(int which) { 7637 return mNumConnectivityChange; 7638 } 7639 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)7640 @Override public long getGpsSignalQualityTime(int strengthBin, 7641 long elapsedRealtimeUs, int which) { 7642 if (strengthBin < 0 || strengthBin >= mGpsSignalQualityTimer.length) { 7643 return 0; 7644 } 7645 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 7646 elapsedRealtimeUs, which); 7647 } 7648 getGpsBatteryDrainMaMs()7649 @Override public long getGpsBatteryDrainMaMs() { 7650 final double opVolt = mPowerProfile.getAveragePower( 7651 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 7652 if (opVolt == 0) { 7653 return 0; 7654 } 7655 double energyUsedMaMs = 0.0; 7656 final int which = STATS_SINCE_CHARGED; 7657 final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000; 7658 for(int i=0; i < mGpsSignalQualityTimer.length; i++) { 7659 energyUsedMaMs 7660 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 7661 * (getGpsSignalQualityTime(i, rawRealtimeUs, which) / 1000); 7662 } 7663 return (long) energyUsedMaMs; 7664 } 7665 getPhoneOnTime(long elapsedRealtimeUs, int which)7666 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 7667 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7668 } 7669 getPhoneOnCount(int which)7670 @Override public int getPhoneOnCount(int which) { 7671 return mPhoneOnTimer.getCountLocked(which); 7672 } 7673 getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)7674 @Override public long getPhoneSignalStrengthTime(int strengthBin, 7675 long elapsedRealtimeUs, int which) { 7676 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 7677 elapsedRealtimeUs, which); 7678 } 7679 getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)7680 @Override public long getPhoneSignalScanningTime( 7681 long elapsedRealtimeUs, int which) { 7682 return mPhoneSignalScanningTimer.getTotalTimeLocked( 7683 elapsedRealtimeUs, which); 7684 } 7685 getPhoneSignalScanningTimer()7686 @Override public Timer getPhoneSignalScanningTimer() { 7687 return mPhoneSignalScanningTimer; 7688 } 7689 getPhoneSignalStrengthCount(int strengthBin, int which)7690 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 7691 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 7692 } 7693 getPhoneSignalStrengthTimer(int strengthBin)7694 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 7695 return mPhoneSignalStrengthsTimer[strengthBin]; 7696 } 7697 getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)7698 @Override public long getPhoneDataConnectionTime(int dataType, 7699 long elapsedRealtimeUs, int which) { 7700 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 7701 elapsedRealtimeUs, which); 7702 } 7703 getPhoneDataConnectionCount(int dataType, int which)7704 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 7705 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 7706 } 7707 getPhoneDataConnectionTimer(int dataType)7708 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 7709 return mPhoneDataConnectionsTimer[dataType]; 7710 } 7711 getNrNsaTime(long elapsedRealtimeUs)7712 @Override public long getNrNsaTime(long elapsedRealtimeUs) { 7713 return mNrNsaTimer.getTotalTimeLocked(elapsedRealtimeUs, STATS_SINCE_CHARGED); 7714 } 7715 getActiveRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)7716 @Override public long getActiveRadioDurationMs(@RadioAccessTechnology int rat, 7717 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, 7718 long elapsedRealtimeMs) { 7719 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7720 if (stats == null) return 0L; 7721 7722 final int freqCount = stats.perStateTimers.length; 7723 if (frequencyRange < 0 || frequencyRange >= freqCount) return 0L; 7724 7725 final StopwatchTimer[] strengthTimers = stats.perStateTimers[frequencyRange]; 7726 final int strengthCount = strengthTimers.length; 7727 if (signalStrength < 0 || signalStrength >= strengthCount) return 0L; 7728 7729 return stats.perStateTimers[frequencyRange][signalStrength].getTotalTimeLocked( 7730 elapsedRealtimeMs * 1000, STATS_SINCE_CHARGED) / 1000; 7731 } 7732 7733 @Override getActiveTxRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)7734 public long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat, 7735 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, 7736 long elapsedRealtimeMs) { 7737 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7738 if (stats == null) return DURATION_UNAVAILABLE; 7739 7740 final LongSamplingCounter counter = stats.getTxDurationCounter(frequencyRange, 7741 signalStrength, false); 7742 if (counter == null) return DURATION_UNAVAILABLE; 7743 7744 return counter.getCountLocked(STATS_SINCE_CHARGED); 7745 } 7746 7747 @Override getActiveRxRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs)7748 public long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat, 7749 @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs) { 7750 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7751 if (stats == null) return DURATION_UNAVAILABLE; 7752 7753 final LongSamplingCounter counter = stats.getRxDurationCounter(frequencyRange, false); 7754 if (counter == null) return DURATION_UNAVAILABLE; 7755 7756 return counter.getCountLocked(STATS_SINCE_CHARGED); 7757 } 7758 getMobileRadioActiveTime(long elapsedRealtimeUs, int which)7759 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 7760 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7761 } 7762 getMobileRadioActiveCount(int which)7763 @Override public int getMobileRadioActiveCount(int which) { 7764 return mMobileRadioActiveTimer.getCountLocked(which); 7765 } 7766 getMobileRadioActiveAdjustedTime(int which)7767 @Override public long getMobileRadioActiveAdjustedTime(int which) { 7768 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 7769 } 7770 getMobileRadioActiveUnknownTime(int which)7771 @Override public long getMobileRadioActiveUnknownTime(int which) { 7772 return mMobileRadioActiveUnknownTime.getCountLocked(which); 7773 } 7774 getMobileRadioActiveUnknownCount(int which)7775 @Override public int getMobileRadioActiveUnknownCount(int which) { 7776 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 7777 } 7778 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)7779 @Override public long getWifiMulticastWakelockTime( 7780 long elapsedRealtimeUs, int which) { 7781 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 7782 elapsedRealtimeUs, which); 7783 } 7784 getWifiMulticastWakelockCount(int which)7785 @Override public int getWifiMulticastWakelockCount(int which) { 7786 return mWifiMulticastWakelockTimer.getCountLocked(which); 7787 } 7788 getWifiOnTime(long elapsedRealtimeUs, int which)7789 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 7790 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7791 } 7792 getWifiActiveTime(long elapsedRealtimeUs, int which)7793 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 7794 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7795 } 7796 getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)7797 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 7798 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7799 } 7800 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)7801 @Override public long getWifiStateTime(int wifiState, 7802 long elapsedRealtimeUs, int which) { 7803 return mWifiStateTimer[wifiState].getTotalTimeLocked( 7804 elapsedRealtimeUs, which); 7805 } 7806 getWifiStateCount(int wifiState, int which)7807 @Override public int getWifiStateCount(int wifiState, int which) { 7808 return mWifiStateTimer[wifiState].getCountLocked(which); 7809 } 7810 getWifiStateTimer(int wifiState)7811 @Override public Timer getWifiStateTimer(int wifiState) { 7812 return mWifiStateTimer[wifiState]; 7813 } 7814 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)7815 @Override public long getWifiSupplStateTime(int state, 7816 long elapsedRealtimeUs, int which) { 7817 return mWifiSupplStateTimer[state].getTotalTimeLocked( 7818 elapsedRealtimeUs, which); 7819 } 7820 getWifiSupplStateCount(int state, int which)7821 @Override public int getWifiSupplStateCount(int state, int which) { 7822 return mWifiSupplStateTimer[state].getCountLocked(which); 7823 } 7824 getWifiSupplStateTimer(int state)7825 @Override public Timer getWifiSupplStateTimer(int state) { 7826 return mWifiSupplStateTimer[state]; 7827 } 7828 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)7829 @Override public long getWifiSignalStrengthTime(int strengthBin, 7830 long elapsedRealtimeUs, int which) { 7831 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 7832 elapsedRealtimeUs, which); 7833 } 7834 getWifiSignalStrengthCount(int strengthBin, int which)7835 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 7836 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 7837 } 7838 getWifiSignalStrengthTimer(int strengthBin)7839 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 7840 return mWifiSignalStrengthsTimer[strengthBin]; 7841 } 7842 7843 @Override getBluetoothControllerActivity()7844 public ControllerActivityCounter getBluetoothControllerActivity() { 7845 return mBluetoothActivity; 7846 } 7847 7848 @Override getWifiControllerActivity()7849 public ControllerActivityCounter getWifiControllerActivity() { 7850 return mWifiActivity; 7851 } 7852 7853 @Override getModemControllerActivity()7854 public ControllerActivityCounter getModemControllerActivity() { 7855 return mModemActivity; 7856 } 7857 7858 @Override hasBluetoothActivityReporting()7859 public boolean hasBluetoothActivityReporting() { 7860 return mHasBluetoothReporting; 7861 } 7862 7863 @Override hasWifiActivityReporting()7864 public boolean hasWifiActivityReporting() { 7865 return mHasWifiReporting; 7866 } 7867 7868 @Override hasModemActivityReporting()7869 public boolean hasModemActivityReporting() { 7870 return mHasModemReporting; 7871 } 7872 7873 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)7874 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 7875 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7876 } 7877 7878 @Override getFlashlightOnCount(int which)7879 public long getFlashlightOnCount(int which) { 7880 return mFlashlightOnTimer.getCountLocked(which); 7881 } 7882 7883 @Override getCameraOnTime(long elapsedRealtimeUs, int which)7884 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 7885 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7886 } 7887 7888 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)7889 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 7890 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7891 } 7892 7893 @Override getNetworkActivityBytes(int type, int which)7894 public long getNetworkActivityBytes(int type, int which) { 7895 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 7896 return mNetworkByteActivityCounters[type].getCountLocked(which); 7897 } else { 7898 return 0; 7899 } 7900 } 7901 7902 @Override getNetworkActivityPackets(int type, int which)7903 public long getNetworkActivityPackets(int type, int which) { 7904 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 7905 return mNetworkPacketActivityCounters[type].getCountLocked(which); 7906 } else { 7907 return 0; 7908 } 7909 } 7910 7911 @GuardedBy("this") 7912 @Override getBluetoothEnergyConsumptionUC()7913 public long getBluetoothEnergyConsumptionUC() { 7914 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH); 7915 } 7916 7917 @GuardedBy("this") 7918 @Override getCpuEnergyConsumptionUC()7919 public long getCpuEnergyConsumptionUC() { 7920 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU); 7921 } 7922 7923 @GuardedBy("this") 7924 @Override getGnssEnergyConsumptionUC()7925 public long getGnssEnergyConsumptionUC() { 7926 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_GNSS); 7927 } 7928 7929 @GuardedBy("this") 7930 @Override getMobileRadioEnergyConsumptionUC()7931 public long getMobileRadioEnergyConsumptionUC() { 7932 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 7933 } 7934 7935 @GuardedBy("this") 7936 @Override getPhoneEnergyConsumptionUC()7937 public long getPhoneEnergyConsumptionUC() { 7938 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_PHONE); 7939 } 7940 7941 @GuardedBy("this") 7942 @Override getScreenOnEnergyConsumptionUC()7943 public long getScreenOnEnergyConsumptionUC() { 7944 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON); 7945 } 7946 7947 @GuardedBy("this") 7948 @Override getScreenDozeEnergyConsumptionUC()7949 public long getScreenDozeEnergyConsumptionUC() { 7950 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_DOZE); 7951 } 7952 7953 @GuardedBy("this") 7954 @Override getWifiEnergyConsumptionUC()7955 public long getWifiEnergyConsumptionUC() { 7956 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI); 7957 } 7958 7959 @GuardedBy("this") 7960 @Override getCameraEnergyConsumptionUC()7961 public long getCameraEnergyConsumptionUC() { 7962 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CAMERA); 7963 } 7964 7965 /** 7966 * Returns the consumption (in microcoulombs) that the given standard power bucket consumed. 7967 * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable 7968 * 7969 * @param bucket standard power bucket of interest 7970 * @return charge (in microcoulombs) used for this power bucket 7971 */ 7972 @GuardedBy("this") getPowerBucketConsumptionUC(@tandardPowerBucket int bucket)7973 private long getPowerBucketConsumptionUC(@StandardPowerBucket int bucket) { 7974 if (mGlobalEnergyConsumerStats == null) { 7975 return POWER_DATA_UNAVAILABLE; 7976 } 7977 return mGlobalEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket); 7978 } 7979 7980 @GuardedBy("this") 7981 @Override getCustomEnergyConsumerBatteryConsumptionUC()7982 public @Nullable long[] getCustomEnergyConsumerBatteryConsumptionUC() { 7983 if (mGlobalEnergyConsumerStats == null) { 7984 return null; 7985 } 7986 return mGlobalEnergyConsumerStats.getAccumulatedCustomBucketCharges(); 7987 } 7988 7989 /** 7990 * Returns the names of custom power components. 7991 */ 7992 @Override getCustomEnergyConsumerNames()7993 public @NonNull String[] getCustomEnergyConsumerNames() { 7994 synchronized (this) { 7995 if (mEnergyConsumerStatsConfig == null) { 7996 return new String[0]; 7997 } 7998 final String[] names = mEnergyConsumerStatsConfig.getCustomBucketNames(); 7999 for (int i = 0; i < names.length; i++) { 8000 if (TextUtils.isEmpty(names[i])) { 8001 names[i] = "CUSTOM_" + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i; 8002 } 8003 } 8004 return names; 8005 } 8006 } 8007 8008 @Override getStartClockTime()8009 public long getStartClockTime() { 8010 synchronized (this) { 8011 final long currentTimeMs = mClock.currentTimeMillis(); 8012 if ((currentTimeMs > MILLISECONDS_IN_YEAR 8013 && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR)) 8014 || (mStartClockTimeMs > currentTimeMs)) { 8015 // If the start clock time has changed by more than a year, then presumably 8016 // the previous time was completely bogus. So we are going to figure out a 8017 // new time based on how much time has elapsed since we started counting. 8018 mHistory.recordCurrentTimeChange(mClock.elapsedRealtime(), mClock.uptimeMillis(), 8019 currentTimeMs); 8020 adjustStartClockTime(currentTimeMs); 8021 } 8022 return mStartClockTimeMs; 8023 } 8024 } 8025 8026 /** 8027 * Returns the monotonic time when the BatteryStats session started. 8028 */ getMonotonicStartTime()8029 public long getMonotonicStartTime() { 8030 return mMonotonicStartTime; 8031 } 8032 8033 /** 8034 * Returns the monotonic time when the BatteryStats session ended, or 8035 * {@link MonotonicClock#UNDEFINED} if the session is still ongoing. 8036 */ getMonotonicEndTime()8037 public long getMonotonicEndTime() { 8038 return mMonotonicEndTime; 8039 } 8040 getStartPlatformVersion()8041 @Override public String getStartPlatformVersion() { 8042 return mStartPlatformVersion; 8043 } 8044 getEndPlatformVersion()8045 @Override public String getEndPlatformVersion() { 8046 return mEndPlatformVersion; 8047 } 8048 getParcelVersion()8049 @Override public int getParcelVersion() { 8050 return VERSION; 8051 } 8052 getIsOnBattery()8053 @Override public boolean getIsOnBattery() { 8054 return mOnBattery; 8055 } 8056 getStatsStartRealtime()8057 @Override public long getStatsStartRealtime() { 8058 return mRealtimeStartUs; 8059 } 8060 getUidStats()8061 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 8062 return mUidStats; 8063 } 8064 resetIfNotNull(T t, boolean detachIfReset, long elapsedRealtimeUs)8065 private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset, 8066 long elapsedRealtimeUs) { 8067 if (t != null) { 8068 return t.reset(detachIfReset, elapsedRealtimeUs); 8069 } 8070 return true; 8071 } 8072 resetIfNotNull(T[] t, boolean detachIfReset, long elapsedRealtimeUs)8073 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset, 8074 long elapsedRealtimeUs) { 8075 if (t != null) { 8076 boolean ret = true; 8077 for (int i = 0; i < t.length; i++) { 8078 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 8079 } 8080 return ret; 8081 } 8082 return true; 8083 } 8084 resetIfNotNull(T[][] t, boolean detachIfReset, long elapsedRealtimeUs)8085 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset, 8086 long elapsedRealtimeUs) { 8087 if (t != null) { 8088 boolean ret = true; 8089 for (int i = 0; i < t.length; i++) { 8090 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 8091 } 8092 return ret; 8093 } 8094 return true; 8095 } 8096 resetIfNotNull(ControllerActivityCounterImpl counter, boolean detachIfReset, long elapsedRealtimeUs)8097 private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, 8098 boolean detachIfReset, long elapsedRealtimeUs) { 8099 if (counter != null) { 8100 counter.reset(detachIfReset, elapsedRealtimeUs); 8101 } 8102 return true; 8103 } 8104 detachIfNotNull(T t)8105 private static <T extends TimeBaseObs> void detachIfNotNull(T t) { 8106 if (t != null) { 8107 t.detach(); 8108 } 8109 } 8110 detachIfNotNull(T[] t)8111 private static <T extends TimeBaseObs> void detachIfNotNull(T[] t) { 8112 if (t != null) { 8113 for (int i = 0; i < t.length; i++) { 8114 detachIfNotNull(t[i]); 8115 } 8116 } 8117 } 8118 detachIfNotNull(T[][] t)8119 private static <T extends TimeBaseObs> void detachIfNotNull(T[][] t) { 8120 if (t != null) { 8121 for (int i = 0; i < t.length; i++) { 8122 detachIfNotNull(t[i]); 8123 } 8124 } 8125 } 8126 detachIfNotNull(ControllerActivityCounterImpl counter)8127 private static void detachIfNotNull(ControllerActivityCounterImpl counter) { 8128 if (counter != null) { 8129 counter.detach(); 8130 } 8131 } 8132 8133 /** 8134 * Accumulates stats for a specific binder transaction. 8135 */ 8136 @VisibleForTesting 8137 protected static class BinderCallStats { 8138 public Class<? extends Binder> binderClass; 8139 public int transactionCode; 8140 public String methodName; 8141 8142 public long callCount; 8143 public long recordedCallCount; 8144 public long recordedCpuTimeMicros; 8145 8146 8147 @Override hashCode()8148 public int hashCode() { 8149 return binderClass.hashCode() * 31 + transactionCode; 8150 } 8151 8152 @Override equals(Object obj)8153 public boolean equals(Object obj) { 8154 if (!(obj instanceof BinderCallStats)) { 8155 return false; 8156 } 8157 BinderCallStats bcsk = (BinderCallStats) obj; 8158 return binderClass.equals(bcsk.binderClass) && transactionCode == bcsk.transactionCode; 8159 } 8160 getClassName()8161 public String getClassName() { 8162 return binderClass.getName(); 8163 } 8164 getMethodName()8165 public String getMethodName() { 8166 return methodName; 8167 } 8168 8169 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) ensureMethodName(BinderTransactionNameResolver resolver)8170 public void ensureMethodName(BinderTransactionNameResolver resolver) { 8171 if (methodName == null) { 8172 methodName = resolver.getMethodName(binderClass, transactionCode); 8173 } 8174 } 8175 8176 @Override toString()8177 public String toString() { 8178 return "BinderCallStats{" 8179 + binderClass 8180 + " transaction=" + transactionCode 8181 + " callCount=" + callCount 8182 + " recordedCallCount=" + recordedCallCount 8183 + " recorderCpuTimeMicros=" + recordedCpuTimeMicros 8184 + "}"; 8185 } 8186 } 8187 8188 /** 8189 * The statistics associated with a particular uid. 8190 */ 8191 public static class Uid extends BatteryStats.Uid { 8192 /** 8193 * BatteryStatsImpl that we are associated with. 8194 */ 8195 protected BatteryStatsImpl mBsi; 8196 8197 final int mUid; 8198 8199 /** TimeBase for when uid is in background and device is on battery. */ 8200 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 8201 public final TimeBase mOnBatteryBackgroundTimeBase; 8202 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 8203 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 8204 8205 boolean mWifiRunning; 8206 StopwatchTimer mWifiRunningTimer; 8207 8208 boolean mFullWifiLockOut; 8209 StopwatchTimer mFullWifiLockTimer; 8210 8211 boolean mWifiScanStarted; 8212 DualTimer mWifiScanTimer; 8213 8214 static final int NO_BATCHED_SCAN_STARTED = -1; 8215 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8216 StopwatchTimer[] mWifiBatchedScanTimer; 8217 8218 int mWifiMulticastWakelockCount; 8219 StopwatchTimer mWifiMulticastTimer; 8220 8221 StopwatchTimer mAudioTurnedOnTimer; 8222 StopwatchTimer mVideoTurnedOnTimer; 8223 StopwatchTimer mFlashlightTurnedOnTimer; 8224 StopwatchTimer mCameraTurnedOnTimer; 8225 StopwatchTimer mForegroundActivityTimer; 8226 StopwatchTimer mForegroundServiceTimer; 8227 /** Total time spent by the uid holding any partial wakelocks. */ 8228 DualTimer mAggregatedPartialWakelockTimer; 8229 DualTimer mBluetoothScanTimer; 8230 DualTimer mBluetoothUnoptimizedScanTimer; 8231 Counter mBluetoothScanResultCounter; 8232 Counter mBluetoothScanResultBgCounter; 8233 8234 int mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 8235 StopwatchTimer[] mProcessStateTimer; 8236 8237 boolean mInForegroundService = false; 8238 8239 BatchTimer mVibratorOnTimer; 8240 8241 Counter[] mUserActivityCounters; 8242 8243 LongSamplingCounter[] mNetworkByteActivityCounters; 8244 LongSamplingCounter[] mNetworkPacketActivityCounters; 8245 TimeMultiStateCounter mMobileRadioActiveTime; 8246 LongSamplingCounter mMobileRadioActiveCount; 8247 8248 /** 8249 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 8250 */ 8251 private LongSamplingCounter mMobileRadioApWakeupCount; 8252 8253 /** 8254 * How many times this UID woke up the Application Processor due to a Wifi packet. 8255 */ 8256 private LongSamplingCounter mWifiRadioApWakeupCount; 8257 8258 /** 8259 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 8260 * Can be null if the UID has had no such activity. 8261 */ 8262 private ControllerActivityCounterImpl mWifiControllerActivity; 8263 8264 /** 8265 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 8266 * Can be null if the UID has had no such activity. 8267 */ 8268 private ControllerActivityCounterImpl mBluetoothControllerActivity; 8269 8270 /** 8271 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 8272 * Can be null if the UID has had no such activity. 8273 */ 8274 private ControllerActivityCounterImpl mModemControllerActivity; 8275 8276 /** 8277 * The CPU times we had at the last history details update. 8278 */ 8279 long mLastStepUserTimeMs; 8280 long mLastStepSystemTimeMs; 8281 long mCurStepUserTimeMs; 8282 long mCurStepSystemTimeMs; 8283 8284 LongSamplingCounter mUserCpuTime; 8285 LongSamplingCounter mSystemCpuTime; 8286 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 8287 TimeMultiStateCounter mCpuActiveTimeMs; 8288 8289 LongSamplingCounterArray mCpuFreqTimeMs; 8290 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 8291 LongSamplingCounterArray mCpuClusterTimesMs; 8292 8293 TimeInFreqMultiStateCounter mProcStateTimeMs; 8294 TimeInFreqMultiStateCounter mProcStateScreenOffTimeMs; 8295 8296 SparseArray<ChildUid> mChildUids; 8297 8298 /** 8299 * The statistics we have collected for this uid's wake locks. 8300 */ 8301 final OverflowArrayMap<Wakelock> mWakelockStats; 8302 8303 /** 8304 * The statistics we have collected for this uid's syncs. 8305 */ 8306 final OverflowArrayMap<DualTimer> mSyncStats; 8307 8308 /** 8309 * The statistics we have collected for this uid's jobs. 8310 */ 8311 final OverflowArrayMap<DualTimer> mJobStats; 8312 8313 /** 8314 * Count of the jobs that have completed and the reasons why they completed. 8315 */ 8316 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 8317 8318 /** 8319 * Count of app launch events that had associated deferred job counts or info about 8320 * last time a job was run. 8321 */ 8322 Counter mJobsDeferredEventCount; 8323 8324 /** 8325 * Count of deferred jobs that were pending when the app was launched or brought to 8326 * the foreground through a user interaction. 8327 */ 8328 Counter mJobsDeferredCount; 8329 8330 /** 8331 * Sum of time since the last time a job was run for this app before it was launched. 8332 */ 8333 LongSamplingCounter mJobsFreshnessTimeMs; 8334 8335 /** 8336 * Array of counts of instances where the time since the last job was run for the app 8337 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 8338 */ 8339 final Counter[] mJobsFreshnessBuckets; 8340 8341 /** 8342 * The statistics we have collected for this uid's sensor activations. 8343 */ 8344 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 8345 8346 /** 8347 * The statistics we have collected for this uid's processes. 8348 */ 8349 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 8350 8351 /** 8352 * The statistics we have collected for this uid's processes. 8353 */ 8354 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 8355 8356 /** 8357 * The transient wake stats we have collected for this uid's pids. 8358 */ 8359 final SparseArray<Pid> mPids = new SparseArray<>(); 8360 8361 /** 8362 * Grand total of system server binder calls made by this uid. 8363 */ 8364 private long mBinderCallCount; 8365 8366 /** 8367 * Detailed information about system server binder calls made by this uid. 8368 */ 8369 private final ArraySet<BinderCallStats> mBinderCallStats = new ArraySet<>(); 8370 8371 /** 8372 * EnergyConsumer consumption by this uid while on battery. 8373 * Its '<b>custom</b> power buckets' correspond to the 8374 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 8375 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 8376 * 8377 * Will be null if energy consumer data is completely unavailable (in which case 8378 * {@link #mGlobalEnergyConsumerStats} will also be null) or if the power usage by this uid 8379 * is 0 for every bucket. 8380 */ 8381 private EnergyConsumerStats mUidEnergyConsumerStats; 8382 8383 /** 8384 * Estimated total time spent by the system server handling requests from this uid. 8385 */ 8386 private long mSystemServiceTimeUs; 8387 8388 /** 8389 * Estimated proportion of system server binder call CPU cost for this uid. 8390 */ 8391 private double mProportionalSystemServiceUsage; 8392 Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs)8393 public Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs) { 8394 mBsi = bsi; 8395 mUid = uid; 8396 8397 /* Observer list of TimeBase object in Uid is short */ 8398 mOnBatteryBackgroundTimeBase = new TimeBase(false); 8399 mOnBatteryBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 8400 /* Observer list of TimeBase object in Uid is short */ 8401 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); 8402 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 8403 8404 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8405 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8406 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 8407 8408 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 8409 @Override public Wakelock instantiateObject() { 8410 return new Wakelock(mBsi, Uid.this); 8411 } 8412 }; 8413 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 8414 @Override public DualTimer instantiateObject() { 8415 return new DualTimer(mBsi.mClock, Uid.this, SYNC, null, 8416 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8417 } 8418 }; 8419 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 8420 @Override public DualTimer instantiateObject() { 8421 return new DualTimer(mBsi.mClock, Uid.this, JOB, null, 8422 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8423 } 8424 }; 8425 8426 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, this, WIFI_RUNNING, 8427 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 8428 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, this, FULL_WIFI_LOCK, 8429 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 8430 mWifiScanTimer = new DualTimer(mBsi.mClock, this, WIFI_SCAN, 8431 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8432 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 8433 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, this, WIFI_MULTICAST_ENABLED, 8434 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 8435 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 8436 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 8437 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 8438 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8439 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 8440 } 8441 8442 @GuardedBy("mBsi") 8443 @VisibleForTesting setProcessStateForTest(int procState, long elapsedTimeMs)8444 public void setProcessStateForTest(int procState, long elapsedTimeMs) { 8445 mProcessState = procState; 8446 getProcStateTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs); 8447 getProcStateScreenOffTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs); 8448 final int batteryConsumerProcessState = 8449 mapUidProcessStateToBatteryConsumerProcessState(procState); 8450 getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); 8451 getMobileRadioActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); 8452 final ControllerActivityCounterImpl wifiControllerActivity = 8453 getWifiControllerActivity(); 8454 if (wifiControllerActivity != null) { 8455 wifiControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs); 8456 } 8457 final ControllerActivityCounterImpl bluetoothControllerActivity = 8458 getBluetoothControllerActivity(); 8459 if (bluetoothControllerActivity != null) { 8460 bluetoothControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs); 8461 } 8462 final EnergyConsumerStats energyStats = 8463 getOrCreateEnergyConsumerStatsIfSupportedLocked(); 8464 if (energyStats != null) { 8465 energyStats.setState(batteryConsumerProcessState, elapsedTimeMs); 8466 } 8467 } 8468 8469 @Override getCpuFreqTimes(int which)8470 public long[] getCpuFreqTimes(int which) { 8471 return nullIfAllZeros(mCpuFreqTimeMs, which); 8472 } 8473 8474 @Override getScreenOffCpuFreqTimes(int which)8475 public long[] getScreenOffCpuFreqTimes(int which) { 8476 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 8477 } 8478 getCpuActiveTimeCounter()8479 private TimeMultiStateCounter getCpuActiveTimeCounter() { 8480 if (mCpuActiveTimeMs == null) { 8481 final long timestampMs = mBsi.mClock.elapsedRealtime(); 8482 mCpuActiveTimeMs = new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, 8483 BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 8484 mCpuActiveTimeMs.setState( 8485 mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 8486 timestampMs); 8487 } 8488 return mCpuActiveTimeMs; 8489 } 8490 8491 @Override getCpuActiveTime()8492 public long getCpuActiveTime() { 8493 if (mCpuActiveTimeMs == null) { 8494 return 0; 8495 } 8496 8497 long activeTime = 0; 8498 for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { 8499 activeTime += mCpuActiveTimeMs.getCountForProcessState(procState); 8500 } 8501 return activeTime; 8502 } 8503 8504 @Override getCpuActiveTime(int procState)8505 public long getCpuActiveTime(int procState) { 8506 if (mCpuActiveTimeMs == null 8507 || procState < 0 || procState >= BatteryConsumer.PROCESS_STATE_COUNT) { 8508 return 0; 8509 } 8510 8511 return mCpuActiveTimeMs.getCountForProcessState(procState); 8512 } 8513 8514 @Override getCpuClusterTimes()8515 public long[] getCpuClusterTimes() { 8516 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 8517 } 8518 8519 @GuardedBy("mBsi") 8520 @Override getCpuFreqTimes(long[] timesInFreqMs, int procState)8521 public boolean getCpuFreqTimes(long[] timesInFreqMs, int procState) { 8522 if (procState < 0 || procState >= NUM_PROCESS_STATE) { 8523 return false; 8524 } 8525 if (mProcStateTimeMs == null) { 8526 return false; 8527 } 8528 if (!mBsi.mPerProcStateCpuTimesAvailable) { 8529 mProcStateTimeMs = null; 8530 return false; 8531 } 8532 return mProcStateTimeMs.getCountsLocked(timesInFreqMs, procState); 8533 } 8534 8535 @GuardedBy("mBsi") 8536 @Override getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState)8537 public boolean getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState) { 8538 if (procState < 0 || procState >= NUM_PROCESS_STATE) { 8539 return false; 8540 } 8541 if (mProcStateScreenOffTimeMs == null) { 8542 return false; 8543 } 8544 if (!mBsi.mPerProcStateCpuTimesAvailable) { 8545 mProcStateScreenOffTimeMs = null; 8546 return false; 8547 } 8548 return mProcStateScreenOffTimeMs.getCountsLocked(timesInFreqMs, procState); 8549 } 8550 getBinderCallCount()8551 public long getBinderCallCount() { 8552 return mBinderCallCount; 8553 } 8554 8555 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) getBinderCallStats()8556 public ArraySet<BinderCallStats> getBinderCallStats() { 8557 return mBinderCallStats; 8558 } 8559 8560 @Override getProportionalSystemServiceUsage()8561 public double getProportionalSystemServiceUsage() { 8562 return mProportionalSystemServiceUsage; 8563 } 8564 8565 /** 8566 * Adds isolated UID to the list of children. 8567 */ addIsolatedUid(int isolatedUid)8568 public void addIsolatedUid(int isolatedUid) { 8569 if (mChildUids == null) { 8570 mChildUids = new SparseArray<>(); 8571 } else if (mChildUids.indexOfKey(isolatedUid) >= 0) { 8572 return; 8573 } 8574 mChildUids.put(isolatedUid, new ChildUid()); 8575 } 8576 8577 /** 8578 * Removes isolated UID from the list of children. 8579 */ removeIsolatedUid(int isolatedUid)8580 public void removeIsolatedUid(int isolatedUid) { 8581 final int idx = mChildUids == null ? -1 : mChildUids.indexOfKey(isolatedUid); 8582 if (idx < 0) { 8583 return; 8584 } 8585 mChildUids.remove(idx); 8586 } 8587 8588 @GuardedBy("mBsi") getChildUid(int childUid)8589 ChildUid getChildUid(int childUid) { 8590 return mChildUids == null ? null : mChildUids.get(childUid); 8591 } 8592 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)8593 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 8594 if (cpuTimesMs == null) { 8595 return null; 8596 } 8597 final long[] counts = cpuTimesMs.getCountsLocked(which); 8598 if (counts == null) { 8599 return null; 8600 } 8601 // Return counts only if at least one of the elements is non-zero. 8602 for (int i = counts.length - 1; i >= 0; --i) { 8603 if (counts[i] != 0) { 8604 return counts; 8605 } 8606 } 8607 return null; 8608 } 8609 8610 @GuardedBy("mBsi") ensureMultiStateCounters(long timestampMs)8611 private void ensureMultiStateCounters(long timestampMs) { 8612 if (mBsi.mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 8613 throw new IllegalStateException("Multi-state counters used in streamlined mode"); 8614 } 8615 8616 if (mProcStateTimeMs == null) { 8617 mProcStateTimeMs = 8618 new TimeInFreqMultiStateCounter(mBsi.mOnBatteryTimeBase, 8619 PROC_STATE_TIME_COUNTER_STATE_COUNT, 8620 mBsi.mCpuScalingPolicies.getScalingStepCount(), 8621 timestampMs); 8622 } 8623 if (mProcStateScreenOffTimeMs == null) { 8624 mProcStateScreenOffTimeMs = 8625 new TimeInFreqMultiStateCounter(mBsi.mOnBatteryScreenOffTimeBase, 8626 PROC_STATE_TIME_COUNTER_STATE_COUNT, 8627 mBsi.mCpuScalingPolicies.getScalingStepCount(), 8628 timestampMs); 8629 } 8630 } 8631 8632 @GuardedBy("mBsi") getProcStateTimeCounter(long timestampMs)8633 private TimeInFreqMultiStateCounter getProcStateTimeCounter(long timestampMs) { 8634 ensureMultiStateCounters(timestampMs); 8635 return mProcStateTimeMs; 8636 } 8637 8638 @GuardedBy("mBsi") getProcStateScreenOffTimeCounter(long timestampMs)8639 private TimeInFreqMultiStateCounter getProcStateScreenOffTimeCounter(long timestampMs) { 8640 ensureMultiStateCounters(timestampMs); 8641 return mProcStateScreenOffTimeMs; 8642 } 8643 8644 @Override getAggregatedPartialWakelockTimer()8645 public Timer getAggregatedPartialWakelockTimer() { 8646 return mAggregatedPartialWakelockTimer; 8647 } 8648 8649 @Override getWakelockStats()8650 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 8651 return mWakelockStats.getMap(); 8652 } 8653 8654 @Override getMulticastWakelockStats()8655 public Timer getMulticastWakelockStats() { 8656 return mWifiMulticastTimer; 8657 } 8658 8659 @Override getSyncStats()8660 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 8661 return mSyncStats.getMap(); 8662 } 8663 8664 @Override getJobStats()8665 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 8666 return mJobStats.getMap(); 8667 } 8668 8669 @Override getJobCompletionStats()8670 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 8671 return mJobCompletions; 8672 } 8673 8674 @Override getSensorStats()8675 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 8676 return mSensorStats; 8677 } 8678 8679 @Override getProcessStats()8680 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 8681 return mProcessStats; 8682 } 8683 8684 @Override getPackageStats()8685 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 8686 return mPackageStats; 8687 } 8688 8689 @Override getUid()8690 public int getUid() { 8691 return mUid; 8692 } 8693 8694 @Override noteWifiRunningLocked(long elapsedRealtimeMs)8695 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 8696 if (!mWifiRunning) { 8697 mWifiRunning = true; 8698 if (mWifiRunningTimer == null) { 8699 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, Uid.this, WIFI_RUNNING, 8700 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 8701 } 8702 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 8703 } 8704 } 8705 8706 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)8707 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 8708 if (mWifiRunning) { 8709 mWifiRunning = false; 8710 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 8711 } 8712 } 8713 8714 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)8715 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 8716 if (!mFullWifiLockOut) { 8717 mFullWifiLockOut = true; 8718 if (mFullWifiLockTimer == null) { 8719 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, Uid.this, FULL_WIFI_LOCK, 8720 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 8721 } 8722 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 8723 } 8724 } 8725 8726 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)8727 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 8728 if (mFullWifiLockOut) { 8729 mFullWifiLockOut = false; 8730 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 8731 } 8732 } 8733 8734 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)8735 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 8736 if (!mWifiScanStarted) { 8737 mWifiScanStarted = true; 8738 if (mWifiScanTimer == null) { 8739 mWifiScanTimer = new DualTimer(mBsi.mClock, Uid.this, WIFI_SCAN, 8740 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 8741 mOnBatteryBackgroundTimeBase); 8742 } 8743 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 8744 } 8745 } 8746 8747 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)8748 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 8749 if (mWifiScanStarted) { 8750 mWifiScanStarted = false; 8751 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 8752 } 8753 } 8754 8755 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)8756 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 8757 int bin = 0; 8758 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 8759 csph = csph >> 3; 8760 bin++; 8761 } 8762 8763 if (mWifiBatchedScanBinStarted == bin) return; 8764 8765 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 8766 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 8767 stopRunningLocked(elapsedRealtimeMs); 8768 } 8769 mWifiBatchedScanBinStarted = bin; 8770 if (mWifiBatchedScanTimer[bin] == null) { 8771 makeWifiBatchedScanBin(bin, null); 8772 } 8773 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 8774 } 8775 8776 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)8777 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 8778 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 8779 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 8780 stopRunningLocked(elapsedRealtimeMs); 8781 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8782 } 8783 } 8784 8785 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)8786 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 8787 if (mWifiMulticastWakelockCount == 0) { 8788 if (mWifiMulticastTimer == null) { 8789 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 8790 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 8791 } 8792 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 8793 } 8794 mWifiMulticastWakelockCount++; 8795 } 8796 8797 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)8798 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 8799 if (mWifiMulticastWakelockCount == 0) { 8800 return; 8801 } 8802 8803 mWifiMulticastWakelockCount--; 8804 if (mWifiMulticastWakelockCount == 0) { 8805 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 8806 } 8807 } 8808 8809 @Override getWifiControllerActivity()8810 public ControllerActivityCounterImpl getWifiControllerActivity() { 8811 return mWifiControllerActivity; 8812 } 8813 8814 @Override getBluetoothControllerActivity()8815 public ControllerActivityCounterImpl getBluetoothControllerActivity() { 8816 return mBluetoothControllerActivity; 8817 } 8818 8819 @Override getModemControllerActivity()8820 public ControllerActivityCounter getModemControllerActivity() { 8821 return mModemControllerActivity; 8822 } 8823 getOrCreateWifiControllerActivityLocked()8824 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 8825 if (mWifiControllerActivity == null) { 8826 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8827 mBsi.mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 8828 } 8829 return mWifiControllerActivity; 8830 } 8831 getOrCreateBluetoothControllerActivityLocked()8832 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 8833 if (mBluetoothControllerActivity == null) { 8834 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8835 mBsi.mOnBatteryTimeBase, NUM_BT_TX_LEVELS); 8836 } 8837 return mBluetoothControllerActivity; 8838 } 8839 getOrCreateModemControllerActivityLocked()8840 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 8841 if (mModemControllerActivity == null) { 8842 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8843 mBsi.mOnBatteryTimeBase, mBsi.MODEM_TX_POWER_LEVEL_COUNT); 8844 } 8845 return mModemControllerActivity; 8846 } 8847 8848 @GuardedBy("mBsi") getOrCreateEnergyConsumerStatsLocked()8849 private EnergyConsumerStats getOrCreateEnergyConsumerStatsLocked() { 8850 if (mUidEnergyConsumerStats == null) { 8851 mUidEnergyConsumerStats = new EnergyConsumerStats(mBsi.mEnergyConsumerStatsConfig); 8852 } 8853 return mUidEnergyConsumerStats; 8854 } 8855 8856 @GuardedBy("mBsi") getOrCreateEnergyConsumerStatsIfSupportedLocked()8857 private EnergyConsumerStats getOrCreateEnergyConsumerStatsIfSupportedLocked() { 8858 if (mUidEnergyConsumerStats == null && mBsi.mEnergyConsumerStatsConfig != null) { 8859 mUidEnergyConsumerStats = new EnergyConsumerStats(mBsi.mEnergyConsumerStatsConfig); 8860 } 8861 return mUidEnergyConsumerStats; 8862 } 8863 8864 /** Adds the given charge to the given standard power bucket for this uid. */ 8865 @GuardedBy("mBsi") addChargeToStandardBucketLocked(long chargeDeltaUC, @StandardPowerBucket int powerBucket, long timestampMs)8866 private void addChargeToStandardBucketLocked(long chargeDeltaUC, 8867 @StandardPowerBucket int powerBucket, long timestampMs) { 8868 final EnergyConsumerStats energyConsumerStats = 8869 getOrCreateEnergyConsumerStatsLocked(); 8870 energyConsumerStats.updateStandardBucket(powerBucket, chargeDeltaUC, timestampMs); 8871 } 8872 8873 /** Adds the given charge to the given custom power bucket for this uid. */ 8874 @GuardedBy("mBsi") addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket)8875 private void addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket) { 8876 getOrCreateEnergyConsumerStatsLocked().updateCustomBucket(powerBucket, chargeDeltaUC, 8877 mBsi.mClock.elapsedRealtime()); 8878 } 8879 8880 /** 8881 * Returns the battery consumption (in microcoulomb) of this uid for a standard power bucket 8882 * of interest. 8883 * @param bucket standard power bucket of interest 8884 * @return consumption (in microcolombs) used by this uid for this power bucket 8885 */ 8886 @GuardedBy("mBsi") getEnergyConsumptionUC(@tandardPowerBucket int bucket)8887 public long getEnergyConsumptionUC(@StandardPowerBucket int bucket) { 8888 if (mBsi.mGlobalEnergyConsumerStats == null 8889 || !mBsi.mGlobalEnergyConsumerStats.isStandardBucketSupported(bucket)) { 8890 return POWER_DATA_UNAVAILABLE; 8891 } 8892 if (mUidEnergyConsumerStats == null) { 8893 return 0L; // It is supported, but was never filled, so it must be 0 8894 } 8895 return mUidEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket); 8896 } 8897 8898 /** 8899 * Returns the battery consumption (in microcoulombs) of this uid for a standard power 8900 * bucket and a process state, such as Uid.PROCESS_STATE_TOP. 8901 */ 8902 @GuardedBy("mBsi") getEnergyConsumptionUC(@tandardPowerBucket int bucket, int processState)8903 public long getEnergyConsumptionUC(@StandardPowerBucket int bucket, 8904 int processState) { 8905 if (mBsi.mGlobalEnergyConsumerStats == null 8906 || !mBsi.mGlobalEnergyConsumerStats.isStandardBucketSupported(bucket)) { 8907 return POWER_DATA_UNAVAILABLE; 8908 } 8909 if (mUidEnergyConsumerStats == null) { 8910 return 0L; // It is supported, but was never filled, so it must be 0 8911 } 8912 return mUidEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket, processState); 8913 } 8914 8915 @GuardedBy("mBsi") 8916 @Override getCustomEnergyConsumerBatteryConsumptionUC()8917 public long[] getCustomEnergyConsumerBatteryConsumptionUC() { 8918 if (mBsi.mGlobalEnergyConsumerStats == null) { 8919 return null; 8920 } 8921 if (mUidEnergyConsumerStats == null) { 8922 // Custom buckets may exist. But all values for this uid are 0 so we report all 0s. 8923 return new long[mBsi.mGlobalEnergyConsumerStats.getNumberCustomPowerBuckets()]; 8924 } 8925 return mUidEnergyConsumerStats.getAccumulatedCustomBucketCharges(); 8926 } 8927 8928 @GuardedBy("mBsi") 8929 @Override getBluetoothEnergyConsumptionUC()8930 public long getBluetoothEnergyConsumptionUC() { 8931 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH); 8932 } 8933 8934 @GuardedBy("mBsi") 8935 @Override getBluetoothEnergyConsumptionUC( @atteryConsumer.ProcessState int processState)8936 public long getBluetoothEnergyConsumptionUC( 8937 @BatteryConsumer.ProcessState int processState) { 8938 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 8939 processState); 8940 } 8941 8942 @GuardedBy("mBsi") 8943 @Override getCpuEnergyConsumptionUC()8944 public long getCpuEnergyConsumptionUC() { 8945 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU); 8946 } 8947 8948 @GuardedBy("mBsi") 8949 @Override getCpuEnergyConsumptionUC( @atteryConsumer.ProcessState int processState)8950 public long getCpuEnergyConsumptionUC( 8951 @BatteryConsumer.ProcessState int processState) { 8952 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU, 8953 processState); 8954 } 8955 8956 @GuardedBy("mBsi") 8957 @Override getGnssEnergyConsumptionUC()8958 public long getGnssEnergyConsumptionUC() { 8959 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_GNSS); 8960 } 8961 8962 @GuardedBy("mBsi") 8963 @Override getMobileRadioEnergyConsumptionUC()8964 public long getMobileRadioEnergyConsumptionUC() { 8965 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 8966 } 8967 8968 @GuardedBy("mBsi") 8969 @Override getMobileRadioEnergyConsumptionUC(int processState)8970 public long getMobileRadioEnergyConsumptionUC(int processState) { 8971 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 8972 processState); 8973 } 8974 8975 @GuardedBy("mBsi") 8976 @Override getScreenOnEnergyConsumptionUC()8977 public long getScreenOnEnergyConsumptionUC() { 8978 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON); 8979 } 8980 8981 @GuardedBy("mBsi") 8982 @Override getWifiEnergyConsumptionUC()8983 public long getWifiEnergyConsumptionUC() { 8984 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI); 8985 } 8986 8987 @GuardedBy("mBsi") 8988 @Override getWifiEnergyConsumptionUC(int processState)8989 public long getWifiEnergyConsumptionUC(int processState) { 8990 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI, 8991 processState); 8992 } 8993 8994 @GuardedBy("mBsi") 8995 @Override getCameraEnergyConsumptionUC()8996 public long getCameraEnergyConsumptionUC() { 8997 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CAMERA); 8998 } 8999 9000 /** 9001 * Gets the minimum of the uid's foreground activity time and its PROCESS_STATE_TOP time 9002 * since last marked. Also sets the mark time for both these timers. 9003 * 9004 * @see CpuPowerCalculator 9005 * 9006 * @param doCalc if true, then calculate the minimum; else don't bother and return 0. Either 9007 * way, the mark is set. 9008 */ markProcessForegroundTimeUs(long elapsedRealtimeMs, boolean doCalc)9009 private long markProcessForegroundTimeUs(long elapsedRealtimeMs, 9010 boolean doCalc) { 9011 long fgTimeUs = 0; 9012 final StopwatchTimer fgTimer = mForegroundActivityTimer; 9013 if (fgTimer != null) { 9014 if (doCalc) fgTimeUs = fgTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 9015 fgTimer.setMark(elapsedRealtimeMs); 9016 } 9017 9018 long topTimeUs = 0; 9019 final StopwatchTimer topTimer = mProcessStateTimer[PROCESS_STATE_TOP]; 9020 if (topTimer != null) { 9021 if (doCalc) topTimeUs = topTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 9022 topTimer.setMark(elapsedRealtimeMs); 9023 } 9024 9025 // Return the min of the two 9026 return (topTimeUs < fgTimeUs) ? topTimeUs : fgTimeUs; 9027 } 9028 9029 9030 /** 9031 * Gets the uid's time spent using the GNSS since last marked. Also sets the mark time for 9032 * the GNSS timer. 9033 */ markGnssTimeUs(long elapsedRealtimeMs)9034 private long markGnssTimeUs(long elapsedRealtimeMs) { 9035 final Sensor sensor = mSensorStats.get(Sensor.GPS); 9036 if (sensor == null) { 9037 return 0; 9038 } 9039 9040 final StopwatchTimer timer = sensor.mTimer; 9041 if (timer == null) { 9042 return 0; 9043 } 9044 9045 final long gnssTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 9046 timer.setMark(elapsedRealtimeMs); 9047 return gnssTimeUs; 9048 } 9049 9050 /** 9051 * Gets the uid's time spent using the camera since last marked. Also sets the mark time for 9052 * the camera timer. 9053 */ markCameraTimeUs(long elapsedRealtimeMs)9054 private long markCameraTimeUs(long elapsedRealtimeMs) { 9055 final StopwatchTimer timer = mCameraTurnedOnTimer; 9056 if (timer == null) { 9057 return 0; 9058 } 9059 final long cameraTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 9060 timer.setMark(elapsedRealtimeMs); 9061 return cameraTimeUs; 9062 } 9063 createAudioTurnedOnTimerLocked()9064 public StopwatchTimer createAudioTurnedOnTimerLocked() { 9065 if (mAudioTurnedOnTimer == null) { 9066 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, AUDIO_TURNED_ON, 9067 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9068 } 9069 return mAudioTurnedOnTimer; 9070 } 9071 noteAudioTurnedOnLocked(long elapsedRealtimeMs)9072 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 9073 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9074 } 9075 noteAudioTurnedOffLocked(long elapsedRealtimeMs)9076 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 9077 if (mAudioTurnedOnTimer != null) { 9078 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9079 } 9080 } 9081 noteResetAudioLocked(long elapsedRealtimeMs)9082 public void noteResetAudioLocked(long elapsedRealtimeMs) { 9083 if (mAudioTurnedOnTimer != null) { 9084 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9085 } 9086 } 9087 createVideoTurnedOnTimerLocked()9088 public StopwatchTimer createVideoTurnedOnTimerLocked() { 9089 if (mVideoTurnedOnTimer == null) { 9090 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, VIDEO_TURNED_ON, 9091 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9092 } 9093 return mVideoTurnedOnTimer; 9094 } 9095 noteVideoTurnedOnLocked(long elapsedRealtimeMs)9096 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 9097 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9098 } 9099 noteVideoTurnedOffLocked(long elapsedRealtimeMs)9100 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 9101 if (mVideoTurnedOnTimer != null) { 9102 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9103 } 9104 } 9105 noteResetVideoLocked(long elapsedRealtimeMs)9106 public void noteResetVideoLocked(long elapsedRealtimeMs) { 9107 if (mVideoTurnedOnTimer != null) { 9108 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9109 } 9110 } 9111 createFlashlightTurnedOnTimerLocked()9112 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 9113 if (mFlashlightTurnedOnTimer == null) { 9114 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9115 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9116 } 9117 return mFlashlightTurnedOnTimer; 9118 } 9119 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)9120 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 9121 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9122 } 9123 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)9124 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 9125 if (mFlashlightTurnedOnTimer != null) { 9126 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9127 } 9128 } 9129 noteResetFlashlightLocked(long elapsedRealtimeMs)9130 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 9131 if (mFlashlightTurnedOnTimer != null) { 9132 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9133 } 9134 } 9135 createCameraTurnedOnTimerLocked()9136 public StopwatchTimer createCameraTurnedOnTimerLocked() { 9137 if (mCameraTurnedOnTimer == null) { 9138 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, CAMERA_TURNED_ON, 9139 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9140 } 9141 return mCameraTurnedOnTimer; 9142 } 9143 noteCameraTurnedOnLocked(long elapsedRealtimeMs)9144 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 9145 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9146 } 9147 noteCameraTurnedOffLocked(long elapsedRealtimeMs)9148 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 9149 if (mCameraTurnedOnTimer != null) { 9150 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9151 } 9152 } 9153 noteResetCameraLocked(long elapsedRealtimeMs)9154 public void noteResetCameraLocked(long elapsedRealtimeMs) { 9155 if (mCameraTurnedOnTimer != null) { 9156 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9157 } 9158 } 9159 createForegroundActivityTimerLocked()9160 public StopwatchTimer createForegroundActivityTimerLocked() { 9161 if (mForegroundActivityTimer == null) { 9162 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9163 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 9164 } 9165 return mForegroundActivityTimer; 9166 } 9167 createForegroundServiceTimerLocked()9168 public StopwatchTimer createForegroundServiceTimerLocked() { 9169 if (mForegroundServiceTimer == null) { 9170 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9171 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 9172 } 9173 return mForegroundServiceTimer; 9174 } 9175 createAggregatedPartialWakelockTimerLocked()9176 public DualTimer createAggregatedPartialWakelockTimerLocked() { 9177 if (mAggregatedPartialWakelockTimer == null) { 9178 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClock, this, 9179 AGGREGATED_WAKE_TYPE_PARTIAL, null, 9180 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 9181 } 9182 return mAggregatedPartialWakelockTimer; 9183 } 9184 createBluetoothScanTimerLocked()9185 public DualTimer createBluetoothScanTimerLocked() { 9186 if (mBluetoothScanTimer == null) { 9187 mBluetoothScanTimer = new DualTimer(mBsi.mClock, Uid.this, BLUETOOTH_SCAN_ON, 9188 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 9189 mOnBatteryBackgroundTimeBase); 9190 } 9191 return mBluetoothScanTimer; 9192 } 9193 createBluetoothUnoptimizedScanTimerLocked()9194 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 9195 if (mBluetoothUnoptimizedScanTimer == null) { 9196 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClock, Uid.this, 9197 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 9198 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 9199 } 9200 return mBluetoothUnoptimizedScanTimer; 9201 } 9202 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)9203 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 9204 boolean isUnoptimized) { 9205 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 9206 if (isUnoptimized) { 9207 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 9208 } 9209 } 9210 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)9211 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 9212 if (mBluetoothScanTimer != null) { 9213 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 9214 } 9215 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 9216 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 9217 } 9218 } 9219 noteResetBluetoothScanLocked(long elapsedRealtimeMs)9220 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 9221 if (mBluetoothScanTimer != null) { 9222 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 9223 } 9224 if (mBluetoothUnoptimizedScanTimer != null) { 9225 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 9226 } 9227 } 9228 createBluetoothScanResultCounterLocked()9229 public Counter createBluetoothScanResultCounterLocked() { 9230 if (mBluetoothScanResultCounter == null) { 9231 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 9232 } 9233 return mBluetoothScanResultCounter; 9234 } 9235 createBluetoothScanResultBgCounterLocked()9236 public Counter createBluetoothScanResultBgCounterLocked() { 9237 if (mBluetoothScanResultBgCounter == null) { 9238 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 9239 } 9240 return mBluetoothScanResultBgCounter; 9241 } 9242 noteBluetoothScanResultsLocked(int numNewResults)9243 public void noteBluetoothScanResultsLocked(int numNewResults) { 9244 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 9245 // Uses background timebase, so the count will only be incremented if uid in background. 9246 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 9247 } 9248 9249 @Override noteActivityResumedLocked(long elapsedRealtimeMs)9250 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 9251 // We always start, since we want multiple foreground PIDs to nest 9252 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 9253 } 9254 9255 @Override noteActivityPausedLocked(long elapsedRealtimeMs)9256 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 9257 if (mForegroundActivityTimer != null) { 9258 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 9259 } 9260 } 9261 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)9262 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 9263 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 9264 } 9265 noteForegroundServicePausedLocked(long elapsedRealtimeMs)9266 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 9267 if (mForegroundServiceTimer != null) { 9268 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 9269 } 9270 } 9271 createVibratorOnTimerLocked()9272 public BatchTimer createVibratorOnTimerLocked() { 9273 if (mVibratorOnTimer == null) { 9274 mVibratorOnTimer = new BatchTimer(mBsi.mClock, Uid.this, VIBRATOR_ON, 9275 mBsi.mOnBatteryTimeBase); 9276 } 9277 return mVibratorOnTimer; 9278 } 9279 noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs)9280 public void noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs) { 9281 createVibratorOnTimerLocked().addDuration(durationMillis, elapsedRealtimeMs); 9282 } 9283 noteVibratorOffLocked(long elapsedRealtimeMs)9284 public void noteVibratorOffLocked(long elapsedRealtimeMs) { 9285 if (mVibratorOnTimer != null) { 9286 mVibratorOnTimer.abortLastDuration(elapsedRealtimeMs); 9287 } 9288 } 9289 9290 @Override getWifiRunningTime(long elapsedRealtimeUs, int which)9291 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 9292 if (mWifiRunningTimer == null) { 9293 return 0; 9294 } 9295 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9296 } 9297 9298 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)9299 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 9300 if (mFullWifiLockTimer == null) { 9301 return 0; 9302 } 9303 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9304 } 9305 9306 @Override getWifiScanTime(long elapsedRealtimeUs, int which)9307 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 9308 if (mWifiScanTimer == null) { 9309 return 0; 9310 } 9311 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9312 } 9313 9314 @Override getWifiScanCount(int which)9315 public int getWifiScanCount(int which) { 9316 if (mWifiScanTimer == null) { 9317 return 0; 9318 } 9319 return mWifiScanTimer.getCountLocked(which); 9320 } 9321 9322 @Override getWifiScanTimer()9323 public Timer getWifiScanTimer() { 9324 return mWifiScanTimer; 9325 } 9326 9327 @Override getWifiScanBackgroundCount(int which)9328 public int getWifiScanBackgroundCount(int which) { 9329 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 9330 return 0; 9331 } 9332 return mWifiScanTimer.getSubTimer().getCountLocked(which); 9333 } 9334 9335 @Override getWifiScanActualTime(final long elapsedRealtimeUs)9336 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 9337 if (mWifiScanTimer == null) { 9338 return 0; 9339 } 9340 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 9341 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 9342 } 9343 9344 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)9345 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 9346 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 9347 return 0; 9348 } 9349 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 9350 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 9351 } 9352 9353 @Override getWifiScanBackgroundTimer()9354 public Timer getWifiScanBackgroundTimer() { 9355 if (mWifiScanTimer == null) { 9356 return null; 9357 } 9358 return mWifiScanTimer.getSubTimer(); 9359 } 9360 9361 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)9362 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 9363 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 9364 if (mWifiBatchedScanTimer[csphBin] == null) { 9365 return 0; 9366 } 9367 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 9368 } 9369 9370 @Override getWifiBatchedScanCount(int csphBin, int which)9371 public int getWifiBatchedScanCount(int csphBin, int which) { 9372 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 9373 if (mWifiBatchedScanTimer[csphBin] == null) { 9374 return 0; 9375 } 9376 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 9377 } 9378 9379 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)9380 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 9381 if (mWifiMulticastTimer == null) { 9382 return 0; 9383 } 9384 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9385 } 9386 9387 @Override getAudioTurnedOnTimer()9388 public Timer getAudioTurnedOnTimer() { 9389 return mAudioTurnedOnTimer; 9390 } 9391 9392 @Override getVideoTurnedOnTimer()9393 public Timer getVideoTurnedOnTimer() { 9394 return mVideoTurnedOnTimer; 9395 } 9396 9397 @Override getFlashlightTurnedOnTimer()9398 public Timer getFlashlightTurnedOnTimer() { 9399 return mFlashlightTurnedOnTimer; 9400 } 9401 9402 @Override getCameraTurnedOnTimer()9403 public Timer getCameraTurnedOnTimer() { 9404 return mCameraTurnedOnTimer; 9405 } 9406 9407 @Override getForegroundActivityTimer()9408 public Timer getForegroundActivityTimer() { 9409 return mForegroundActivityTimer; 9410 } 9411 9412 @Override getForegroundServiceTimer()9413 public Timer getForegroundServiceTimer() { 9414 return mForegroundServiceTimer; 9415 } 9416 9417 @Override getBluetoothScanTimer()9418 public Timer getBluetoothScanTimer() { 9419 return mBluetoothScanTimer; 9420 } 9421 9422 @Override getBluetoothScanBackgroundTimer()9423 public Timer getBluetoothScanBackgroundTimer() { 9424 if (mBluetoothScanTimer == null) { 9425 return null; 9426 } 9427 return mBluetoothScanTimer.getSubTimer(); 9428 } 9429 9430 @Override getBluetoothUnoptimizedScanTimer()9431 public Timer getBluetoothUnoptimizedScanTimer() { 9432 return mBluetoothUnoptimizedScanTimer; 9433 } 9434 9435 @Override getBluetoothUnoptimizedScanBackgroundTimer()9436 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 9437 if (mBluetoothUnoptimizedScanTimer == null) { 9438 return null; 9439 } 9440 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 9441 } 9442 9443 @Override getBluetoothScanResultCounter()9444 public Counter getBluetoothScanResultCounter() { 9445 return mBluetoothScanResultCounter; 9446 } 9447 9448 @Override getBluetoothScanResultBgCounter()9449 public Counter getBluetoothScanResultBgCounter() { 9450 return mBluetoothScanResultBgCounter; 9451 } 9452 makeProcessState(int i, Parcel in)9453 void makeProcessState(int i, Parcel in) { 9454 if (i < 0 || i >= NUM_PROCESS_STATE) return; 9455 9456 detachIfNotNull(mProcessStateTimer[i]); 9457 if (in == null) { 9458 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClock, this, PROCESS_STATE, null, 9459 mBsi.mOnBatteryTimeBase); 9460 } else { 9461 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClock, this, PROCESS_STATE, null, 9462 mBsi.mOnBatteryTimeBase, in); 9463 } 9464 } 9465 9466 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)9467 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 9468 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 9469 if (mProcessStateTimer[state] == null) { 9470 return 0; 9471 } 9472 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 9473 } 9474 9475 @Override getProcessStateTimer(int state)9476 public Timer getProcessStateTimer(int state) { 9477 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 9478 return mProcessStateTimer[state]; 9479 } 9480 9481 @Override getVibratorOnTimer()9482 public Timer getVibratorOnTimer() { 9483 return mVibratorOnTimer; 9484 } 9485 9486 @Override noteUserActivityLocked(@owerManager.UserActivityEvent int event)9487 public void noteUserActivityLocked(@PowerManager.UserActivityEvent int event) { 9488 if (mUserActivityCounters == null) { 9489 initUserActivityLocked(); 9490 } 9491 if (event >= 0 && event < NUM_USER_ACTIVITY_TYPES) { 9492 mUserActivityCounters[event].stepAtomic(); 9493 } else { 9494 Slog.w(TAG, "Unknown user activity type " + event + " was specified.", 9495 new Throwable()); 9496 } 9497 } 9498 9499 @Override hasUserActivity()9500 public boolean hasUserActivity() { 9501 return mUserActivityCounters != null; 9502 } 9503 9504 @Override getUserActivityCount(int type, int which)9505 public int getUserActivityCount(int type, int which) { 9506 if (mUserActivityCounters == null) { 9507 return 0; 9508 } 9509 return mUserActivityCounters[type].getCountLocked(which); 9510 } 9511 makeWifiBatchedScanBin(int i, Parcel in)9512 void makeWifiBatchedScanBin(int i, Parcel in) { 9513 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 9514 9515 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 9516 if (collected == null) { 9517 collected = new ArrayList<StopwatchTimer>(); 9518 mBsi.mWifiBatchedScanTimers.put(i, collected); 9519 } 9520 detachIfNotNull(mWifiBatchedScanTimer[i]); 9521 if (in == null) { 9522 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClock, this, WIFI_BATCHED_SCAN, 9523 collected, mBsi.mOnBatteryTimeBase); 9524 } else { 9525 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClock, this, WIFI_BATCHED_SCAN, 9526 collected, mBsi.mOnBatteryTimeBase, in); 9527 } 9528 } 9529 9530 initUserActivityLocked()9531 void initUserActivityLocked() { 9532 detachIfNotNull(mUserActivityCounters); 9533 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 9534 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 9535 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 9536 } 9537 } 9538 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)9539 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 9540 ensureNetworkActivityLocked(); 9541 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 9542 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 9543 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 9544 } else { 9545 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 9546 new Throwable()); 9547 } 9548 } 9549 noteMobileRadioActiveTimeLocked(long batteryUptimeDeltaUs, long elapsedTimeMs)9550 void noteMobileRadioActiveTimeLocked(long batteryUptimeDeltaUs, long elapsedTimeMs) { 9551 ensureNetworkActivityLocked(); 9552 getMobileRadioActiveTimeCounter().increment(batteryUptimeDeltaUs, elapsedTimeMs); 9553 mMobileRadioActiveCount.addCountLocked(1); 9554 } 9555 getMobileRadioActiveTimeCounter()9556 private TimeMultiStateCounter getMobileRadioActiveTimeCounter() { 9557 if (mMobileRadioActiveTime == null) { 9558 final long timestampMs = mBsi.mClock.elapsedRealtime(); 9559 mMobileRadioActiveTime = new TimeMultiStateCounter( 9560 mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 9561 mMobileRadioActiveTime.setState( 9562 mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 9563 timestampMs); 9564 mMobileRadioActiveTime.update(0, timestampMs); 9565 } 9566 return mMobileRadioActiveTime; 9567 } 9568 9569 @Override hasNetworkActivity()9570 public boolean hasNetworkActivity() { 9571 return mNetworkByteActivityCounters != null; 9572 } 9573 9574 @Override getNetworkActivityBytes(int type, int which)9575 public long getNetworkActivityBytes(int type, int which) { 9576 if (mNetworkByteActivityCounters != null && type >= 0 9577 && type < mNetworkByteActivityCounters.length) { 9578 return mNetworkByteActivityCounters[type].getCountLocked(which); 9579 } else { 9580 return 0; 9581 } 9582 } 9583 9584 @Override getNetworkActivityPackets(int type, int which)9585 public long getNetworkActivityPackets(int type, int which) { 9586 if (mNetworkPacketActivityCounters != null && type >= 0 9587 && type < mNetworkPacketActivityCounters.length) { 9588 return mNetworkPacketActivityCounters[type].getCountLocked(which); 9589 } else { 9590 return 0; 9591 } 9592 } 9593 9594 @Override getMobileRadioActiveTime(int which)9595 public long getMobileRadioActiveTime(int which) { 9596 return getMobileRadioActiveTimeInProcessState(BatteryConsumer.PROCESS_STATE_ANY); 9597 } 9598 9599 @Override getMobileRadioActiveTimeInProcessState( @atteryConsumer.ProcessState int processState)9600 public long getMobileRadioActiveTimeInProcessState( 9601 @BatteryConsumer.ProcessState int processState) { 9602 if (mMobileRadioActiveTime == null) { 9603 return 0; 9604 } 9605 if (processState == BatteryConsumer.PROCESS_STATE_ANY) { 9606 return mMobileRadioActiveTime.getTotalCountLocked(); 9607 } else { 9608 return mMobileRadioActiveTime.getCountForProcessState(processState); 9609 } 9610 } 9611 9612 @Override getMobileRadioActiveCount(int which)9613 public int getMobileRadioActiveCount(int which) { 9614 return mMobileRadioActiveCount != null 9615 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 9616 } 9617 9618 @Override getUserCpuTimeUs(int which)9619 public long getUserCpuTimeUs(int which) { 9620 return mUserCpuTime.getCountLocked(which); 9621 } 9622 9623 @Override getSystemCpuTimeUs(int which)9624 public long getSystemCpuTimeUs(int which) { 9625 return mSystemCpuTime.getCountLocked(which); 9626 } 9627 9628 @Override 9629 @Deprecated getTimeAtCpuSpeed(int cluster, int step, int which)9630 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 9631 if (mCpuClusterSpeedTimesUs != null) { 9632 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 9633 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 9634 if (cpuSpeedTimesUs != null) { 9635 if (step >= 0 && step < cpuSpeedTimesUs.length) { 9636 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 9637 if (c != null) { 9638 return c.getCountLocked(which); 9639 } 9640 } 9641 } 9642 } 9643 } 9644 return 0; 9645 } 9646 noteMobileRadioApWakeupLocked()9647 public void noteMobileRadioApWakeupLocked() { 9648 if (mMobileRadioApWakeupCount == null) { 9649 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9650 } 9651 mMobileRadioApWakeupCount.addCountLocked(1); 9652 } 9653 9654 @Override getMobileRadioApWakeupCount(int which)9655 public long getMobileRadioApWakeupCount(int which) { 9656 if (mMobileRadioApWakeupCount != null) { 9657 return mMobileRadioApWakeupCount.getCountLocked(which); 9658 } 9659 return 0; 9660 } 9661 noteWifiRadioApWakeupLocked()9662 public void noteWifiRadioApWakeupLocked() { 9663 if (mWifiRadioApWakeupCount == null) { 9664 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9665 } 9666 mWifiRadioApWakeupCount.addCountLocked(1); 9667 } 9668 9669 @Override getWifiRadioApWakeupCount(int which)9670 public long getWifiRadioApWakeupCount(int which) { 9671 if (mWifiRadioApWakeupCount != null) { 9672 return mWifiRadioApWakeupCount.getCountLocked(which); 9673 } 9674 return 0; 9675 } 9676 9677 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)9678 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 9679 sb.setLength(0); 9680 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 9681 if (deferredEventCount == 0) { 9682 return; 9683 } 9684 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 9685 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 9686 sb.append(deferredEventCount); sb.append(','); 9687 sb.append(deferredCount); sb.append(','); 9688 sb.append(totalLatency); 9689 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9690 if (mJobsFreshnessBuckets[i] == null) { 9691 sb.append(",0"); 9692 } else { 9693 sb.append(","); 9694 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 9695 } 9696 } 9697 } 9698 9699 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)9700 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 9701 sb.setLength(0); 9702 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 9703 if (deferredEventCount == 0) { 9704 return; 9705 } 9706 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 9707 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 9708 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 9709 sb.append("count="); sb.append(deferredCount); sb.append(", "); 9710 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 9711 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9712 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 9713 if (mJobsFreshnessBuckets[i] == null) { 9714 sb.append("0"); 9715 } else { 9716 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 9717 } 9718 sb.append(" "); 9719 } 9720 } 9721 ensureNetworkActivityLocked()9722 void ensureNetworkActivityLocked() { 9723 if (mNetworkByteActivityCounters != null) { 9724 return; 9725 } 9726 9727 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9728 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9729 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9730 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9731 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9732 } 9733 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9734 } 9735 9736 /** 9737 * Clear all stats for this uid. Returns true if the uid is completely 9738 * inactive so can be dropped. 9739 */ 9740 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptimeUs, long realtimeUs, int resetReason)9741 public boolean reset(long uptimeUs, long realtimeUs, int resetReason) { 9742 boolean active = false; 9743 9744 mOnBatteryBackgroundTimeBase.init(uptimeUs, realtimeUs); 9745 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeUs, realtimeUs); 9746 9747 if (mWifiRunningTimer != null) { 9748 active |= !mWifiRunningTimer.reset(false, realtimeUs); 9749 active |= mWifiRunning; 9750 } 9751 if (mFullWifiLockTimer != null) { 9752 active |= !mFullWifiLockTimer.reset(false, realtimeUs); 9753 active |= mFullWifiLockOut; 9754 } 9755 if (mWifiScanTimer != null) { 9756 active |= !mWifiScanTimer.reset(false, realtimeUs); 9757 active |= mWifiScanStarted; 9758 } 9759 if (mWifiBatchedScanTimer != null) { 9760 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 9761 if (mWifiBatchedScanTimer[i] != null) { 9762 active |= !mWifiBatchedScanTimer[i].reset(false, realtimeUs); 9763 } 9764 } 9765 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 9766 } 9767 if (mWifiMulticastTimer != null) { 9768 active |= !mWifiMulticastTimer.reset(false, realtimeUs); 9769 active |= (mWifiMulticastWakelockCount > 0); 9770 } 9771 9772 active |= !resetIfNotNull(mAudioTurnedOnTimer, false, realtimeUs); 9773 active |= !resetIfNotNull(mVideoTurnedOnTimer, false, realtimeUs); 9774 active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false, realtimeUs); 9775 active |= !resetIfNotNull(mCameraTurnedOnTimer, false, realtimeUs); 9776 active |= !resetIfNotNull(mForegroundActivityTimer, false, realtimeUs); 9777 active |= !resetIfNotNull(mForegroundServiceTimer, false, realtimeUs); 9778 active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false, realtimeUs); 9779 active |= !resetIfNotNull(mBluetoothScanTimer, false, realtimeUs); 9780 active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false, realtimeUs); 9781 9782 resetIfNotNull(mBluetoothScanResultCounter, false, realtimeUs); 9783 resetIfNotNull(mBluetoothScanResultBgCounter, false, realtimeUs); 9784 9785 if (mProcessStateTimer != null) { 9786 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 9787 active |= !resetIfNotNull(mProcessStateTimer[i], false, realtimeUs); 9788 } 9789 active |= (mProcessState != Uid.PROCESS_STATE_NONEXISTENT); 9790 } 9791 if (mVibratorOnTimer != null) { 9792 if (mVibratorOnTimer.reset(false, realtimeUs)) { 9793 mVibratorOnTimer.detach(); 9794 mVibratorOnTimer = null; 9795 } else { 9796 active = true; 9797 } 9798 } 9799 9800 resetIfNotNull(mUserActivityCounters, false, realtimeUs); 9801 9802 resetIfNotNull(mNetworkByteActivityCounters, false, realtimeUs); 9803 resetIfNotNull(mNetworkPacketActivityCounters, false, realtimeUs); 9804 resetIfNotNull(mMobileRadioActiveTime, false, realtimeUs); 9805 resetIfNotNull(mMobileRadioActiveCount, false, realtimeUs); 9806 9807 resetIfNotNull(mWifiControllerActivity, false, realtimeUs); 9808 resetIfNotNull(mBluetoothControllerActivity, false, realtimeUs); 9809 resetIfNotNull(mModemControllerActivity, false, realtimeUs); 9810 9811 if (resetReason == RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE) { 9812 mUidEnergyConsumerStats = null; 9813 } else { 9814 EnergyConsumerStats.resetIfNotNull(mUidEnergyConsumerStats); 9815 } 9816 9817 resetIfNotNull(mUserCpuTime, false, realtimeUs); 9818 resetIfNotNull(mSystemCpuTime, false, realtimeUs); 9819 9820 resetIfNotNull(mCpuClusterSpeedTimesUs, false, realtimeUs); 9821 9822 resetIfNotNull(mCpuFreqTimeMs, false, realtimeUs /* unused */); 9823 resetIfNotNull(mScreenOffCpuFreqTimeMs, false, realtimeUs /* unused */); 9824 9825 9826 resetIfNotNull(mCpuActiveTimeMs, false, realtimeUs /* unused */); 9827 resetIfNotNull(mCpuClusterTimesMs, false, realtimeUs /* unused */); 9828 9829 resetIfNotNull(mProcStateTimeMs, false, realtimeUs /* unused */); 9830 9831 resetIfNotNull(mProcStateScreenOffTimeMs, false, realtimeUs /* unused */); 9832 9833 resetIfNotNull(mMobileRadioApWakeupCount, false, realtimeUs); 9834 9835 resetIfNotNull(mWifiRadioApWakeupCount, false, realtimeUs); 9836 9837 9838 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9839 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 9840 Wakelock wl = wakeStats.valueAt(iw); 9841 if (wl.reset(realtimeUs)) { 9842 wakeStats.removeAt(iw); 9843 } else { 9844 active = true; 9845 } 9846 } 9847 final long realtimeMs = realtimeUs / 1000; 9848 mWakelockStats.cleanup(realtimeMs); 9849 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9850 for (int is=syncStats.size()-1; is>=0; is--) { 9851 DualTimer timer = syncStats.valueAt(is); 9852 if (timer.reset(false, realtimeUs)) { 9853 syncStats.removeAt(is); 9854 timer.detach(); 9855 } else { 9856 active = true; 9857 } 9858 } 9859 mSyncStats.cleanup(realtimeMs); 9860 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9861 for (int ij=jobStats.size()-1; ij>=0; ij--) { 9862 DualTimer timer = jobStats.valueAt(ij); 9863 if (timer.reset(false, realtimeUs)) { 9864 jobStats.removeAt(ij); 9865 timer.detach(); 9866 } else { 9867 active = true; 9868 } 9869 } 9870 mJobStats.cleanup(realtimeMs); 9871 mJobCompletions.clear(); 9872 9873 resetIfNotNull(mJobsDeferredEventCount, false, realtimeUs); 9874 resetIfNotNull(mJobsDeferredCount, false, realtimeUs); 9875 resetIfNotNull(mJobsFreshnessTimeMs, false, realtimeUs /* unused */); 9876 resetIfNotNull(mJobsFreshnessBuckets, false, realtimeUs); 9877 9878 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 9879 Sensor s = mSensorStats.valueAt(ise); 9880 if (s.reset(realtimeUs)) { 9881 mSensorStats.removeAt(ise); 9882 } else { 9883 active = true; 9884 } 9885 } 9886 9887 for (int ip = mProcessStats.size() - 1; ip >= 0; ip--) { 9888 Proc proc = mProcessStats.valueAt(ip); 9889 proc.detach(); 9890 } 9891 mProcessStats.clear(); 9892 9893 for (int i = mPids.size() - 1; i >= 0; i--) { 9894 Pid pid = mPids.valueAt(i); 9895 if (pid.mWakeNesting > 0) { 9896 active = true; 9897 } else { 9898 mPids.removeAt(i); 9899 } 9900 } 9901 9902 9903 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 9904 Pkg p = mPackageStats.valueAt(i); 9905 p.detach(); 9906 } 9907 mPackageStats.clear(); 9908 9909 mBinderCallCount = 0; 9910 mBinderCallStats.clear(); 9911 9912 mProportionalSystemServiceUsage = 0; 9913 9914 mLastStepUserTimeMs = mLastStepSystemTimeMs = 0; 9915 mCurStepUserTimeMs = mCurStepSystemTimeMs = 0; 9916 9917 9918 return !active; 9919 } 9920 9921 /** 9922 * This method MUST be called whenever the Uid object is destructed, otherwise it is a 9923 * memory leak in {@link TimeBase#mObservers} list. 9924 * Typically the Uid object is destructed when it is removed from 9925 * {@link BatteryStatsImpl#mUidStats} 9926 */ detachFromTimeBase()9927 void detachFromTimeBase() { 9928 detachIfNotNull(mWifiRunningTimer); 9929 detachIfNotNull(mFullWifiLockTimer); 9930 detachIfNotNull(mWifiScanTimer); 9931 detachIfNotNull(mWifiBatchedScanTimer); 9932 detachIfNotNull(mWifiMulticastTimer); 9933 detachIfNotNull(mAudioTurnedOnTimer); 9934 detachIfNotNull(mVideoTurnedOnTimer); 9935 detachIfNotNull(mFlashlightTurnedOnTimer); 9936 9937 detachIfNotNull(mCameraTurnedOnTimer); 9938 detachIfNotNull(mForegroundActivityTimer); 9939 detachIfNotNull(mForegroundServiceTimer); 9940 9941 detachIfNotNull(mAggregatedPartialWakelockTimer); 9942 9943 detachIfNotNull(mBluetoothScanTimer); 9944 detachIfNotNull(mBluetoothUnoptimizedScanTimer); 9945 detachIfNotNull(mBluetoothScanResultCounter); 9946 detachIfNotNull(mBluetoothScanResultBgCounter); 9947 9948 detachIfNotNull(mProcessStateTimer); 9949 9950 detachIfNotNull(mVibratorOnTimer); 9951 9952 detachIfNotNull(mUserActivityCounters); 9953 9954 detachIfNotNull(mNetworkByteActivityCounters); 9955 detachIfNotNull(mNetworkPacketActivityCounters); 9956 9957 detachIfNotNull(mMobileRadioActiveTime); 9958 detachIfNotNull(mMobileRadioActiveCount); 9959 detachIfNotNull(mMobileRadioApWakeupCount); 9960 detachIfNotNull(mWifiRadioApWakeupCount); 9961 9962 detachIfNotNull(mWifiControllerActivity); 9963 detachIfNotNull(mBluetoothControllerActivity); 9964 detachIfNotNull(mModemControllerActivity); 9965 9966 mPids.clear(); 9967 9968 detachIfNotNull(mUserCpuTime); 9969 detachIfNotNull(mSystemCpuTime); 9970 9971 detachIfNotNull(mCpuClusterSpeedTimesUs); 9972 9973 detachIfNotNull(mCpuActiveTimeMs); 9974 detachIfNotNull(mCpuFreqTimeMs); 9975 9976 detachIfNotNull(mScreenOffCpuFreqTimeMs); 9977 9978 detachIfNotNull(mCpuClusterTimesMs); 9979 9980 detachIfNotNull(mProcStateTimeMs); 9981 9982 detachIfNotNull(mProcStateScreenOffTimeMs); 9983 9984 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9985 for (int iw = wakeStats.size() - 1; iw >= 0; iw--) { 9986 Wakelock wl = wakeStats.valueAt(iw); 9987 wl.detachFromTimeBase(); 9988 } 9989 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9990 for (int is = syncStats.size() - 1; is >= 0; is--) { 9991 DualTimer timer = syncStats.valueAt(is); 9992 detachIfNotNull(timer); 9993 } 9994 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9995 for (int ij = jobStats.size() - 1; ij >= 0; ij--) { 9996 DualTimer timer = jobStats.valueAt(ij); 9997 detachIfNotNull(timer); 9998 } 9999 10000 detachIfNotNull(mJobsDeferredEventCount); 10001 detachIfNotNull(mJobsDeferredCount); 10002 detachIfNotNull(mJobsFreshnessTimeMs); 10003 detachIfNotNull(mJobsFreshnessBuckets); 10004 10005 10006 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 10007 Sensor s = mSensorStats.valueAt(ise); 10008 s.detachFromTimeBase(); 10009 } 10010 10011 for (int ip= mProcessStats.size() - 1; ip >= 0; ip--) { 10012 Proc proc = mProcessStats.valueAt(ip); 10013 proc.detach(); 10014 } 10015 mProcessStats.clear(); 10016 10017 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 10018 Pkg p = mPackageStats.valueAt(i); 10019 p.detach(); 10020 } 10021 mPackageStats.clear(); 10022 } 10023 writeJobCompletionsToParcelLocked(Parcel out)10024 void writeJobCompletionsToParcelLocked(Parcel out) { 10025 int NJC = mJobCompletions.size(); 10026 out.writeInt(NJC); 10027 for (int ijc=0; ijc<NJC; ijc++) { 10028 out.writeString(mJobCompletions.keyAt(ijc)); 10029 SparseIntArray types = mJobCompletions.valueAt(ijc); 10030 int NT = types.size(); 10031 out.writeInt(NT); 10032 for (int it=0; it<NT; it++) { 10033 out.writeInt(types.keyAt(it)); 10034 out.writeInt(types.valueAt(it)); 10035 } 10036 } 10037 } 10038 readJobCompletionsFromParcelLocked(Parcel in)10039 void readJobCompletionsFromParcelLocked(Parcel in) { 10040 int numJobCompletions = in.readInt(); 10041 mJobCompletions.clear(); 10042 for (int j = 0; j < numJobCompletions; j++) { 10043 String jobName = in.readString(); 10044 int numTypes = in.readInt(); 10045 if (numTypes > 0) { 10046 SparseIntArray types = new SparseIntArray(); 10047 for (int k = 0; k < numTypes; k++) { 10048 int type = in.readInt(); 10049 int count = in.readInt(); 10050 types.put(type, count); 10051 } 10052 mJobCompletions.put(jobName, types); 10053 } 10054 } 10055 } 10056 noteJobsDeferredLocked(int numDeferred, long sinceLast)10057 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 10058 mJobsDeferredEventCount.addAtomic(1); 10059 mJobsDeferredCount.addAtomic(numDeferred); 10060 if (sinceLast != 0) { 10061 // Add the total time, which can be divided by the event count to get an average 10062 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 10063 // Also keep track of how many times there were in these different buckets. 10064 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 10065 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 10066 if (mJobsFreshnessBuckets[i] == null) { 10067 mJobsFreshnessBuckets[i] = new Counter( 10068 mBsi.mOnBatteryTimeBase); 10069 } 10070 mJobsFreshnessBuckets[i].addAtomic(1); 10071 break; 10072 } 10073 } 10074 } 10075 } 10076 10077 // Reusable object used as a key to lookup values in mBinderCallStats 10078 private static BinderCallStats sTempBinderCallStats = new BinderCallStats(); 10079 10080 /** 10081 * Notes incoming binder call stats associated with this work source UID. 10082 */ noteBinderCallStatsLocked(long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)10083 public void noteBinderCallStatsLocked(long incrementalCallCount, 10084 Collection<BinderCallsStats.CallStat> callStats) { 10085 if (DEBUG) { 10086 Slog.d(TAG, "noteBinderCalls() workSourceUid = [" + mUid + "], " 10087 + " incrementalCallCount: " + incrementalCallCount + " callStats = [" 10088 + new ArrayList<>(callStats) + "]"); 10089 } 10090 mBinderCallCount += incrementalCallCount; 10091 for (BinderCallsStats.CallStat stat : callStats) { 10092 BinderCallStats bcs; 10093 sTempBinderCallStats.binderClass = stat.binderClass; 10094 sTempBinderCallStats.transactionCode = stat.transactionCode; 10095 int index = mBinderCallStats.indexOf(sTempBinderCallStats); 10096 if (index >= 0) { 10097 bcs = mBinderCallStats.valueAt(index); 10098 } else { 10099 bcs = new BinderCallStats(); 10100 bcs.binderClass = stat.binderClass; 10101 bcs.transactionCode = stat.transactionCode; 10102 mBinderCallStats.add(bcs); 10103 } 10104 10105 bcs.callCount += stat.incrementalCallCount; 10106 bcs.recordedCallCount = stat.recordedCallCount; 10107 bcs.recordedCpuTimeMicros = stat.cpuTimeMicros; 10108 } 10109 } 10110 10111 /** 10112 * The statistics associated with a particular wake lock. 10113 */ 10114 public static class Wakelock extends BatteryStats.Uid.Wakelock { 10115 /** 10116 * BatteryStatsImpl that we are associated with. 10117 */ 10118 protected BatteryStatsImpl mBsi; 10119 10120 /** 10121 * BatteryStatsImpl that we are associated with. 10122 */ 10123 protected Uid mUid; 10124 10125 /** 10126 * How long (in ms) this uid has been keeping the device partially awake. 10127 * Tracks both the total time and the time while the app was in the background. 10128 */ 10129 DualTimer mTimerPartial; 10130 10131 /** 10132 * How long (in ms) this uid has been keeping the device fully awake. 10133 */ 10134 StopwatchTimer mTimerFull; 10135 10136 /** 10137 * How long (in ms) this uid has had a window keeping the device awake. 10138 */ 10139 StopwatchTimer mTimerWindow; 10140 10141 /** 10142 * How long (in ms) this uid has had a draw wake lock. 10143 */ 10144 StopwatchTimer mTimerDraw; 10145 Wakelock(BatteryStatsImpl bsi, Uid uid)10146 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 10147 mBsi = bsi; 10148 mUid = uid; 10149 } 10150 10151 /** 10152 * Reads a possibly null Timer from a Parcel. The timer is associated with the 10153 * proper timer pool from the given BatteryStatsImpl object. 10154 * 10155 * @param in the Parcel to be read from. 10156 * return a new Timer, or null. 10157 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)10158 private StopwatchTimer readStopwatchTimerFromParcel(int type, 10159 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 10160 if (in.readInt() == 0) { 10161 return null; 10162 } 10163 10164 return new StopwatchTimer(mBsi.mClock, mUid, type, pool, timeBase, in); 10165 } 10166 10167 /** 10168 * Reads a possibly null Timer from a Parcel. The timer is associated with the 10169 * proper timer pool from the given BatteryStatsImpl object. 10170 * 10171 * @param in the Parcel to be read from. 10172 * return a new Timer, or null. 10173 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10174 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 10175 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10176 if (in.readInt() == 0) { 10177 return null; 10178 } 10179 10180 return new DualTimer(mBsi.mClock, mUid, type, pool, timeBase, bgTimeBase, in); 10181 } 10182 reset(long elapsedRealtimeUs)10183 boolean reset(long elapsedRealtimeUs) { 10184 boolean wlactive = false; 10185 10186 wlactive |= !resetIfNotNull(mTimerFull, false, elapsedRealtimeUs); 10187 wlactive |= !resetIfNotNull(mTimerPartial, false, elapsedRealtimeUs); 10188 wlactive |= !resetIfNotNull(mTimerWindow, false, elapsedRealtimeUs); 10189 wlactive |= !resetIfNotNull(mTimerDraw, false, elapsedRealtimeUs); 10190 10191 if (!wlactive) { 10192 detachIfNotNull(mTimerFull); 10193 mTimerFull = null; 10194 10195 detachIfNotNull(mTimerPartial); 10196 mTimerPartial = null; 10197 10198 detachIfNotNull(mTimerWindow); 10199 mTimerWindow = null; 10200 10201 detachIfNotNull(mTimerDraw); 10202 mTimerDraw = null; 10203 } 10204 return !wlactive; 10205 } 10206 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)10207 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 10208 TimeBase screenOffBgTimeBase, Parcel in) { 10209 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 10210 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 10211 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 10212 mBsi.mFullTimers, timeBase, in); 10213 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 10214 mBsi.mWindowTimers, timeBase, in); 10215 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 10216 mBsi.mDrawTimers, timeBase, in); 10217 } 10218 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)10219 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 10220 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 10221 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 10222 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 10223 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 10224 } 10225 10226 @Override getWakeTime(int type)10227 public Timer getWakeTime(int type) { 10228 switch (type) { 10229 case WAKE_TYPE_FULL: return mTimerFull; 10230 case WAKE_TYPE_PARTIAL: return mTimerPartial; 10231 case WAKE_TYPE_WINDOW: return mTimerWindow; 10232 case WAKE_TYPE_DRAW: return mTimerDraw; 10233 default: throw new IllegalArgumentException("type = " + type); 10234 } 10235 } 10236 detachFromTimeBase()10237 public void detachFromTimeBase() { 10238 detachIfNotNull(mTimerPartial); 10239 detachIfNotNull(mTimerFull); 10240 detachIfNotNull(mTimerWindow); 10241 detachIfNotNull(mTimerDraw); 10242 } 10243 } 10244 10245 public static class Sensor extends BatteryStats.Uid.Sensor { 10246 /** 10247 * BatteryStatsImpl that we are associated with. 10248 */ 10249 protected BatteryStatsImpl mBsi; 10250 10251 /** 10252 * Uid that we are associated with. 10253 */ 10254 protected Uid mUid; 10255 10256 final int mHandle; 10257 DualTimer mTimer; 10258 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)10259 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 10260 mBsi = bsi; 10261 mUid = uid; 10262 mHandle = handle; 10263 } 10264 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10265 private DualTimer readTimersFromParcel( 10266 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10267 if (in.readInt() == 0) { 10268 return null; 10269 } 10270 10271 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 10272 if (pool == null) { 10273 pool = new ArrayList<StopwatchTimer>(); 10274 mBsi.mSensorTimers.put(mHandle, pool); 10275 } 10276 return new DualTimer(mBsi.mClock, mUid, 0, pool, timeBase, bgTimeBase, in); 10277 } 10278 reset(long elapsedRealtimeUs)10279 boolean reset(long elapsedRealtimeUs) { 10280 if (mTimer.reset(true, elapsedRealtimeUs)) { 10281 mTimer = null; 10282 return true; 10283 } 10284 return false; 10285 } 10286 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10287 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10288 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 10289 } 10290 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)10291 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 10292 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 10293 } 10294 10295 @Override getSensorTime()10296 public Timer getSensorTime() { 10297 return mTimer; 10298 } 10299 10300 @Override getSensorBackgroundTime()10301 public Timer getSensorBackgroundTime() { 10302 if (mTimer == null) { 10303 return null; 10304 } 10305 return mTimer.getSubTimer(); 10306 } 10307 10308 @Override getHandle()10309 public int getHandle() { 10310 return mHandle; 10311 } 10312 detachFromTimeBase()10313 public void detachFromTimeBase() { 10314 detachIfNotNull(mTimer); 10315 } 10316 } 10317 10318 /** 10319 * The statistics associated with a particular process. 10320 */ 10321 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 10322 /** 10323 * BatteryStatsImpl that we are associated with. 10324 */ 10325 protected BatteryStatsImpl mBsi; 10326 10327 /** 10328 * The name of this process. 10329 */ 10330 final String mName; 10331 10332 /** 10333 * Remains true until removed from the stats. 10334 */ 10335 boolean mActive = true; 10336 10337 /** 10338 * Total time (in ms) spent executing in user code. 10339 */ 10340 long mUserTimeMs; 10341 10342 /** 10343 * Total time (in ms) spent executing in kernel code. 10344 */ 10345 long mSystemTimeMs; 10346 10347 /** 10348 * Amount of time (in ms) the process was running in the foreground. 10349 */ 10350 long mForegroundTimeMs; 10351 10352 /** 10353 * Number of times the process has been started. 10354 */ 10355 int mStarts; 10356 10357 /** 10358 * Number of times the process has crashed. 10359 */ 10360 int mNumCrashes; 10361 10362 /** 10363 * Number of times the process has had an ANR. 10364 */ 10365 int mNumAnrs; 10366 10367 ArrayList<ExcessivePower> mExcessivePower; 10368 Proc(BatteryStatsImpl bsi, String name)10369 public Proc(BatteryStatsImpl bsi, String name) { 10370 mBsi = bsi; 10371 mName = name; 10372 mBsi.mOnBatteryTimeBase.add(this); 10373 } 10374 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10375 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10376 long baseRealtimeUs) { 10377 } 10378 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10379 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10380 long baseRealtimeUs) { 10381 } 10382 10383 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10384 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10385 if (detachIfReset) { 10386 this.detach(); 10387 } 10388 return true; 10389 } 10390 10391 @Override detach()10392 public void detach() { 10393 mActive = false; 10394 mBsi.mOnBatteryTimeBase.remove(this); 10395 } 10396 countExcessivePowers()10397 public int countExcessivePowers() { 10398 return mExcessivePower != null ? mExcessivePower.size() : 0; 10399 } 10400 getExcessivePower(int i)10401 public ExcessivePower getExcessivePower(int i) { 10402 if (mExcessivePower != null) { 10403 return mExcessivePower.get(i); 10404 } 10405 return null; 10406 } 10407 addExcessiveCpu(long overTimeMs, long usedTimeMs)10408 public void addExcessiveCpu(long overTimeMs, long usedTimeMs) { 10409 if (mExcessivePower == null) { 10410 mExcessivePower = new ArrayList<ExcessivePower>(); 10411 } 10412 ExcessivePower ew = new ExcessivePower(); 10413 ew.type = ExcessivePower.TYPE_CPU; 10414 ew.overTime = overTimeMs; 10415 ew.usedTime = usedTimeMs; 10416 mExcessivePower.add(ew); 10417 } 10418 writeExcessivePowerToParcelLocked(Parcel out)10419 void writeExcessivePowerToParcelLocked(Parcel out) { 10420 if (mExcessivePower == null) { 10421 out.writeInt(0); 10422 return; 10423 } 10424 10425 final int N = mExcessivePower.size(); 10426 out.writeInt(N); 10427 for (int i=0; i<N; i++) { 10428 ExcessivePower ew = mExcessivePower.get(i); 10429 out.writeInt(ew.type); 10430 out.writeLong(ew.overTime); 10431 out.writeLong(ew.usedTime); 10432 } 10433 } 10434 readExcessivePowerFromParcelLocked(Parcel in)10435 void readExcessivePowerFromParcelLocked(Parcel in) { 10436 final int N = in.readInt(); 10437 if (N == 0) { 10438 mExcessivePower = null; 10439 return; 10440 } 10441 10442 if (N > 10000) { 10443 throw new ParcelFormatException( 10444 "File corrupt: too many excessive power entries " + N); 10445 } 10446 10447 mExcessivePower = new ArrayList<>(); 10448 for (int i=0; i<N; i++) { 10449 ExcessivePower ew = new ExcessivePower(); 10450 ew.type = in.readInt(); 10451 ew.overTime = in.readLong(); 10452 ew.usedTime = in.readLong(); 10453 mExcessivePower.add(ew); 10454 } 10455 } 10456 writeToParcelLocked(Parcel out)10457 void writeToParcelLocked(Parcel out) { 10458 out.writeLong(mUserTimeMs); 10459 out.writeLong(mSystemTimeMs); 10460 out.writeLong(mForegroundTimeMs); 10461 out.writeInt(mStarts); 10462 out.writeInt(mNumCrashes); 10463 out.writeInt(mNumAnrs); 10464 writeExcessivePowerToParcelLocked(out); 10465 } 10466 readFromParcelLocked(Parcel in)10467 void readFromParcelLocked(Parcel in) { 10468 mUserTimeMs = in.readLong(); 10469 mSystemTimeMs = in.readLong(); 10470 mForegroundTimeMs = in.readLong(); 10471 mStarts = in.readInt(); 10472 mNumCrashes = in.readInt(); 10473 mNumAnrs = in.readInt(); 10474 readExcessivePowerFromParcelLocked(in); 10475 } 10476 addCpuTimeLocked(int utimeMs, int stimeMs)10477 public void addCpuTimeLocked(int utimeMs, int stimeMs) { 10478 addCpuTimeLocked(utimeMs, stimeMs, mBsi.mOnBatteryTimeBase.isRunning()); 10479 } 10480 addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning)10481 public void addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning) { 10482 if (isRunning) { 10483 mUserTimeMs += utimeMs; 10484 mSystemTimeMs += stimeMs; 10485 } 10486 } 10487 addForegroundTimeLocked(long ttimeMs)10488 public void addForegroundTimeLocked(long ttimeMs) { 10489 mForegroundTimeMs += ttimeMs; 10490 } 10491 incStartsLocked()10492 public void incStartsLocked() { 10493 mStarts++; 10494 } 10495 incNumCrashesLocked()10496 public void incNumCrashesLocked() { 10497 mNumCrashes++; 10498 } 10499 incNumAnrsLocked()10500 public void incNumAnrsLocked() { 10501 mNumAnrs++; 10502 } 10503 10504 @Override isActive()10505 public boolean isActive() { 10506 return mActive; 10507 } 10508 10509 @Override getUserTime(int which)10510 public long getUserTime(int which) { 10511 return mUserTimeMs; 10512 } 10513 10514 @Override getSystemTime(int which)10515 public long getSystemTime(int which) { 10516 return mSystemTimeMs; 10517 } 10518 10519 @Override getForegroundTime(int which)10520 public long getForegroundTime(int which) { 10521 return mForegroundTimeMs; 10522 } 10523 10524 @Override getStarts(int which)10525 public int getStarts(int which) { 10526 return mStarts; 10527 } 10528 10529 @Override getNumCrashes(int which)10530 public int getNumCrashes(int which) { 10531 return mNumCrashes; 10532 } 10533 10534 @Override getNumAnrs(int which)10535 public int getNumAnrs(int which) { 10536 return mNumAnrs; 10537 } 10538 } 10539 10540 /** 10541 * The statistics associated with a particular package. 10542 */ 10543 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 10544 /** 10545 * BatteryStatsImpl that we are associated with. 10546 */ 10547 protected BatteryStatsImpl mBsi; 10548 10549 /** 10550 * Number of times wakeup alarms have occurred for this app. 10551 * On screen-off timebase starting in report v25. 10552 */ 10553 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 10554 10555 /** 10556 * The statics we have collected for this package's services. 10557 */ 10558 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 10559 Pkg(BatteryStatsImpl bsi)10560 public Pkg(BatteryStatsImpl bsi) { 10561 mBsi = bsi; 10562 mBsi.mOnBatteryScreenOffTimeBase.add(this); 10563 } 10564 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10565 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10566 long baseRealtimeUs) { 10567 } 10568 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10569 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10570 long baseRealtimeUs) { 10571 } 10572 10573 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10574 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10575 if (detachIfReset) { 10576 this.detach(); 10577 } 10578 return true; 10579 } 10580 10581 @Override detach()10582 public void detach() { 10583 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 10584 for (int j = mWakeupAlarms.size() - 1; j >= 0; j--) { 10585 detachIfNotNull(mWakeupAlarms.valueAt(j)); 10586 } 10587 for (int j = mServiceStats.size() - 1; j >= 0; j--) { 10588 detachIfNotNull(mServiceStats.valueAt(j)); 10589 } 10590 } 10591 readFromParcelLocked(Parcel in)10592 void readFromParcelLocked(Parcel in) { 10593 int numWA = in.readInt(); 10594 mWakeupAlarms.clear(); 10595 for (int i=0; i<numWA; i++) { 10596 String tag = in.readString(); 10597 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 10598 } 10599 10600 int numServs = in.readInt(); 10601 mServiceStats.clear(); 10602 for (int m = 0; m < numServs; m++) { 10603 String serviceName = in.readString(); 10604 Uid.Pkg.Serv serv = new Serv(mBsi); 10605 mServiceStats.put(serviceName, serv); 10606 10607 serv.readFromParcelLocked(in); 10608 } 10609 } 10610 writeToParcelLocked(Parcel out)10611 void writeToParcelLocked(Parcel out) { 10612 int numWA = mWakeupAlarms.size(); 10613 out.writeInt(numWA); 10614 for (int i=0; i<numWA; i++) { 10615 out.writeString(mWakeupAlarms.keyAt(i)); 10616 mWakeupAlarms.valueAt(i).writeToParcel(out); 10617 } 10618 10619 final int NS = mServiceStats.size(); 10620 out.writeInt(NS); 10621 for (int i=0; i<NS; i++) { 10622 out.writeString(mServiceStats.keyAt(i)); 10623 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 10624 serv.writeToParcelLocked(out); 10625 } 10626 } 10627 10628 @Override getWakeupAlarmStats()10629 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 10630 return mWakeupAlarms; 10631 } 10632 noteWakeupAlarmLocked(String tag)10633 public void noteWakeupAlarmLocked(String tag) { 10634 Counter c = mWakeupAlarms.get(tag); 10635 if (c == null) { 10636 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 10637 mWakeupAlarms.put(tag, c); 10638 } 10639 c.stepAtomic(); 10640 } 10641 10642 @Override getServiceStats()10643 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 10644 return mServiceStats; 10645 } 10646 10647 /** 10648 * The statistics associated with a particular service. 10649 */ 10650 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 10651 /** 10652 * BatteryStatsImpl that we are associated with. 10653 */ 10654 protected BatteryStatsImpl mBsi; 10655 10656 /** 10657 * The android package in which this service resides. 10658 */ 10659 protected Pkg mPkg; 10660 10661 /** 10662 * Total time (ms in battery uptime) the service has been left started. 10663 */ 10664 protected long mStartTimeMs; 10665 10666 /** 10667 * If service has been started and not yet stopped, this is 10668 * when it was started. 10669 */ 10670 protected long mRunningSinceMs; 10671 10672 /** 10673 * True if we are currently running. 10674 */ 10675 protected boolean mRunning; 10676 10677 /** 10678 * Total number of times startService() has been called. 10679 */ 10680 protected int mStarts; 10681 10682 /** 10683 * Total time (ms in battery uptime) the service has been left launched. 10684 */ 10685 protected long mLaunchedTimeMs; 10686 10687 /** 10688 * If service has been launched and not yet exited, this is 10689 * when it was launched (ms in battery uptime). 10690 */ 10691 protected long mLaunchedSinceMs; 10692 10693 /** 10694 * True if we are currently launched. 10695 */ 10696 protected boolean mLaunched; 10697 10698 /** 10699 * Total number times the service has been launched. 10700 */ 10701 protected int mLaunches; 10702 10703 /** 10704 * Construct a Serv. Also adds it to the on-battery time base as a listener. 10705 */ Serv(BatteryStatsImpl bsi)10706 public Serv(BatteryStatsImpl bsi) { 10707 mBsi = bsi; 10708 mBsi.mOnBatteryTimeBase.add(this); 10709 } 10710 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10711 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10712 long baseRealtimeUs) { 10713 } 10714 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10715 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10716 long baseRealtimeUs) { 10717 } 10718 10719 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10720 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10721 if (detachIfReset) { 10722 this.detach(); 10723 } 10724 return true; 10725 } 10726 10727 /** 10728 * Remove this Serv as a listener from the time base. 10729 Ms*/ 10730 @Override detach()10731 public void detach() { 10732 mBsi.mOnBatteryTimeBase.remove(this); 10733 } 10734 readFromParcelLocked(Parcel in)10735 public void readFromParcelLocked(Parcel in) { 10736 mStartTimeMs = in.readLong(); 10737 mRunningSinceMs = in.readLong(); 10738 mRunning = in.readInt() != 0; 10739 mStarts = in.readInt(); 10740 mLaunchedTimeMs = in.readLong(); 10741 mLaunchedSinceMs = in.readLong(); 10742 mLaunched = in.readInt() != 0; 10743 mLaunches = in.readInt(); 10744 } 10745 writeToParcelLocked(Parcel out)10746 public void writeToParcelLocked(Parcel out) { 10747 out.writeLong(mStartTimeMs); 10748 out.writeLong(mRunningSinceMs); 10749 out.writeInt(mRunning ? 1 : 0); 10750 out.writeInt(mStarts); 10751 out.writeLong(mLaunchedTimeMs); 10752 out.writeLong(mLaunchedSinceMs); 10753 out.writeInt(mLaunched ? 1 : 0); 10754 out.writeInt(mLaunches); 10755 } 10756 getLaunchTimeToNowLocked(long batteryUptimeMs)10757 public long getLaunchTimeToNowLocked(long batteryUptimeMs) { 10758 if (!mLaunched) return mLaunchedTimeMs; 10759 return mLaunchedTimeMs + batteryUptimeMs - mLaunchedSinceMs; 10760 } 10761 getStartTimeToNowLocked(long batteryUptimeMs)10762 public long getStartTimeToNowLocked(long batteryUptimeMs) { 10763 if (!mRunning) return mStartTimeMs; 10764 return mStartTimeMs + batteryUptimeMs - mRunningSinceMs; 10765 } 10766 startLaunchedLocked()10767 public void startLaunchedLocked() { 10768 startLaunchedLocked(mBsi.mClock.uptimeMillis()); 10769 } 10770 startLaunchedLocked(long uptimeMs)10771 public void startLaunchedLocked(long uptimeMs) { 10772 if (!mLaunched) { 10773 mLaunches++; 10774 mLaunchedSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10775 mLaunched = true; 10776 } 10777 } 10778 stopLaunchedLocked()10779 public void stopLaunchedLocked() { 10780 stopLaunchedLocked(mBsi.mClock.uptimeMillis()); 10781 } 10782 stopLaunchedLocked(long uptimeMs)10783 public void stopLaunchedLocked(long uptimeMs) { 10784 if (mLaunched) { 10785 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10786 - mLaunchedSinceMs; 10787 if (timeMs > 0) { 10788 mLaunchedTimeMs += timeMs; 10789 } else { 10790 mLaunches--; 10791 } 10792 mLaunched = false; 10793 } 10794 } 10795 startRunningLocked()10796 public void startRunningLocked() { 10797 startRunningLocked(mBsi.mClock.uptimeMillis()); 10798 } 10799 startRunningLocked(long uptimeMs)10800 public void startRunningLocked(long uptimeMs) { 10801 if (!mRunning) { 10802 mStarts++; 10803 mRunningSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10804 mRunning = true; 10805 } 10806 } 10807 stopRunningLocked()10808 public void stopRunningLocked() { 10809 stopRunningLocked(mBsi.mClock.uptimeMillis()); 10810 } 10811 stopRunningLocked(long uptimeMs)10812 public void stopRunningLocked(long uptimeMs) { 10813 if (mRunning) { 10814 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10815 - mRunningSinceMs; 10816 if (timeMs > 0) { 10817 mStartTimeMs += timeMs; 10818 } else { 10819 mStarts--; 10820 } 10821 mRunning = false; 10822 } 10823 } 10824 getBatteryStats()10825 public BatteryStatsImpl getBatteryStats() { 10826 return mBsi; 10827 } 10828 10829 @Override getLaunches(int which)10830 public int getLaunches(int which) { 10831 return mLaunches; 10832 } 10833 10834 @Override getStartTime(long now, int which)10835 public long getStartTime(long now, int which) { 10836 return getStartTimeToNowLocked(now); 10837 } 10838 10839 @Override getStarts(int which)10840 public int getStarts(int which) { 10841 return mStarts; 10842 } 10843 } 10844 newServiceStatsLocked()10845 final Serv newServiceStatsLocked() { 10846 return new Serv(mBsi); 10847 } 10848 } 10849 10850 private class ChildUid { 10851 public final TimeMultiStateCounter cpuActiveCounter; 10852 public final LongArrayMultiStateCounter cpuTimeInFreqCounter; 10853 ChildUid()10854 ChildUid() { 10855 final long timestampMs = mBsi.mClock.elapsedRealtime(); 10856 cpuActiveCounter = 10857 new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, 1, timestampMs); 10858 cpuActiveCounter.setState(0, timestampMs); 10859 10860 if (mBsi.trackPerProcStateCpuTimes()) { 10861 final int cpuFreqCount = mBsi.mCpuScalingPolicies.getScalingStepCount(); 10862 10863 cpuTimeInFreqCounter = new LongArrayMultiStateCounter(1, cpuFreqCount); 10864 10865 // Set initial values to all 0. This is a child UID and we want to include 10866 // the entirety of its CPU time-in-freq stats into the parent's stats. 10867 cpuTimeInFreqCounter.updateValues(new long[cpuFreqCount], timestampMs); 10868 } else { 10869 cpuTimeInFreqCounter = null; 10870 } 10871 } 10872 } 10873 10874 /** 10875 * Retrieve the statistics object for a particular process, creating 10876 * if needed. 10877 */ getProcessStatsLocked(String name)10878 public Proc getProcessStatsLocked(String name) { 10879 Proc ps = mProcessStats.get(name); 10880 if (ps == null) { 10881 ps = new Proc(mBsi, name); 10882 mProcessStats.put(name, ps); 10883 } 10884 10885 return ps; 10886 } 10887 10888 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState, long elapsedRealtimeMs, long uptimeMs)10889 public void updateUidProcessStateLocked(int procState, 10890 long elapsedRealtimeMs, long uptimeMs) { 10891 int uidRunningState; 10892 // Make special note of Foreground Services 10893 final boolean userAwareService = ActivityManager.isForegroundService(procState); 10894 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 10895 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 10896 return; 10897 } 10898 10899 if (mProcessState != uidRunningState) { 10900 if (mProcessState != Uid.PROCESS_STATE_NONEXISTENT) { 10901 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 10902 } 10903 if (uidRunningState != Uid.PROCESS_STATE_NONEXISTENT) { 10904 if (mProcessStateTimer[uidRunningState] == null) { 10905 makeProcessState(uidRunningState, null); 10906 } 10907 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 10908 } 10909 10910 if (!mBsi.mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU) 10911 && mBsi.trackPerProcStateCpuTimes()) { 10912 mBsi.updateProcStateCpuTimesLocked(mUid, elapsedRealtimeMs, uptimeMs); 10913 10914 LongArrayMultiStateCounter onBatteryCounter = 10915 getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 10916 LongArrayMultiStateCounter onBatteryScreenOffCounter = 10917 getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 10918 10919 onBatteryCounter.setState(uidRunningState, elapsedRealtimeMs); 10920 onBatteryScreenOffCounter.setState(uidRunningState, elapsedRealtimeMs); 10921 } 10922 10923 final int prevBatteryConsumerProcessState = 10924 mapUidProcessStateToBatteryConsumerProcessState(mProcessState); 10925 10926 mProcessState = uidRunningState; 10927 10928 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10929 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10930 10931 final int batteryConsumerProcessState = 10932 mapUidProcessStateToBatteryConsumerProcessState(uidRunningState); 10933 if (mBsi.mSystemReady) { 10934 mBsi.mHistory.recordProcessStateChange(elapsedRealtimeMs, uptimeMs, mUid, 10935 batteryConsumerProcessState); 10936 } 10937 getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedRealtimeMs); 10938 10939 getMobileRadioActiveTimeCounter() 10940 .setState(batteryConsumerProcessState, elapsedRealtimeMs); 10941 10942 final ControllerActivityCounterImpl wifiControllerActivity = 10943 getWifiControllerActivity(); 10944 if (wifiControllerActivity != null) { 10945 wifiControllerActivity.setState(batteryConsumerProcessState, elapsedRealtimeMs); 10946 } 10947 10948 final ControllerActivityCounterImpl bluetoothControllerActivity = 10949 getBluetoothControllerActivity(); 10950 if (bluetoothControllerActivity != null) { 10951 bluetoothControllerActivity.setState(batteryConsumerProcessState, 10952 elapsedRealtimeMs); 10953 } 10954 10955 final EnergyConsumerStats energyStats = 10956 getOrCreateEnergyConsumerStatsIfSupportedLocked(); 10957 if (energyStats != null) { 10958 energyStats.setState(batteryConsumerProcessState, elapsedRealtimeMs); 10959 } 10960 maybeScheduleExternalStatsSync(prevBatteryConsumerProcessState, 10961 batteryConsumerProcessState); 10962 } 10963 10964 if (userAwareService != mInForegroundService) { 10965 if (userAwareService) { 10966 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 10967 } else { 10968 noteForegroundServicePausedLocked(elapsedRealtimeMs); 10969 } 10970 mInForegroundService = userAwareService; 10971 } 10972 } 10973 10974 @GuardedBy("mBsi") maybeScheduleExternalStatsSync( @atteryConsumer.ProcessState int oldProcessState, @BatteryConsumer.ProcessState int newProcessState)10975 private void maybeScheduleExternalStatsSync( 10976 @BatteryConsumer.ProcessState int oldProcessState, 10977 @BatteryConsumer.ProcessState int newProcessState) { 10978 if (oldProcessState == newProcessState) { 10979 return; 10980 } 10981 // Transitions between BACKGROUND and such non-foreground states like cached 10982 // or nonexistent do not warrant doing a sync. If some of the stats for those 10983 // proc states bleed into the PROCESS_STATE_BACKGROUND, that's ok. 10984 if ((oldProcessState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED 10985 && newProcessState == BatteryConsumer.PROCESS_STATE_BACKGROUND) 10986 || (oldProcessState == BatteryConsumer.PROCESS_STATE_BACKGROUND 10987 && newProcessState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED)) { 10988 return; 10989 } 10990 10991 int flags = ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE; 10992 // Skip querying for inactive radio, where power usage is probably negligible. 10993 if (!BatteryStatsImpl.isActiveRadioPowerState(mBsi.mMobileRadioPowerState)) { 10994 flags &= ~ExternalStatsSync.UPDATE_RADIO; 10995 } 10996 10997 mBsi.mExternalSync.scheduleSyncDueToProcessStateChange(flags, 10998 mBsi.mConstants.PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 10999 } 11000 11001 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()11002 public boolean isInBackground() { 11003 // Note that PROCESS_STATE_CACHED and Uid.PROCESS_STATE_NONEXISTENT is 11004 // also considered to be 'background' for our purposes, because it's not foreground. 11005 return mProcessState >= PROCESS_STATE_BACKGROUND; 11006 } 11007 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)11008 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 11009 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 11010 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 11011 } 11012 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)11013 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 11014 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 11015 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 11016 } 11017 getPidStats()11018 public SparseArray<? extends Pid> getPidStats() { 11019 return mPids; 11020 } 11021 getPidStatsLocked(int pid)11022 public Pid getPidStatsLocked(int pid) { 11023 Pid p = mPids.get(pid); 11024 if (p == null) { 11025 p = new Pid(); 11026 mPids.put(pid, p); 11027 } 11028 return p; 11029 } 11030 11031 /** 11032 * Retrieve the statistics object for a particular service, creating 11033 * if needed. 11034 */ getPackageStatsLocked(String name)11035 public Pkg getPackageStatsLocked(String name) { 11036 Pkg ps = mPackageStats.get(name); 11037 if (ps == null) { 11038 ps = new Pkg(mBsi); 11039 mPackageStats.put(name, ps); 11040 } 11041 11042 return ps; 11043 } 11044 11045 /** 11046 * Retrieve the statistics object for a particular service, creating 11047 * if needed. 11048 */ getServiceStatsLocked(String pkg, String serv)11049 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 11050 Pkg ps = getPackageStatsLocked(pkg); 11051 Pkg.Serv ss = ps.mServiceStats.get(serv); 11052 if (ss == null) { 11053 ss = ps.newServiceStatsLocked(); 11054 ps.mServiceStats.put(serv, ss); 11055 } 11056 11057 return ss; 11058 } 11059 readSyncSummaryFromParcelLocked(String name, Parcel in)11060 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 11061 DualTimer timer = mSyncStats.instantiateObject(); 11062 timer.readSummaryFromParcelLocked(in); 11063 mSyncStats.add(name, timer); 11064 } 11065 readJobSummaryFromParcelLocked(String name, Parcel in)11066 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 11067 DualTimer timer = mJobStats.instantiateObject(); 11068 timer.readSummaryFromParcelLocked(in); 11069 mJobStats.add(name, timer); 11070 } 11071 readWakeSummaryFromParcelLocked(String wlName, Parcel in)11072 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 11073 Wakelock wl = new Wakelock(mBsi, this); 11074 mWakelockStats.add(wlName, wl); 11075 if (in.readInt() != 0) { 11076 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 11077 } 11078 if (in.readInt() != 0) { 11079 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 11080 } 11081 if (in.readInt() != 0) { 11082 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 11083 } 11084 if (in.readInt() != 0) { 11085 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 11086 } 11087 } 11088 getSensorTimerLocked(int sensor, boolean create)11089 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 11090 Sensor se = mSensorStats.get(sensor); 11091 if (se == null) { 11092 if (!create) { 11093 return null; 11094 } 11095 se = new Sensor(mBsi, this, sensor); 11096 mSensorStats.put(sensor, se); 11097 } 11098 DualTimer t = se.mTimer; 11099 if (t != null) { 11100 return t; 11101 } 11102 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 11103 if (timers == null) { 11104 timers = new ArrayList<StopwatchTimer>(); 11105 mBsi.mSensorTimers.put(sensor, timers); 11106 } 11107 t = new DualTimer(mBsi.mClock, this, BatteryStats.SENSOR, timers, 11108 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 11109 se.mTimer = t; 11110 return t; 11111 } 11112 noteStartSyncLocked(String name, long elapsedRealtimeMs)11113 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 11114 DualTimer t = mSyncStats.startObject(name, elapsedRealtimeMs); 11115 if (t != null) { 11116 t.startRunningLocked(elapsedRealtimeMs); 11117 } 11118 } 11119 noteStopSyncLocked(String name, long elapsedRealtimeMs)11120 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 11121 DualTimer t = mSyncStats.stopObject(name, elapsedRealtimeMs); 11122 if (t != null) { 11123 t.stopRunningLocked(elapsedRealtimeMs); 11124 } 11125 } 11126 noteStartJobLocked(String name, long elapsedRealtimeMs)11127 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 11128 DualTimer t = mJobStats.startObject(name, elapsedRealtimeMs); 11129 if (t != null) { 11130 t.startRunningLocked(elapsedRealtimeMs); 11131 } 11132 } 11133 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)11134 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 11135 DualTimer t = mJobStats.stopObject(name, elapsedRealtimeMs); 11136 if (t != null) { 11137 t.stopRunningLocked(elapsedRealtimeMs); 11138 } 11139 if (mBsi.mOnBatteryTimeBase.isRunning()) { 11140 SparseIntArray types = mJobCompletions.get(name); 11141 if (types == null) { 11142 types = new SparseIntArray(); 11143 mJobCompletions.put(name, types); 11144 } 11145 int last = types.get(stopReason, 0); 11146 types.put(stopReason, last + 1); 11147 } 11148 } 11149 getWakelockTimerLocked(Wakelock wl, int type)11150 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 11151 if (wl == null) { 11152 return null; 11153 } 11154 switch (type) { 11155 case WAKE_TYPE_PARTIAL: { 11156 DualTimer t = wl.mTimerPartial; 11157 if (t == null) { 11158 t = new DualTimer(mBsi.mClock, this, WAKE_TYPE_PARTIAL, 11159 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 11160 mOnBatteryScreenOffBackgroundTimeBase); 11161 wl.mTimerPartial = t; 11162 } 11163 return t; 11164 } 11165 case WAKE_TYPE_FULL: { 11166 StopwatchTimer t = wl.mTimerFull; 11167 if (t == null) { 11168 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_FULL, 11169 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 11170 wl.mTimerFull = t; 11171 } 11172 return t; 11173 } 11174 case WAKE_TYPE_WINDOW: { 11175 StopwatchTimer t = wl.mTimerWindow; 11176 if (t == null) { 11177 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_WINDOW, 11178 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 11179 wl.mTimerWindow = t; 11180 } 11181 return t; 11182 } 11183 case WAKE_TYPE_DRAW: { 11184 StopwatchTimer t = wl.mTimerDraw; 11185 if (t == null) { 11186 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_DRAW, 11187 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 11188 wl.mTimerDraw = t; 11189 } 11190 return t; 11191 } 11192 default: 11193 throw new IllegalArgumentException("type=" + type); 11194 } 11195 } 11196 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)11197 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 11198 Wakelock wl = mWakelockStats.startObject(name, elapsedRealtimeMs); 11199 if (wl != null) { 11200 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 11201 } 11202 if (type == WAKE_TYPE_PARTIAL) { 11203 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 11204 if (pid >= 0) { 11205 Pid p = getPidStatsLocked(pid); 11206 if (p.mWakeNesting++ == 0) { 11207 p.mWakeStartMs = elapsedRealtimeMs; 11208 } 11209 } 11210 } 11211 } 11212 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)11213 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 11214 Wakelock wl = mWakelockStats.stopObject(name, elapsedRealtimeMs); 11215 if (wl != null) { 11216 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 11217 wlt.stopRunningLocked(elapsedRealtimeMs); 11218 } 11219 if (type == WAKE_TYPE_PARTIAL) { 11220 if (mAggregatedPartialWakelockTimer != null) { 11221 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 11222 } 11223 if (pid >= 0) { 11224 Pid p = mPids.get(pid); 11225 if (p != null && p.mWakeNesting > 0) { 11226 if (p.mWakeNesting-- == 1) { 11227 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 11228 p.mWakeStartMs = 0; 11229 } 11230 } 11231 } 11232 } 11233 } 11234 reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs)11235 public void reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs) { 11236 Proc p = getProcessStatsLocked(proc); 11237 if (p != null) { 11238 p.addExcessiveCpu(overTimeMs, usedTimeMs); 11239 } 11240 } 11241 noteStartSensor(int sensor, long elapsedRealtimeMs)11242 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 11243 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 11244 t.startRunningLocked(elapsedRealtimeMs); 11245 } 11246 noteStopSensor(int sensor, long elapsedRealtimeMs)11247 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 11248 // Don't create a timer if one doesn't already exist 11249 DualTimer t = getSensorTimerLocked(sensor, false); 11250 if (t != null) { 11251 t.stopRunningLocked(elapsedRealtimeMs); 11252 } 11253 } 11254 noteStartGps(long elapsedRealtimeMs)11255 public void noteStartGps(long elapsedRealtimeMs) { 11256 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 11257 } 11258 noteStopGps(long elapsedRealtimeMs)11259 public void noteStopGps(long elapsedRealtimeMs) { 11260 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 11261 } 11262 } 11263 11264 @GuardedBy("this") getCpuScalingPolicies()11265 public CpuScalingPolicies getCpuScalingPolicies() { 11266 return mCpuScalingPolicies; 11267 } 11268 11269 @GuardedBy("this") getCpuTimeInFreqContainer()11270 private long[] getCpuTimeInFreqContainer() { 11271 if (mTmpCpuTimeInFreq == null) { 11272 mTmpCpuTimeInFreq = new long[mCpuScalingPolicies.getScalingStepCount()]; 11273 } 11274 return mTmpCpuTimeInFreq; 11275 } 11276 11277 WakelockStatsFrameworkEvents mFrameworkEvents = new WakelockStatsFrameworkEvents(); 11278 PowerManagerFlags mPowerManagerFlags = new PowerManagerFlags(); 11279 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)11280 public BatteryStatsImpl(@NonNull BatteryStatsConfig config, @NonNull Clock clock, 11281 @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, 11282 @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback, 11283 @Nullable EnergyStatsRetriever energyStatsRetriever, 11284 @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile, 11285 @NonNull CpuScalingPolicies cpuScalingPolicies, 11286 @NonNull PowerStatsUidResolver powerStatsUidResolver) { 11287 this(config, clock, monotonicClock, systemDir, 11288 systemDir != null ? new BatteryHistoryDirectory(new File(systemDir, HISTORY_DIR), 11289 config.getMaxHistorySizeBytes()) : null, 11290 handler, platformIdleStateCallback, 11291 energyStatsRetriever, userInfoProvider, powerProfile, cpuScalingPolicies, 11292 powerStatsUidResolver, new FrameworkStatsLogger(), 11293 new BatteryStatsHistory.TraceDelegate(), new BatteryStatsHistory.EventLogger()); 11294 } 11295 BatteryStatsImpl(@onNull BatteryStatsConfig config, @NonNull Clock clock, @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, @Nullable BatteryHistoryDirectory batteryHistoryDirectory, @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)11296 public BatteryStatsImpl(@NonNull BatteryStatsConfig config, @NonNull Clock clock, 11297 @NonNull MonotonicClock monotonicClock, @Nullable File systemDir, 11298 @Nullable BatteryHistoryDirectory batteryHistoryDirectory, 11299 @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback, 11300 @Nullable EnergyStatsRetriever energyStatsRetriever, 11301 @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile, 11302 @NonNull CpuScalingPolicies cpuScalingPolicies, 11303 @NonNull PowerStatsUidResolver powerStatsUidResolver, 11304 @NonNull FrameworkStatsLogger frameworkStatsLogger, 11305 @NonNull BatteryStatsHistory.TraceDelegate traceDelegate, 11306 @NonNull BatteryStatsHistory.EventLogger eventLogger) { 11307 mClock = clock; 11308 initKernelStatsReaders(); 11309 11310 mBatteryStatsConfig = config; 11311 mMonotonicClock = monotonicClock; 11312 mHandler = new MyHandler(handler.getLooper()); 11313 mConstants = new Constants(mHandler); 11314 11315 mPowerProfile = powerProfile; 11316 mCpuScalingPolicies = cpuScalingPolicies; 11317 mPowerStatsUidResolver = powerStatsUidResolver; 11318 mFrameworkStatsLogger = frameworkStatsLogger; 11319 11320 initPowerProfile(); 11321 11322 if (systemDir != null) { 11323 mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); 11324 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 11325 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 11326 } else { 11327 mStatsFile = null; 11328 mCheckinFile = null; 11329 mDailyFile = null; 11330 } 11331 11332 mBatteryHistoryDirectory = batteryHistoryDirectory; 11333 mHistory = new BatteryStatsHistory(null /* historyBuffer */, mConstants.MAX_HISTORY_BUFFER, 11334 mBatteryHistoryDirectory, mClock, mMonotonicClock, traceDelegate, eventLogger); 11335 11336 mCpuPowerStatsCollector = new CpuPowerStatsCollector(mPowerStatsCollectorInjector); 11337 mCpuPowerStatsCollector.addConsumer(this::recordPowerStats); 11338 11339 mWakelockPowerStatsCollector = new WakelockPowerStatsCollector( 11340 mPowerStatsCollectorInjector); 11341 mWakelockPowerStatsCollector.addConsumer(this::recordPowerStats); 11342 11343 mScreenPowerStatsCollector = new ScreenPowerStatsCollector(mPowerStatsCollectorInjector); 11344 mScreenPowerStatsCollector.addConsumer(this::recordPowerStats); 11345 11346 mMobileRadioPowerStatsCollector = new MobileRadioPowerStatsCollector( 11347 mPowerStatsCollectorInjector, this::onMobileRadioPowerStatsRetrieved); 11348 mMobileRadioPowerStatsCollector.addConsumer(this::recordPowerStats); 11349 11350 mWifiPowerStatsCollector = new WifiPowerStatsCollector(mPowerStatsCollectorInjector, 11351 this::onWifiPowerStatsRetrieved); 11352 mWifiPowerStatsCollector.addConsumer(this::recordPowerStats); 11353 11354 mBluetoothPowerStatsCollector = new BluetoothPowerStatsCollector( 11355 mPowerStatsCollectorInjector, this::onBluetoothPowerStatsRetrieved); 11356 mBluetoothPowerStatsCollector.addConsumer(this::recordPowerStats); 11357 11358 mCameraPowerStatsCollector = new CameraPowerStatsCollector(mPowerStatsCollectorInjector); 11359 mCameraPowerStatsCollector.addConsumer(this::recordPowerStats); 11360 11361 mGnssPowerStatsCollector = new GnssPowerStatsCollector(mPowerStatsCollectorInjector); 11362 mGnssPowerStatsCollector.addConsumer(this::recordPowerStats); 11363 11364 mCustomEnergyConsumerPowerStatsCollector = 11365 new CustomEnergyConsumerPowerStatsCollector(mPowerStatsCollectorInjector); 11366 mCustomEnergyConsumerPowerStatsCollector.addConsumer(this::recordPowerStats); 11367 11368 mStartCount++; 11369 initTimersAndCounters(); 11370 mOnBattery = mOnBatteryInternal = false; 11371 long uptimeUs = mClock.uptimeMillis() * 1000; 11372 long realtimeUs = mClock.elapsedRealtime() * 1000; 11373 initTimes(uptimeUs, realtimeUs); 11374 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 11375 initDischarge(realtimeUs); 11376 updateDailyDeadlineLocked(); 11377 mPlatformIdleStateCallback = platformIdleStateCallback; 11378 mEnergyConsumerRetriever = energyStatsRetriever; 11379 mUserInfoProvider = userInfoProvider; 11380 11381 mPowerStatsUidResolver.addListener(new PowerStatsUidResolver.Listener() { 11382 @Override 11383 public void onIsolatedUidAdded(int isolatedUid, int parentUid) { 11384 BatteryStatsImpl.this.onIsolatedUidAdded(isolatedUid, parentUid); 11385 } 11386 11387 @Override 11388 public void onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid) { 11389 BatteryStatsImpl.this.onBeforeIsolatedUidRemoved(isolatedUid, parentUid); 11390 } 11391 11392 @Override 11393 public void onAfterIsolatedUidRemoved(int isolatedUid, int parentUid) { 11394 BatteryStatsImpl.this.onAfterIsolatedUidRemoved(isolatedUid, parentUid); 11395 } 11396 }); 11397 11398 // Notify statsd that the system is initially not in doze. 11399 mDeviceIdleMode = DEVICE_IDLE_MODE_OFF; 11400 mFrameworkStatsLogger.deviceIdleModeStateChanged(mDeviceIdleMode); 11401 } 11402 recordPowerStats(PowerStats stats)11403 private void recordPowerStats(PowerStats stats) { 11404 if (stats.durationMs > 0) { 11405 synchronized (this) { 11406 mHistory.recordPowerStats(mClock.elapsedRealtime(), mClock.uptimeMillis(), stats); 11407 } 11408 } 11409 } 11410 11411 @VisibleForTesting initTimersAndCounters()11412 protected void initTimersAndCounters() { 11413 mScreenOnTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase); 11414 mScreenDozeTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase); 11415 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11416 mScreenBrightnessTimer[i] = new StopwatchTimer(mClock, null, -100 - i, null, 11417 mOnBatteryTimeBase); 11418 } 11419 11420 mInteractiveTimer = new StopwatchTimer(mClock, null, -10, null, mOnBatteryTimeBase); 11421 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClock, null, -2, null, 11422 mOnBatteryTimeBase); 11423 mDeviceIdleModeLightTimer = new StopwatchTimer(mClock, null, -11, null, 11424 mOnBatteryTimeBase); 11425 mDeviceIdleModeFullTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase); 11426 mDeviceLightIdlingTimer = new StopwatchTimer(mClock, null, -15, null, mOnBatteryTimeBase); 11427 mDeviceIdlingTimer = new StopwatchTimer(mClock, null, -12, null, mOnBatteryTimeBase); 11428 mPhoneOnTimer = new StopwatchTimer(mClock, null, -3, null, mOnBatteryTimeBase); 11429 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 11430 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -200 - i, null, 11431 mOnBatteryTimeBase); 11432 } 11433 mPhoneSignalScanningTimer = new StopwatchTimer(mClock, null, -200 + 1, null, 11434 mOnBatteryTimeBase); 11435 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11436 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClock, null, -300 - i, null, 11437 mOnBatteryTimeBase); 11438 } 11439 mNrNsaTimer = new StopwatchTimer(mClock, null, -200 + 2, null, mOnBatteryTimeBase); 11440 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11441 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 11442 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 11443 } 11444 mWifiActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 11445 NUM_WIFI_TX_LEVELS); 11446 mBluetoothActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 11447 NUM_BT_TX_LEVELS); 11448 mModemActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 11449 MODEM_TX_POWER_LEVEL_COUNT); 11450 mMobileRadioActiveTimer = new StopwatchTimer(mClock, null, -400, null, mOnBatteryTimeBase); 11451 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClock, null, -401, null, 11452 mOnBatteryTimeBase); 11453 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 11454 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 11455 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 11456 mWifiMulticastWakelockTimer = new StopwatchTimer(mClock, null, 11457 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 11458 mWifiOnTimer = new StopwatchTimer(mClock, null, -4, null, mOnBatteryTimeBase); 11459 mGlobalWifiRunningTimer = new StopwatchTimer(mClock, null, -5, null, mOnBatteryTimeBase); 11460 for (int i=0; i<NUM_WIFI_STATES; i++) { 11461 mWifiStateTimer[i] = new StopwatchTimer(mClock, null, -600 - i, null, 11462 mOnBatteryTimeBase); 11463 } 11464 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11465 mWifiSupplStateTimer[i] = new StopwatchTimer(mClock, null, -700 - i, null, 11466 mOnBatteryTimeBase); 11467 } 11468 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11469 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -800 - i, null, 11470 mOnBatteryTimeBase); 11471 } 11472 mWifiActiveTimer = new StopwatchTimer(mClock, null, -900, null, mOnBatteryTimeBase); 11473 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 11474 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClock, null, -1000 - i, null, 11475 mOnBatteryTimeBase); 11476 } 11477 mAudioOnTimer = new StopwatchTimer(mClock, null, -7, null, mOnBatteryTimeBase); 11478 mVideoOnTimer = new StopwatchTimer(mClock, null, -8, null, mOnBatteryTimeBase); 11479 mFlashlightOnTimer = new StopwatchTimer(mClock, null, -9, null, mOnBatteryTimeBase); 11480 mCameraOnTimer = new StopwatchTimer(mClock, null, -13, null, mOnBatteryTimeBase); 11481 mBluetoothScanTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase); 11482 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 11483 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11484 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11485 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11486 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11487 mDischargeUnplugLevel = 0; 11488 mDischargePlugLevel = -1; 11489 mDischargeCurrentLevel = 0; 11490 mBatteryLevel = 0; 11491 } 11492 initPowerProfile()11493 private void initPowerProfile() { 11494 int[] policies = mCpuScalingPolicies.getPolicies(); 11495 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[policies.length]; 11496 for (int i = 0; i < policies.length; i++) { 11497 int[] cpus = mCpuScalingPolicies.getRelatedCpus(policies[i]); 11498 int[] freqs = mCpuScalingPolicies.getFrequencies(policies[i]); 11499 // We need to initialize the KernelCpuSpeedReaders to read from 11500 // the first cpu of each core. Once we have the CpuScalingPolicy, we have access to this 11501 // information. 11502 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(cpus[0], freqs.length); 11503 } 11504 11505 // Initialize CPU power bracket map, which combines CPU states (cluster/freq pairs) 11506 // into a small number of brackets 11507 mCpuPowerBracketMap = new int[mCpuScalingPolicies.getScalingStepCount()]; 11508 int index = 0; 11509 for (int policy : policies) { 11510 int steps = mCpuScalingPolicies.getFrequencies(policy).length; 11511 for (int step = 0; step < steps; step++) { 11512 mCpuPowerBracketMap[index++] = 11513 mPowerProfile.getCpuPowerBracketForScalingStep(policy, step); 11514 } 11515 } 11516 11517 if (mEstimatedBatteryCapacityMah == -1) { 11518 // Initialize the estimated battery capacity to a known preset one. 11519 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 11520 } 11521 11522 setDisplayCountLocked(mPowerProfile.getNumDisplays()); 11523 } 11524 11525 /** 11526 * Starts tracking CPU time-in-state for threads of the system server process, 11527 * keeping a separate account of threads receiving incoming binder calls. 11528 */ startTrackingSystemServerCpuTime()11529 public void startTrackingSystemServerCpuTime() { 11530 mSystemServerCpuThreadReader.startTrackingThreadCpuTime(); 11531 } 11532 getSystemServiceCpuThreadTimes()11533 public SystemServiceCpuThreadTimes getSystemServiceCpuThreadTimes() { 11534 return mSystemServerCpuThreadReader.readAbsolute(); 11535 } 11536 setCallback(BatteryCallback cb)11537 public void setCallback(BatteryCallback cb) { 11538 mCallback = cb; 11539 } 11540 updateCpuDetails()11541 void updateCpuDetails() { 11542 if (mCallback != null) { 11543 mCallback.batteryNeedsCpuUpdate(); 11544 } 11545 } 11546 setRadioScanningTimeoutLocked(long timeoutUs)11547 public void setRadioScanningTimeoutLocked(long timeoutUs) { 11548 if (mPhoneSignalScanningTimer != null) { 11549 mPhoneSignalScanningTimer.setTimeout(timeoutUs); 11550 } 11551 } 11552 setExternalStatsSyncLocked(ExternalStatsSync sync)11553 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 11554 mExternalSync = sync; 11555 } 11556 11557 /** 11558 * Initialize and set multi display timers and states. 11559 */ setDisplayCountLocked(int numDisplays)11560 public void setDisplayCountLocked(int numDisplays) { 11561 mPerDisplayBatteryStats = new DisplayBatteryStats[numDisplays]; 11562 for (int i = 0; i < numDisplays; i++) { 11563 mPerDisplayBatteryStats[i] = new DisplayBatteryStats(mClock, mOnBatteryTimeBase); 11564 } 11565 } 11566 updateDailyDeadlineLocked()11567 public void updateDailyDeadlineLocked() { 11568 // Get the current time. 11569 long currentTimeMs = mDailyStartTimeMs = mClock.currentTimeMillis(); 11570 Calendar calDeadline = Calendar.getInstance(); 11571 calDeadline.setTimeInMillis(currentTimeMs); 11572 11573 // Move time up to the next day, ranging from 1am to 3pm. 11574 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 11575 calDeadline.set(Calendar.MILLISECOND, 0); 11576 calDeadline.set(Calendar.SECOND, 0); 11577 calDeadline.set(Calendar.MINUTE, 0); 11578 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 11579 mNextMinDailyDeadlineMs = calDeadline.getTimeInMillis(); 11580 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 11581 mNextMaxDailyDeadlineMs = calDeadline.getTimeInMillis(); 11582 } 11583 recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs)11584 public void recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs) { 11585 if (currentTimeMs >= mNextMaxDailyDeadlineMs) { 11586 recordDailyStatsLocked(); 11587 } else if (settled && currentTimeMs >= mNextMinDailyDeadlineMs) { 11588 recordDailyStatsLocked(); 11589 } else if (currentTimeMs < (mDailyStartTimeMs - (1000 * 60 * 60 * 24))) { 11590 recordDailyStatsLocked(); 11591 } 11592 } 11593 recordDailyStatsLocked()11594 public void recordDailyStatsLocked() { 11595 DailyItem item = new DailyItem(); 11596 item.mStartTime = mDailyStartTimeMs; 11597 item.mEndTime = mClock.currentTimeMillis(); 11598 boolean hasData = false; 11599 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 11600 hasData = true; 11601 item.mDischargeSteps = new LevelStepTracker( 11602 mDailyDischargeStepTracker.mNumStepDurations, 11603 mDailyDischargeStepTracker.mStepDurations); 11604 } 11605 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 11606 hasData = true; 11607 item.mChargeSteps = new LevelStepTracker( 11608 mDailyChargeStepTracker.mNumStepDurations, 11609 mDailyChargeStepTracker.mStepDurations); 11610 } 11611 if (mDailyPackageChanges != null) { 11612 hasData = true; 11613 item.mPackageChanges = mDailyPackageChanges; 11614 mDailyPackageChanges = null; 11615 } 11616 mDailyDischargeStepTracker.init(); 11617 mDailyChargeStepTracker.init(); 11618 updateDailyDeadlineLocked(); 11619 11620 if (hasData) { 11621 final long startTimeMs = SystemClock.uptimeMillis(); 11622 mDailyItems.add(item); 11623 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 11624 mDailyItems.remove(0); 11625 } 11626 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 11627 try { 11628 TypedXmlSerializer out = Xml.resolveSerializer(memStream); 11629 writeDailyItemsLocked(out); 11630 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 11631 BackgroundThread.getHandler().post(new Runnable() { 11632 @Override 11633 public void run() { 11634 synchronized (mCheckinFile) { 11635 final long startTimeMs2 = SystemClock.uptimeMillis(); 11636 FileOutputStream stream = null; 11637 try { 11638 stream = mDailyFile.startWrite(); 11639 memStream.writeTo(stream); 11640 stream.flush(); 11641 mDailyFile.finishWrite(stream); 11642 mFrameworkStatsLogger.writeCommitSysConfigFile("batterystats-daily", 11643 initialTimeMs + SystemClock.uptimeMillis() - startTimeMs2); 11644 } catch (IOException e) { 11645 Slog.w("BatteryStats", 11646 "Error writing battery daily items", e); 11647 mDailyFile.failWrite(stream); 11648 } 11649 } 11650 } 11651 }); 11652 } catch (IOException e) { 11653 } 11654 } 11655 } 11656 writeDailyItemsLocked(TypedXmlSerializer out)11657 private void writeDailyItemsLocked(TypedXmlSerializer out) throws IOException { 11658 StringBuilder sb = new StringBuilder(64); 11659 out.startDocument(null, true); 11660 out.startTag(null, "daily-items"); 11661 for (int i=0; i<mDailyItems.size(); i++) { 11662 final DailyItem dit = mDailyItems.get(i); 11663 out.startTag(null, "item"); 11664 out.attributeLong(null, "start", dit.mStartTime); 11665 out.attributeLong(null, "end", dit.mEndTime); 11666 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 11667 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 11668 if (dit.mPackageChanges != null) { 11669 for (int j=0; j<dit.mPackageChanges.size(); j++) { 11670 PackageChange pc = dit.mPackageChanges.get(j); 11671 if (pc.mUpdate) { 11672 out.startTag(null, "upd"); 11673 out.attribute(null, "pkg", pc.mPackageName); 11674 out.attributeLong(null, "ver", pc.mVersionCode); 11675 out.endTag(null, "upd"); 11676 } else { 11677 out.startTag(null, "rem"); 11678 out.attribute(null, "pkg", pc.mPackageName); 11679 out.endTag(null, "rem"); 11680 } 11681 } 11682 } 11683 out.endTag(null, "item"); 11684 } 11685 out.endTag(null, "daily-items"); 11686 out.endDocument(); 11687 } 11688 writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)11689 private void writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, 11690 StringBuilder tmpBuilder) throws IOException { 11691 if (steps != null) { 11692 out.startTag(null, tag); 11693 out.attributeInt(null, "n", steps.mNumStepDurations); 11694 for (int i=0; i<steps.mNumStepDurations; i++) { 11695 out.startTag(null, "s"); 11696 tmpBuilder.setLength(0); 11697 steps.encodeEntryAt(i, tmpBuilder); 11698 out.attribute(null, "v", tmpBuilder.toString()); 11699 out.endTag(null, "s"); 11700 } 11701 out.endTag(null, tag); 11702 } 11703 } 11704 11705 @GuardedBy("this") readDailyStatsLocked()11706 public void readDailyStatsLocked() { 11707 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 11708 mDailyItems.clear(); 11709 FileInputStream stream; 11710 try { 11711 stream = mDailyFile.openRead(); 11712 } catch (FileNotFoundException e) { 11713 return; 11714 } 11715 try { 11716 TypedXmlPullParser parser = Xml.resolvePullParser(stream); 11717 readDailyItemsLocked(parser); 11718 } catch (IOException e) { 11719 } finally { 11720 try { 11721 stream.close(); 11722 } catch (IOException e) { 11723 } 11724 } 11725 } 11726 readDailyItemsLocked(TypedXmlPullParser parser)11727 private void readDailyItemsLocked(TypedXmlPullParser parser) { 11728 try { 11729 int type; 11730 while ((type = parser.next()) != XmlPullParser.START_TAG 11731 && type != XmlPullParser.END_DOCUMENT) { 11732 ; 11733 } 11734 11735 if (type != XmlPullParser.START_TAG) { 11736 throw new IllegalStateException("no start tag found"); 11737 } 11738 11739 int outerDepth = parser.getDepth(); 11740 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11741 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11742 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11743 continue; 11744 } 11745 11746 String tagName = parser.getName(); 11747 if (tagName.equals("item")) { 11748 readDailyItemTagLocked(parser); 11749 } else { 11750 Slog.w(TAG, "Unknown element under <daily-items>: " 11751 + parser.getName()); 11752 XmlUtils.skipCurrentTag(parser); 11753 } 11754 } 11755 11756 } catch (IllegalStateException e) { 11757 Slog.w(TAG, "Failed parsing daily " + e); 11758 } catch (NullPointerException e) { 11759 Slog.w(TAG, "Failed parsing daily " + e); 11760 } catch (NumberFormatException e) { 11761 Slog.w(TAG, "Failed parsing daily " + e); 11762 } catch (XmlPullParserException e) { 11763 Slog.w(TAG, "Failed parsing daily " + e); 11764 } catch (IOException e) { 11765 Slog.w(TAG, "Failed parsing daily " + e); 11766 } catch (IndexOutOfBoundsException e) { 11767 Slog.w(TAG, "Failed parsing daily " + e); 11768 } 11769 } 11770 readDailyItemTagLocked(TypedXmlPullParser parser)11771 void readDailyItemTagLocked(TypedXmlPullParser parser) throws NumberFormatException, 11772 XmlPullParserException, IOException { 11773 DailyItem dit = new DailyItem(); 11774 dit.mStartTime = parser.getAttributeLong(null, "start", 0); 11775 dit.mEndTime = parser.getAttributeLong(null, "end", 0); 11776 int outerDepth = parser.getDepth(); 11777 int type; 11778 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11779 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11780 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11781 continue; 11782 } 11783 11784 String tagName = parser.getName(); 11785 if (tagName.equals("dis")) { 11786 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 11787 } else if (tagName.equals("chg")) { 11788 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 11789 } else if (tagName.equals("upd")) { 11790 if (dit.mPackageChanges == null) { 11791 dit.mPackageChanges = new ArrayList<>(); 11792 } 11793 PackageChange pc = new PackageChange(); 11794 pc.mUpdate = true; 11795 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11796 pc.mVersionCode = parser.getAttributeLong(null, "ver", 0); 11797 dit.mPackageChanges.add(pc); 11798 XmlUtils.skipCurrentTag(parser); 11799 } else if (tagName.equals("rem")) { 11800 if (dit.mPackageChanges == null) { 11801 dit.mPackageChanges = new ArrayList<>(); 11802 } 11803 PackageChange pc = new PackageChange(); 11804 pc.mUpdate = false; 11805 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11806 dit.mPackageChanges.add(pc); 11807 XmlUtils.skipCurrentTag(parser); 11808 } else { 11809 Slog.w(TAG, "Unknown element under <item>: " 11810 + parser.getName()); 11811 XmlUtils.skipCurrentTag(parser); 11812 } 11813 } 11814 mDailyItems.add(dit); 11815 } 11816 readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, String tag)11817 void readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, 11818 String tag) 11819 throws NumberFormatException, XmlPullParserException, IOException { 11820 final int num = parser.getAttributeInt(null, "n", -1); 11821 if (num == -1) { 11822 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 11823 XmlUtils.skipCurrentTag(parser); 11824 return; 11825 } 11826 LevelStepTracker steps = new LevelStepTracker(num); 11827 if (isCharge) { 11828 dit.mChargeSteps = steps; 11829 } else { 11830 dit.mDischargeSteps = steps; 11831 } 11832 int i = 0; 11833 int outerDepth = parser.getDepth(); 11834 int type; 11835 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11836 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11837 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11838 continue; 11839 } 11840 11841 String tagName = parser.getName(); 11842 if ("s".equals(tagName)) { 11843 if (i < num) { 11844 String valueAttr = parser.getAttributeValue(null, "v"); 11845 if (valueAttr != null) { 11846 steps.decodeEntryAt(i, valueAttr); 11847 i++; 11848 } 11849 } 11850 } else { 11851 Slog.w(TAG, "Unknown element under <" + tag + ">: " 11852 + parser.getName()); 11853 XmlUtils.skipCurrentTag(parser); 11854 } 11855 } 11856 steps.mNumStepDurations = i; 11857 } 11858 11859 @Override getDailyItemLocked(int daysAgo)11860 public DailyItem getDailyItemLocked(int daysAgo) { 11861 int index = mDailyItems.size()-1-daysAgo; 11862 return index >= 0 ? mDailyItems.get(index) : null; 11863 } 11864 11865 @Override getCurrentDailyStartTime()11866 public long getCurrentDailyStartTime() { 11867 return mDailyStartTimeMs; 11868 } 11869 11870 @Override getNextMinDailyDeadline()11871 public long getNextMinDailyDeadline() { 11872 return mNextMinDailyDeadlineMs; 11873 } 11874 11875 @Override getNextMaxDailyDeadline()11876 public long getNextMaxDailyDeadline() { 11877 return mNextMaxDailyDeadlineMs; 11878 } 11879 getHistoryTotalSize()11880 public int getHistoryTotalSize() { 11881 return mBatteryHistoryDirectory.getMaxHistorySize(); 11882 } 11883 getHistoryUsedSize()11884 public int getHistoryUsedSize() { 11885 return mHistory.getHistoryUsedSize(); 11886 } 11887 11888 /** 11889 * Creates an iterator for battery stats history. 11890 */ 11891 @Override iterateBatteryStatsHistory(long startTimeMs, long endTimeMs)11892 public BatteryStatsHistoryIterator iterateBatteryStatsHistory(long startTimeMs, 11893 long endTimeMs) { 11894 return mHistory.iterate(startTimeMs, endTimeMs); 11895 } 11896 11897 @Override getHistoryStringPoolSize()11898 public int getHistoryStringPoolSize() { 11899 return mHistory.getHistoryStringPoolSize(); 11900 } 11901 11902 @Override getHistoryStringPoolBytes()11903 public int getHistoryStringPoolBytes() { 11904 return mHistory.getHistoryStringPoolBytes(); 11905 } 11906 11907 @Override getHistoryTagPoolString(int index)11908 public String getHistoryTagPoolString(int index) { 11909 return mHistory.getHistoryTagPoolString(index); 11910 } 11911 11912 @Override getHistoryTagPoolUid(int index)11913 public int getHistoryTagPoolUid(int index) { 11914 return mHistory.getHistoryTagPoolUid(index); 11915 } 11916 11917 @Override getStartCount()11918 public int getStartCount() { 11919 return mStartCount; 11920 } 11921 isOnBattery()11922 public boolean isOnBattery() { 11923 return mOnBattery; 11924 } 11925 isCharging()11926 public boolean isCharging() { 11927 return mCharging; 11928 } 11929 initTimes(long uptimeUs, long realtimeUs)11930 void initTimes(long uptimeUs, long realtimeUs) { 11931 mStartClockTimeMs = mClock.currentTimeMillis(); 11932 mOnBatteryTimeBase.init(uptimeUs, realtimeUs); 11933 mOnBatteryScreenOffTimeBase.init(uptimeUs, realtimeUs); 11934 mRealtimeUs = 0; 11935 mUptimeUs = 0; 11936 mRealtimeStartUs = realtimeUs; 11937 mUptimeStartUs = uptimeUs; 11938 mMonotonicStartTime = mMonotonicClock.monotonicTime(); 11939 } 11940 initDischarge(long elapsedRealtimeUs)11941 void initDischarge(long elapsedRealtimeUs) { 11942 mLowDischargeAmountSinceCharge = 0; 11943 mHighDischargeAmountSinceCharge = 0; 11944 mDischargeAmountScreenOn = 0; 11945 mDischargeAmountScreenOnSinceCharge = 0; 11946 mDischargeAmountScreenOff = 0; 11947 mDischargeAmountScreenOffSinceCharge = 0; 11948 mDischargeAmountScreenDoze = 0; 11949 mDischargeAmountScreenDozeSinceCharge = 0; 11950 mDischargeStepTracker.init(); 11951 mChargeStepTracker.init(); 11952 mDischargeScreenOffCounter.reset(false, elapsedRealtimeUs); 11953 mDischargeScreenDozeCounter.reset(false, elapsedRealtimeUs); 11954 mDischargeLightDozeCounter.reset(false, elapsedRealtimeUs); 11955 mDischargeDeepDozeCounter.reset(false, elapsedRealtimeUs); 11956 mDischargeCounter.reset(false, elapsedRealtimeUs); 11957 } 11958 11959 /** 11960 * Associates the BatteryStatsImpl object with a BatteryUsageStatsProvider and PowerStatsStore 11961 * to allow for a snapshot of battery usage stats to be taken and stored just before battery 11962 * reset. 11963 */ saveBatteryUsageStatsOnReset( @onNull BatteryUsageStatsProvider batteryUsageStatsProvider, @NonNull PowerStatsStore powerStatsStore, boolean accumulateBatteryUsageStats)11964 public void saveBatteryUsageStatsOnReset( 11965 @NonNull BatteryUsageStatsProvider batteryUsageStatsProvider, 11966 @NonNull PowerStatsStore powerStatsStore, 11967 boolean accumulateBatteryUsageStats) { 11968 mSaveBatteryUsageStatsOnReset = true; 11969 mBatteryUsageStatsProvider = batteryUsageStatsProvider; 11970 mPowerStatsStore = powerStatsStore; 11971 mAccumulateBatteryUsageStats = accumulateBatteryUsageStats; 11972 } 11973 11974 /** 11975 * Enables or disables battery history reset at the beginning of a battery stats session. 11976 */ resetBatteryHistoryOnNewSession(boolean enabled)11977 public void resetBatteryHistoryOnNewSession(boolean enabled) { 11978 mResetBatteryHistoryOnNewSession = enabled; 11979 } 11980 11981 /** 11982 * Enables or disables battery history file compression. 11983 */ setBatteryHistoryCompressionEnabled(boolean enabled)11984 public void setBatteryHistoryCompressionEnabled(boolean enabled) { 11985 mBatteryHistoryDirectory.setFileCompressionEnabled(enabled); 11986 } 11987 11988 @GuardedBy("this") resetAllStatsAndHistoryLocked(int reason)11989 public void resetAllStatsAndHistoryLocked(int reason) { 11990 final long mSecUptime = mClock.uptimeMillis(); 11991 long uptimeUs = mSecUptime * 1000; 11992 long mSecRealtime = mClock.elapsedRealtime(); 11993 long realtimeUs = mSecRealtime * 1000; 11994 resetAllStatsLocked(mSecUptime, mSecRealtime, reason); 11995 pullPendingStateUpdatesLocked(); 11996 mHistory.writeHistoryItem(mSecRealtime, mSecUptime); 11997 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel = mBatteryLevel; 11998 mOnBatteryTimeBase.reset(uptimeUs, realtimeUs); 11999 mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs); 12000 if (!mBatteryPluggedIn) { 12001 if (Display.isOnState(mScreenState)) { 12002 mDischargeScreenOnUnplugLevel = mBatteryLevel; 12003 mDischargeScreenDozeUnplugLevel = 0; 12004 mDischargeScreenOffUnplugLevel = 0; 12005 } else if (Display.isDozeState(mScreenState)) { 12006 mDischargeScreenOnUnplugLevel = 0; 12007 mDischargeScreenDozeUnplugLevel = mBatteryLevel; 12008 mDischargeScreenOffUnplugLevel = 0; 12009 } else { 12010 mDischargeScreenOnUnplugLevel = 0; 12011 mDischargeScreenDozeUnplugLevel = 0; 12012 mDischargeScreenOffUnplugLevel = mBatteryLevel; 12013 } 12014 mDischargeAmountScreenOn = 0; 12015 mDischargeAmountScreenOff = 0; 12016 mDischargeAmountScreenDoze = 0; 12017 } 12018 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 12019 } 12020 12021 /** 12022 * Starts a new battery stats session, resetting counters and timers. If this method is called 12023 * before MIN_BATTERY_SESSION_DURATION_MILLIS from the beginning of the current session, the 12024 * call is ignored. 12025 */ startNewSession(int reason)12026 public void startNewSession(int reason) { 12027 if (mMonotonicClock.monotonicTime() 12028 < mMonotonicStartTime + MIN_BATTERY_SESSION_DURATION_MILLIS) { 12029 Slog.i(TAG, "Battery session session duration is too short, ignoring reset request"); 12030 return; 12031 } 12032 12033 mHandler.post(()-> { 12034 saveBatteryUsageStatsOnReset(); 12035 synchronized (BatteryStatsImpl.this) { 12036 resetAllStatsLocked(mClock.uptimeMillis(), mClock.elapsedRealtime(), reason); 12037 } 12038 }); 12039 } 12040 12041 @GuardedBy("this") resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, int resetReason)12042 private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, 12043 int resetReason) { 12044 final long uptimeUs = uptimeMillis * 1000; 12045 final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000; 12046 mStartCount = 0; 12047 initTimes(uptimeUs, elapsedRealtimeUs); 12048 mScreenOnTimer.reset(false, elapsedRealtimeUs); 12049 mScreenDozeTimer.reset(false, elapsedRealtimeUs); 12050 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 12051 mScreenBrightnessTimer[i].reset(false, elapsedRealtimeUs); 12052 } 12053 12054 final int numDisplays = mPerDisplayBatteryStats.length; 12055 for (int i = 0; i < numDisplays; i++) { 12056 mPerDisplayBatteryStats[i].reset(elapsedRealtimeUs); 12057 } 12058 12059 if (mPowerProfile != null) { 12060 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 12061 } else { 12062 mEstimatedBatteryCapacityMah = -1; 12063 } 12064 mLastLearnedBatteryCapacityUah = -1; 12065 mMinLearnedBatteryCapacityUah = -1; 12066 mMaxLearnedBatteryCapacityUah = -1; 12067 mInteractiveTimer.reset(false, elapsedRealtimeUs); 12068 mPowerSaveModeEnabledTimer.reset(false, elapsedRealtimeUs); 12069 mLastIdleTimeStartMs = elapsedRealtimeMillis; 12070 mLongestLightIdleTimeMs = 0; 12071 mLongestFullIdleTimeMs = 0; 12072 mDeviceIdleModeLightTimer.reset(false, elapsedRealtimeUs); 12073 mDeviceIdleModeFullTimer.reset(false, elapsedRealtimeUs); 12074 mDeviceLightIdlingTimer.reset(false, elapsedRealtimeUs); 12075 mDeviceIdlingTimer.reset(false, elapsedRealtimeUs); 12076 mPhoneOnTimer.reset(false, elapsedRealtimeUs); 12077 mAudioOnTimer.reset(false, elapsedRealtimeUs); 12078 mVideoOnTimer.reset(false, elapsedRealtimeUs); 12079 mFlashlightOnTimer.reset(false, elapsedRealtimeUs); 12080 mCameraOnTimer.reset(false, elapsedRealtimeUs); 12081 mBluetoothScanTimer.reset(false, elapsedRealtimeUs); 12082 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 12083 mPhoneSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 12084 } 12085 mPhoneSignalScanningTimer.reset(false, elapsedRealtimeUs); 12086 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 12087 mPhoneDataConnectionsTimer[i].reset(false, elapsedRealtimeUs); 12088 } 12089 mNrNsaTimer.reset(false, elapsedRealtimeUs); 12090 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 12091 mNetworkByteActivityCounters[i].reset(false, elapsedRealtimeUs); 12092 mNetworkPacketActivityCounters[i].reset(false, elapsedRealtimeUs); 12093 } 12094 for (int i = 0; i < RADIO_ACCESS_TECHNOLOGY_COUNT; i++) { 12095 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[i]; 12096 if (stats == null) continue; 12097 stats.reset(elapsedRealtimeUs); 12098 } 12099 mMobileRadioActiveTimer.reset(false, elapsedRealtimeUs); 12100 mMobileRadioActivePerAppTimer.reset(false, elapsedRealtimeUs); 12101 mMobileRadioActiveAdjustedTime.reset(false, elapsedRealtimeUs); 12102 mMobileRadioActiveUnknownTime.reset(false, elapsedRealtimeUs); 12103 mMobileRadioActiveUnknownCount.reset(false, elapsedRealtimeUs); 12104 mWifiOnTimer.reset(false, elapsedRealtimeUs); 12105 mGlobalWifiRunningTimer.reset(false, elapsedRealtimeUs); 12106 for (int i=0; i<NUM_WIFI_STATES; i++) { 12107 mWifiStateTimer[i].reset(false, elapsedRealtimeUs); 12108 } 12109 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 12110 mWifiSupplStateTimer[i].reset(false, elapsedRealtimeUs); 12111 } 12112 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 12113 mWifiSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 12114 } 12115 mWifiMulticastWakelockTimer.reset(false, elapsedRealtimeUs); 12116 mWifiActiveTimer.reset(false, elapsedRealtimeUs); 12117 mWifiActivity.reset(false, elapsedRealtimeUs); 12118 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 12119 mGpsSignalQualityTimer[i].reset(false, elapsedRealtimeUs); 12120 } 12121 mBluetoothActivity.reset(false, elapsedRealtimeUs); 12122 mModemActivity.reset(false, elapsedRealtimeUs); 12123 mNumConnectivityChange = 0; 12124 12125 for (int i=0; i<mUidStats.size(); i++) { 12126 if (mUidStats.valueAt(i).reset(uptimeUs, elapsedRealtimeUs, resetReason)) { 12127 mUidStats.valueAt(i).detachFromTimeBase(); 12128 mUidStats.remove(mUidStats.keyAt(i)); 12129 i--; 12130 } 12131 } 12132 12133 if (mRpmStats.size() > 0) { 12134 for (SamplingTimer timer : mRpmStats.values()) { 12135 mOnBatteryTimeBase.remove(timer); 12136 } 12137 mRpmStats.clear(); 12138 } 12139 if (mScreenOffRpmStats.size() > 0) { 12140 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 12141 mOnBatteryScreenOffTimeBase.remove(timer); 12142 } 12143 mScreenOffRpmStats.clear(); 12144 } 12145 12146 if (mKernelWakelockStats.size() > 0) { 12147 for (SamplingTimer timer : mKernelWakelockStats.values()) { 12148 mOnBatteryScreenOffTimeBase.remove(timer); 12149 } 12150 mKernelWakelockStats.clear(); 12151 } 12152 12153 if (mKernelMemoryStats.size() > 0) { 12154 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 12155 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 12156 } 12157 mKernelMemoryStats.clear(); 12158 } 12159 12160 if (mWakeupReasonStats.size() > 0) { 12161 for (SamplingTimer timer : mWakeupReasonStats.values()) { 12162 mOnBatteryTimeBase.remove(timer); 12163 } 12164 mWakeupReasonStats.clear(); 12165 } 12166 12167 mStepDetailsProvider.reset(); 12168 12169 if (mTmpRailStats != null) { 12170 mTmpRailStats.reset(); 12171 } 12172 12173 EnergyConsumerStats.resetIfNotNull(mGlobalEnergyConsumerStats); 12174 12175 if (!Flags.disableSystemServicePowerAttr()) { 12176 resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs); 12177 } 12178 12179 mNumAllUidCpuTimeReads = 0; 12180 mNumUidsRemoved = 0; 12181 12182 initDischarge(elapsedRealtimeUs); 12183 12184 if ((resetReason != RESET_REASON_FULL_CHARGE 12185 && resetReason != RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION) 12186 || mResetBatteryHistoryOnNewSession) { 12187 mHistory.reset(); 12188 } 12189 12190 // Store the empty state to disk to ensure consistency 12191 writeSyncLocked(); 12192 12193 if (mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)) { 12194 schedulePowerStatsSampleCollection(); 12195 } 12196 12197 // Flush external data, gathering snapshots, but don't process it since it is pre-reset data 12198 mIgnoreNextExternalStats = true; 12199 mExternalSync.scheduleSync("reset", ExternalStatsSync.UPDATE_ON_RESET); 12200 12201 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 12202 } 12203 saveBatteryUsageStatsOnReset()12204 private void saveBatteryUsageStatsOnReset() { 12205 if (!mSaveBatteryUsageStatsOnReset) { 12206 return; 12207 } 12208 12209 if (mAccumulateBatteryUsageStats) { 12210 mBatteryUsageStatsProvider.accumulateBatteryUsageStats(getBatteryStatsSession(), 12211 mHandler); 12212 } else { 12213 final BatteryUsageStats batteryUsageStats; 12214 synchronized (this) { 12215 batteryUsageStats = mBatteryUsageStatsProvider.getBatteryUsageStats(this, 12216 new BatteryUsageStatsQuery.Builder() 12217 .setMaxStatsAgeMs(0) 12218 .includePowerModels() 12219 .includeProcessStateData() 12220 .build()); 12221 } 12222 12223 // TODO(b/188068523): BatteryUsageStats should use monotonic time for start and end 12224 // Once that change is made, we will be able to use the BatteryUsageStats' monotonic 12225 // start time 12226 long monotonicStartTime = 12227 mMonotonicClock.monotonicTime() - batteryUsageStats.getStatsDuration(); 12228 commitMonotonicClock(); 12229 mPowerStatsStore.storeBatteryUsageStatsAsync(monotonicStartTime, batteryUsageStats); 12230 } 12231 } 12232 12233 @GuardedBy("this") initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)12234 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 12235 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 12236 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 12237 // Not recording process starts/stops. 12238 continue; 12239 } 12240 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 12241 if (active == null) { 12242 continue; 12243 } 12244 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 12245 SparseIntArray uids = ent.getValue(); 12246 for (int j=0; j<uids.size(); j++) { 12247 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 12248 uids.keyAt(j)); 12249 } 12250 } 12251 } 12252 } 12253 12254 @GuardedBy("this") updateDischargeScreenLevelsLocked(int oldState, int newState)12255 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 12256 updateOldDischargeScreenLevelLocked(oldState); 12257 updateNewDischargeScreenLevelLocked(newState); 12258 } 12259 12260 @GuardedBy("this") updateOldDischargeScreenLevelLocked(int state)12261 private void updateOldDischargeScreenLevelLocked(int state) { 12262 if (Display.isOnState(state)) { 12263 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 12264 if (diff > 0) { 12265 mDischargeAmountScreenOn += diff; 12266 mDischargeAmountScreenOnSinceCharge += diff; 12267 } 12268 } else if (Display.isDozeState(state)) { 12269 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 12270 if (diff > 0) { 12271 mDischargeAmountScreenDoze += diff; 12272 mDischargeAmountScreenDozeSinceCharge += diff; 12273 } 12274 } else if (Display.isOffState(state)) { 12275 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 12276 if (diff > 0) { 12277 mDischargeAmountScreenOff += diff; 12278 mDischargeAmountScreenOffSinceCharge += diff; 12279 } 12280 } 12281 } 12282 12283 @GuardedBy("this") updateNewDischargeScreenLevelLocked(int state)12284 private void updateNewDischargeScreenLevelLocked(int state) { 12285 if (Display.isOnState(state)) { 12286 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 12287 mDischargeScreenOffUnplugLevel = 0; 12288 mDischargeScreenDozeUnplugLevel = 0; 12289 } else if (Display.isDozeState(state)) { 12290 mDischargeScreenOnUnplugLevel = 0; 12291 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 12292 mDischargeScreenOffUnplugLevel = 0; 12293 } else if (Display.isOffState(state)) { 12294 mDischargeScreenOnUnplugLevel = 0; 12295 mDischargeScreenDozeUnplugLevel = 0; 12296 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 12297 } 12298 } 12299 12300 @GuardedBy("this") pullPendingStateUpdatesLocked()12301 public void pullPendingStateUpdatesLocked() { 12302 if (mOnBatteryInternal) { 12303 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 12304 } 12305 } 12306 12307 private final Object mWifiNetworkLock = new Object(); 12308 12309 @GuardedBy("mWifiNetworkLock") 12310 private String[] mWifiIfaces = EmptyArray.STRING; 12311 12312 @GuardedBy("mWifiNetworkLock") 12313 private NetworkStats mLastWifiNetworkStats; 12314 12315 private final Object mModemNetworkLock = new Object(); 12316 12317 @GuardedBy("mModemNetworkLock") 12318 private String[] mModemIfaces = EmptyArray.STRING; 12319 12320 @GuardedBy("mModemNetworkLock") 12321 private NetworkStats mLastModemNetworkStats; 12322 12323 @VisibleForTesting readMobileNetworkStatsLocked( @onNull NetworkStatsManager networkStatsManager)12324 protected NetworkStats readMobileNetworkStatsLocked( 12325 @NonNull NetworkStatsManager networkStatsManager) { 12326 return networkStatsManager.getMobileUidStats(); 12327 } 12328 12329 @VisibleForTesting readWifiNetworkStatsLocked( @onNull NetworkStatsManager networkStatsManager)12330 protected NetworkStats readWifiNetworkStatsLocked( 12331 @NonNull NetworkStatsManager networkStatsManager) { 12332 return networkStatsManager.getWifiUidStats(); 12333 } 12334 12335 @VisibleForTesting networkStatsDelta(@onNull NetworkStats stats, @Nullable NetworkStats oldStats)12336 protected NetworkStats networkStatsDelta(@NonNull NetworkStats stats, 12337 @Nullable NetworkStats oldStats) { 12338 if (oldStats == null) { 12339 return stats; 12340 } 12341 return stats.subtract(oldStats); 12342 } 12343 12344 /** 12345 * Distribute WiFi energy info and network traffic to apps. 12346 * 12347 * @param info The energy information from the WiFi controller. 12348 */ 12349 @GuardedBy("this") updateWifiState(@ullable final WifiActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, @NonNull NetworkStatsManager networkStatsManager)12350 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info, 12351 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, 12352 @NonNull NetworkStatsManager networkStatsManager) { 12353 if (DEBUG_ENERGY) { 12354 synchronized (mWifiNetworkLock) { 12355 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 12356 } 12357 } 12358 12359 NetworkStats delta; 12360 // Grab a separate lock to acquire the network stats, which may do I/O. 12361 synchronized (mWifiNetworkLock) { 12362 final NetworkStats latestStats = readWifiNetworkStatsLocked(networkStatsManager); 12363 if (latestStats != null) { 12364 delta = networkStatsDelta(latestStats, mLastWifiNetworkStats); 12365 mLastWifiNetworkStats = latestStats; 12366 } else { 12367 delta = null; 12368 } 12369 } 12370 updateWifiBatteryStats(info, delta, consumedChargeUC, elapsedRealtimeMs, uptimeMs); 12371 } 12372 onWifiPowerStatsRetrieved(WifiActivityEnergyInfo wifiActivityEnergyInfo, NetworkStats networkStatsDelta, long elapsedRealtimeMs, long uptimeMs)12373 private void onWifiPowerStatsRetrieved(WifiActivityEnergyInfo wifiActivityEnergyInfo, 12374 NetworkStats networkStatsDelta, long elapsedRealtimeMs, long uptimeMs) { 12375 // Do not populate consumed energy, because energy attribution is done by 12376 // WifiPowerStatsProcessor. 12377 updateWifiBatteryStats(wifiActivityEnergyInfo, networkStatsDelta, POWER_DATA_UNAVAILABLE, 12378 elapsedRealtimeMs, uptimeMs); 12379 } 12380 updateWifiBatteryStats(WifiActivityEnergyInfo info, NetworkStats delta, long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)12381 private void updateWifiBatteryStats(WifiActivityEnergyInfo info, 12382 NetworkStats delta, long consumedChargeUC, long elapsedRealtimeMs, 12383 long uptimeMs) { 12384 synchronized (this) { 12385 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12386 if (mIgnoreNextExternalStats) { 12387 // TODO: Strictly speaking, we should re-mark all 5 timers for each uid (and the 12388 // global one) here like we do for display. But I'm not sure it's worth the 12389 // complicated code for a codepath that shouldn't ever actually happen in real 12390 // life. 12391 } 12392 return; 12393 } 12394 12395 final SparseDoubleArray uidEstimatedConsumptionMah = 12396 (mGlobalEnergyConsumerStats != null 12397 && mWifiPowerCalculator != null && consumedChargeUC > 0) ? 12398 new SparseDoubleArray() : null; 12399 double totalEstimatedConsumptionMah = 0; 12400 12401 SparseLongArray rxPackets = new SparseLongArray(); 12402 SparseLongArray txPackets = new SparseLongArray(); 12403 SparseLongArray rxTimesMs = new SparseLongArray(); 12404 SparseLongArray txTimesMs = new SparseLongArray(); 12405 long totalTxPackets = 0; 12406 long totalRxPackets = 0; 12407 if (delta != null) { 12408 for (NetworkStats.Entry entry : delta) { 12409 if (DEBUG_ENERGY) { 12410 Slog.d(TAG, "Wifi uid " + entry.getUid() 12411 + ": delta rx=" + entry.getRxBytes() 12412 + " tx=" + entry.getTxBytes() 12413 + " rxPackets=" + entry.getRxPackets() 12414 + " txPackets=" + entry.getTxPackets()); 12415 } 12416 12417 if (entry.getRxBytes() == 0 && entry.getTxBytes() == 0) { 12418 // Skip the lookup below since there is no work to do. 12419 continue; 12420 } 12421 12422 final int uid = mapUid(entry.getUid()); 12423 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 12424 if (entry.getRxBytes() != 0) { 12425 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.getRxBytes(), 12426 entry.getRxPackets()); 12427 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 12428 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.getRxBytes(), 12429 entry.getRxPackets()); 12430 } 12431 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 12432 entry.getRxBytes()); 12433 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 12434 entry.getRxPackets()); 12435 12436 rxPackets.incrementValue(uid, entry.getRxPackets()); 12437 12438 // Sum the total number of packets so that the Rx Power can 12439 // be evenly distributed amongst the apps. 12440 totalRxPackets += entry.getRxPackets(); 12441 } 12442 12443 if (entry.getTxBytes() != 0) { 12444 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.getTxBytes(), 12445 entry.getTxPackets()); 12446 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 12447 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.getTxBytes(), 12448 entry.getTxPackets()); 12449 } 12450 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 12451 entry.getTxBytes()); 12452 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 12453 entry.getTxPackets()); 12454 12455 txPackets.incrementValue(uid, entry.getTxPackets()); 12456 12457 // Sum the total number of packets so that the Tx Power can 12458 // be evenly distributed amongst the apps. 12459 totalTxPackets += entry.getTxPackets(); 12460 } 12461 12462 // Calculate consumed energy for this uid. Only do so if WifiReporting isn't 12463 // enabled (if it is, we'll do it later instead using info). 12464 if (uidEstimatedConsumptionMah != null && info == null && !mHasWifiReporting) { 12465 final long uidRunningMs = u.mWifiRunningTimer 12466 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12467 if (uidRunningMs > 0) u.mWifiRunningTimer.setMark(elapsedRealtimeMs); 12468 12469 final long uidScanMs = u.mWifiScanTimer 12470 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12471 if (uidScanMs > 0) u.mWifiScanTimer.setMark(elapsedRealtimeMs); 12472 12473 long uidBatchScanMs = 0; 12474 for (int bn = 0; bn < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bn++) { 12475 if (u.mWifiBatchedScanTimer[bn] != null) { 12476 long bnMs = u.mWifiBatchedScanTimer[bn] 12477 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12478 if (bnMs > 0) { 12479 u.mWifiBatchedScanTimer[bn].setMark(elapsedRealtimeMs); 12480 } 12481 uidBatchScanMs += bnMs; 12482 } 12483 } 12484 12485 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 12486 mWifiPowerCalculator.calcPowerWithoutControllerDataMah( 12487 entry.getRxPackets(), entry.getTxPackets(), 12488 uidRunningMs, uidScanMs, uidBatchScanMs)); 12489 } 12490 } 12491 delta = null; 12492 } 12493 12494 if (info != null) { 12495 mHasWifiReporting = true; 12496 12497 // Measured in mAms 12498 final long txTimeMs = info.getControllerTxDurationMillis(); 12499 final long rxTimeMs = info.getControllerRxDurationMillis(); 12500 final long scanTimeMs = info.getControllerScanDurationMillis(); 12501 final long idleTimeMs = info.getControllerIdleDurationMillis(); 12502 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 12503 12504 long leftOverRxTimeMs = rxTimeMs; 12505 long leftOverTxTimeMs = txTimeMs; 12506 12507 if (DEBUG_ENERGY) { 12508 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 12509 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 12510 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 12511 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 12512 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 12513 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 12514 } 12515 12516 long totalWifiLockTimeMs = 0; 12517 long totalScanTimeMs = 0; 12518 12519 // On the first pass, collect some totals so that we can normalize power 12520 // calculations if we need to. 12521 final int uidStatsSize = mUidStats.size(); 12522 for (int i = 0; i < uidStatsSize; i++) { 12523 final Uid uid = mUidStats.valueAt(i); 12524 12525 // Sum the total scan power for all apps. 12526 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 12527 elapsedRealtimeMs * 1000) / 1000; 12528 12529 // Sum the total time holding wifi lock for all apps. 12530 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 12531 elapsedRealtimeMs * 1000) / 1000; 12532 } 12533 12534 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 12535 Slog.d(TAG, 12536 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 12537 + rxTimeMs + " ms). Normalizing scan time."); 12538 } 12539 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 12540 Slog.d(TAG, 12541 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 12542 + txTimeMs + " ms). Normalizing scan time."); 12543 } 12544 12545 // Actually assign and distribute power usage to apps. 12546 for (int i = 0; i < uidStatsSize; i++) { 12547 final Uid uid = mUidStats.valueAt(i); 12548 12549 final long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 12550 elapsedRealtimeMs * 1000) / 1000; 12551 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 12552 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 12553 if (scanTimeSinceMarkMs > 0) { 12554 // Set the new mark so that next time we get new data since this point. 12555 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 12556 12557 // Our total scan time is more than the reported Tx/Rx time. 12558 // This is possible because the cost of a scan is approximate. 12559 // Let's normalize the result so that we evenly blame each app 12560 // scanning. 12561 // 12562 // This means that we may have apps that transmitted/received packets not be 12563 // blamed for this, but this is fine as scans are relatively more expensive. 12564 if (totalScanTimeMs > rxTimeMs) { 12565 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 12566 totalScanTimeMs; 12567 } 12568 if (totalScanTimeMs > txTimeMs) { 12569 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 12570 totalScanTimeMs; 12571 } 12572 12573 if (DEBUG_ENERGY) { 12574 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 12575 + scanRxTimeSinceMarkMs + " ms Tx:" 12576 + scanTxTimeSinceMarkMs + " ms)"); 12577 } 12578 12579 rxTimesMs.incrementValue(uid.getUid(), scanRxTimeSinceMarkMs); 12580 txTimesMs.incrementValue(uid.getUid(), scanTxTimeSinceMarkMs); 12581 12582 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 12583 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 12584 } 12585 12586 // Distribute evenly the power consumed while Idle to each app holding a WiFi 12587 // lock. 12588 long myIdleTimeMs = 0; 12589 final long wifiLockTimeSinceMarkMs = 12590 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 12591 elapsedRealtimeMs * 1000) / 1000; 12592 if (wifiLockTimeSinceMarkMs > 0) { 12593 // Set the new mark so that next time we get new data since this point. 12594 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 12595 12596 myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) / totalWifiLockTimeMs; 12597 if (DEBUG_ENERGY) { 12598 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 12599 + myIdleTimeMs + " ms"); 12600 } 12601 uid.getOrCreateWifiControllerActivityLocked().getOrCreateIdleTimeCounter() 12602 .increment(myIdleTimeMs, elapsedRealtimeMs); 12603 } 12604 12605 if (uidEstimatedConsumptionMah != null) { 12606 double uidEstMah = mWifiPowerCalculator.calcPowerFromControllerDataMah( 12607 scanRxTimeSinceMarkMs, scanTxTimeSinceMarkMs, myIdleTimeMs); 12608 uidEstimatedConsumptionMah.incrementValue(uid.getUid(), uidEstMah); 12609 } 12610 } 12611 12612 if (DEBUG_ENERGY) { 12613 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 12614 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 12615 } 12616 12617 // Distribute the remaining Tx power appropriately between all apps that transmitted 12618 // packets. 12619 if (totalTxPackets != 0 && leftOverTxTimeMs != 0) { 12620 for (int i = 0; i < txPackets.size(); i++) { 12621 final int uid = txPackets.keyAt(i); 12622 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 12623 / totalTxPackets; 12624 txTimesMs.incrementValue(uid, myTxTimeMs); 12625 } 12626 } 12627 12628 // Distribute the remaining Rx power appropriately between all apps that received 12629 // packets. 12630 if (totalRxPackets != 0 && leftOverRxTimeMs != 0) { 12631 for (int i = 0; i < rxPackets.size(); i++) { 12632 final int uid = rxPackets.keyAt(i); 12633 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 12634 / totalRxPackets; 12635 rxTimesMs.incrementValue(uid, myRxTimeMs); 12636 } 12637 } 12638 12639 for (int i = 0; i < txTimesMs.size(); i++) { 12640 final int uid = txTimesMs.keyAt(i); 12641 final long myTxTimeMs = txTimesMs.valueAt(i); 12642 if (DEBUG_ENERGY) { 12643 Slog.d(TAG, " TxTime for UID " + uid + ": " + myTxTimeMs + " ms"); 12644 } 12645 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 12646 .getOrCreateWifiControllerActivityLocked() 12647 .getOrCreateTxTimeCounters()[0] 12648 .increment(myTxTimeMs, elapsedRealtimeMs); 12649 if (uidEstimatedConsumptionMah != null) { 12650 uidEstimatedConsumptionMah.incrementValue(uid, 12651 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12652 0, myTxTimeMs, 0)); 12653 } 12654 } 12655 12656 for (int i = 0; i < rxTimesMs.size(); i++) { 12657 final int uid = rxTimesMs.keyAt(i); 12658 final long myRxTimeMs = rxTimesMs.valueAt(i); 12659 if (DEBUG_ENERGY) { 12660 Slog.d(TAG, " RxTime for UID " + uid + ": " + myRxTimeMs + " ms"); 12661 } 12662 12663 getUidStatsLocked(rxTimesMs.keyAt(i), elapsedRealtimeMs, uptimeMs) 12664 .getOrCreateWifiControllerActivityLocked() 12665 .getOrCreateRxTimeCounter() 12666 .increment(myRxTimeMs, elapsedRealtimeMs); 12667 if (uidEstimatedConsumptionMah != null) { 12668 uidEstimatedConsumptionMah.incrementValue(uid, 12669 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12670 myRxTimeMs, 0, 0)); 12671 } 12672 } 12673 12674 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 12675 12676 // Update WiFi controller stats. 12677 mWifiActivity.getOrCreateRxTimeCounter().increment( 12678 info.getControllerRxDurationMillis(), elapsedRealtimeMs); 12679 mWifiActivity.getOrCreateTxTimeCounters()[0].increment( 12680 info.getControllerTxDurationMillis(), elapsedRealtimeMs); 12681 mWifiActivity.getScanTimeCounter().addCountLocked( 12682 info.getControllerScanDurationMillis()); 12683 mWifiActivity.getOrCreateIdleTimeCounter().increment( 12684 info.getControllerIdleDurationMillis(), elapsedRealtimeMs); 12685 12686 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12687 final double opVolt = mPowerProfile.getAveragePower( 12688 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12689 double controllerMaMs = 0; 12690 if (opVolt != 0) { 12691 // We store the power drain as mAms. 12692 controllerMaMs = info.getControllerEnergyUsedMicroJoules() / opVolt; 12693 mWifiActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 12694 } 12695 // Converting uWs to mAms. 12696 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 12697 long monitoredRailChargeConsumedMaMs = mTmpRailStats != null 12698 ? (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt) 12699 : 0L; 12700 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 12701 monitoredRailChargeConsumedMaMs); 12702 mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs, 12703 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR)); 12704 if (mTmpRailStats != null) { 12705 mTmpRailStats.resetWifiTotalEnergyUsed(); 12706 } 12707 12708 if (uidEstimatedConsumptionMah != null) { 12709 totalEstimatedConsumptionMah = Math.max(controllerMaMs / MILLISECONDS_IN_HOUR, 12710 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12711 rxTimeMs, txTimeMs, idleTimeMs)); 12712 } 12713 } 12714 12715 // Update the EnergyConsumerStats information. 12716 if (uidEstimatedConsumptionMah != null) { 12717 mGlobalEnergyConsumerStats.updateStandardBucket( 12718 EnergyConsumerStats.POWER_BUCKET_WIFI, consumedChargeUC); 12719 12720 // Now calculate the consumption for each uid, according to its proportional usage. 12721 if (!mHasWifiReporting) { 12722 final long globalTimeMs = mGlobalWifiRunningTimer 12723 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12724 mGlobalWifiRunningTimer.setMark(elapsedRealtimeMs); 12725 totalEstimatedConsumptionMah = mWifiPowerCalculator 12726 .calcGlobalPowerWithoutControllerDataMah(globalTimeMs); 12727 } 12728 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_WIFI, 12729 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedConsumptionMah, 12730 elapsedRealtimeMs); 12731 } 12732 } 12733 } 12734 12735 private ModemActivityInfo mLastModemActivityInfo = null; 12736 12737 /** 12738 * Distribute Cell radio energy info and network traffic to apps. 12739 */ noteModemControllerActivity(@ullable final ModemActivityInfo activityInfo, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, @NonNull NetworkStatsManager networkStatsManager)12740 public void noteModemControllerActivity(@Nullable final ModemActivityInfo activityInfo, 12741 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, 12742 @NonNull NetworkStatsManager networkStatsManager) { 12743 if (DEBUG_ENERGY) { 12744 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 12745 } 12746 ModemActivityInfo deltaInfo = mLastModemActivityInfo == null 12747 ? (activityInfo == null ? null : activityInfo.getDelta(activityInfo)) 12748 : mLastModemActivityInfo.getDelta(activityInfo); 12749 mLastModemActivityInfo = activityInfo; 12750 12751 // Grab a separate lock to acquire the network stats, which may do I/O. 12752 NetworkStats delta = null; 12753 synchronized (mModemNetworkLock) { 12754 final NetworkStats latestStats = readMobileNetworkStatsLocked(networkStatsManager); 12755 if (latestStats != null) { 12756 delta = networkStatsDelta(latestStats, mLastModemNetworkStats); 12757 mLastModemNetworkStats = latestStats; 12758 } 12759 } 12760 12761 updateCellularBatteryStats(deltaInfo, delta, consumedChargeUC, elapsedRealtimeMs, uptimeMs); 12762 } 12763 onMobileRadioPowerStatsRetrieved(ModemActivityInfo modemActivityInfo, NetworkStats networkStatsDelta, long elapsedRealtimeMs, long uptimeMs)12764 private void onMobileRadioPowerStatsRetrieved(ModemActivityInfo modemActivityInfo, 12765 NetworkStats networkStatsDelta, long elapsedRealtimeMs, long uptimeMs) { 12766 // Do not populate consumed energy, because energy attribution is done by 12767 // MobileRadioPowerStatsProcessor. 12768 updateCellularBatteryStats(modemActivityInfo, networkStatsDelta, POWER_DATA_UNAVAILABLE, 12769 elapsedRealtimeMs, uptimeMs); 12770 } 12771 updateCellularBatteryStats(@ullable ModemActivityInfo deltaInfo, @Nullable NetworkStats delta, long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)12772 private void updateCellularBatteryStats(@Nullable ModemActivityInfo deltaInfo, 12773 @Nullable NetworkStats delta, long consumedChargeUC, long elapsedRealtimeMs, 12774 long uptimeMs) { 12775 // Add modem tx power to history. 12776 addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs); 12777 12778 synchronized (this) { 12779 final long totalRadioDurationMs = 12780 mMobileRadioActiveTimer.getTimeSinceMarkLocked( 12781 elapsedRealtimeMs * 1000) / 1000; 12782 mMobileRadioActiveTimer.setMark(elapsedRealtimeMs); 12783 final long phoneOnDurationMs = Math.min(totalRadioDurationMs, 12784 mPhoneOnTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000); 12785 mPhoneOnTimer.setMark(elapsedRealtimeMs); 12786 12787 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12788 return; 12789 } 12790 12791 final SparseDoubleArray uidEstimatedConsumptionMah; 12792 final long dataConsumedChargeUC; 12793 if (consumedChargeUC > 0 && isMobileRadioEnergyConsumerSupportedLocked()) { 12794 final long phoneConsumedChargeUC; 12795 if (totalRadioDurationMs == 0) { 12796 phoneConsumedChargeUC = 0; 12797 } else { 12798 // Crudely attribute power consumption. Added (totalRadioDurationMs / 2) to the 12799 // numerator for long rounding. 12800 phoneConsumedChargeUC = 12801 (consumedChargeUC * phoneOnDurationMs + totalRadioDurationMs / 2) 12802 / totalRadioDurationMs; 12803 } 12804 dataConsumedChargeUC = consumedChargeUC - phoneConsumedChargeUC; 12805 12806 mGlobalEnergyConsumerStats.updateStandardBucket( 12807 EnergyConsumerStats.POWER_BUCKET_PHONE, phoneConsumedChargeUC); 12808 mGlobalEnergyConsumerStats.updateStandardBucket( 12809 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, dataConsumedChargeUC); 12810 uidEstimatedConsumptionMah = new SparseDoubleArray(); 12811 } else { 12812 uidEstimatedConsumptionMah = null; 12813 dataConsumedChargeUC = POWER_DATA_UNAVAILABLE; 12814 } 12815 12816 RxTxConsumption rxTxConsumption = null; 12817 boolean attributeWithModemActivityInfo = false; 12818 if (deltaInfo != null) { 12819 mHasModemReporting = true; 12820 mModemActivity.getOrCreateIdleTimeCounter() 12821 .increment(deltaInfo.getIdleTimeMillis(), elapsedRealtimeMs); 12822 mModemActivity.getSleepTimeCounter().addCountLocked( 12823 deltaInfo.getSleepTimeMillis()); 12824 mModemActivity.getOrCreateRxTimeCounter() 12825 .increment(deltaInfo.getReceiveTimeMillis(), elapsedRealtimeMs); 12826 for (int lvl = 0; lvl < MODEM_TX_POWER_LEVEL_COUNT; lvl++) { 12827 mModemActivity.getOrCreateTxTimeCounters()[lvl] 12828 .increment(deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl), 12829 elapsedRealtimeMs); 12830 } 12831 12832 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12833 final double opVolt = mPowerProfile.getAveragePower( 12834 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12835 if (opVolt != 0) { 12836 double energyUsed = 12837 deltaInfo.getSleepTimeMillis() * 12838 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 12839 + deltaInfo.getIdleTimeMillis() * 12840 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 12841 + deltaInfo.getReceiveTimeMillis() * 12842 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 12843 for (int i = 0; i < Math.min(MODEM_TX_POWER_LEVEL_COUNT, 12844 CELL_SIGNAL_STRENGTH_LEVEL_COUNT); i++) { 12845 energyUsed += deltaInfo.getTransmitDurationMillisAtPowerLevel(i) 12846 * mPowerProfile.getAveragePower( 12847 PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 12848 } 12849 12850 // We store the power drain as mAms. 12851 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 12852 // Converting uWs to mAms. 12853 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 12854 long monitoredRailChargeConsumedMaMs = 12855 (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt); 12856 mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 12857 monitoredRailChargeConsumedMaMs); 12858 mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs, 12859 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR)); 12860 mTmpRailStats.resetCellularTotalEnergyUsed(); 12861 } 12862 12863 rxTxConsumption = incrementPerRatDataLocked(deltaInfo, elapsedRealtimeMs); 12864 12865 attributeWithModemActivityInfo = mConstants.PER_UID_MODEM_MODEL 12866 == PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX 12867 && rxTxConsumption != null; 12868 } 12869 long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 12870 elapsedRealtimeMs * 1000); 12871 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 12872 12873 long totalRxPackets = 0; 12874 long totalTxPackets = 0; 12875 if (delta != null) { 12876 for (NetworkStats.Entry entry : delta) { 12877 if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { 12878 continue; 12879 } 12880 12881 if (DEBUG_ENERGY) { 12882 Slog.d(TAG, "Mobile uid " + entry.getUid() + ": delta rx=" 12883 + entry.getRxBytes() + " tx=" + entry.getTxBytes() 12884 + " rxPackets=" + entry.getRxPackets() 12885 + " txPackets=" + entry.getTxPackets()); 12886 } 12887 12888 totalRxPackets += entry.getRxPackets(); 12889 totalTxPackets += entry.getTxPackets(); 12890 12891 final Uid u = getUidStatsLocked( 12892 mapUid(entry.getUid()), elapsedRealtimeMs, uptimeMs); 12893 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.getRxBytes(), 12894 entry.getRxPackets()); 12895 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.getTxBytes(), 12896 entry.getTxPackets()); 12897 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 12898 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 12899 entry.getRxBytes(), entry.getRxPackets()); 12900 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 12901 entry.getTxBytes(), entry.getTxPackets()); 12902 } 12903 12904 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 12905 entry.getRxBytes()); 12906 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12907 entry.getTxBytes()); 12908 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 12909 entry.getRxPackets()); 12910 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12911 entry.getTxPackets()); 12912 } 12913 12914 // Now distribute proportional blame to the apps that did networking. 12915 long totalPackets = totalRxPackets + totalTxPackets; 12916 if (totalPackets > 0) { 12917 for (NetworkStats.Entry entry : delta) { 12918 if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { 12919 continue; 12920 } 12921 12922 final Uid u = getUidStatsLocked(mapUid(entry.getUid()), 12923 elapsedRealtimeMs, uptimeMs); 12924 12925 // Distribute total radio active time in to this app. 12926 final long appPackets = entry.getRxPackets() + entry.getTxPackets(); 12927 final long appRadioTimeUs = 12928 (totalAppRadioTimeUs * appPackets) / totalPackets; 12929 u.noteMobileRadioActiveTimeLocked(appRadioTimeUs, elapsedRealtimeMs); 12930 12931 if (uidEstimatedConsumptionMah != null) { 12932 final double uidConsumptionMah; 12933 if (attributeWithModemActivityInfo) { 12934 // Distribute measured mobile radio charge consumption based on 12935 // rx/tx packets and estimated rx/tx charge consumption. 12936 uidConsumptionMah = smearModemActivityInfoRxTxConsumptionMah( 12937 rxTxConsumption, entry.getRxPackets(), entry.getTxPackets(), 12938 totalRxPackets, totalTxPackets); 12939 } else { 12940 // Distribute mobile radio charge consumption based on app radio 12941 // active time 12942 uidConsumptionMah = 12943 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12944 appRadioTimeUs / 1000); 12945 } 12946 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 12947 uidConsumptionMah); 12948 } 12949 12950 // Remove this app from the totals, so that we don't lose any time 12951 // due to rounding. 12952 totalAppRadioTimeUs -= appRadioTimeUs; 12953 totalPackets -= appPackets; 12954 12955 if (deltaInfo != null) { 12956 ControllerActivityCounterImpl activityCounter = 12957 u.getOrCreateModemControllerActivityLocked(); 12958 if (totalRxPackets > 0 && entry.getRxPackets() > 0) { 12959 final long rxMs = (entry.getRxPackets() 12960 * deltaInfo.getReceiveTimeMillis()) / totalRxPackets; 12961 activityCounter.getOrCreateRxTimeCounter() 12962 .increment(rxMs, elapsedRealtimeMs); 12963 } 12964 12965 if (totalTxPackets > 0 && entry.getTxPackets() > 0) { 12966 for (int lvl = 0; lvl < MODEM_TX_POWER_LEVEL_COUNT; 12967 lvl++) { 12968 long txMs = entry.getTxPackets() 12969 * deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl); 12970 txMs /= totalTxPackets; 12971 activityCounter.getOrCreateTxTimeCounters()[lvl] 12972 .increment(txMs, elapsedRealtimeMs); 12973 } 12974 } 12975 } 12976 } 12977 } 12978 12979 if (totalAppRadioTimeUs > 0) { 12980 // Whoops, there is some radio time we can't blame on an app! 12981 mMobileRadioActiveUnknownTime.addCountLocked(totalAppRadioTimeUs); 12982 mMobileRadioActiveUnknownCount.addCountLocked(1); 12983 } 12984 12985 // Update the EnergyConsumerStats information. 12986 if (uidEstimatedConsumptionMah != null) { 12987 double totalEstimatedConsumptionMah = 0.0; 12988 if (attributeWithModemActivityInfo) { 12989 // Estimate inactive modem power consumption and combine with previously 12990 // estimated active power consumption for an estimate of total modem 12991 // power consumption. 12992 final long sleepTimeMs = deltaInfo.getSleepTimeMillis(); 12993 final long idleTimeMs = deltaInfo.getIdleTimeMillis(); 12994 final double inactiveConsumptionMah = 12995 mMobileRadioPowerCalculator.calcInactiveStatePowerMah(sleepTimeMs, 12996 idleTimeMs); 12997 totalEstimatedConsumptionMah += inactiveConsumptionMah; 12998 totalEstimatedConsumptionMah += rxTxConsumption.rxConsumptionMah; 12999 totalEstimatedConsumptionMah += rxTxConsumption.txConsumptionMah; 13000 } else { 13001 // Estimate total active radio power consumption since last mark. 13002 totalEstimatedConsumptionMah += 13003 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 13004 totalRadioDurationMs); 13005 13006 // Estimate idle power consumption at each signal strength level 13007 final int numSignalStrengthLevels = mPhoneSignalStrengthsTimer.length; 13008 for (int lvl = 0; lvl < numSignalStrengthLevels; lvl++) { 13009 final long strengthLevelDurationMs = 13010 mPhoneSignalStrengthsTimer[lvl].getTimeSinceMarkLocked( 13011 elapsedRealtimeMs * 1000) / 1000; 13012 mPhoneSignalStrengthsTimer[lvl].setMark(elapsedRealtimeMs); 13013 13014 totalEstimatedConsumptionMah += 13015 mMobileRadioPowerCalculator.calcIdlePowerAtSignalStrengthMah( 13016 strengthLevelDurationMs, lvl); 13017 } 13018 13019 // Estimate total active radio power consumption since last mark. 13020 final long scanTimeMs = mPhoneSignalScanningTimer.getTimeSinceMarkLocked( 13021 elapsedRealtimeMs * 1000) / 1000; 13022 mPhoneSignalScanningTimer.setMark(elapsedRealtimeMs); 13023 totalEstimatedConsumptionMah += 13024 mMobileRadioPowerCalculator.calcScanTimePowerMah(scanTimeMs); 13025 } 13026 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 13027 dataConsumedChargeUC, uidEstimatedConsumptionMah, 13028 totalEstimatedConsumptionMah, elapsedRealtimeMs); 13029 } 13030 } 13031 } 13032 } 13033 13034 private static class RxTxConsumption { 13035 public final double rxConsumptionMah; 13036 public final long rxDurationMs; 13037 public final double txConsumptionMah; 13038 public final long txDurationMs; 13039 13040 /** 13041 * Represents the ratio between time spent transmitting and the total active time. 13042 */ 13043 public final double txToTotalRatio; 13044 RxTxConsumption(double rxMah, long rxMs, double txMah, long txMs)13045 RxTxConsumption(double rxMah, long rxMs, double txMah, long txMs) { 13046 rxConsumptionMah = rxMah; 13047 rxDurationMs = rxMs; 13048 txConsumptionMah = txMah; 13049 txDurationMs = txMs; 13050 13051 final long activeDurationMs = txDurationMs + rxDurationMs; 13052 if (activeDurationMs == 0) { 13053 txToTotalRatio = 0.0; 13054 } else { 13055 txToTotalRatio = ((double) txDurationMs) / activeDurationMs; 13056 } 13057 } 13058 } 13059 13060 @GuardedBy("this") 13061 @Nullable incrementPerRatDataLocked(ModemActivityInfo deltaInfo, long elapsedRealtimeMs)13062 private RxTxConsumption incrementPerRatDataLocked(ModemActivityInfo deltaInfo, 13063 long elapsedRealtimeMs) { 13064 double rxConsumptionMah = 0.0; 13065 long rxDurationMs = 0; 13066 double txConsumptionMah = 0.0; 13067 long txDurationMs = 0; 13068 13069 final int infoSize = deltaInfo.getSpecificInfoLength(); 13070 if (infoSize == 1 && deltaInfo.getSpecificInfoRat(0) 13071 == AccessNetworkConstants.AccessNetworkType.UNKNOWN 13072 && deltaInfo.getSpecificInfoFrequencyRange(0) 13073 == ServiceState.FREQUENCY_RANGE_UNKNOWN) { 13074 // Specific info data unavailable. Proportionally smear Rx and Tx times across each RAT. 13075 final int levelCount = CELL_SIGNAL_STRENGTH_LEVEL_COUNT; 13076 long[] perSignalStrengthActiveTimeMs = new long[levelCount]; 13077 long totalActiveTimeMs = 0; 13078 13079 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13080 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13081 if (ratStats == null) continue; 13082 13083 final int freqCount = ratStats.getFrequencyRangeCount(); 13084 for (int freq = 0; freq < freqCount; freq++) { 13085 for (int level = 0; level < levelCount; level++) { 13086 final long durationMs = ratStats.getTimeSinceMark(freq, level, 13087 elapsedRealtimeMs); 13088 perSignalStrengthActiveTimeMs[level] += durationMs; 13089 totalActiveTimeMs += durationMs; 13090 } 13091 } 13092 } 13093 if (totalActiveTimeMs != 0) { 13094 // Smear the provided Tx/Rx durations across each RAT, frequency, and signal 13095 // strength. 13096 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13097 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13098 if (ratStats == null) continue; 13099 13100 final int freqCount = ratStats.getFrequencyRangeCount(); 13101 for (int freq = 0; freq < freqCount; freq++) { 13102 long frequencyDurationMs = 0; 13103 for (int level = 0; level < levelCount; level++) { 13104 final long durationMs = ratStats.getTimeSinceMark(freq, level, 13105 elapsedRealtimeMs); 13106 final long totalLvlDurationMs = 13107 perSignalStrengthActiveTimeMs[level]; 13108 if (totalLvlDurationMs == 0) continue; 13109 final long totalTxLvlDurations = 13110 deltaInfo.getTransmitDurationMillisAtPowerLevel(level); 13111 // Smear HAL provided Tx power level duration based on active modem 13112 // duration in a given state. (Add totalLvlDurationMs / 2 before 13113 // the integer division with totalLvlDurationMs for rounding.) 13114 final long proportionalTxDurationMs = 13115 (durationMs * totalTxLvlDurations 13116 + (totalLvlDurationMs / 2)) / totalLvlDurationMs; 13117 ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs); 13118 frequencyDurationMs += durationMs; 13119 13120 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13121 // Accumulate the power cost of time spent transmitting in a 13122 // particular state. 13123 final double txStatePowerConsumptionMah = 13124 mMobileRadioPowerCalculator.calcTxStatePowerMah(rat, freq, 13125 level, proportionalTxDurationMs); 13126 txConsumptionMah += txStatePowerConsumptionMah; 13127 txDurationMs += proportionalTxDurationMs; 13128 } 13129 } 13130 final long totalRxDuration = deltaInfo.getReceiveTimeMillis(); 13131 // Smear HAL provided Rx power duration based on active modem 13132 // duration in a given state. (Add totalActiveTimeMs / 2 before the 13133 // integer division with totalActiveTimeMs for rounding.) 13134 final long proportionalRxDurationMs = 13135 (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs 13136 / 2)) / totalActiveTimeMs; 13137 ratStats.incrementRxDuration(freq, proportionalRxDurationMs); 13138 13139 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13140 // Accumulate the power cost of time spent receiving in a particular 13141 // state. 13142 final double rxStatePowerConsumptionMah = 13143 mMobileRadioPowerCalculator.calcRxStatePowerMah(rat, freq, 13144 proportionalRxDurationMs); 13145 rxConsumptionMah += rxStatePowerConsumptionMah; 13146 rxDurationMs += proportionalRxDurationMs; 13147 } 13148 } 13149 13150 } 13151 } 13152 } else { 13153 // Specific data available. 13154 for (int index = 0; index < infoSize; index++) { 13155 final int rat = deltaInfo.getSpecificInfoRat(index); 13156 final int freq = deltaInfo.getSpecificInfoFrequencyRange(index); 13157 13158 // Map RadioAccessNetworkType to course grain RadioAccessTechnology. 13159 final int ratBucket = MobileRadioPowerStatsLayout 13160 .mapRadioAccessNetworkTypeToRadioAccessTechnology(rat); 13161 final RadioAccessTechnologyBatteryStats ratStats = getRatBatteryStatsLocked( 13162 ratBucket); 13163 13164 final long rxTimeMs = deltaInfo.getReceiveTimeMillis(rat, freq); 13165 final int[] txTimesMs = deltaInfo.getTransmitTimeMillis(rat, freq); 13166 ratStats.incrementRxDuration(freq, rxTimeMs); 13167 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13168 // Accumulate the power cost of time spent receiving in a particular state. 13169 final double rxStatePowerConsumptionMah = 13170 mMobileRadioPowerCalculator.calcRxStatePowerMah(ratBucket, freq, 13171 rxTimeMs); 13172 rxConsumptionMah += rxStatePowerConsumptionMah; 13173 rxDurationMs += rxTimeMs; 13174 } 13175 13176 final int numTxLvl = txTimesMs.length; 13177 for (int lvl = 0; lvl < numTxLvl; lvl++) { 13178 final long txTimeMs = txTimesMs[lvl]; 13179 ratStats.incrementTxDuration(freq, lvl, txTimeMs); 13180 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13181 // Accumulate the power cost of time spent transmitting in a particular 13182 // state. 13183 final double txStatePowerConsumptionMah = 13184 mMobileRadioPowerCalculator.calcTxStatePowerMah(ratBucket, freq, 13185 lvl, txTimeMs); 13186 txConsumptionMah += txStatePowerConsumptionMah; 13187 txDurationMs += txTimeMs; 13188 } 13189 } 13190 } 13191 } 13192 13193 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13194 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13195 if (ratStats == null) continue; 13196 ratStats.setMark(elapsedRealtimeMs); 13197 } 13198 13199 if (isMobileRadioEnergyConsumerSupportedLocked()) { 13200 return new RxTxConsumption(rxConsumptionMah, rxDurationMs, txConsumptionMah, 13201 txDurationMs); 13202 } else { 13203 return null; 13204 } 13205 } 13206 13207 /** 13208 * Smear modem Rx/Tx power consumption calculated from {@link ModemActivityInfo} using Rx/Tx 13209 * packets. 13210 * 13211 * @return the combine Rx/Tx smeared power consumption in milliamp-hours. 13212 */ smearModemActivityInfoRxTxConsumptionMah(RxTxConsumption rxTxConsumption, long rxPackets, long txPackets, long totalRxPackets, long totalTxPackets)13213 private double smearModemActivityInfoRxTxConsumptionMah(RxTxConsumption rxTxConsumption, 13214 long rxPackets, long txPackets, long totalRxPackets, long totalTxPackets) { 13215 // Distribute measured mobile radio charge consumption based on 13216 // rx/tx packets and estimated rx/tx charge consumption. 13217 double consumptionMah = 0.0; 13218 if (totalRxPackets != 0) { 13219 // Proportionally distribute receive battery consumption. 13220 consumptionMah += rxTxConsumption.rxConsumptionMah * rxPackets 13221 / totalRxPackets; 13222 } 13223 if (totalTxPackets != 0 || (totalRxPackets != 0 && rxTxConsumption.txToTotalRatio != 0.0)) { 13224 // ModemActivityInfo Tx time represents time spent both transmitting and receiving. 13225 // There is currently no way to distinguish how many Rx packets were received during 13226 // Rx time vs Tx time. 13227 // Assumption: The number of packets received while transmitting is proportional 13228 // to the time spent transmitting over total active time. 13229 final double totalPacketsDuringTxTime = 13230 totalTxPackets + rxTxConsumption.txToTotalRatio * totalRxPackets; 13231 final double packetsDuringTxTime = 13232 txPackets + rxTxConsumption.txToTotalRatio * rxPackets; 13233 consumptionMah += rxTxConsumption.txConsumptionMah * packetsDuringTxTime 13234 / totalPacketsDuringTxTime; 13235 } 13236 return consumptionMah; 13237 } 13238 13239 /** 13240 * Add modem tx power to history 13241 * Device is said to be in high cellular transmit power when it has spent most of the transmit 13242 * time at the highest power level. 13243 * @param activityInfo 13244 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo, long elapsedRealtimeMs, long uptimeMs)13245 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo, 13246 long elapsedRealtimeMs, long uptimeMs) { 13247 if (activityInfo == null) { 13248 return; 13249 } 13250 int levelMaxTimeSpent = 0; 13251 for (int i = 1; i < MODEM_TX_POWER_LEVEL_COUNT; i++) { 13252 if (activityInfo.getTransmitDurationMillisAtPowerLevel(i) 13253 > activityInfo.getTransmitDurationMillisAtPowerLevel(levelMaxTimeSpent)) { 13254 levelMaxTimeSpent = i; 13255 } 13256 } 13257 if (levelMaxTimeSpent == MODEM_TX_POWER_LEVEL_COUNT - 1) { 13258 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 13259 HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG); 13260 } 13261 } 13262 13263 private final class BluetoothActivityInfoCache { 13264 long idleTimeMs; 13265 long rxTimeMs; 13266 long txTimeMs; 13267 long energy; 13268 13269 SparseLongArray uidRxBytes = new SparseLongArray(); 13270 SparseLongArray uidTxBytes = new SparseLongArray(); 13271 set(BluetoothActivityEnergyInfo info)13272 void set(BluetoothActivityEnergyInfo info) { 13273 idleTimeMs = info.getControllerIdleTimeMillis(); 13274 rxTimeMs = info.getControllerRxTimeMillis(); 13275 txTimeMs = info.getControllerTxTimeMillis(); 13276 energy = info.getControllerEnergyUsed(); 13277 if (!info.getUidTraffic().isEmpty()) { 13278 for (UidTraffic traffic : info.getUidTraffic()) { 13279 uidRxBytes.put(traffic.getUid(), traffic.getRxBytes()); 13280 uidTxBytes.put(traffic.getUid(), traffic.getTxBytes()); 13281 } 13282 } 13283 } 13284 reset()13285 void reset() { 13286 idleTimeMs = 0; 13287 rxTimeMs = 0; 13288 txTimeMs = 0; 13289 energy = 0; 13290 uidRxBytes.clear(); 13291 uidTxBytes.clear(); 13292 } 13293 } 13294 13295 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 13296 = new BluetoothActivityInfoCache(); 13297 onBluetoothPowerStatsRetrieved(BluetoothActivityEnergyInfo info, long elapsedRealtimeMs, long uptimeMs)13298 private void onBluetoothPowerStatsRetrieved(BluetoothActivityEnergyInfo info, 13299 long elapsedRealtimeMs, long uptimeMs) { 13300 // Do not populate consumed energy, because energy attribution is done by 13301 // BluetoothPowerStatsProcessor. 13302 updateBluetoothStateLocked(info, POWER_DATA_UNAVAILABLE, elapsedRealtimeMs, uptimeMs); 13303 } 13304 13305 /** 13306 * Distribute Bluetooth energy info and network traffic to apps. 13307 * 13308 * @param info The accumulated energy information from the bluetooth controller. 13309 */ 13310 @GuardedBy("this") updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)13311 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info, 13312 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 13313 if (DEBUG_ENERGY) { 13314 Slog.d(TAG, "Updating bluetooth stats: " + info); 13315 } 13316 13317 if (info == null) { 13318 return; 13319 } 13320 13321 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 13322 mLastBluetoothActivityInfo.set(info); 13323 return; 13324 } 13325 13326 mHasBluetoothReporting = true; 13327 13328 if (info.getControllerRxTimeMillis() < mLastBluetoothActivityInfo.rxTimeMs 13329 || info.getControllerTxTimeMillis() < mLastBluetoothActivityInfo.txTimeMs 13330 || info.getControllerIdleTimeMillis() < mLastBluetoothActivityInfo.idleTimeMs 13331 || info.getControllerEnergyUsed() < mLastBluetoothActivityInfo.energy) { 13332 // A drop in accumulated Bluetooth stats is a sign of a Bluetooth crash. 13333 // Reset the preserved previous snapshot in order to restart accumulating deltas. 13334 mLastBluetoothActivityInfo.reset(); 13335 } 13336 13337 final long rxTimeMs = 13338 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 13339 final long txTimeMs = 13340 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 13341 final long idleTimeMs = 13342 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 13343 13344 if (DEBUG_ENERGY) { 13345 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 13346 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 13347 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 13348 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 13349 } 13350 13351 final SparseDoubleArray uidEstimatedConsumptionMah = 13352 (mGlobalEnergyConsumerStats != null 13353 && mBluetoothPowerCalculator != null && consumedChargeUC > 0) ? 13354 new SparseDoubleArray() : null; 13355 long totalScanTimeMs = 0; 13356 13357 final int uidCount = mUidStats.size(); 13358 for (int i = 0; i < uidCount; i++) { 13359 final Uid u = mUidStats.valueAt(i); 13360 if (u.mBluetoothScanTimer == null) { 13361 continue; 13362 } 13363 13364 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 13365 elapsedRealtimeMs * 1000) / 1000; 13366 } 13367 13368 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 13369 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 13370 13371 if (DEBUG_ENERGY) { 13372 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 13373 + " TX=" + normalizeScanTxTime); 13374 } 13375 13376 long leftOverRxTimeMs = rxTimeMs; 13377 long leftOverTxTimeMs = txTimeMs; 13378 13379 final SparseLongArray rxTimesMs = new SparseLongArray(uidCount); 13380 final SparseLongArray txTimesMs = new SparseLongArray(uidCount); 13381 13382 for (int i = 0; i < uidCount; i++) { 13383 final Uid u = mUidStats.valueAt(i); 13384 if (u.mBluetoothScanTimer == null) { 13385 continue; 13386 } 13387 13388 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 13389 elapsedRealtimeMs * 1000) / 1000; 13390 if (scanTimeSinceMarkMs > 0) { 13391 // Set the new mark so that next time we get new data since this point. 13392 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 13393 13394 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 13395 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 13396 13397 if (normalizeScanRxTime) { 13398 // Scan time is longer than the total rx time in the controller, 13399 // so distribute the scan time proportionately. This means regular traffic 13400 // will not blamed, but scans are more expensive anyways. 13401 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 13402 } 13403 13404 if (normalizeScanTxTime) { 13405 // Scan time is longer than the total tx time in the controller, 13406 // so distribute the scan time proportionately. This means regular traffic 13407 // will not blamed, but scans are more expensive anyways. 13408 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 13409 } 13410 13411 rxTimesMs.incrementValue(u.getUid(), scanTimeRxSinceMarkMs); 13412 txTimesMs.incrementValue(u.getUid(), scanTimeTxSinceMarkMs); 13413 13414 if (uidEstimatedConsumptionMah != null) { 13415 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 13416 mBluetoothPowerCalculator.calculatePowerMah( 13417 scanTimeRxSinceMarkMs, scanTimeTxSinceMarkMs, 0)); 13418 } 13419 13420 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 13421 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 13422 } 13423 } 13424 13425 if (DEBUG_ENERGY) { 13426 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 13427 + leftOverTxTimeMs); 13428 } 13429 13430 // 13431 // Now distribute blame to apps that did bluetooth traffic. 13432 // 13433 13434 long totalTxBytes = 0; 13435 long totalRxBytes = 0; 13436 13437 final List<UidTraffic> uidTraffic = info.getUidTraffic(); 13438 final int numUids = uidTraffic.size(); 13439 for (int i = 0; i < numUids; i++) { 13440 final UidTraffic traffic = uidTraffic.get(i); 13441 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 13442 traffic.getUid()); 13443 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 13444 traffic.getUid()); 13445 13446 // Add to the global counters. 13447 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 13448 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 13449 13450 // Add to the UID counters. 13451 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()), elapsedRealtimeMs, uptimeMs); 13452 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 13453 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 13454 13455 // Calculate the total traffic. 13456 totalRxBytes += rxBytes; 13457 totalTxBytes += txBytes; 13458 } 13459 13460 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 13461 || leftOverTxTimeMs != 0)) { 13462 for (int i = 0; i < numUids; i++) { 13463 final UidTraffic traffic = uidTraffic.get(i); 13464 final int uid = traffic.getUid(); 13465 final long rxBytes = 13466 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 13467 final long txBytes = 13468 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 13469 13470 final Uid u = getUidStatsLocked(mapUid(uid), elapsedRealtimeMs, uptimeMs); 13471 final ControllerActivityCounterImpl counter = 13472 u.getOrCreateBluetoothControllerActivityLocked(); 13473 13474 if (totalRxBytes > 0 && rxBytes > 0) { 13475 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 13476 rxTimesMs.incrementValue(uid, timeRxMs); 13477 } 13478 13479 if (totalTxBytes > 0 && txBytes > 0) { 13480 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 13481 txTimesMs.incrementValue(uid, timeTxMs); 13482 } 13483 } 13484 13485 for (int i = 0; i < txTimesMs.size(); i++) { 13486 final int uid = txTimesMs.keyAt(i); 13487 final long myTxTimeMs = txTimesMs.valueAt(i); 13488 if (DEBUG_ENERGY) { 13489 Slog.d(TAG, " TxTime for UID " + uid + ": " + myTxTimeMs + " ms"); 13490 } 13491 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 13492 .getOrCreateBluetoothControllerActivityLocked() 13493 .getOrCreateTxTimeCounters()[0] 13494 .increment(myTxTimeMs, elapsedRealtimeMs); 13495 if (uidEstimatedConsumptionMah != null) { 13496 uidEstimatedConsumptionMah.incrementValue(uid, 13497 mBluetoothPowerCalculator.calculatePowerMah(0, myTxTimeMs, 0)); 13498 } 13499 } 13500 13501 for (int i = 0; i < rxTimesMs.size(); i++) { 13502 final int uid = rxTimesMs.keyAt(i); 13503 final long myRxTimeMs = rxTimesMs.valueAt(i); 13504 if (DEBUG_ENERGY) { 13505 Slog.d(TAG, " RxTime for UID " + uid + ": " + myRxTimeMs + " ms"); 13506 } 13507 13508 getUidStatsLocked(rxTimesMs.keyAt(i), elapsedRealtimeMs, uptimeMs) 13509 .getOrCreateBluetoothControllerActivityLocked() 13510 .getOrCreateRxTimeCounter() 13511 .increment(myRxTimeMs, elapsedRealtimeMs); 13512 if (uidEstimatedConsumptionMah != null) { 13513 uidEstimatedConsumptionMah.incrementValue(uid, 13514 mBluetoothPowerCalculator.calculatePowerMah(myRxTimeMs, 0, 0)); 13515 } 13516 } 13517 } 13518 13519 mBluetoothActivity.getOrCreateRxTimeCounter().increment(rxTimeMs, elapsedRealtimeMs); 13520 mBluetoothActivity.getOrCreateTxTimeCounters()[0].increment(txTimeMs, elapsedRealtimeMs); 13521 mBluetoothActivity.getOrCreateIdleTimeCounter().increment(idleTimeMs, elapsedRealtimeMs); 13522 13523 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 13524 final double opVolt = mPowerProfile.getAveragePower( 13525 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 13526 double controllerMaMs = 0; 13527 if (opVolt != 0) { 13528 controllerMaMs = (info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 13529 / opVolt; 13530 // We store the power drain as mAms. 13531 mBluetoothActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 13532 } 13533 13534 // Update the EnergyConsumerStats information. 13535 if (uidEstimatedConsumptionMah != null) { 13536 mGlobalEnergyConsumerStats.updateStandardBucket( 13537 EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, consumedChargeUC); 13538 13539 double totalEstimatedMah 13540 = mBluetoothPowerCalculator.calculatePowerMah(rxTimeMs, txTimeMs, idleTimeMs); 13541 totalEstimatedMah = Math.max(totalEstimatedMah, controllerMaMs / MILLISECONDS_IN_HOUR); 13542 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 13543 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedMah, 13544 elapsedRealtimeMs); 13545 } 13546 13547 mLastBluetoothActivityInfo.set(info); 13548 } 13549 /** 13550 * Read Resource Power Manager (RPM) state and voter times. 13551 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 13552 * instead of fetching it anew. 13553 * 13554 * Note: This should be called without synchronizing this BatteryStatsImpl object 13555 */ fillLowPowerStats()13556 public void fillLowPowerStats() { 13557 if (mPlatformIdleStateCallback == null) return; 13558 13559 RpmStats rpmStats = new RpmStats(); 13560 long now = SystemClock.elapsedRealtime(); 13561 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 13562 mPlatformIdleStateCallback.fillLowPowerStats(rpmStats); 13563 synchronized (this) { 13564 mTmpRpmStats = rpmStats; 13565 mLastRpmStatsUpdateTimeMs = now; 13566 } 13567 } 13568 } 13569 13570 /** 13571 * Record Resource Power Manager (RPM) state and voter times. 13572 * TODO(b/185252376): Remove this logging. PowerStatsService logs the same data more 13573 * efficiently. 13574 */ updateRpmStatsLocked(long elapsedRealtimeUs)13575 public void updateRpmStatsLocked(long elapsedRealtimeUs) { 13576 if (mTmpRpmStats == null) return; 13577 13578 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 13579 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 13580 13581 // Update values for this platform state. 13582 final String pName = pstate.getKey(); 13583 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 13584 final int pCount = pstate.getValue().mCount; 13585 getRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 13586 if (SCREEN_OFF_RPM_STATS_ENABLED) { 13587 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 13588 } 13589 13590 // Update values for each voter of this platform state. 13591 for (Map.Entry<String, RpmStats.PowerStateElement> voter 13592 : pstate.getValue().mVoters.entrySet()) { 13593 final String vName = pName + "." + voter.getKey(); 13594 final long vTimeUs = voter.getValue().mTimeMs * 1000; 13595 final int vCount = voter.getValue().mCount; 13596 getRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 13597 if (SCREEN_OFF_RPM_STATS_ENABLED) { 13598 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 13599 } 13600 } 13601 } 13602 13603 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 13604 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 13605 13606 final String subsysName = subsys.getKey(); 13607 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 13608 : subsys.getValue().mStates.entrySet()) { 13609 final String name = subsysName + "." + sstate.getKey(); 13610 final long timeUs = sstate.getValue().mTimeMs * 1000; 13611 final int count = sstate.getValue().mCount; 13612 getRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 13613 if (SCREEN_OFF_RPM_STATS_ENABLED) { 13614 getScreenOffRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 13615 } 13616 } 13617 } 13618 } 13619 13620 /** 13621 * Accumulate Cpu charge consumption and distribute it to the correct state and the apps. 13622 * Only call if device is on battery. 13623 * 13624 * @param clusterChargeUC amount of charge (microcoulombs) consumed by each Cpu Cluster 13625 * @param accumulator collection of calculated uid cpu power consumption to smear 13626 * clusterChargeUC against. 13627 */ 13628 @GuardedBy("this") 13629 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToStandardBucketLocked updateCpuEnergyConsumerStatsLocked(@onNull long[] clusterChargeUC, @NonNull CpuDeltaPowerAccumulator accumulator)13630 private void updateCpuEnergyConsumerStatsLocked(@NonNull long[] clusterChargeUC, 13631 @NonNull CpuDeltaPowerAccumulator accumulator) { 13632 if (DEBUG_ENERGY) { 13633 Slog.d(TAG, "Updating cpu cluster stats: " + Arrays.toString(clusterChargeUC)); 13634 } 13635 if (mGlobalEnergyConsumerStats == null) { 13636 return; 13637 } 13638 13639 final int numClusters = clusterChargeUC.length; 13640 long totalCpuChargeUC = 0; 13641 for (int i = 0; i < numClusters; i++) { 13642 totalCpuChargeUC += clusterChargeUC[i]; 13643 } 13644 if (totalCpuChargeUC <= 0) return; 13645 13646 final long timestampMs = mClock.elapsedRealtime(); 13647 13648 mGlobalEnergyConsumerStats.updateStandardBucket(EnergyConsumerStats.POWER_BUCKET_CPU, 13649 totalCpuChargeUC, timestampMs); 13650 13651 // Calculate the microcoulombs/milliamp-hour charge ratio for each 13652 // cluster to normalize each uid's estimated power usage against actual power usage for 13653 // a given cluster. 13654 final double[] clusterChargeRatio = new double[numClusters]; 13655 for (int cluster = 0; cluster < numClusters; cluster++) { 13656 13657 final double totalClusterChargeMah = accumulator.totalClusterChargesMah[cluster]; 13658 if (totalClusterChargeMah <= 0.0) { 13659 // This cluster did not have any work on it, since last update. 13660 // Avoid dividing by zero. 13661 clusterChargeRatio[cluster] = 0.0; 13662 } else { 13663 clusterChargeRatio[cluster] = 13664 clusterChargeUC[cluster] / accumulator.totalClusterChargesMah[cluster]; 13665 } 13666 } 13667 13668 // Assign and distribute power usage to apps based on their calculated cpu cluster charge. 13669 final long uidChargeArraySize = accumulator.perUidCpuClusterChargesMah.size(); 13670 for (int i = 0; i < uidChargeArraySize; i++) { 13671 final Uid uid = accumulator.perUidCpuClusterChargesMah.keyAt(i); 13672 final double[] uidClusterChargesMah = accumulator.perUidCpuClusterChargesMah.valueAt(i); 13673 13674 // Iterate each cpu cluster and sum the proportional cpu cluster charge to 13675 // get the total cpu charge consumed by a uid. 13676 long uidCpuChargeUC = 0; 13677 for (int cluster = 0; cluster < numClusters; cluster++) { 13678 final double uidClusterChargeMah = uidClusterChargesMah[cluster]; 13679 13680 // Proportionally allocate the cpu cluster charge to a uid using the 13681 // cluster charge/charge ratio. Add 0.5 to round the proportional 13682 // charge double to the nearest long value. 13683 final long uidClusterChargeUC = 13684 (long) (uidClusterChargeMah * clusterChargeRatio[cluster] 13685 + 0.5); 13686 13687 uidCpuChargeUC += uidClusterChargeUC; 13688 } 13689 13690 if (uidCpuChargeUC < 0) { 13691 Slog.wtf(TAG, "Unexpected proportional EnergyConsumer charge " 13692 + "(" + uidCpuChargeUC + ") for uid " + uid.mUid); 13693 continue; 13694 } 13695 13696 uid.addChargeToStandardBucketLocked(uidCpuChargeUC, 13697 EnergyConsumerStats.POWER_BUCKET_CPU, timestampMs); 13698 } 13699 } 13700 13701 /** 13702 * Accumulate Display charge consumption and distribute it to the correct state and the apps. 13703 * 13704 * NOTE: The algorithm used makes the strong assumption that app foreground activity time 13705 * is always 0 when the screen is not "ON" and whenever the rail energy is 0 (if supported). 13706 * To the extent that those assumptions are violated, the algorithm will err. 13707 * 13708 * @param chargesUC amount of charge (microcoulombs) used by each Display since this was last 13709 * called. 13710 * @param screenStates each screen state at the time this data collection was scheduled 13711 */ 13712 @GuardedBy("this") updateDisplayEnergyConsumerStatsLocked(long[] chargesUC, int[] screenStates, long elapsedRealtimeMs)13713 public void updateDisplayEnergyConsumerStatsLocked(long[] chargesUC, int[] screenStates, 13714 long elapsedRealtimeMs) { 13715 if (DEBUG_ENERGY) Slog.d(TAG, "Updating display stats: " + Arrays.toString(chargesUC)); 13716 if (mGlobalEnergyConsumerStats == null) { 13717 return; 13718 } 13719 13720 final int numDisplays; 13721 if (mPerDisplayBatteryStats.length == screenStates.length) { 13722 numDisplays = screenStates.length; 13723 } else { 13724 // if this point is reached, it will be reached every display state change. 13725 // Rate limit the wtf logging to once every 100 display updates. 13726 if (mDisplayMismatchWtfCount++ % 100 == 0) { 13727 Slog.wtf(TAG, "Mismatch between PowerProfile reported display count (" 13728 + mPerDisplayBatteryStats.length 13729 + ") and PowerStatsHal reported display count (" + screenStates.length 13730 + ")"); 13731 } 13732 // Keep the show going, use the shorter of the two. 13733 numDisplays = mPerDisplayBatteryStats.length < screenStates.length 13734 ? mPerDisplayBatteryStats.length : screenStates.length; 13735 } 13736 13737 final int[] oldScreenStates = new int[numDisplays]; 13738 for (int i = 0; i < numDisplays; i++) { 13739 final int screenState = screenStates[i]; 13740 oldScreenStates[i] = mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement; 13741 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 13742 } 13743 13744 if (!mOnBatteryInternal) { 13745 // There's nothing further to update. 13746 return; 13747 } 13748 if (mIgnoreNextExternalStats) { 13749 // Although under ordinary resets we won't get here, and typically a new sync will 13750 // happen right after the reset, strictly speaking we need to set all mark times to now. 13751 final int uidStatsSize = mUidStats.size(); 13752 for (int i = 0; i < uidStatsSize; i++) { 13753 final Uid uid = mUidStats.valueAt(i); 13754 uid.markProcessForegroundTimeUs(elapsedRealtimeMs, false); 13755 } 13756 return; 13757 } 13758 13759 long totalScreenOnChargeUC = 0; 13760 for (int i = 0; i < numDisplays; i++) { 13761 final long chargeUC = chargesUC[i]; 13762 if (chargeUC <= 0) { 13763 // There's nothing further to update. 13764 continue; 13765 } 13766 13767 final @StandardPowerBucket int powerBucket = 13768 EnergyConsumerStats.getDisplayPowerBucket(oldScreenStates[i]); 13769 mGlobalEnergyConsumerStats.updateStandardBucket(powerBucket, chargeUC); 13770 if (powerBucket == EnergyConsumerStats.POWER_BUCKET_SCREEN_ON) { 13771 totalScreenOnChargeUC += chargeUC; 13772 } 13773 } 13774 13775 // Now we blame individual apps, but only if the display was ON. 13776 if (totalScreenOnChargeUC <= 0) { 13777 return; 13778 } 13779 // TODO(b/175726779): Consider unifying the code with the non-rail display power blaming. 13780 13781 // NOTE: fg time is NOT pooled. If two uids are both somehow in fg, then that time is 13782 // 'double counted' and will simply exceed the realtime that elapsed. 13783 // TODO(b/175726779): collect per display uid visibility for display power attribution. 13784 13785 // Collect total time since mark so that we can normalize power. 13786 final SparseDoubleArray fgTimeUsArray = new SparseDoubleArray(); 13787 final long elapsedRealtimeUs = elapsedRealtimeMs * 1000; 13788 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 13789 final int uidStatsSize = mUidStats.size(); 13790 for (int i = 0; i < uidStatsSize; i++) { 13791 final Uid uid = mUidStats.valueAt(i); 13792 final long fgTimeUs = uid.markProcessForegroundTimeUs(elapsedRealtimeMs, true); 13793 if (fgTimeUs == 0) continue; 13794 fgTimeUsArray.put(uid.getUid(), (double) fgTimeUs); 13795 } 13796 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON, 13797 totalScreenOnChargeUC, fgTimeUsArray, 0, elapsedRealtimeMs); 13798 } 13799 13800 /** 13801 * Accumulate GNSS charge consumption and distribute it to the correct state and the apps. 13802 * 13803 * @param chargeUC amount of charge (microcoulombs) used by GNSS since this was last called. 13804 */ 13805 @GuardedBy("this") 13806 public void updateGnssEnergyConsumerStatsLocked(long chargeUC, long elapsedRealtimeMs) { 13807 if (DEBUG_ENERGY) Slog.d(TAG, "Updating gnss stats: " + chargeUC); 13808 if (mGlobalEnergyConsumerStats == null) { 13809 return; 13810 } 13811 13812 if (!mOnBatteryInternal || chargeUC <= 0) { 13813 // There's nothing further to update. 13814 return; 13815 } 13816 if (mIgnoreNextExternalStats) { 13817 // Although under ordinary resets we won't get here, and typically a new sync will 13818 // happen right after the reset, strictly speaking we need to set all mark times to now. 13819 final int uidStatsSize = mUidStats.size(); 13820 for (int i = 0; i < uidStatsSize; i++) { 13821 final Uid uid = mUidStats.valueAt(i); 13822 uid.markGnssTimeUs(elapsedRealtimeMs); 13823 } 13824 return; 13825 } 13826 13827 mGlobalEnergyConsumerStats.updateStandardBucket(EnergyConsumerStats.POWER_BUCKET_GNSS, 13828 chargeUC); 13829 13830 // Collect the per uid time since mark so that we can normalize power. 13831 final SparseDoubleArray gnssTimeUsArray = new SparseDoubleArray(); 13832 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 13833 final int uidStatsSize = mUidStats.size(); 13834 for (int i = 0; i < uidStatsSize; i++) { 13835 final Uid uid = mUidStats.valueAt(i); 13836 final long gnssTimeUs = uid.markGnssTimeUs(elapsedRealtimeMs); 13837 if (gnssTimeUs == 0) continue; 13838 gnssTimeUsArray.put(uid.getUid(), (double) gnssTimeUs); 13839 } 13840 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_GNSS, chargeUC, 13841 gnssTimeUsArray, 0, elapsedRealtimeMs); 13842 } 13843 13844 /** 13845 * Accumulate camera charge consumption and distribute it to the correct state and the apps. 13846 * 13847 * @param chargeUC amount of charge (microcoulombs) used by the camera since this was last 13848 * called. 13849 */ 13850 @GuardedBy("this") 13851 public void updateCameraEnergyConsumerStatsLocked(long chargeUC, long elapsedRealtimeMs) { 13852 if (DEBUG_ENERGY) Slog.d(TAG, "Updating camera stats: " + chargeUC); 13853 if (mGlobalEnergyConsumerStats == null) { 13854 return; 13855 } 13856 13857 if (!mOnBatteryInternal || chargeUC <= 0) { 13858 // There's nothing further to update. 13859 return; 13860 } 13861 13862 if (mIgnoreNextExternalStats) { 13863 // Although under ordinary resets we won't get here, and typically a new sync will 13864 // happen right after the reset, strictly speaking we need to set all mark times to now. 13865 final int uidStatsSize = mUidStats.size(); 13866 for (int i = 0; i < uidStatsSize; i++) { 13867 final Uid uid = mUidStats.valueAt(i); 13868 uid.markCameraTimeUs(elapsedRealtimeMs); 13869 } 13870 return; 13871 } 13872 13873 mGlobalEnergyConsumerStats.updateStandardBucket( 13874 EnergyConsumerStats.POWER_BUCKET_CAMERA, chargeUC); 13875 13876 // Collect the per uid time since mark so that we can normalize power. 13877 final SparseDoubleArray cameraTimeUsArray = new SparseDoubleArray(); 13878 13879 // Note: Iterating over all UIDs may be suboptimal. 13880 final int uidStatsSize = mUidStats.size(); 13881 for (int i = 0; i < uidStatsSize; i++) { 13882 final Uid uid = mUidStats.valueAt(i); 13883 final long cameraTimeUs = uid.markCameraTimeUs(elapsedRealtimeMs); 13884 if (cameraTimeUs == 0) continue; 13885 cameraTimeUsArray.put(uid.getUid(), (double) cameraTimeUs); 13886 } 13887 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_CAMERA, chargeUC, 13888 cameraTimeUsArray, 0, elapsedRealtimeMs); 13889 } 13890 13891 /** 13892 * Accumulate Custom power bucket charge, globally and for each app. 13893 * 13894 * @param totalChargeUC charge (microcoulombs) used for this bucket since this was last called. 13895 * @param uidCharges map of uid->charge (microcoulombs) for this bucket since last called. 13896 * Data inside uidCharges will not be modified (treated immutable). 13897 * Uids not already known to BatteryStats will be ignored. 13898 */ 13899 @GuardedBy("this") 13900 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToCustomBucketLocked 13901 public void updateCustomEnergyConsumerStatsLocked(int customPowerBucket, 13902 long totalChargeUC, @Nullable SparseLongArray uidCharges) { 13903 if (DEBUG_ENERGY) { 13904 Slog.d(TAG, "Updating attributed EnergyConsumer stats for custom bucket " 13905 + customPowerBucket 13906 + " with total charge " + totalChargeUC 13907 + " and uid charges " + uidCharges); 13908 } 13909 if (mGlobalEnergyConsumerStats == null) return; 13910 if (!mOnBatteryInternal || mIgnoreNextExternalStats || totalChargeUC <= 0) return; 13911 13912 mGlobalEnergyConsumerStats.updateCustomBucket(customPowerBucket, totalChargeUC, 13913 mClock.elapsedRealtime()); 13914 13915 if (uidCharges == null) return; 13916 final int numUids = uidCharges.size(); 13917 for (int i = 0; i < numUids; i++) { 13918 final int uidInt = mapUid(uidCharges.keyAt(i)); 13919 final long uidChargeUC = uidCharges.valueAt(i); 13920 if (uidChargeUC == 0) continue; 13921 13922 final Uid uidObj = getAvailableUidStatsLocked(uidInt); 13923 if (uidObj != null) { 13924 uidObj.addChargeToCustomBucketLocked(uidChargeUC, customPowerBucket); 13925 } else { 13926 // Ignore any uid not already known to BatteryStats, rather than creating a new Uid. 13927 // Otherwise we could end up reviving dead Uids. Note that the CPU data is updated 13928 // first, so any uid that has used any CPU should already be known to BatteryStats. 13929 // Recently removed uids (especially common for isolated uids) can reach this path 13930 // and are ignored. 13931 if (!Process.isIsolated(uidInt)) { 13932 Slog.w(TAG, "Received EnergyConsumer charge " + totalChargeUC 13933 + " for custom bucket " + customPowerBucket + " for non-existent uid " 13934 + uidInt); 13935 } 13936 } 13937 } 13938 } 13939 13940 /** 13941 * Attributes energy (for the given bucket) to each uid according to the following formula: 13942 * blamedEnergy[uid] = totalEnergy * ratioNumerators[uid] / ratioDenominator; 13943 * <p>Does nothing if ratioDenominator is 0. 13944 * 13945 * <p>Here, ratioDenominator = max(sumOfAllRatioNumerators, minRatioDenominator), 13946 * so if given minRatioDenominator <= 0, then sumOfAllRatioNumerators will be used implicitly. 13947 * 13948 * <p>Note that ratioNumerators and minRatioDenominator must use the same units, but need not 13949 * use the same units as totalConsumedChargeUC (which must be in microcoulombs). 13950 * 13951 * <p>A consequence of minRatioDenominator is that the sum over all uids might be less than 13952 * totalConsumedChargeUC. This is intentional; the remainder is purposefully unnaccounted rather 13953 * than incorrectly blamed on uids, and implies unknown (non-uid) sources of drain. 13954 * 13955 * <p>All uids in ratioNumerators must exist in mUidStats already. 13956 */ 13957 @GuardedBy("this") 13958 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToStandardBucketLocked 13959 private void distributeEnergyToUidsLocked(@StandardPowerBucket int bucket, 13960 long totalConsumedChargeUC, SparseDoubleArray ratioNumerators, 13961 double minRatioDenominator, long timestampMs) { 13962 13963 // If the sum of all app usage was greater than the total, use that instead: 13964 double sumRatioNumerators = 0; 13965 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 13966 sumRatioNumerators += ratioNumerators.valueAt(i); 13967 } 13968 final double ratioDenominator = Math.max(sumRatioNumerators, minRatioDenominator); 13969 if (ratioDenominator <= 0) return; 13970 13971 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 13972 final Uid uid = getAvailableUidStatsLocked(ratioNumerators.keyAt(i)); 13973 final double ratioNumerator = ratioNumerators.valueAt(i); 13974 final long uidActualUC 13975 = (long) (totalConsumedChargeUC * ratioNumerator / ratioDenominator + 0.5); 13976 uid.addChargeToStandardBucketLocked(uidActualUC, bucket, timestampMs); 13977 } 13978 } 13979 13980 /** 13981 * Read and record Rail Energy data. 13982 */ 13983 public void updateRailStatsLocked() { 13984 if (mCustomEnergyConsumerPowerStatsCollector.isEnabled()) { 13985 mCustomEnergyConsumerPowerStatsCollector.schedule(); 13986 return; 13987 } 13988 13989 if (mEnergyConsumerRetriever == null || !mTmpRailStats.isRailStatsAvailable()) { 13990 return; 13991 } 13992 mEnergyConsumerRetriever.fillRailDataStats(mTmpRailStats); 13993 } 13994 13995 /** Informs that external stats data has been completely flushed. */ 13996 public void informThatAllExternalStatsAreFlushed() { 13997 synchronized (this) { 13998 // Any data from the pre-reset era is flushed, so we can henceforth process future data. 13999 mIgnoreNextExternalStats = false; 14000 } 14001 } 14002 14003 /** 14004 * Read and distribute kernel wake lock use across apps. 14005 */ 14006 public void updateKernelWakelocksLocked(long elapsedRealtimeUs) { 14007 if (mKernelWakelockReader == null) { 14008 return; 14009 } 14010 14011 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 14012 mTmpWakelockStats); 14013 if (wakelockStats == null) { 14014 // Not crashing might make board bringup easier. 14015 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 14016 return; 14017 } 14018 14019 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 14020 String name = ent.getKey(); 14021 KernelWakelockStats.Entry kws = ent.getValue(); 14022 14023 SamplingTimer kwlt = mKernelWakelockStats.get(name); 14024 if (kwlt == null) { 14025 kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 14026 mKernelWakelockStats.put(name, kwlt); 14027 } 14028 14029 kwlt.update(kws.totalTimeUs, kws.activeTimeUs, kws.count, elapsedRealtimeUs); 14030 kwlt.setUpdateVersion(kws.version); 14031 } 14032 14033 int numWakelocksSetStale = 0; 14034 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 14035 // this time. 14036 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 14037 SamplingTimer st = ent.getValue(); 14038 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 14039 st.endSample(elapsedRealtimeUs); 14040 numWakelocksSetStale++; 14041 } 14042 } 14043 14044 if (DEBUG) { 14045 // Record whether we've seen a non-zero time (for debugging b/22716723). 14046 if (wakelockStats.isEmpty()) { 14047 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 14048 } 14049 14050 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 14051 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" 14052 + wakelockStats.kernelWakelockVersion); 14053 } 14054 } 14055 } 14056 14057 // We use an anonymous class to access these variables, 14058 // so they can't live on the stack or they'd have to be 14059 // final MutableLong objects (more allocations). 14060 // Used in updateCpuTimeLocked(). 14061 long mTempTotalCpuUserTimeUs; 14062 long mTempTotalCpuSystemTimeUs; 14063 long[][] mWakeLockAllocationsUs; 14064 14065 /** 14066 * Reads the newest memory stats from the kernel. 14067 */ 14068 public void updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs) { 14069 mKernelMemoryBandwidthStats.updateStats(); 14070 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 14071 final int bandwidthEntryCount = bandwidthEntries.size(); 14072 int index; 14073 for (int i = 0; i < bandwidthEntryCount; i++) { 14074 SamplingTimer timer; 14075 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 14076 timer = mKernelMemoryStats.valueAt(index); 14077 } else { 14078 timer = new SamplingTimer(mClock, mOnBatteryTimeBase); 14079 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 14080 } 14081 timer.update(bandwidthEntries.valueAt(i), 1, elapsedRealtimeUs); 14082 if (DEBUG_MEMORY) { 14083 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 14084 + "mUnpluggedReportedTotalTimeUs %d size %d", bandwidthEntries.keyAt(i), 14085 mKernelMemoryStats.get( 14086 bandwidthEntries.keyAt(i)).mBaseReportedTotalTimeUs, 14087 mKernelMemoryStats.size())); 14088 } 14089 } 14090 } 14091 14092 public boolean isOnBatteryLocked() { 14093 return mOnBatteryTimeBase.isRunning(); 14094 } 14095 14096 public boolean isOnBatteryScreenOffLocked() { 14097 return mOnBatteryScreenOffTimeBase.isRunning(); 14098 } 14099 14100 /** 14101 * Object for calculating and accumulating the estimated cpu power used while reading the 14102 * various cpu kernel files. 14103 */ 14104 @VisibleForTesting 14105 public static class CpuDeltaPowerAccumulator { 14106 // Keeps track of total charge used per cluster. 14107 public final double[] totalClusterChargesMah; 14108 // Keeps track of charge used per cluster per uid. 14109 public final ArrayMap<Uid, double[]> perUidCpuClusterChargesMah; 14110 14111 private final CpuPowerCalculator mCalculator; 14112 private Uid mCachedUid = null; 14113 private double[] mUidClusterCache = null; 14114 14115 CpuDeltaPowerAccumulator(CpuPowerCalculator calculator, int nClusters) { 14116 mCalculator = calculator; 14117 totalClusterChargesMah = new double[nClusters]; 14118 perUidCpuClusterChargesMah = new ArrayMap<>(); 14119 } 14120 14121 /** Add per cpu cluster durations to the currently cached uid. */ 14122 public void addCpuClusterDurationsMs(Uid uid, long[] durationsMs) { 14123 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 14124 for (int cluster = 0; cluster < durationsMs.length; cluster++) { 14125 final double estimatedDeltaMah = mCalculator.calculatePerCpuClusterPowerMah(cluster, 14126 durationsMs[cluster]); 14127 uidChargesMah[cluster] += estimatedDeltaMah; 14128 totalClusterChargesMah[cluster] += estimatedDeltaMah; 14129 } 14130 } 14131 14132 /** Add per speed per cpu cluster durations to the currently cached uid. */ 14133 public void addCpuClusterSpeedDurationsMs(Uid uid, int cluster, int speed, 14134 long durationsMs) { 14135 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 14136 final double estimatedDeltaMah = mCalculator.calculatePerCpuFreqPowerMah(cluster, speed, 14137 durationsMs); 14138 uidChargesMah[cluster] += estimatedDeltaMah; 14139 totalClusterChargesMah[cluster] += estimatedDeltaMah; 14140 } 14141 14142 private double[] getOrCreateUidCpuClusterCharges(Uid uid) { 14143 // Repeated additions on the same uid is very likely. 14144 // Skip a lookup if getting the same uid as the last get. 14145 if (uid == mCachedUid) return mUidClusterCache; 14146 14147 double[] uidChargesMah = perUidCpuClusterChargesMah.get(uid); 14148 if (uidChargesMah == null) { 14149 uidChargesMah = new double[totalClusterChargesMah.length]; 14150 perUidCpuClusterChargesMah.put(uid, uidChargesMah); 14151 } 14152 mCachedUid = uid; 14153 mUidClusterCache = uidChargesMah; 14154 return uidChargesMah; 14155 } 14156 } 14157 14158 /** 14159 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 14160 * and we are on battery with screen off, we give more of the cpu time to those apps holding 14161 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 14162 * It's possible this will be invoked after the internal battery/screen states are updated, so 14163 * passing the appropriate battery/screen states to try attribute the cpu times to correct 14164 * buckets. 14165 */ 14166 @GuardedBy("this") 14167 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff, 14168 long[] cpuClusterChargeUC) { 14169 if (DEBUG_ENERGY_CPU) { 14170 Slog.d(TAG, "!Cpu updating!"); 14171 } 14172 14173 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 14174 // usually holding the wakelock on behalf of an app. 14175 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 14176 ArrayList<StopwatchTimer> partialTimersToConsider = null; 14177 if (onBatteryScreenOff) { 14178 partialTimersToConsider = new ArrayList<>(); 14179 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 14180 final StopwatchTimer timer = mPartialTimers.get(i); 14181 // Since the collection and blaming of wakelocks can be scheduled to run after 14182 // some delay, the mPartialTimers list may have new entries. We can't blame 14183 // the newly added timer for past cpu time, so we only consider timers that 14184 // were present for one round of collection. Once a timer has gone through 14185 // a round of collection, its mInList field is set to true. 14186 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 14187 partialTimersToConsider.add(timer); 14188 } 14189 } 14190 } 14191 markPartialTimersAsEligible(); 14192 14193 // When the battery is not on, we don't attribute the cpu times to any timers but we still 14194 // need to take the snapshots. 14195 if (!onBattery) { 14196 mCpuUidUserSysTimeReader.readDelta(false, null); 14197 mCpuUidFreqTimeReader.readDelta(false, null); 14198 mNumAllUidCpuTimeReads += 2; 14199 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 14200 mCpuUidActiveTimeReader.readDelta(false, null); 14201 mCpuUidClusterTimeReader.readDelta(false, null); 14202 mNumAllUidCpuTimeReads += 2; 14203 } 14204 for (int i = mKernelCpuSpeedReaders.length - 1; i >= 0; --i) { 14205 if (mKernelCpuSpeedReaders[i] != null) { 14206 mKernelCpuSpeedReaders[i].readDelta(); 14207 } 14208 } 14209 if (!Flags.disableSystemServicePowerAttr()) { 14210 mSystemServerCpuThreadReader.readDelta(); 14211 } 14212 return; 14213 } 14214 14215 mUserInfoProvider.refreshUserIds(); 14216 final SparseLongArray updatedUids = mCpuUidFreqTimeReader.allUidTimesAvailable() 14217 ? null : new SparseLongArray(); 14218 14219 final CpuDeltaPowerAccumulator powerAccumulator; 14220 if (mGlobalEnergyConsumerStats != null 14221 && mGlobalEnergyConsumerStats.isStandardBucketSupported( 14222 EnergyConsumerStats.POWER_BUCKET_CPU)) { 14223 if (cpuClusterChargeUC == null) { 14224 Slog.wtf(TAG, 14225 "POWER_BUCKET_CPU supported but no EnergyConsumer Cpu Cluster charge " 14226 + "reported on updateCpuTimeLocked!"); 14227 powerAccumulator = null; 14228 } else { 14229 if (mCpuPowerCalculator == null) { 14230 mCpuPowerCalculator = new CpuPowerCalculator(mCpuScalingPolicies, 14231 mPowerProfile); 14232 } 14233 // Cpu EnergyConsumer is supported, create an object to accumulate the estimated 14234 // charge consumption since the last cpu update 14235 powerAccumulator = new CpuDeltaPowerAccumulator(mCpuPowerCalculator, 14236 mCpuScalingPolicies.getPolicies().length); 14237 } 14238 } else { 14239 powerAccumulator = null; 14240 } 14241 14242 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 14243 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 14244 // freqs, so no need to approximate these values. 14245 if (updatedUids != null) { 14246 updateClusterSpeedTimes(updatedUids, onBattery, powerAccumulator); 14247 } 14248 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff, 14249 powerAccumulator); 14250 mNumAllUidCpuTimeReads += 2; 14251 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 14252 // Cpu Active times do not get any info ony how to attribute Cpu Cluster 14253 // charge, so not need to provide the powerAccumulator 14254 readKernelUidCpuActiveTimesLocked(onBattery); 14255 readKernelUidCpuClusterTimesLocked(onBattery, powerAccumulator); 14256 mNumAllUidCpuTimeReads += 2; 14257 } 14258 14259 if (!Flags.disableSystemServicePowerAttr()) { 14260 updateSystemServerThreadStats(); 14261 } 14262 14263 if (powerAccumulator != null) { 14264 updateCpuEnergyConsumerStatsLocked(cpuClusterChargeUC, powerAccumulator); 14265 } 14266 } 14267 14268 /** 14269 * Estimates the proportion of the System Server CPU activity (per cluster per speed) 14270 * spent on handling incoming binder calls. 14271 */ 14272 @VisibleForTesting 14273 public void updateSystemServerThreadStats() { 14274 // There are some simplifying assumptions made in this algorithm 14275 // 1) We assume that if a thread handles incoming binder calls, all of its activity 14276 // is spent doing that. Most incoming calls are handled by threads allocated 14277 // by the native layer in the binder thread pool, so this assumption is reasonable. 14278 // 2) We use the aggregate CPU time spent in different threads as a proxy for the CPU 14279 // cost. In reality, in multi-core CPUs, the CPU cost may not be linearly 14280 // affected by additional threads. 14281 14282 SystemServerCpuThreadReader.SystemServiceCpuThreadTimes systemServiceCpuThreadTimes = 14283 mSystemServerCpuThreadReader.readDelta(); 14284 if (systemServiceCpuThreadTimes == null) { 14285 return; 14286 } 14287 14288 if (mBinderThreadCpuTimesUs == null) { 14289 mBinderThreadCpuTimesUs = new LongSamplingCounterArray(mOnBatteryTimeBase); 14290 } 14291 mBinderThreadCpuTimesUs.addCountLocked(systemServiceCpuThreadTimes.binderThreadCpuTimesUs); 14292 14293 if (DEBUG_BINDER_STATS) { 14294 Slog.d(TAG, "System server threads per CPU cluster (incoming binder threads)"); 14295 long binderThreadTimeMs = 0; 14296 final long[] binderThreadCpuTimesUs = mBinderThreadCpuTimesUs.getCountsLocked( 14297 BatteryStats.STATS_SINCE_CHARGED); 14298 int index = 0; 14299 int[] policies = mCpuScalingPolicies.getPolicies(); 14300 for (int policy : policies) { 14301 StringBuilder sb = new StringBuilder(); 14302 sb.append("policy").append(policy).append(": ["); 14303 int numSpeeds = mCpuScalingPolicies.getFrequencies(policy).length; 14304 for (int speed = 0; speed < numSpeeds; speed++) { 14305 if (speed != 0) { 14306 sb.append(", "); 14307 } 14308 long binderCountMs = binderThreadCpuTimesUs[index] / 1000; 14309 sb.append(TextUtils.formatSimple("%10d", binderCountMs)); 14310 14311 binderThreadTimeMs += binderCountMs; 14312 index++; 14313 } 14314 Slog.d(TAG, sb.toString()); 14315 } 14316 } 14317 } 14318 14319 /** 14320 * Mark the current partial timers as gone through a collection so that they will be 14321 * considered in the next cpu times distribution to wakelock holders. 14322 */ 14323 @VisibleForTesting 14324 public void markPartialTimersAsEligible() { 14325 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 14326 // No difference, so each timer is now considered for the next collection. 14327 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 14328 mPartialTimers.get(i).mInList = true; 14329 } 14330 } else { 14331 // The lists are different, meaning we added (or removed a timer) since the last 14332 // collection. 14333 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 14334 mLastPartialTimers.get(i).mInList = false; 14335 } 14336 mLastPartialTimers.clear(); 14337 14338 // Mark the current timers as gone through a collection. 14339 final int numPartialTimers = mPartialTimers.size(); 14340 for (int i = 0; i < numPartialTimers; ++i) { 14341 final StopwatchTimer timer = mPartialTimers.get(i); 14342 timer.mInList = true; 14343 mLastPartialTimers.add(timer); 14344 } 14345 } 14346 } 14347 14348 /** 14349 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 14350 * calculate cpu times spent by each uid at different frequencies. Will also add estimated 14351 * power consumptions, if powerAccumulator data structure is provided. 14352 * 14353 * @param updatedUids The uids for which times spent at different frequencies are calculated. 14354 * @param onBattery whether or not this is onBattery 14355 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 14356 */ 14357 @VisibleForTesting 14358 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery, 14359 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 14360 long totalCpuClustersTimeMs = 0; 14361 // Read the time spent for each cluster at various cpu frequencies. 14362 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 14363 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 14364 if (mKernelCpuSpeedReaders[cluster] != null) { 14365 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 14366 if (clusterSpeedTimesMs[cluster] != null) { 14367 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 14368 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 14369 } 14370 } 14371 } 14372 } 14373 if (totalCpuClustersTimeMs != 0) { 14374 // We have cpu times per freq aggregated over all uids but we need the times per uid. 14375 // So, we distribute total time spent by an uid to different cpu freqs based on the 14376 // amount of time cpu was running at that freq. 14377 final int updatedUidsCount = updatedUids.size(); 14378 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14379 final long uptimeMs = mClock.uptimeMillis(); 14380 for (int i = 0; i < updatedUidsCount; ++i) { 14381 final Uid u = getUidStatsLocked(updatedUids.keyAt(i), elapsedRealtimeMs, uptimeMs); 14382 final long appCpuTimeUs = updatedUids.valueAt(i); 14383 // Add the cpu speeds to this UID. 14384 int[] policies = mCpuScalingPolicies.getPolicies(); 14385 if (u.mCpuClusterSpeedTimesUs == null || 14386 u.mCpuClusterSpeedTimesUs.length != policies.length) { 14387 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[policies.length][]; 14388 } 14389 14390 for (int cluster = 0; cluster < policies.length; cluster++) { 14391 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 14392 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 14393 u.mCpuClusterSpeedTimesUs[cluster].length) { 14394 u.mCpuClusterSpeedTimesUs[cluster] 14395 = new LongSamplingCounter[speedsInCluster]; 14396 } 14397 14398 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 14399 for (int speed = 0; speed < speedsInCluster; speed++) { 14400 if (cpuSpeeds[speed] == null) { 14401 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 14402 } 14403 final long deltaSpeedCount = appCpuTimeUs 14404 * clusterSpeedTimesMs[cluster][speed] 14405 / totalCpuClustersTimeMs; 14406 cpuSpeeds[speed].addCountLocked(deltaSpeedCount, onBattery); 14407 14408 if (powerAccumulator != null) { 14409 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14410 speed, deltaSpeedCount); 14411 } 14412 } 14413 } 14414 } 14415 } 14416 } 14417 14418 /** 14419 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 14420 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 14421 * wakelock holders. 14422 * 14423 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 14424 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 14425 */ 14426 @VisibleForTesting 14427 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 14428 @Nullable SparseLongArray updatedUids, boolean onBattery) { 14429 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 14430 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 14431 final long startTimeMs = mClock.uptimeMillis(); 14432 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14433 14434 mCpuUidUserSysTimeReader.readDelta(false, (uid, timesUs) -> { 14435 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 14436 14437 uid = mapUid(uid); 14438 if (Process.isIsolated(uid)) { 14439 // This could happen if the isolated uid mapping was removed before that process 14440 // was actually killed. 14441 if (DEBUG) Slog.d(TAG, "Got readings for an isolated uid: " + uid); 14442 return; 14443 } 14444 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14445 if (DEBUG) Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 14446 return; 14447 } 14448 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 14449 14450 // Accumulate the total system and user time. 14451 mTempTotalCpuUserTimeUs += userTimeUs; 14452 mTempTotalCpuSystemTimeUs += systemTimeUs; 14453 14454 StringBuilder sb = null; 14455 if (DEBUG_ENERGY_CPU) { 14456 sb = new StringBuilder(); 14457 sb.append(" got time for uid=").append(u.mUid).append(": u="); 14458 TimeUtils.formatDuration(userTimeUs / 1000, sb); 14459 sb.append(" s="); 14460 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 14461 sb.append("\n"); 14462 } 14463 14464 if (numWakelocks > 0) { 14465 // We have wakelocks being held, so only give a portion of the 14466 // time to the process. The rest will be distributed among wakelock 14467 // holders. 14468 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 14469 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 14470 } 14471 14472 if (sb != null) { 14473 sb.append(" adding to uid=").append(u.mUid).append(": u="); 14474 TimeUtils.formatDuration(userTimeUs / 1000, sb); 14475 sb.append(" s="); 14476 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 14477 Slog.d(TAG, sb.toString()); 14478 } 14479 14480 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 14481 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 14482 if (updatedUids != null) { 14483 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 14484 } 14485 }); 14486 14487 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14488 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14489 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 14490 } 14491 14492 if (numWakelocks > 0) { 14493 // Distribute a portion of the total cpu time to wakelock holders. 14494 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 14495 mTempTotalCpuSystemTimeUs = 14496 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 14497 14498 for (int i = 0; i < numWakelocks; ++i) { 14499 final StopwatchTimer timer = partialTimers.get(i); 14500 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 14501 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 14502 14503 if (DEBUG_ENERGY_CPU) { 14504 final StringBuilder sb = new StringBuilder(); 14505 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 14506 .append(": u="); 14507 TimeUtils.formatDuration(userTimeUs / 1000, sb); 14508 sb.append(" s="); 14509 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 14510 Slog.d(TAG, sb.toString()); 14511 } 14512 14513 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 14514 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 14515 if (updatedUids != null) { 14516 final int uid = timer.mUid.getUid(); 14517 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 14518 } 14519 14520 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 14521 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 14522 14523 mTempTotalCpuUserTimeUs -= userTimeUs; 14524 mTempTotalCpuSystemTimeUs -= systemTimeUs; 14525 } 14526 } 14527 } 14528 14529 /** 14530 * Take a snapshot of the cpu times spent by each uid in each freq and update the 14531 * corresponding counters. Will also add estimated power consumptions, if powerAccumulator 14532 * data structure is provided. 14533 * 14534 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 14535 * @param onBattery whether or not this is onBattery 14536 * @param onBatteryScreenOff whether or not this is onBattery with the screen off. 14537 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 14538 */ 14539 @VisibleForTesting 14540 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 14541 boolean onBattery, boolean onBatteryScreenOff, 14542 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 14543 final boolean perClusterTimesAvailable = 14544 mCpuUidFreqTimeReader.perClusterTimesAvailable(); 14545 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 14546 final int[] policies = mCpuScalingPolicies.getPolicies(); 14547 final int numClusters = policies.length; 14548 mWakeLockAllocationsUs = null; 14549 final long startTimeMs = mClock.uptimeMillis(); 14550 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14551 // If power is being accumulated for attribution, data needs to be read immediately. 14552 final boolean forceRead = powerAccumulator != null; 14553 mCpuUidFreqTimeReader.readDelta(forceRead, (uid, cpuFreqTimeMs) -> { 14554 uid = mapUid(uid); 14555 if (Process.isIsolated(uid)) { 14556 if (DEBUG) Slog.d(TAG, "Got freq readings for an isolated uid: " + uid); 14557 return; 14558 } 14559 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14560 if (DEBUG) Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 14561 return; 14562 } 14563 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 14564 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 14565 detachIfNotNull(u.mCpuFreqTimeMs); 14566 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 14567 } 14568 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 14569 if (u.mScreenOffCpuFreqTimeMs == null || 14570 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 14571 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 14572 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 14573 mOnBatteryScreenOffTimeBase); 14574 } 14575 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 14576 14577 if (perClusterTimesAvailable) { 14578 if (u.mCpuClusterSpeedTimesUs == null || 14579 u.mCpuClusterSpeedTimesUs.length != numClusters) { 14580 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 14581 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 14582 } 14583 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 14584 mWakeLockAllocationsUs = new long[numClusters][]; 14585 } 14586 14587 int freqIndex = 0; 14588 for (int cluster = 0; cluster < numClusters; cluster++) { 14589 final int[] freqs = mCpuScalingPolicies.getFrequencies(policies[cluster]); 14590 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 14591 u.mCpuClusterSpeedTimesUs[cluster].length != freqs.length) { 14592 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 14593 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[freqs.length]; 14594 } 14595 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 14596 mWakeLockAllocationsUs[cluster] = new long[freqs.length]; 14597 } 14598 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 14599 for (int speed = 0; speed < freqs.length; ++speed) { 14600 if (cpuTimesUs[speed] == null) { 14601 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 14602 } 14603 final long appAllocationUs; 14604 if (mWakeLockAllocationsUs != null) { 14605 appAllocationUs = 14606 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 14607 mWakeLockAllocationsUs[cluster][speed] += 14608 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 14609 } else { 14610 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 14611 } 14612 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 14613 14614 if (powerAccumulator != null) { 14615 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14616 speed, appAllocationUs / 1000); 14617 } 14618 freqIndex++; 14619 } 14620 } 14621 } 14622 }); 14623 14624 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14625 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14626 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 14627 } 14628 14629 if (mWakeLockAllocationsUs != null) { 14630 for (int i = 0; i < numWakelocks; ++i) { 14631 final Uid u = partialTimers.get(i).mUid; 14632 if (u.mCpuClusterSpeedTimesUs == null || 14633 u.mCpuClusterSpeedTimesUs.length != numClusters) { 14634 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 14635 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 14636 } 14637 14638 for (int cluster = 0; cluster < numClusters; ++cluster) { 14639 final int speedsInCluster = 14640 mCpuScalingPolicies.getFrequencies(policies[cluster]).length; 14641 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 14642 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 14643 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 14644 u.mCpuClusterSpeedTimesUs[cluster] 14645 = new LongSamplingCounter[speedsInCluster]; 14646 } 14647 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 14648 for (int speed = 0; speed < speedsInCluster; ++speed) { 14649 if (cpuTimeUs[speed] == null) { 14650 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 14651 } 14652 final long allocationUs = 14653 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 14654 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 14655 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 14656 14657 if (powerAccumulator != null) { 14658 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14659 speed, allocationUs / 1000); 14660 } 14661 } 14662 } 14663 } 14664 } 14665 } 14666 14667 /** 14668 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 14669 * counters. 14670 */ 14671 @VisibleForTesting 14672 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 14673 final long startTimeMs = mClock.uptimeMillis(); 14674 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14675 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { 14676 final int parentUid = mapUid(uid); 14677 if (Process.isIsolated(parentUid)) { 14678 if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); 14679 return; 14680 } 14681 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14682 if (DEBUG) Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 14683 return; 14684 } 14685 final Uid u = getUidStatsLocked(parentUid, elapsedRealtimeMs, startTimeMs); 14686 if (parentUid == uid) { 14687 u.getCpuActiveTimeCounter().update(cpuActiveTimesMs, elapsedRealtimeMs); 14688 } else { 14689 final SparseArray<Uid.ChildUid> childUids = u.mChildUids; 14690 if (childUids == null) { 14691 return; 14692 } 14693 14694 Uid.ChildUid childUid = childUids.get(uid); 14695 if (childUid != null) { 14696 final long delta = 14697 childUid.cpuActiveCounter.update(cpuActiveTimesMs, elapsedRealtimeMs); 14698 u.getCpuActiveTimeCounter().increment(delta, elapsedRealtimeMs); 14699 } 14700 } 14701 }); 14702 14703 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14704 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14705 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 14706 } 14707 } 14708 14709 /** 14710 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 14711 * counters. Will also add estimated power consumptions, if powerAccumulator data structure 14712 * is provided. 14713 * 14714 * @param onBattery whether or not this is onBattery 14715 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 14716 */ 14717 @VisibleForTesting 14718 public void readKernelUidCpuClusterTimesLocked(boolean onBattery, 14719 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 14720 final long startTimeMs = mClock.uptimeMillis(); 14721 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14722 // If power is being accumulated for attribution, data needs to be read immediately. 14723 final boolean forceRead = powerAccumulator != null; 14724 mCpuUidClusterTimeReader.readDelta(forceRead, (uid, cpuClusterTimesMs) -> { 14725 uid = mapUid(uid); 14726 if (Process.isIsolated(uid)) { 14727 if (DEBUG) Slog.w(TAG, "Got cluster times for an isolated uid: " + uid); 14728 return; 14729 } 14730 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14731 if (DEBUG) Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 14732 return; 14733 } 14734 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 14735 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 14736 14737 if (powerAccumulator != null) { 14738 powerAccumulator.addCpuClusterDurationsMs(u, cpuClusterTimesMs); 14739 } 14740 }); 14741 14742 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14743 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14744 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 14745 } 14746 } 14747 14748 boolean setChargingLocked(boolean charging) { 14749 // if the device is no longer charging, remove the callback 14750 // if the device is now charging, it means that this is either called 14751 // 1. directly when level >= 90 14752 // 2. or from within the runnable that we deferred 14753 // For 1. if we have an existing callback, remove it, since we will immediately send a 14754 // ACTION_CHARGING 14755 // For 2. we remove existing callback so we don't send multiple ACTION_CHARGING 14756 mHandler.removeCallbacks(mDeferSetCharging); 14757 if (mCharging != charging) { 14758 mCharging = charging; 14759 mHistory.setChargingState(charging); 14760 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 14761 return true; 14762 } 14763 return false; 14764 } 14765 14766 /** 14767 * Notifies BatteryStatsImpl that the system server is ready. 14768 */ 14769 public void onSystemReady(Context context) { 14770 if (mCpuUidFreqTimeReader != null) { 14771 mCpuUidFreqTimeReader.onSystemReady(); 14772 } 14773 14774 mStepDetailsProvider.onSystemReady(); 14775 14776 mPowerStatsCollectorInjector.setContext(context); 14777 14778 mCpuPowerStatsCollector.setEnabled( 14779 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CPU)); 14780 mCpuPowerStatsCollector.schedule(); 14781 14782 mWakelockPowerStatsCollector.setEnabled( 14783 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_WAKELOCK)); 14784 mWakelockPowerStatsCollector.schedule(); 14785 14786 mScreenPowerStatsCollector.setEnabled( 14787 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_SCREEN)); 14788 mScreenPowerStatsCollector.schedule(); 14789 14790 mMobileRadioPowerStatsCollector.setEnabled( 14791 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)); 14792 mMobileRadioPowerStatsCollector.schedule(); 14793 14794 mWifiPowerStatsCollector.setEnabled( 14795 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_WIFI)); 14796 mWifiPowerStatsCollector.schedule(); 14797 14798 mBluetoothPowerStatsCollector.setEnabled( 14799 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_BLUETOOTH)); 14800 mBluetoothPowerStatsCollector.schedule(); 14801 14802 mCameraPowerStatsCollector.setEnabled( 14803 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_CAMERA)); 14804 mCameraPowerStatsCollector.schedule(); 14805 14806 mGnssPowerStatsCollector.setEnabled( 14807 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS)); 14808 mGnssPowerStatsCollector.schedule(); 14809 14810 mCustomEnergyConsumerPowerStatsCollector.setEnabled( 14811 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_ANY)); 14812 mCustomEnergyConsumerPowerStatsCollector.schedule(); 14813 14814 mSystemReady = true; 14815 } 14816 14817 /** 14818 * Returns a PowerStatsCollector for the specified power component or null if unavailable. 14819 */ 14820 @Nullable 14821 PowerStatsCollector getPowerStatsCollector( 14822 @BatteryConsumer.PowerComponent int powerComponent) { 14823 switch (powerComponent) { 14824 case BatteryConsumer.POWER_COMPONENT_CPU: 14825 return mCpuPowerStatsCollector; 14826 case BatteryConsumer.POWER_COMPONENT_WAKELOCK: 14827 return mWakelockPowerStatsCollector; 14828 case BatteryConsumer.POWER_COMPONENT_SCREEN: 14829 return mScreenPowerStatsCollector; 14830 case BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO: 14831 return mMobileRadioPowerStatsCollector; 14832 case BatteryConsumer.POWER_COMPONENT_WIFI: 14833 return mWifiPowerStatsCollector; 14834 case BatteryConsumer.POWER_COMPONENT_BLUETOOTH: 14835 return mBluetoothPowerStatsCollector; 14836 case BatteryConsumer.POWER_COMPONENT_CAMERA: 14837 return mCameraPowerStatsCollector; 14838 case BatteryConsumer.POWER_COMPONENT_GNSS: 14839 return mGnssPowerStatsCollector; 14840 } 14841 return null; 14842 } 14843 14844 14845 /** 14846 * Force recording of all history events regardless of the "charging" state. 14847 */ 14848 @VisibleForTesting 14849 public void forceRecordAllHistory() { 14850 mHistory.forceRecordAllHistory(); 14851 mRecordAllHistory = true; 14852 } 14853 14854 /** 14855 * Might reset battery stats if conditions are met. Assumed the device is currently plugged in. 14856 */ 14857 @VisibleForTesting 14858 @GuardedBy("this") 14859 public void maybeResetWhilePluggedInLocked() { 14860 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14861 if (shouldResetWhilePluggedInLocked(elapsedRealtimeMs)) { 14862 Slog.i(TAG, 14863 "Resetting due to long plug in duration. elapsed time = " + elapsedRealtimeMs 14864 + " ms, last plug in time = " + mBatteryPluggedInRealTimeMs 14865 + " ms, last reset time = " + mRealtimeStartUs / 1000); 14866 startNewSession(RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION); 14867 } 14868 14869 scheduleNextResetWhilePluggedInCheck(); 14870 } 14871 14872 @GuardedBy("this") 14873 private void scheduleNextResetWhilePluggedInCheck() { 14874 if (mAlarmManager == null) return; 14875 final long timeoutMs = mClock.currentTimeMillis() 14876 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14877 * DateUtils.HOUR_IN_MILLIS; 14878 Calendar nextAlarm = Calendar.getInstance(); 14879 nextAlarm.setTimeInMillis(timeoutMs); 14880 14881 // Find the 2 AM the same day as the end of the minimum duration. 14882 // This logic does not handle a Daylight Savings transition, or a timezone change 14883 // while the alarm has been set. The need to reset after a long period while plugged 14884 // in is not strict enough to warrant a well architected out solution. 14885 nextAlarm.set(Calendar.MILLISECOND, 0); 14886 nextAlarm.set(Calendar.SECOND, 0); 14887 nextAlarm.set(Calendar.MINUTE, 0); 14888 nextAlarm.set(Calendar.HOUR_OF_DAY, 2); 14889 long possibleNextTimeMs = nextAlarm.getTimeInMillis(); 14890 if (possibleNextTimeMs < timeoutMs) { 14891 // The 2AM on the day of the timeout, move on the next day. 14892 possibleNextTimeMs += DateUtils.DAY_IN_MILLIS; 14893 } 14894 final long nextTimeMs = possibleNextTimeMs; 14895 final AlarmManager am = mAlarmManager; 14896 mHandler.post(() -> am.setWindow(AlarmManager.RTC, nextTimeMs, 14897 DateUtils.HOUR_IN_MILLIS, 14898 TAG, mLongPlugInAlarmHandler, mHandler)); 14899 } 14900 14901 14902 @GuardedBy("this") 14903 private boolean shouldResetWhilePluggedInLocked(long elapsedRealtimeMs) { 14904 if (mNoAutoReset) return false; 14905 if (!mSystemReady) return false; 14906 if (!mHistory.isResetEnabled()) return false; 14907 14908 final long pluggedInThresholdMs = mBatteryPluggedInRealTimeMs 14909 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14910 * DateUtils.HOUR_IN_MILLIS; 14911 if (elapsedRealtimeMs >= pluggedInThresholdMs) { 14912 // The device has been plugged in for a long time. 14913 final long resetThresholdMs = mRealtimeStartUs / 1000 14914 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14915 * DateUtils.HOUR_IN_MILLIS; 14916 if (elapsedRealtimeMs >= resetThresholdMs) { 14917 // And it has been a long time since the last reset. 14918 return true; 14919 } 14920 } 14921 14922 return false; 14923 } 14924 14925 @GuardedBy("this") 14926 private boolean shouldResetOnUnplugLocked(int batteryStatus, int batteryLevel) { 14927 if (mNoAutoReset) return false; 14928 if (!mSystemReady) return false; 14929 if (!mHistory.isResetEnabled()) return false; 14930 if (mBatteryStatsConfig.shouldResetOnUnplugHighBatteryLevel()) { 14931 // Allow resetting due to currently being at high battery level 14932 if (batteryStatus == BatteryManager.BATTERY_STATUS_FULL) return true; 14933 if (batteryLevel >= 90) return true; 14934 } 14935 if (mBatteryStatsConfig.shouldResetOnUnplugAfterSignificantCharge()) { 14936 // Allow resetting after a significant charge (from a very low level to a now very 14937 // high level). 14938 if (mDischargePlugLevel < 20 && batteryLevel >= 80) return true; 14939 } 14940 if (getHighDischargeAmountSinceCharge() >= 200) { 14941 // Reset the stats if battery got partially charged and discharged repeatedly without 14942 // ever reaching the full charge. 14943 // This reset is done in order to prevent stats sessions from going on forever. 14944 // Exceedingly long battery sessions would lead to an overflow of 14945 // data structures such as mWakeupReasonStats. 14946 return true; 14947 } 14948 14949 return false; 14950 } 14951 14952 @GuardedBy("this") 14953 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 14954 final boolean onBattery, final int oldStatus, final int level, final int chargeUah) { 14955 boolean doWrite = false; 14956 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 14957 m.arg1 = onBattery ? 1 : 0; 14958 mHandler.sendMessage(m); 14959 14960 final long uptimeUs = mSecUptime * 1000; 14961 final long realtimeUs = mSecRealtime * 1000; 14962 final int screenState = mScreenState; 14963 if (onBattery) { 14964 boolean reset = false; 14965 if (shouldResetOnUnplugLocked(oldStatus, level)) { 14966 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 14967 + " dischargeLevel=" + mDischargePlugLevel 14968 + " lowAmount=" + getLowDischargeAmountSinceCharge() 14969 + " highAmount=" + getHighDischargeAmountSinceCharge()); 14970 // Before we write, collect a snapshot of the final aggregated 14971 // stats to be reported in the next checkin. Only do this if we have 14972 // a sufficient amount of data to make it interesting. 14973 if (getLowDischargeAmountSinceCharge() >= 20) { 14974 final long startTimeMs = SystemClock.uptimeMillis(); 14975 final Parcel parcel = Parcel.obtain(); 14976 writeSummaryToParcel(parcel, true); 14977 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 14978 BackgroundThread.getHandler().post(new Runnable() { 14979 @Override public void run() { 14980 synchronized (mCheckinFile) { 14981 final long startTimeMs2 = SystemClock.uptimeMillis(); 14982 FileOutputStream stream = null; 14983 try { 14984 stream = mCheckinFile.startWrite(); 14985 stream.write(parcel.marshall()); 14986 stream.flush(); 14987 mCheckinFile.finishWrite(stream); 14988 mFrameworkStatsLogger.writeCommitSysConfigFile( 14989 "batterystats-checkin", 14990 initialTimeMs + SystemClock.uptimeMillis() 14991 - startTimeMs2); 14992 } catch (IOException e) { 14993 Slog.w("BatteryStats", 14994 "Error writing checkin battery statistics", e); 14995 mCheckinFile.failWrite(stream); 14996 } finally { 14997 parcel.recycle(); 14998 } 14999 } 15000 } 15001 }); 15002 } 15003 doWrite = true; 15004 startNewSession(RESET_REASON_FULL_CHARGE); 15005 if (chargeUah > 0 && level > 0) { 15006 // Only use the reported coulomb charge value if it is supported and reported. 15007 mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0)); 15008 } 15009 reset = true; 15010 mDischargeStepTracker.init(); 15011 } 15012 if (mCharging) { 15013 setChargingLocked(false); 15014 } 15015 mOnBattery = mOnBatteryInternal = true; 15016 mLastDischargeStepLevel = level; 15017 mMinDischargeStepLevel = level; 15018 mDischargeStepTracker.clearTime(); 15019 mDailyDischargeStepTracker.clearTime(); 15020 mInitStepMode = mCurStepMode; 15021 mModStepMode = 0; 15022 pullPendingStateUpdatesLocked(); 15023 if (reset) { 15024 mHistory.startRecordingHistory(mSecRealtime, mSecUptime, reset); 15025 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 15026 } 15027 mBatteryPluggedIn = false; 15028 if (mAlarmManager != null) { 15029 final AlarmManager am = mAlarmManager; 15030 mHandler.post(() -> { 15031 // No longer plugged in. Cancel the long plug in alarm. 15032 am.cancel(mLongPlugInAlarmHandler); 15033 }); 15034 } 15035 mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn); 15036 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 15037 if (Display.isOnState(screenState)) { 15038 mDischargeScreenOnUnplugLevel = level; 15039 mDischargeScreenDozeUnplugLevel = 0; 15040 mDischargeScreenOffUnplugLevel = 0; 15041 } else if (Display.isDozeState(screenState)) { 15042 mDischargeScreenOnUnplugLevel = 0; 15043 mDischargeScreenDozeUnplugLevel = level; 15044 mDischargeScreenOffUnplugLevel = 0; 15045 } else { 15046 mDischargeScreenOnUnplugLevel = 0; 15047 mDischargeScreenDozeUnplugLevel = 0; 15048 mDischargeScreenOffUnplugLevel = level; 15049 } 15050 mDischargeAmountScreenOn = 0; 15051 mDischargeAmountScreenDoze = 0; 15052 mDischargeAmountScreenOff = 0; 15053 updateTimeBasesLocked(true, screenState, uptimeUs, realtimeUs); 15054 } else { 15055 mOnBattery = mOnBatteryInternal = false; 15056 pullPendingStateUpdatesLocked(); 15057 mBatteryPluggedIn = true; 15058 mBatteryPluggedInRealTimeMs = mSecRealtime; 15059 mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn); 15060 mDischargeCurrentLevel = mDischargePlugLevel = level; 15061 if (level < mDischargeUnplugLevel) { 15062 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 15063 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 15064 } 15065 updateDischargeScreenLevelsLocked(screenState, screenState); 15066 updateTimeBasesLocked(false, screenState, uptimeUs, realtimeUs); 15067 mChargeStepTracker.init(); 15068 mLastChargeStepLevel = level; 15069 mMaxChargeStepLevel = level; 15070 mInitStepMode = mCurStepMode; 15071 mModStepMode = 0; 15072 scheduleNextResetWhilePluggedInCheck(); 15073 } 15074 if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) { 15075 if (mStatsFile != null && !mHistory.isReadOnly()) { 15076 writeAsyncLocked(); 15077 } 15078 } 15079 } 15080 15081 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 15082 if (mExternalSync != null) { 15083 mExternalSync.scheduleSync(reason, updateFlags); 15084 } 15085 } 15086 15087 // This should probably be exposed in the API, though it's not critical 15088 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 15089 15090 @GuardedBy("this") 15091 public void setBatteryStateLocked(final int status, final int health, final int plugType, 15092 final int level, final int temp, final int voltageMv, final int chargeUah, 15093 final int chargeFullUah, final long chargeTimeToFullSeconds, 15094 final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs) { 15095 15096 reportChangesToStatsLog(status, plugType, level); 15097 15098 boolean requestStepDetails = false; 15099 final boolean onBattery = isOnBattery(plugType, status); 15100 if (!mHaveBatteryLevel) { 15101 mHaveBatteryLevel = true; 15102 // We start out assuming that the device is plugged in (not 15103 // on battery). If our first report is now that we are indeed 15104 // plugged in, then twiddle our state to correctly reflect that 15105 // since we won't be going through the full setOnBattery(). 15106 if (onBattery == mOnBattery) { 15107 mHistory.setPluggedInState(!onBattery); 15108 } 15109 mBatteryStatus = status; 15110 mBatteryLevel = level; 15111 mBatteryChargeUah = chargeUah; 15112 15113 // Always start out assuming charging, that will be updated later. 15114 mHistory.setBatteryState(true /* charging */, status, level, chargeUah); 15115 15116 mMaxChargeStepLevel = mMinDischargeStepLevel = 15117 mLastChargeStepLevel = mLastDischargeStepLevel = level; 15118 requestStepDetails = true; 15119 } else if (mBatteryLevel != level || mOnBattery != onBattery) { 15120 recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs); 15121 } 15122 int oldStatus = mBatteryStatus; 15123 if (onBattery) { 15124 mDischargeCurrentLevel = level; 15125 if (!mHistory.isRecordingHistory()) { 15126 mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 15127 } 15128 } else if (level < 96 && 15129 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 15130 if (!mHistory.isRecordingHistory()) { 15131 mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 15132 } 15133 } 15134 if (mDischargePlugLevel < 0) { 15135 mDischargePlugLevel = level; 15136 } 15137 15138 if (onBattery != mOnBattery) { 15139 mBatteryLevel = level; 15140 mBatteryStatus = status; 15141 mBatteryHealth = health; 15142 mBatteryPlugType = plugType; 15143 mBatteryTemperature = temp; 15144 mBatteryVoltageMv = voltageMv; 15145 mHistory.setBatteryState(status, level, health, plugType, temp, voltageMv, chargeUah); 15146 if (chargeUah < mBatteryChargeUah) { 15147 // Only record discharges 15148 final long chargeDiff = (long) mBatteryChargeUah - chargeUah; 15149 mDischargeCounter.addCountLocked(chargeDiff); 15150 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 15151 if (Display.isDozeState(mScreenState)) { 15152 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 15153 } 15154 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 15155 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 15156 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 15157 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 15158 } 15159 } 15160 mBatteryChargeUah = chargeUah; 15161 setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUah); 15162 requestStepDetails = true; 15163 } else { 15164 boolean changed = false; 15165 if (mBatteryLevel != level) { 15166 mBatteryLevel = level; 15167 changed = true; 15168 requestStepDetails = true; 15169 } 15170 if (mBatteryStatus != status) { 15171 mBatteryStatus = status; 15172 changed = true; 15173 } 15174 if (mBatteryHealth != health) { 15175 mBatteryHealth = health; 15176 changed = true; 15177 } 15178 if (mBatteryPlugType != plugType) { 15179 mBatteryPlugType = plugType; 15180 changed = true; 15181 } 15182 if (temp >= (mBatteryTemperature + 10) 15183 || temp <= (mBatteryTemperature - 10)) { 15184 mBatteryTemperature = temp; 15185 changed = true; 15186 } 15187 if (voltageMv > (mBatteryVoltageMv + 20) 15188 || voltageMv < (mBatteryVoltageMv - 20)) { 15189 mBatteryVoltageMv = voltageMv; 15190 changed = true; 15191 } 15192 if (chargeUah >= (mBatteryChargeUah + 10) 15193 || chargeUah <= (mBatteryChargeUah - 10)) { 15194 if (chargeUah < mBatteryChargeUah) { 15195 // Only record discharges 15196 final long chargeDiff = (long) mBatteryChargeUah - chargeUah; 15197 mDischargeCounter.addCountLocked(chargeDiff); 15198 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 15199 if (Display.isDozeState(mScreenState)) { 15200 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 15201 } 15202 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 15203 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 15204 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 15205 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 15206 } 15207 } 15208 mBatteryChargeUah = chargeUah; 15209 changed = true; 15210 } 15211 15212 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 15213 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 15214 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 15215 if (onBattery) { 15216 changed |= setChargingLocked(false); 15217 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 15218 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 15219 modeBits, elapsedRealtimeMs); 15220 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 15221 modeBits, elapsedRealtimeMs); 15222 mLastDischargeStepLevel = level; 15223 mMinDischargeStepLevel = level; 15224 mInitStepMode = mCurStepMode; 15225 mModStepMode = 0; 15226 } 15227 } else { 15228 if (level >= mConstants.BATTERY_CHARGING_ENFORCE_LEVEL) { 15229 // If the battery level is at least Constants.BATTERY_CHARGING_ENFORCE_LEVEL, 15230 // always consider the device to be charging even if it happens to go down a 15231 // level. 15232 changed |= setChargingLocked(true); 15233 } else if (!mCharging) { 15234 if (mLastChargeStepLevel < level) { 15235 // We have not reported that we are charging, but the level has gone up, 15236 // but we would like to not have tons of activity from charging-constraint 15237 // jobs, so instead of reporting ACTION_CHARGING immediately, we defer it. 15238 if (!mHandler.hasCallbacks(mDeferSetCharging)) { 15239 mHandler.postDelayed( 15240 mDeferSetCharging, 15241 mConstants.BATTERY_CHARGED_DELAY_MS); 15242 } 15243 } else if (mLastChargeStepLevel > level) { 15244 // if we had deferred a runnable due to charge level increasing, but then 15245 // later the charge level drops (could be due to thermal issues), we don't 15246 // want to trigger the deferred runnable, so remove it here 15247 mHandler.removeCallbacks(mDeferSetCharging); 15248 } 15249 } else { 15250 if (mLastChargeStepLevel > level) { 15251 // We had reported that the device was charging, but here we are with 15252 // power connected and the level going down. Looks like the current 15253 // power supplied isn't enough, so consider the device to now be 15254 // discharging. 15255 changed |= setChargingLocked(false); 15256 } 15257 } 15258 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 15259 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 15260 modeBits, elapsedRealtimeMs); 15261 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 15262 modeBits, elapsedRealtimeMs); 15263 mMaxChargeStepLevel = level; 15264 mInitStepMode = mCurStepMode; 15265 mModStepMode = 0; 15266 } 15267 mLastChargeStepLevel = level; 15268 } 15269 if (changed) { 15270 mHistory.setBatteryState(mBatteryStatus, mBatteryLevel, mBatteryHealth, 15271 mBatteryPlugType, mBatteryTemperature, mBatteryVoltageMv, 15272 mBatteryChargeUah); 15273 mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs); 15274 } 15275 } 15276 mLastLearnedBatteryCapacityUah = chargeFullUah; 15277 if (mMinLearnedBatteryCapacityUah == -1) { 15278 mMinLearnedBatteryCapacityUah = chargeFullUah; 15279 } else { 15280 mMinLearnedBatteryCapacityUah = Math.min(mMinLearnedBatteryCapacityUah, chargeFullUah); 15281 } 15282 mMaxLearnedBatteryCapacityUah = Math.max(mMaxLearnedBatteryCapacityUah, chargeFullUah); 15283 15284 mBatteryTimeToFullSeconds = chargeTimeToFullSeconds; 15285 15286 if (mAccumulateBatteryUsageStats) { 15287 mBatteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(this, mHandler); 15288 } 15289 if (requestStepDetails) { 15290 mStepDetailsProvider.requestUpdate(); 15291 } 15292 } 15293 15294 public static boolean isOnBattery(int plugType, int status) { 15295 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 15296 } 15297 15298 // Inform StatsLog of setBatteryState changes. 15299 private void reportChangesToStatsLog(final int status, final int plugType, final int level) { 15300 if (!mHaveBatteryLevel || mBatteryStatus != status) { 15301 mFrameworkStatsLogger.chargingStateChanged(status); 15302 } 15303 if (!mHaveBatteryLevel || mBatteryPlugType != plugType) { 15304 mFrameworkStatsLogger.pluggedStateChanged(plugType); 15305 } 15306 if (!mHaveBatteryLevel || mBatteryLevel != level) { 15307 mFrameworkStatsLogger.batteryLevelChanged(level); 15308 } 15309 } 15310 15311 public long getAwakeTimeBattery() { 15312 // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); 15313 // for over a decade, but surely that was a mistake. 15314 return getBatteryUptimeLocked(mClock.uptimeMillis()); 15315 } 15316 15317 public long getAwakeTimePlugged() { 15318 return (mClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 15319 } 15320 15321 @Override 15322 public long computeUptime(long curTimeUs, int which) { 15323 return mUptimeUs + (curTimeUs - mUptimeStartUs); 15324 } 15325 15326 @Override 15327 public long computeRealtime(long curTimeUs, int which) { 15328 return mRealtimeUs + (curTimeUs - mRealtimeStartUs); 15329 } 15330 15331 @Override 15332 public long computeBatteryUptime(long curTimeUs, int which) { 15333 return mOnBatteryTimeBase.computeUptime(curTimeUs, which); 15334 } 15335 15336 @Override 15337 public long computeBatteryRealtime(long curTimeUs, int which) { 15338 return mOnBatteryTimeBase.computeRealtime(curTimeUs, which); 15339 } 15340 15341 @Override 15342 public long computeBatteryScreenOffUptime(long curTimeUs, int which) { 15343 return mOnBatteryScreenOffTimeBase.computeUptime(curTimeUs, which); 15344 } 15345 15346 @Override 15347 public long computeBatteryScreenOffRealtime(long curTimeUs, int which) { 15348 return mOnBatteryScreenOffTimeBase.computeRealtime(curTimeUs, which); 15349 } 15350 15351 @Override 15352 public long computeBatteryTimeRemaining(long curTime) { 15353 if (!mOnBattery) { 15354 return -1; 15355 } 15356 /* Simple implementation just looks at the average discharge per level across the 15357 entire sample period. 15358 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 15359 if (discharge < 2) { 15360 return -1; 15361 } 15362 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 15363 if (duration < 1000*1000) { 15364 return -1; 15365 } 15366 long usPerLevel = duration/discharge; 15367 return usPerLevel * mCurrentBatteryLevel; 15368 */ 15369 if (mDischargeStepTracker.mNumStepDurations < 1) { 15370 return -1; 15371 } 15372 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 15373 if (msPerLevel <= 0) { 15374 return -1; 15375 } 15376 return (msPerLevel * mBatteryLevel) * 1000; 15377 } 15378 15379 @Override 15380 public LevelStepTracker getDischargeLevelStepTracker() { 15381 return mDischargeStepTracker; 15382 } 15383 15384 @Override 15385 public LevelStepTracker getDailyDischargeLevelStepTracker() { 15386 return mDailyDischargeStepTracker; 15387 } 15388 15389 @Override 15390 public long computeChargeTimeRemaining(long curTime) { 15391 if (mOnBattery) { 15392 // Not yet working. 15393 return -1; 15394 } 15395 if (mBatteryTimeToFullSeconds >= 0) { 15396 return mBatteryTimeToFullSeconds * (1000 * 1000); // s to us 15397 } 15398 // Else use algorithmic approach 15399 if (mChargeStepTracker.mNumStepDurations < 1) { 15400 return -1; 15401 } 15402 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 15403 if (msPerLevel <= 0) { 15404 return -1; 15405 } 15406 return (msPerLevel * (100 - mBatteryLevel)) * 1000; 15407 } 15408 15409 /*@hide */ 15410 public CellularBatteryStats getCellularBatteryStats() { 15411 final int which = STATS_SINCE_CHARGED; 15412 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 15413 final ControllerActivityCounter counter = getModemControllerActivity(); 15414 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 15415 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 15416 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 15417 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 15418 final long monitoredRailChargeConsumedMaMs = 15419 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 15420 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 15421 for (int i = 0; i < timeInRatMs.length; i++) { 15422 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTimeUs, which) / 1000; 15423 } 15424 long[] timeInRxSignalStrengthLevelMs = 15425 new long[CELL_SIGNAL_STRENGTH_LEVEL_COUNT]; 15426 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { 15427 timeInRxSignalStrengthLevelMs[i] = 15428 getPhoneSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 15429 } 15430 long[] txTimeMs = new long[Math.min(MODEM_TX_POWER_LEVEL_COUNT, 15431 counter.getTxTimeCounters().length)]; 15432 long totalTxTimeMs = 0; 15433 for (int i = 0; i < txTimeMs.length; i++) { 15434 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which); 15435 totalTxTimeMs += txTimeMs[i]; 15436 } 15437 15438 return new CellularBatteryStats(computeBatteryRealtime(rawRealTimeUs, which) / 1000, 15439 getMobileRadioActiveTime(rawRealTimeUs, which) / 1000, 15440 getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which), 15441 getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which), 15442 getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which), 15443 getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which), 15444 sleepTimeMs, idleTimeMs, rxTimeMs, energyConsumedMaMs, timeInRatMs, 15445 timeInRxSignalStrengthLevelMs, txTimeMs, 15446 monitoredRailChargeConsumedMaMs); 15447 } 15448 15449 /*@hide */ 15450 public WifiBatteryStats getWifiBatteryStats() { 15451 final int which = STATS_SINCE_CHARGED; 15452 final long rawRealTimeUs = mClock.elapsedRealtime() * 1000; 15453 final ControllerActivityCounter counter = getWifiControllerActivity(); 15454 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 15455 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); 15456 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 15457 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); 15458 final long totalControllerActivityTimeMs = 15459 computeBatteryRealtime(mClock.elapsedRealtime() * 1000, which) / 1000; 15460 final long sleepTimeMs = Math.max(0, 15461 totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs)); 15462 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 15463 final long monitoredRailChargeConsumedMaMs = 15464 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 15465 long numAppScanRequest = 0; 15466 for (int i = 0; i < mUidStats.size(); i++) { 15467 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); 15468 } 15469 long[] timeInStateMs = new long[NUM_WIFI_STATES]; 15470 for (int i=0; i<NUM_WIFI_STATES; i++) { 15471 timeInStateMs[i] = getWifiStateTime(i, rawRealTimeUs, which) / 1000; 15472 } 15473 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; 15474 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15475 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTimeUs, which) / 1000; 15476 } 15477 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 15478 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15479 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 15480 } 15481 return new WifiBatteryStats( 15482 computeBatteryRealtime(rawRealTimeUs, which) / 1000, 15483 getWifiActiveTime(rawRealTimeUs, which) / 1000, 15484 getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which), 15485 getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which), 15486 getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which), 15487 getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which), 15488 sleepTimeMs, scanTimeMs, idleTimeMs, rxTimeMs, txTimeMs, energyConsumedMaMs, 15489 numAppScanRequest, timeInStateMs, timeSignalStrengthTimeMs, timeInSupplStateMs, 15490 monitoredRailChargeConsumedMaMs); 15491 } 15492 15493 /*@hide */ 15494 public GpsBatteryStats getGpsBatteryStats() { 15495 GpsBatteryStats s = new GpsBatteryStats(); 15496 final int which = STATS_SINCE_CHARGED; 15497 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 15498 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTimeUs, which) / 1000); 15499 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); 15500 long[] time = new long[mGpsSignalQualityTimer.length]; 15501 for (int i=0; i<time.length; i++) { 15502 time[i] = getGpsSignalQualityTime(i, rawRealTimeUs, which) / 1000; 15503 } 15504 s.setTimeInGpsSignalQualityLevel(time); 15505 return s; 15506 } 15507 15508 @Override 15509 public LevelStepTracker getChargeLevelStepTracker() { 15510 return mChargeStepTracker; 15511 } 15512 15513 @Override 15514 public LevelStepTracker getDailyChargeLevelStepTracker() { 15515 return mDailyChargeStepTracker; 15516 } 15517 15518 @Override 15519 public ArrayList<PackageChange> getDailyPackageChanges() { 15520 return mDailyPackageChanges; 15521 } 15522 15523 /** 15524 * @return battery uptime in microseconds 15525 */ 15526 protected long getBatteryUptimeLocked(long uptimeMs) { 15527 return mOnBatteryTimeBase.getUptime(uptimeMs * 1000); 15528 } 15529 15530 @Override 15531 public long getBatteryUptime(long curTimeUs) { 15532 return mOnBatteryTimeBase.getUptime(curTimeUs); 15533 } 15534 15535 @Override 15536 public long getBatteryRealtime(long curTimeUs) { 15537 return mOnBatteryTimeBase.getRealtime(curTimeUs); 15538 } 15539 15540 @Override 15541 public int getDischargeStartLevel() { 15542 synchronized(this) { 15543 return getDischargeStartLevelLocked(); 15544 } 15545 } 15546 15547 public int getDischargeStartLevelLocked() { 15548 return mDischargeUnplugLevel; 15549 } 15550 15551 @Override 15552 public int getDischargeCurrentLevel() { 15553 synchronized(this) { 15554 return getDischargeCurrentLevelLocked(); 15555 } 15556 } 15557 15558 public int getDischargeCurrentLevelLocked() { 15559 return mDischargeCurrentLevel; 15560 } 15561 15562 @Override 15563 public int getLowDischargeAmountSinceCharge() { 15564 synchronized(this) { 15565 int val = mLowDischargeAmountSinceCharge; 15566 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 15567 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 15568 } 15569 return val; 15570 } 15571 } 15572 15573 @Override 15574 public int getHighDischargeAmountSinceCharge() { 15575 synchronized(this) { 15576 int val = mHighDischargeAmountSinceCharge; 15577 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 15578 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 15579 } 15580 return val; 15581 } 15582 } 15583 15584 @Override 15585 public int getDischargeAmount(int which) { 15586 int dischargeAmount = which == STATS_SINCE_CHARGED 15587 ? getHighDischargeAmountSinceCharge() 15588 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 15589 if (dischargeAmount < 0) { 15590 dischargeAmount = 0; 15591 } 15592 return dischargeAmount; 15593 } 15594 15595 @Override 15596 public int getDischargeAmountScreenOn() { 15597 synchronized(this) { 15598 int val = mDischargeAmountScreenOn; 15599 if (mOnBattery && Display.isOnState(mScreenState) 15600 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 15601 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 15602 } 15603 return val; 15604 } 15605 } 15606 15607 @Override 15608 public int getDischargeAmountScreenOnSinceCharge() { 15609 synchronized(this) { 15610 int val = mDischargeAmountScreenOnSinceCharge; 15611 if (mOnBattery && Display.isOnState(mScreenState) 15612 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 15613 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 15614 } 15615 return val; 15616 } 15617 } 15618 15619 @Override 15620 public int getDischargeAmountScreenOff() { 15621 synchronized(this) { 15622 int val = mDischargeAmountScreenOff; 15623 if (mOnBattery && Display.isOffState(mScreenState) 15624 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 15625 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 15626 } 15627 // For backward compatibility, doze discharge is counted into screen off. 15628 return val + getDischargeAmountScreenDoze(); 15629 } 15630 } 15631 15632 @Override 15633 public int getDischargeAmountScreenOffSinceCharge() { 15634 synchronized(this) { 15635 int val = mDischargeAmountScreenOffSinceCharge; 15636 if (mOnBattery && Display.isOffState(mScreenState) 15637 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 15638 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 15639 } 15640 // For backward compatibility, doze discharge is counted into screen off. 15641 return val + getDischargeAmountScreenDozeSinceCharge(); 15642 } 15643 } 15644 15645 @Override 15646 public int getDischargeAmountScreenDoze() { 15647 synchronized(this) { 15648 int val = mDischargeAmountScreenDoze; 15649 if (mOnBattery && Display.isDozeState(mScreenState) 15650 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 15651 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 15652 } 15653 return val; 15654 } 15655 } 15656 15657 @Override 15658 public int getDischargeAmountScreenDozeSinceCharge() { 15659 synchronized(this) { 15660 int val = mDischargeAmountScreenDozeSinceCharge; 15661 if (mOnBattery && Display.isDozeState(mScreenState) 15662 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 15663 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 15664 } 15665 return val; 15666 } 15667 } 15668 15669 15670 /** 15671 * Estimates the time spent by the system server handling incoming binder requests. 15672 */ 15673 @Override 15674 public long[] getSystemServiceTimeAtCpuSpeeds() { 15675 if (mBinderThreadCpuTimesUs == null) { 15676 return null; 15677 } 15678 15679 return mBinderThreadCpuTimesUs.getCountsLocked(BatteryStats.STATS_SINCE_CHARGED); 15680 } 15681 15682 /** 15683 * Retrieve the statistics object for a particular uid, creating if needed. 15684 */ 15685 public Uid getUidStatsLocked(int uid) { 15686 return getUidStatsLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 15687 } 15688 15689 public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 15690 Uid u = mUidStats.get(uid); 15691 if (u == null) { 15692 if (Process.isSdkSandboxUid(uid)) { 15693 Log.wtf(TAG, "Tracking an SDK Sandbox UID"); 15694 } 15695 u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 15696 mUidStats.put(uid, u); 15697 } 15698 return u; 15699 } 15700 15701 /** 15702 * Retrieve the statistics object for a particular uid. Returns null if the object is not 15703 * available. 15704 */ 15705 public Uid getAvailableUidStatsLocked(int uid) { 15706 Uid u = mUidStats.get(uid); 15707 return u; 15708 } 15709 15710 @GuardedBy("this") 15711 public void onCleanupUserLocked(int userId, long elapsedRealtimeMs) { 15712 final int firstUidForUser = UserHandle.getUid(userId, 0); 15713 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 15714 mPendingRemovedUids.add( 15715 new UidToRemove(firstUidForUser, lastUidForUser, elapsedRealtimeMs)); 15716 } 15717 15718 @GuardedBy("this") 15719 public void onUserRemovedLocked(int userId) { 15720 if (mExternalSync != null) { 15721 // Clear out the removed user's UIDs after a short delay. The delay is needed 15722 // because at the point that this method is called, some activities are still 15723 // being wrapped up by those UIDs 15724 mExternalSync.scheduleCleanupDueToRemovedUser(userId); 15725 } 15726 } 15727 15728 /** 15729 * Removes battery stats for UIDs corresponding to a removed user. 15730 */ 15731 @GuardedBy("this") 15732 public void clearRemovedUserUidsLocked(int userId) { 15733 final int firstUidForUser = UserHandle.getUid(userId, 0); 15734 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 15735 mUidStats.put(firstUidForUser, null); 15736 mUidStats.put(lastUidForUser, null); 15737 final int firstIndex = mUidStats.indexOfKey(firstUidForUser); 15738 final int lastIndex = mUidStats.indexOfKey(lastUidForUser); 15739 for (int i = firstIndex; i <= lastIndex; i++) { 15740 final Uid uid = mUidStats.valueAt(i); 15741 if (uid != null) { 15742 uid.detachFromTimeBase(); 15743 } 15744 } 15745 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1); 15746 removeCpuStatsForUidRangeLocked(firstUidForUser, lastUidForUser); 15747 } 15748 15749 /** 15750 * @see #removeUidStatsLocked(int) 15751 */ 15752 @GuardedBy("this") 15753 public void removeUidStatsLocked(int uid, long elapsedRealtimeMs) { 15754 final Uid u = mUidStats.get(uid); 15755 if (u != null) { 15756 u.detachFromTimeBase(); 15757 } 15758 mUidStats.remove(uid); 15759 mPendingRemovedUids.add(new UidToRemove(uid, elapsedRealtimeMs)); 15760 } 15761 15762 /** 15763 * Removes the data for the deleted UIDs from the underlying kernel eBPF tables. 15764 */ 15765 @GuardedBy("this") 15766 private void removeCpuStatsForUidRangeLocked(int startUid, int endUid) { 15767 if (startUid == endUid) { 15768 mCpuUidUserSysTimeReader.removeUid(startUid); 15769 mCpuUidFreqTimeReader.removeUid(startUid); 15770 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 15771 mCpuUidActiveTimeReader.removeUid(startUid); 15772 mCpuUidClusterTimeReader.removeUid(startUid); 15773 } 15774 if (mKernelSingleUidTimeReader != null) { 15775 mKernelSingleUidTimeReader.removeUid(startUid); 15776 } 15777 mNumUidsRemoved++; 15778 } else if (startUid < endUid) { 15779 mCpuUidFreqTimeReader.removeUidsInRange(startUid, endUid); 15780 mCpuUidUserSysTimeReader.removeUidsInRange(startUid, endUid); 15781 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 15782 mCpuUidActiveTimeReader.removeUidsInRange(startUid, endUid); 15783 mCpuUidClusterTimeReader.removeUidsInRange(startUid, endUid); 15784 } 15785 if (mKernelSingleUidTimeReader != null) { 15786 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid); 15787 } 15788 mPowerStatsUidResolver.releaseUidsInRange(startUid, endUid); 15789 // Treat as one. We don't know how many uids there are in between. 15790 mNumUidsRemoved++; 15791 } else { 15792 Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid); 15793 } 15794 } 15795 15796 /** 15797 * Retrieve the statistics object for a particular process, creating 15798 * if needed. 15799 */ 15800 public Uid.Proc getProcessStatsLocked(int uid, String name, 15801 long elapsedRealtimeMs, long uptimeMs) { 15802 uid = mapUid(uid); 15803 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15804 return u.getProcessStatsLocked(name); 15805 } 15806 15807 /** 15808 * Retrieve the statistics object for a particular process, creating 15809 * if needed. 15810 */ 15811 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 15812 return getPackageStatsLocked(uid, pkg, mClock.elapsedRealtime(), mClock.uptimeMillis()); 15813 } 15814 15815 /** 15816 * @see getPackageStatsLocked(int, String) 15817 */ 15818 public Uid.Pkg getPackageStatsLocked(int uid, String pkg, 15819 long elapsedRealtimeMs, long uptimeMs) { 15820 uid = mapUid(uid); 15821 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15822 return u.getPackageStatsLocked(pkg); 15823 } 15824 15825 /** 15826 * Retrieve the statistics object for a particular service, creating 15827 * if needed. 15828 */ 15829 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name, 15830 long elapsedRealtimeMs, long uptimeMs) { 15831 uid = mapUid(uid); 15832 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15833 return u.getServiceStatsLocked(pkg, name); 15834 } 15835 15836 @GuardedBy("this") 15837 public void shutdownLocked() { 15838 mHistory.recordShutdownEvent(mClock.elapsedRealtime(), mClock.uptimeMillis(), 15839 mClock.currentTimeMillis()); 15840 writeSyncLocked(); 15841 mShuttingDown = true; 15842 } 15843 15844 @Override 15845 public boolean isProcessStateDataAvailable() { 15846 synchronized (this) { 15847 return trackPerProcStateCpuTimes(); 15848 } 15849 } 15850 15851 @GuardedBy("this") 15852 private boolean trackPerProcStateCpuTimes() { 15853 return mCpuUidFreqTimeReader.isFastCpuTimesReader(); 15854 } 15855 15856 /** 15857 * Enables or disables the PowerStatsCollector mode. 15858 */ 15859 public void setPowerStatsCollectorEnabled(@BatteryConsumer.PowerComponent int powerComponent, 15860 boolean enabled) { 15861 synchronized (this) { 15862 mPowerStatsCollectorEnabled.put(powerComponent, enabled); 15863 } 15864 } 15865 15866 /** 15867 * Controls where the logging of the WakelockStateChanged atom occurs: 15868 * true = Notifier, false = BatteryStatsImpl. 15869 */ 15870 public void setMoveWscLoggingToNotifierEnabled(boolean enabled) { 15871 synchronized (this) { 15872 mMoveWscLoggingToNotifierEnabled = enabled; 15873 } 15874 } 15875 @GuardedBy("this") 15876 public void systemServicesReady(Context context) { 15877 mConstants.startObserving(context.getContentResolver()); 15878 registerUsbStateReceiver(context); 15879 15880 synchronized (this) { 15881 mAlarmManager = context.getSystemService(AlarmManager.class); 15882 if (mBatteryPluggedIn) { 15883 // Already plugged in. Schedule the long plug in alarm. 15884 scheduleNextResetWhilePluggedInCheck(); 15885 } 15886 15887 if (mPowerManagerFlags.isFrameworkWakelockInfoEnabled()) { 15888 mFrameworkEvents.initialize(context); 15889 } 15890 } 15891 } 15892 15893 /** 15894 * Initialize the EnergyConsumer stats data structures. 15895 * 15896 * @param supportedStandardBuckets boolean array indicating which {@link StandardPowerBucket}s 15897 * are currently supported. If null, none are supported 15898 * (regardless of customBucketNames). 15899 * @param customBucketNames names of custom (OTHER) EnergyConsumers on this device 15900 */ 15901 @GuardedBy("this") 15902 public void initEnergyConsumerStatsLocked(@Nullable boolean[] supportedStandardBuckets, 15903 String[] customBucketNames) { 15904 final int numDisplays = mPerDisplayBatteryStats.length; 15905 for (int i = 0; i < numDisplays; i++) { 15906 final int screenState = mPerDisplayBatteryStats[i].screenState; 15907 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 15908 } 15909 15910 if (supportedStandardBuckets != null) { 15911 final EnergyConsumerStats.Config config = new EnergyConsumerStats.Config( 15912 supportedStandardBuckets, customBucketNames, 15913 SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS, 15914 getBatteryConsumerProcessStateNames()); 15915 15916 if (mEnergyConsumerStatsConfig != null 15917 && !mEnergyConsumerStatsConfig.isCompatible(config)) { 15918 // Supported power buckets changed since last boot. 15919 // Save accumulated battery usage stats before resetting 15920 saveBatteryUsageStatsOnReset(); 15921 // Existing data is no longer reliable. 15922 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 15923 RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE); 15924 } 15925 15926 mEnergyConsumerStatsConfig = config; 15927 mGlobalEnergyConsumerStats = new EnergyConsumerStats(config); 15928 15929 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_BLUETOOTH]) { 15930 mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile); 15931 } 15932 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO]) { 15933 mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile); 15934 } 15935 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_WIFI]) { 15936 mWifiPowerCalculator = new WifiPowerCalculator(mPowerProfile); 15937 } 15938 } else { 15939 if (mEnergyConsumerStatsConfig != null) { 15940 // EnergyConsumer no longer supported 15941 // Save accumulated battery usage stats before resetting 15942 saveBatteryUsageStatsOnReset(); 15943 // Wipe out the current battery session data. 15944 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 15945 RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE); 15946 } 15947 mEnergyConsumerStatsConfig = null; 15948 mGlobalEnergyConsumerStats = null; 15949 } 15950 } 15951 15952 @GuardedBy("this") 15953 private boolean isMobileRadioEnergyConsumerSupportedLocked() { 15954 if (mGlobalEnergyConsumerStats == null) return false; 15955 return mGlobalEnergyConsumerStats.isStandardBucketSupported( 15956 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 15957 } 15958 15959 @NonNull 15960 private static String[] getBatteryConsumerProcessStateNames() { 15961 String[] procStateNames = new String[BatteryConsumer.PROCESS_STATE_COUNT]; 15962 for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { 15963 procStateNames[procState] = BatteryConsumer.processStateToString(procState); 15964 } 15965 return procStateNames; 15966 } 15967 15968 /** Get the last known Battery voltage (in millivolts), returns -1 if unknown */ 15969 @GuardedBy("this") 15970 public int getBatteryVoltageMvLocked() { 15971 return mBatteryVoltageMv; 15972 } 15973 15974 @VisibleForTesting 15975 public final class Constants extends ContentObserver { 15976 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME 15977 = "track_cpu_active_cluster_time"; 15978 public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME 15979 = "kernel_uid_readers_throttle_time"; 15980 public static final String KEY_UID_REMOVE_DELAY_MS 15981 = "uid_remove_delay_ms"; 15982 public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 15983 = "external_stats_collection_rate_limit_ms"; 15984 public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS 15985 = "battery_level_collection_delay_ms"; 15986 public static final String KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 15987 "procstate_change_collection_delay_ms"; 15988 public static final String KEY_MAX_HISTORY_SIZE = "max_history_size"; 15989 public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb"; 15990 public static final String KEY_BATTERY_CHARGED_DELAY_MS = 15991 "battery_charged_delay_ms"; 15992 public static final String KEY_BATTERY_CHARGING_ENFORCE_LEVEL = 15993 "battery_charging_enforce_level"; 15994 public static final String KEY_PER_UID_MODEM_POWER_MODEL = 15995 "per_uid_modem_power_model"; 15996 public static final String KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION = 15997 "phone_on_external_stats_collection"; 15998 public static final String KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 15999 "reset_while_plugged_in_minimum_duration_hours"; 16000 16001 public static final String PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME = 16002 "mobile_radio_active_time"; 16003 public static final String PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME = 16004 "modem_activity_info_rx_tx"; 16005 16006 /** Convert {@link PerUidModemPowerModel} to string */ 16007 public String getPerUidModemModelName(@PerUidModemPowerModel int model) { 16008 switch(model) { 16009 case PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME: 16010 return PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME; 16011 case PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX: 16012 return PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME; 16013 default: 16014 Slog.w(TAG, "Unexpected per uid modem model (" + model + ")"); 16015 return "unknown_" + model; 16016 } 16017 } 16018 16019 /** Convert string to {@link PerUidModemPowerModel} */ 16020 @PerUidModemPowerModel 16021 public int getPerUidModemModel(String name) { 16022 switch(name) { 16023 case PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME: 16024 return PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME; 16025 case PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME: 16026 return PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX; 16027 default: 16028 Slog.w(TAG, "Unexpected per uid modem model name (" + name + ")"); 16029 return DEFAULT_PER_UID_MODEM_MODEL; 16030 } 16031 } 16032 16033 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; 16034 private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000; 16035 private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; 16036 private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; 16037 private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; 16038 private static final long DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 60_000; 16039 private static final int DEFAULT_MAX_HISTORY_BUFFER_KB = 128; /*Kilo Bytes*/ 16040 private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/ 16041 private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */ 16042 private static final int DEFAULT_BATTERY_CHARGING_ENFORCE_LEVEL = 90; 16043 @PerUidModemPowerModel 16044 private static final int DEFAULT_PER_UID_MODEM_MODEL = 16045 PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX; 16046 private static final boolean DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION = true; 16047 // Little less than 2 days 16048 private static final int DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 47; 16049 16050 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; 16051 /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an 16052 * update when startObserving. */ 16053 public long KERNEL_UID_READERS_THROTTLE_TIME; 16054 public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; 16055 public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 16056 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 16057 public long BATTERY_LEVEL_COLLECTION_DELAY_MS 16058 = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; 16059 public long PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 16060 DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS; 16061 public int MAX_HISTORY_SIZE; 16062 public int MAX_HISTORY_BUFFER; /*Bytes*/ 16063 public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS; 16064 public int BATTERY_CHARGING_ENFORCE_LEVEL = DEFAULT_BATTERY_CHARGING_ENFORCE_LEVEL; 16065 public int PER_UID_MODEM_MODEL = DEFAULT_PER_UID_MODEM_MODEL; 16066 public boolean PHONE_ON_EXTERNAL_STATS_COLLECTION = 16067 DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION; 16068 public int RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 16069 DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS; 16070 16071 private ContentResolver mResolver; 16072 private final KeyValueListParser mParser = new KeyValueListParser(','); 16073 16074 public Constants(Handler handler) { 16075 super(handler); 16076 if (isLowRamDevice()) { 16077 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB * 1024; 16078 } else { 16079 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_KB * 1024; 16080 } 16081 MAX_HISTORY_SIZE = mBatteryStatsConfig.getMaxHistorySizeBytes(); 16082 } 16083 16084 public void startObserving(ContentResolver resolver) { 16085 mResolver = resolver; 16086 mResolver.registerContentObserver( 16087 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS), 16088 false /* notifyForDescendants */, this); 16089 mResolver.registerContentObserver( 16090 Settings.Global.getUriFor(Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY), 16091 false /* notifyForDescendants */, this); 16092 mResolver.registerContentObserver(Settings.Global.getUriFor( 16093 Settings.Global.BATTERY_CHARGING_STATE_ENFORCE_LEVEL), 16094 false /* notifyForDescendants */, this); 16095 updateConstants(); 16096 } 16097 16098 @Override 16099 public void onChange(boolean selfChange, Uri uri) { 16100 if (uri.equals( 16101 Settings.Global.getUriFor( 16102 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY))) { 16103 synchronized (BatteryStatsImpl.this) { 16104 updateBatteryChargedDelayMsLocked(); 16105 } 16106 return; 16107 } else if (uri.equals(Settings.Global.getUriFor( 16108 Settings.Global.BATTERY_CHARGING_STATE_ENFORCE_LEVEL))) { 16109 synchronized (BatteryStatsImpl.this) { 16110 updateBatteryChargingEnforceLevelLocked(); 16111 } 16112 return; 16113 } 16114 updateConstants(); 16115 } 16116 16117 private void updateConstants() { 16118 synchronized (BatteryStatsImpl.this) { 16119 try { 16120 mParser.setString(Settings.Global.getString(mResolver, 16121 Settings.Global.BATTERY_STATS_CONSTANTS)); 16122 } catch (IllegalArgumentException e) { 16123 // Failed to parse the settings string, log this and move on 16124 // with defaults. 16125 Slog.e(TAG, "Bad batterystats settings", e); 16126 } 16127 16128 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( 16129 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); 16130 updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME, 16131 mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME, 16132 DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME)); 16133 updateUidRemoveDelay( 16134 mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS)); 16135 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( 16136 KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, 16137 DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 16138 BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( 16139 KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, 16140 DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); 16141 PROC_STATE_CHANGE_COLLECTION_DELAY_MS = mParser.getLong( 16142 KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS, 16143 DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 16144 MAX_HISTORY_BUFFER = mParser.getInt(KEY_MAX_HISTORY_BUFFER_KB, 16145 isLowRamDevice() ? DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB 16146 : DEFAULT_MAX_HISTORY_BUFFER_KB) 16147 * 1024; 16148 int maxHistorySize = mParser.getInt(KEY_MAX_HISTORY_SIZE, -1); 16149 if (maxHistorySize == -1) { 16150 // Process the deprecated max_history_files parameter for compatibility 16151 int maxHistoryFiles = mParser.getInt("max_history_files", -1); 16152 if (maxHistoryFiles != -1) { 16153 maxHistorySize = maxHistoryFiles * MAX_HISTORY_BUFFER; 16154 } 16155 } 16156 if (maxHistorySize == -1) { 16157 maxHistorySize = mBatteryStatsConfig.getMaxHistorySizeBytes(); 16158 } 16159 MAX_HISTORY_SIZE = maxHistorySize; 16160 16161 final String perUidModemModel = mParser.getString(KEY_PER_UID_MODEM_POWER_MODEL, 16162 ""); 16163 PER_UID_MODEM_MODEL = getPerUidModemModel(perUidModemModel); 16164 16165 PHONE_ON_EXTERNAL_STATS_COLLECTION = mParser.getBoolean( 16166 KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION, 16167 DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION); 16168 16169 RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = mParser.getInt( 16170 KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS, 16171 DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); 16172 16173 updateBatteryChargedDelayMsLocked(); 16174 updateBatteryChargingEnforceLevelLocked(); 16175 16176 onChange(); 16177 } 16178 } 16179 16180 /** 16181 * Propagates changes in constant values. 16182 */ 16183 @VisibleForTesting 16184 public void onChange() { 16185 if (mBatteryHistoryDirectory != null) { 16186 mBatteryHistoryDirectory.setMaxHistorySize(MAX_HISTORY_SIZE); 16187 } 16188 mHistory.setMaxHistoryBufferSize(MAX_HISTORY_BUFFER); 16189 } 16190 16191 private void updateBatteryChargedDelayMsLocked() { 16192 // a negative value indicates that we should ignore this override 16193 final int delay = Settings.Global.getInt(mResolver, 16194 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 16195 -1); 16196 16197 BATTERY_CHARGED_DELAY_MS = delay >= 0 ? delay : mParser.getInt( 16198 KEY_BATTERY_CHARGED_DELAY_MS, 16199 DEFAULT_BATTERY_CHARGED_DELAY_MS); 16200 16201 if (mHandler.hasCallbacks(mDeferSetCharging)) { 16202 mHandler.removeCallbacks(mDeferSetCharging); 16203 mHandler.postDelayed(mDeferSetCharging, BATTERY_CHARGED_DELAY_MS); 16204 } 16205 } 16206 16207 private void updateBatteryChargingEnforceLevelLocked() { 16208 int lastChargingEnforceLevel = BATTERY_CHARGING_ENFORCE_LEVEL; 16209 final int level = Settings.Global.getInt(mResolver, 16210 Settings.Global.BATTERY_CHARGING_STATE_ENFORCE_LEVEL, 16211 -1); 16212 16213 BATTERY_CHARGING_ENFORCE_LEVEL = level >= 0 ? level : mParser.getInt( 16214 KEY_BATTERY_CHARGING_ENFORCE_LEVEL, DEFAULT_BATTERY_CHARGING_ENFORCE_LEVEL); 16215 16216 if (BATTERY_CHARGING_ENFORCE_LEVEL <= mLastChargeStepLevel 16217 && mLastChargeStepLevel < lastChargingEnforceLevel) { 16218 setChargingLocked(true); 16219 } 16220 } 16221 16222 private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) { 16223 KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs; 16224 if (oldTimeMs != newTimeMs) { 16225 mCpuUidUserSysTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16226 mCpuUidFreqTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16227 mCpuUidActiveTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16228 mCpuUidClusterTimeReader 16229 .setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16230 } 16231 } 16232 16233 @GuardedBy("BatteryStatsImpl.this") 16234 private void updateUidRemoveDelay(long newTimeMs) { 16235 UID_REMOVE_DELAY_MS = newTimeMs; 16236 clearPendingRemovedUidsLocked(); 16237 } 16238 16239 public void dumpLocked(PrintWriter pw) { 16240 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); 16241 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); 16242 pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("="); 16243 pw.println(KERNEL_UID_READERS_THROTTLE_TIME); 16244 pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); 16245 pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 16246 pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); 16247 pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); 16248 pw.print(KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS); pw.print("="); 16249 pw.println(PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 16250 pw.print(KEY_MAX_HISTORY_SIZE); pw.print("="); 16251 pw.println(MAX_HISTORY_SIZE); 16252 pw.print(KEY_MAX_HISTORY_BUFFER_KB); pw.print("="); 16253 pw.println(MAX_HISTORY_BUFFER/1024); 16254 pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("="); 16255 pw.println(BATTERY_CHARGED_DELAY_MS); 16256 pw.print(KEY_BATTERY_CHARGING_ENFORCE_LEVEL); pw.print("="); 16257 pw.println(BATTERY_CHARGING_ENFORCE_LEVEL); 16258 pw.print(KEY_PER_UID_MODEM_POWER_MODEL); pw.print("="); 16259 pw.println(getPerUidModemModelName(PER_UID_MODEM_MODEL)); 16260 pw.print(KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION); pw.print("="); 16261 pw.println(PHONE_ON_EXTERNAL_STATS_COLLECTION); 16262 pw.print(KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); pw.print("="); 16263 pw.println(RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); 16264 } 16265 } 16266 16267 public long getExternalStatsCollectionRateLimitMs() { 16268 synchronized (this) { 16269 return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 16270 } 16271 } 16272 16273 @GuardedBy("this") 16274 public void dumpConstantsLocked(PrintWriter pw) { 16275 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16276 iPw.println("BatteryStats constants:"); 16277 iPw.increaseIndent(); 16278 mConstants.dumpLocked(iPw); 16279 iPw.decreaseIndent(); 16280 } 16281 16282 @GuardedBy("this") 16283 public void dumpCpuStatsLocked(PrintWriter pw) { 16284 int size = mUidStats.size(); 16285 pw.println("Per UID CPU user & system time in ms:"); 16286 for (int i = 0; i < size; i++) { 16287 int u = mUidStats.keyAt(i); 16288 Uid uid = mUidStats.get(u); 16289 pw.print(" "); pw.print(u); pw.print(": "); 16290 pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" "); 16291 pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000); 16292 } 16293 16294 pw.println("Per UID CPU active time in ms:"); 16295 for (int i = 0; i < size; i++) { 16296 int u = mUidStats.keyAt(i); 16297 Uid uid = mUidStats.get(u); 16298 if (uid.getCpuActiveTime() > 0) { 16299 pw.print(" "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime()); 16300 } 16301 } 16302 pw.println("Per UID CPU cluster time in ms:"); 16303 for (int i = 0; i < size; i++) { 16304 int u = mUidStats.keyAt(i); 16305 long[] times = mUidStats.get(u).getCpuClusterTimes(); 16306 if (times != null) { 16307 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 16308 } 16309 } 16310 pw.println("Per UID CPU frequency time in ms:"); 16311 for (int i = 0; i < size; i++) { 16312 int u = mUidStats.keyAt(i); 16313 long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED); 16314 if (times != null) { 16315 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 16316 } 16317 } 16318 16319 if (!Flags.disableSystemServicePowerAttr()) { 16320 updateSystemServiceCallStats(); 16321 if (mBinderThreadCpuTimesUs != null) { 16322 pw.println("Per UID System server binder time in ms:"); 16323 long[] systemServiceTimeAtCpuSpeeds = getSystemServiceTimeAtCpuSpeeds(); 16324 for (int i = 0; i < size; i++) { 16325 int u = mUidStats.keyAt(i); 16326 Uid uid = mUidStats.get(u); 16327 double proportionalSystemServiceUsage = uid.getProportionalSystemServiceUsage(); 16328 long timeUs = 0; 16329 for (int j = systemServiceTimeAtCpuSpeeds.length - 1; j >= 0; j--) { 16330 timeUs += systemServiceTimeAtCpuSpeeds[j] * proportionalSystemServiceUsage; 16331 } 16332 16333 pw.print(" "); 16334 pw.print(u); 16335 pw.print(": "); 16336 pw.println(timeUs / 1000); 16337 } 16338 } 16339 } 16340 } 16341 16342 /** 16343 * Dump EnergyConsumer stats 16344 */ 16345 @GuardedBy("this") 16346 public void dumpEnergyConsumerStatsLocked(PrintWriter pw) { 16347 pw.printf("On-battery energy consumer stats (microcoulombs) \n"); 16348 if (mGlobalEnergyConsumerStats == null) { 16349 pw.printf(" Not supported on this device.\n"); 16350 return; 16351 } 16352 16353 dumpEnergyConsumerStatsLocked(pw, "global usage", mGlobalEnergyConsumerStats); 16354 16355 int size = mUidStats.size(); 16356 for (int i = 0; i < size; i++) { 16357 final int u = mUidStats.keyAt(i); 16358 final Uid uid = mUidStats.get(u); 16359 final String name = "uid " + uid.mUid; 16360 dumpEnergyConsumerStatsLocked(pw, name, uid.mUidEnergyConsumerStats); 16361 } 16362 } 16363 16364 /** Dump EnergyConsumer stats for the given uid */ 16365 @GuardedBy("this") 16366 private void dumpEnergyConsumerStatsLocked(PrintWriter pw, String name, 16367 EnergyConsumerStats stats) { 16368 if (stats == null) return; 16369 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16370 iPw.increaseIndent(); 16371 iPw.printf("%s:\n", name); 16372 iPw.increaseIndent(); 16373 stats.dump(iPw); 16374 iPw.decreaseIndent(); 16375 } 16376 16377 /** 16378 * Dump Power Profile 16379 */ 16380 @GuardedBy("this") 16381 public void dumpPowerProfileLocked(PrintWriter pw) { 16382 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16383 iPw.printf("Power Profile: \n"); 16384 iPw.increaseIndent(); 16385 mPowerProfile.dump(iPw); 16386 iPw.decreaseIndent(); 16387 } 16388 16389 /** 16390 * Schedules an immediate (but asynchronous) collection of PowerStats samples. 16391 * Callers will need to wait for the collection to complete on the handler thread. 16392 */ 16393 public void schedulePowerStatsSampleCollection() { 16394 if (!mSystemReady) { 16395 return; 16396 } 16397 16398 mCpuPowerStatsCollector.forceSchedule(); 16399 mWakelockPowerStatsCollector.forceSchedule(); 16400 mScreenPowerStatsCollector.forceSchedule(); 16401 mMobileRadioPowerStatsCollector.forceSchedule(); 16402 mWifiPowerStatsCollector.forceSchedule(); 16403 mBluetoothPowerStatsCollector.forceSchedule(); 16404 mCameraPowerStatsCollector.forceSchedule(); 16405 mGnssPowerStatsCollector.forceSchedule(); 16406 mCustomEnergyConsumerPowerStatsCollector.forceSchedule(); 16407 } 16408 16409 /** 16410 * Schedules an immediate collection of PowerStats samples and awaits the result. 16411 */ 16412 public void collectPowerStatsSamples() { 16413 schedulePowerStatsSampleCollection(); 16414 ConditionVariable done = new ConditionVariable(); 16415 mHandler.post(done::open); 16416 done.block(); 16417 } 16418 16419 /** 16420 * Grabs one sample of PowerStats and prints it. 16421 */ 16422 public void dumpStatsSample(PrintWriter pw) { 16423 mCpuPowerStatsCollector.collectAndDump(pw); 16424 mWakelockPowerStatsCollector.collectAndDump(pw); 16425 mScreenPowerStatsCollector.collectAndDump(pw); 16426 mMobileRadioPowerStatsCollector.collectAndDump(pw); 16427 mWifiPowerStatsCollector.collectAndDump(pw); 16428 mBluetoothPowerStatsCollector.collectAndDump(pw); 16429 mCameraPowerStatsCollector.collectAndDump(pw); 16430 mGnssPowerStatsCollector.collectAndDump(pw); 16431 mCustomEnergyConsumerPowerStatsCollector.collectAndDump(pw); 16432 } 16433 16434 private final Runnable mWriteAsyncRunnable = () -> { 16435 synchronized (BatteryStatsImpl.this) { 16436 writeSyncLocked(); 16437 } 16438 }; 16439 16440 @GuardedBy("this") 16441 public void writeAsyncLocked() { 16442 BackgroundThread.getHandler().removeCallbacks(mWriteAsyncRunnable); 16443 BackgroundThread.getHandler().post(mWriteAsyncRunnable); 16444 } 16445 16446 @GuardedBy("this") 16447 public void writeSyncLocked() { 16448 BackgroundThread.getHandler().removeCallbacks(mWriteAsyncRunnable); 16449 writeStatsLocked(); 16450 writeHistoryLocked(); 16451 } 16452 16453 @GuardedBy("this") 16454 private void writeStatsLocked() { 16455 if (mStatsFile == null) { 16456 Slog.w(TAG, 16457 "writeStatsLocked: no file associated with this instance"); 16458 return; 16459 } 16460 16461 if (mShuttingDown) { 16462 return; 16463 } 16464 16465 final Parcel p = Parcel.obtain(); 16466 try { 16467 final long start = SystemClock.uptimeMillis(); 16468 writeSummaryToParcel(p, false/*history is in separate file*/); 16469 if (DEBUG) { 16470 Slog.d(TAG, "writeSummaryToParcel duration ms:" 16471 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 16472 } 16473 mLastWriteTimeMs = mClock.elapsedRealtime(); 16474 writeParcelToFileLocked(p, mStatsFile); 16475 } finally { 16476 p.recycle(); 16477 } 16478 } 16479 16480 private void writeHistoryLocked() { 16481 if (mShuttingDown) { 16482 return; 16483 } 16484 16485 mHistory.writeHistory(); 16486 } 16487 16488 private final ReentrantLock mWriteLock = new ReentrantLock(); 16489 private void writeParcelToFileLocked(Parcel p, AtomicFile file) { 16490 mWriteLock.lock(); 16491 FileOutputStream fos = null; 16492 try { 16493 final long startTimeMs = SystemClock.uptimeMillis(); 16494 fos = file.startWrite(); 16495 fos.write(p.marshall()); 16496 fos.flush(); 16497 file.finishWrite(fos); 16498 if (DEBUG) { 16499 Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath() 16500 + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs) 16501 + " bytes:" + p.dataSize()); 16502 } 16503 mFrameworkStatsLogger.writeCommitSysConfigFile( 16504 "batterystats", SystemClock.uptimeMillis() - startTimeMs); 16505 } catch (IOException e) { 16506 Slog.w(TAG, "Error writing battery statistics", e); 16507 file.failWrite(fos); 16508 } finally { 16509 mWriteLock.unlock(); 16510 } 16511 } 16512 16513 @GuardedBy("this") 16514 public void readLocked() { 16515 if (mDailyFile != null) { 16516 readDailyStatsLocked(); 16517 } 16518 16519 if (mStatsFile == null) { 16520 Slog.w(TAG, "readLocked: no file associated with this instance"); 16521 return; 16522 } 16523 16524 mUidStats.clear(); 16525 16526 Parcel stats = Parcel.obtain(); 16527 try { 16528 final long start = SystemClock.uptimeMillis(); 16529 if (mStatsFile.exists()) { 16530 byte[] raw = mStatsFile.readFully(); 16531 stats.unmarshall(raw, 0, raw.length); 16532 stats.setDataPosition(0); 16533 readSummaryFromParcel(stats); 16534 if (DEBUG) { 16535 Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath() 16536 + " bytes:" + raw.length + " took ms:" + (SystemClock.uptimeMillis() 16537 - start)); 16538 } 16539 } 16540 } catch (Exception e) { 16541 Slog.e(TAG, "Error reading battery statistics", e); 16542 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 16543 RESET_REASON_CORRUPT_FILE); 16544 } finally { 16545 stats.recycle(); 16546 } 16547 16548 if (!mHistory.readSummary()) { 16549 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 16550 RESET_REASON_CORRUPT_FILE); 16551 } 16552 16553 mEndPlatformVersion = Build.ID; 16554 16555 mMonotonicEndTime = MonotonicClock.UNDEFINED; 16556 mHistory.continueRecordingHistory(); 16557 16558 recordDailyStatsIfNeededLocked(false, mClock.currentTimeMillis()); 16559 } 16560 16561 @GuardedBy("this") 16562 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 16563 final int version = in.readInt(); 16564 16565 if (version != VERSION) { 16566 Slog.w("BatteryStats", "readFromParcel: version got " + version 16567 + ", expected " + VERSION + "; erasing old stats"); 16568 return; 16569 } 16570 16571 mHistory.readSummaryFromParcel(in); 16572 16573 mStartCount = in.readInt(); 16574 mUptimeUs = in.readLong(); 16575 mRealtimeUs = in.readLong(); 16576 mStartClockTimeMs = in.readLong(); 16577 mMonotonicStartTime = in.readLong(); 16578 mMonotonicEndTime = in.readLong(); 16579 mStartPlatformVersion = in.readString(); 16580 mEndPlatformVersion = in.readString(); 16581 mOnBatteryTimeBase.readSummaryFromParcel(in); 16582 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 16583 mDischargeUnplugLevel = in.readInt(); 16584 mDischargePlugLevel = in.readInt(); 16585 mDischargeCurrentLevel = in.readInt(); 16586 mBatteryLevel = in.readInt(); 16587 mEstimatedBatteryCapacityMah = in.readInt(); 16588 mLastLearnedBatteryCapacityUah = in.readInt(); 16589 mMinLearnedBatteryCapacityUah = in.readInt(); 16590 mMaxLearnedBatteryCapacityUah = in.readInt(); 16591 mLowDischargeAmountSinceCharge = in.readInt(); 16592 mHighDischargeAmountSinceCharge = in.readInt(); 16593 mDischargeAmountScreenOnSinceCharge = in.readInt(); 16594 mDischargeAmountScreenOffSinceCharge = in.readInt(); 16595 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 16596 mDischargeStepTracker.readFromParcel(in); 16597 mChargeStepTracker.readFromParcel(in); 16598 mDailyDischargeStepTracker.readFromParcel(in); 16599 mDailyChargeStepTracker.readFromParcel(in); 16600 mDischargeCounter.readSummaryFromParcelLocked(in); 16601 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 16602 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in); 16603 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in); 16604 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in); 16605 int NPKG = in.readInt(); 16606 if (NPKG > 0) { 16607 mDailyPackageChanges = new ArrayList<>(NPKG); 16608 while (NPKG > 0) { 16609 NPKG--; 16610 PackageChange pc = new PackageChange(); 16611 pc.mPackageName = in.readString(); 16612 pc.mUpdate = in.readInt() != 0; 16613 pc.mVersionCode = in.readLong(); 16614 mDailyPackageChanges.add(pc); 16615 } 16616 } else { 16617 mDailyPackageChanges = null; 16618 } 16619 mDailyStartTimeMs = in.readLong(); 16620 mNextMinDailyDeadlineMs = in.readLong(); 16621 mNextMaxDailyDeadlineMs = in.readLong(); 16622 mBatteryTimeToFullSeconds = in.readLong(); 16623 16624 final EnergyConsumerStats.Config config = EnergyConsumerStats.Config.createFromParcel(in); 16625 final EnergyConsumerStats energyConsumerStats = 16626 EnergyConsumerStats.createAndReadSummaryFromParcel(mEnergyConsumerStatsConfig, in); 16627 if (config != null && Arrays.equals(config.getStateNames(), 16628 getBatteryConsumerProcessStateNames())) { 16629 /** 16630 * WARNING: Supported buckets may have changed across boots. Bucket mismatch is handled 16631 * later when {@link #initEnergyConsumerStatsLocked} is called. 16632 */ 16633 mEnergyConsumerStatsConfig = config; 16634 mGlobalEnergyConsumerStats = energyConsumerStats; 16635 } 16636 16637 mStartCount++; 16638 16639 mScreenState = Display.STATE_UNKNOWN; 16640 mScreenOnTimer.readSummaryFromParcelLocked(in); 16641 mScreenDozeTimer.readSummaryFromParcelLocked(in); 16642 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16643 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 16644 } 16645 final int numDisplays = in.readInt(); 16646 for (int i = 0; i < numDisplays; i++) { 16647 mPerDisplayBatteryStats[i].readSummaryFromParcel(in); 16648 } 16649 mInteractive = false; 16650 mInteractiveTimer.readSummaryFromParcelLocked(in); 16651 mPhoneOn = false; 16652 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 16653 mLongestLightIdleTimeMs = in.readLong(); 16654 mLongestFullIdleTimeMs = in.readLong(); 16655 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 16656 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 16657 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 16658 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 16659 mPhoneOnTimer.readSummaryFromParcelLocked(in); 16660 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 16661 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 16662 } 16663 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 16664 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 16665 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 16666 } 16667 mNrNsaTimer.readSummaryFromParcelLocked(in); 16668 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16669 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 16670 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 16671 } 16672 16673 final int numRat = in.readInt(); 16674 for (int i = 0; i < numRat; i++) { 16675 if (in.readInt() == 0) continue; 16676 getRatBatteryStatsLocked(i).readSummaryFromParcel(in); 16677 } 16678 16679 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 16680 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 16681 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 16682 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 16683 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 16684 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 16685 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in); 16686 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 16687 mWifiOn = false; 16688 mWifiOnTimer.readSummaryFromParcelLocked(in); 16689 mGlobalWifiRunning = false; 16690 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 16691 for (int i=0; i<NUM_WIFI_STATES; i++) { 16692 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 16693 } 16694 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 16695 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 16696 } 16697 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16698 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 16699 } 16700 mWifiActiveTimer.readSummaryFromParcelLocked(in); 16701 mWifiActivity.readSummaryFromParcel(in); 16702 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 16703 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); 16704 } 16705 mBluetoothActivity.readSummaryFromParcel(in); 16706 mModemActivity.readSummaryFromParcel(in); 16707 mHasWifiReporting = in.readInt() != 0; 16708 mHasBluetoothReporting = in.readInt() != 0; 16709 mHasModemReporting = in.readInt() != 0; 16710 16711 mNumConnectivityChange = in.readInt(); 16712 mFlashlightOnNesting = 0; 16713 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 16714 mCameraOnNesting = 0; 16715 mCameraOnTimer.readSummaryFromParcelLocked(in); 16716 mBluetoothScanNesting = 0; 16717 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 16718 16719 int NRPMS = in.readInt(); 16720 if (NRPMS > 10000) { 16721 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 16722 } 16723 for (int irpm = 0; irpm < NRPMS; irpm++) { 16724 if (in.readInt() != 0) { 16725 String rpmName = in.readString(); 16726 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 16727 } 16728 } 16729 int NSORPMS = in.readInt(); 16730 if (NSORPMS > 10000) { 16731 throw new ParcelFormatException( 16732 "File corrupt: too many screen-off rpm stats " + NSORPMS); 16733 } 16734 for (int irpm = 0; irpm < NSORPMS; irpm++) { 16735 if (in.readInt() != 0) { 16736 String rpmName = in.readString(); 16737 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 16738 } 16739 } 16740 int NKW = in.readInt(); 16741 if (NKW > 10000) { 16742 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 16743 } 16744 for (int ikw = 0; ikw < NKW; ikw++) { 16745 if (in.readInt() != 0) { 16746 String kwltName = in.readString(); 16747 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 16748 } 16749 } 16750 16751 int NWR = in.readInt(); 16752 if (NWR > 10000) { 16753 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 16754 } 16755 for (int iwr = 0; iwr < NWR; iwr++) { 16756 if (in.readInt() != 0) { 16757 String reasonName = in.readString(); 16758 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 16759 } 16760 } 16761 16762 int NMS = in.readInt(); 16763 for (int ims = 0; ims < NMS; ims++) { 16764 if (in.readInt() != 0) { 16765 long kmstName = in.readLong(); 16766 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 16767 } 16768 } 16769 16770 final int NU = in.readInt(); 16771 if (NU > 10000) { 16772 throw new ParcelFormatException("File corrupt: too many uids " + NU); 16773 } 16774 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 16775 final long uptimeMs = mClock.uptimeMillis(); 16776 for (int iu = 0; iu < NU; iu++) { 16777 int uid = in.readInt(); 16778 Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 16779 mUidStats.put(uid, u); 16780 16781 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 16782 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 16783 16784 u.mWifiRunning = false; 16785 if (in.readInt() != 0) { 16786 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 16787 } 16788 u.mFullWifiLockOut = false; 16789 if (in.readInt() != 0) { 16790 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 16791 } 16792 u.mWifiScanStarted = false; 16793 if (in.readInt() != 0) { 16794 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 16795 } 16796 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 16797 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 16798 if (in.readInt() != 0) { 16799 u.makeWifiBatchedScanBin(i, null); 16800 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 16801 } 16802 } 16803 u.mWifiMulticastWakelockCount = 0; 16804 if (in.readInt() != 0) { 16805 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 16806 } 16807 if (in.readInt() != 0) { 16808 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16809 } 16810 if (in.readInt() != 0) { 16811 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16812 } 16813 if (in.readInt() != 0) { 16814 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16815 } 16816 if (in.readInt() != 0) { 16817 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16818 } 16819 if (in.readInt() != 0) { 16820 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 16821 } 16822 if (in.readInt() != 0) { 16823 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 16824 } 16825 if (in.readInt() != 0) { 16826 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 16827 } 16828 if (in.readInt() != 0) { 16829 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 16830 } 16831 if (in.readInt() != 0) { 16832 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 16833 } 16834 if (in.readInt() != 0) { 16835 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 16836 } 16837 if (in.readInt() != 0) { 16838 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 16839 } 16840 u.mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 16841 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 16842 if (in.readInt() != 0) { 16843 u.makeProcessState(i, null); 16844 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 16845 } 16846 } 16847 if (in.readInt() != 0) { 16848 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 16849 } 16850 16851 if (in.readInt() != 0) { 16852 if (u.mUserActivityCounters == null) { 16853 u.initUserActivityLocked(); 16854 } 16855 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 16856 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 16857 } 16858 } 16859 16860 if (in.readInt() != 0) { 16861 u.ensureNetworkActivityLocked(); 16862 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16863 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 16864 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 16865 } 16866 if (in.readBoolean()) { 16867 u.mMobileRadioActiveTime = TimeMultiStateCounter.readFromParcel(in, 16868 mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 16869 elapsedRealtimeMs); 16870 } 16871 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 16872 } 16873 16874 u.mUserCpuTime.readSummaryFromParcelLocked(in); 16875 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 16876 16877 if (in.readInt() != 0) { 16878 final int numClusters = in.readInt(); 16879 int[] policies = 16880 mCpuScalingPolicies != null ? mCpuScalingPolicies.getPolicies() : null; 16881 if (policies != null && policies.length != numClusters) { 16882 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 16883 } 16884 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 16885 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 16886 for (int cluster = 0; cluster < numClusters; cluster++) { 16887 if (in.readInt() != 0) { 16888 final int NSB = in.readInt(); 16889 if (policies != null 16890 && mCpuScalingPolicies.getFrequencies(policies[cluster]).length 16891 != NSB) { 16892 throw new ParcelFormatException("File corrupt: too many speed bins " + 16893 NSB); 16894 } 16895 16896 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 16897 for (int speed = 0; speed < NSB; speed++) { 16898 if (in.readInt() != 0) { 16899 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 16900 mOnBatteryTimeBase); 16901 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 16902 } 16903 } 16904 } else { 16905 u.mCpuClusterSpeedTimesUs[cluster] = null; 16906 } 16907 } 16908 } else { 16909 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 16910 u.mCpuClusterSpeedTimesUs = null; 16911 } 16912 16913 detachIfNotNull(u.mCpuFreqTimeMs); 16914 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 16915 in, mOnBatteryTimeBase); 16916 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 16917 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 16918 in, mOnBatteryScreenOffTimeBase); 16919 16920 int stateCount = in.readInt(); 16921 if (stateCount != 0) { 16922 u.mCpuActiveTimeMs = TimeMultiStateCounter.readFromParcel(in, 16923 mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 16924 mClock.elapsedRealtime()); 16925 } 16926 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 16927 16928 detachIfNotNull(u.mProcStateTimeMs); 16929 u.mProcStateTimeMs = null; 16930 16931 stateCount = in.readInt(); 16932 if (stateCount != 0) { 16933 detachIfNotNull(u.mProcStateTimeMs); 16934 u.mProcStateTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 16935 mOnBatteryTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 16936 mCpuScalingPolicies.getScalingStepCount(), mClock.elapsedRealtime()); 16937 } 16938 16939 detachIfNotNull(u.mProcStateScreenOffTimeMs); 16940 u.mProcStateScreenOffTimeMs = null; 16941 16942 stateCount = in.readInt(); 16943 if (stateCount != 0) { 16944 detachIfNotNull(u.mProcStateScreenOffTimeMs); 16945 u.mProcStateScreenOffTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 16946 mOnBatteryScreenOffTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 16947 mCpuScalingPolicies.getScalingStepCount(), mClock.elapsedRealtime()); 16948 } 16949 16950 if (in.readInt() != 0) { 16951 detachIfNotNull(u.mMobileRadioApWakeupCount); 16952 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 16953 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 16954 } else { 16955 detachIfNotNull(u.mMobileRadioApWakeupCount); 16956 u.mMobileRadioApWakeupCount = null; 16957 } 16958 16959 if (in.readInt() != 0) { 16960 detachIfNotNull(u.mWifiRadioApWakeupCount); 16961 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 16962 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 16963 } else { 16964 detachIfNotNull(u.mWifiRadioApWakeupCount); 16965 u.mWifiRadioApWakeupCount = null; 16966 } 16967 16968 u.mUidEnergyConsumerStats = EnergyConsumerStats.createAndReadSummaryFromParcel( 16969 mEnergyConsumerStatsConfig, in); 16970 16971 int NW = in.readInt(); 16972 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 16973 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 16974 } 16975 for (int iw = 0; iw < NW; iw++) { 16976 String wlName = in.readString(); 16977 u.readWakeSummaryFromParcelLocked(wlName, in); 16978 } 16979 16980 int NS = in.readInt(); 16981 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 16982 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 16983 } 16984 for (int is = 0; is < NS; is++) { 16985 String name = in.readString(); 16986 u.readSyncSummaryFromParcelLocked(name, in); 16987 } 16988 16989 int NJ = in.readInt(); 16990 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 16991 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 16992 } 16993 for (int ij = 0; ij < NJ; ij++) { 16994 String name = in.readString(); 16995 u.readJobSummaryFromParcelLocked(name, in); 16996 } 16997 16998 u.readJobCompletionsFromParcelLocked(in); 16999 17000 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 17001 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 17002 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 17003 detachIfNotNull(u.mJobsFreshnessBuckets); 17004 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 17005 if (in.readInt() != 0) { 17006 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 17007 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 17008 } 17009 } 17010 17011 int NP = in.readInt(); 17012 if (NP > 1000) { 17013 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 17014 } 17015 for (int is = 0; is < NP; is++) { 17016 int seNumber = in.readInt(); 17017 if (in.readInt() != 0) { 17018 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 17019 } 17020 } 17021 17022 NP = in.readInt(); 17023 if (NP > 10000) { 17024 throw new ParcelFormatException("File corrupt: too many processes " + NP); 17025 } 17026 for (int ip = 0; ip < NP; ip++) { 17027 String procName = in.readString(); 17028 Uid.Proc p = u.getProcessStatsLocked(procName); 17029 p.mUserTimeMs = in.readLong(); 17030 p.mSystemTimeMs = in.readLong(); 17031 p.mForegroundTimeMs = in.readLong(); 17032 p.mStarts = in.readInt(); 17033 p.mNumCrashes = in.readInt(); 17034 p.mNumAnrs = in.readInt(); 17035 p.readExcessivePowerFromParcelLocked(in); 17036 } 17037 17038 NP = in.readInt(); 17039 if (NP > 10000) { 17040 throw new ParcelFormatException("File corrupt: too many packages " + NP); 17041 } 17042 for (int ip = 0; ip < NP; ip++) { 17043 String pkgName = in.readString(); 17044 detachIfNotNull(u.mPackageStats.get(pkgName)); 17045 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 17046 final int NWA = in.readInt(); 17047 if (NWA > 10000) { 17048 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 17049 } 17050 p.mWakeupAlarms.clear(); 17051 for (int iwa = 0; iwa < NWA; iwa++) { 17052 String tag = in.readString(); 17053 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 17054 c.readSummaryFromParcelLocked(in); 17055 p.mWakeupAlarms.put(tag, c); 17056 } 17057 NS = in.readInt(); 17058 if (NS > 10000) { 17059 throw new ParcelFormatException("File corrupt: too many services " + NS); 17060 } 17061 for (int is = 0; is < NS; is++) { 17062 String servName = in.readString(); 17063 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 17064 s.mStartTimeMs = in.readLong(); 17065 s.mStarts = in.readInt(); 17066 s.mLaunches = in.readInt(); 17067 } 17068 } 17069 } 17070 17071 if (!Flags.disableSystemServicePowerAttr()) { 17072 mBinderThreadCpuTimesUs = 17073 LongSamplingCounterArray.readSummaryFromParcelLocked(in, mOnBatteryTimeBase); 17074 } 17075 } 17076 17077 /** 17078 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 17079 * disk. This format does not allow a lossless round-trip. 17080 * 17081 * @param out the Parcel to be written to. 17082 */ 17083 @GuardedBy("this") 17084 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 17085 pullPendingStateUpdatesLocked(); 17086 17087 // Pull the clock time. This may update the time and make a new history entry 17088 // if we had originally pulled a time before the RTC was set. 17089 getStartClockTime(); 17090 17091 final long nowUptime = mClock.uptimeMillis() * 1000; 17092 final long nowRealtime = mClock.elapsedRealtime() * 1000; 17093 17094 out.writeInt(VERSION); 17095 17096 mHistory.writeSummaryToParcel(out, inclHistory); 17097 17098 out.writeInt(mStartCount); 17099 out.writeLong(computeUptime(nowUptime, STATS_SINCE_CHARGED)); 17100 out.writeLong(computeRealtime(nowRealtime, STATS_SINCE_CHARGED)); 17101 out.writeLong(mStartClockTimeMs); 17102 out.writeLong(mMonotonicStartTime); 17103 out.writeLong(mMonotonicClock.monotonicTime()); 17104 out.writeString(mStartPlatformVersion); 17105 out.writeString(mEndPlatformVersion); 17106 mOnBatteryTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 17107 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 17108 out.writeInt(mDischargeUnplugLevel); 17109 out.writeInt(mDischargePlugLevel); 17110 out.writeInt(mDischargeCurrentLevel); 17111 out.writeInt(mBatteryLevel); 17112 out.writeInt(mEstimatedBatteryCapacityMah); 17113 out.writeInt(mLastLearnedBatteryCapacityUah); 17114 out.writeInt(mMinLearnedBatteryCapacityUah); 17115 out.writeInt(mMaxLearnedBatteryCapacityUah); 17116 out.writeInt(getLowDischargeAmountSinceCharge()); 17117 out.writeInt(getHighDischargeAmountSinceCharge()); 17118 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 17119 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 17120 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 17121 mDischargeStepTracker.writeToParcel(out); 17122 mChargeStepTracker.writeToParcel(out); 17123 mDailyDischargeStepTracker.writeToParcel(out); 17124 mDailyChargeStepTracker.writeToParcel(out); 17125 mDischargeCounter.writeSummaryFromParcelLocked(out); 17126 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 17127 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 17128 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 17129 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 17130 if (mDailyPackageChanges != null) { 17131 final int NPKG = mDailyPackageChanges.size(); 17132 out.writeInt(NPKG); 17133 for (int i=0; i<NPKG; i++) { 17134 PackageChange pc = mDailyPackageChanges.get(i); 17135 out.writeString(pc.mPackageName); 17136 out.writeInt(pc.mUpdate ? 1 : 0); 17137 out.writeLong(pc.mVersionCode); 17138 } 17139 } else { 17140 out.writeInt(0); 17141 } 17142 out.writeLong(mDailyStartTimeMs); 17143 out.writeLong(mNextMinDailyDeadlineMs); 17144 out.writeLong(mNextMaxDailyDeadlineMs); 17145 out.writeLong(mBatteryTimeToFullSeconds); 17146 17147 EnergyConsumerStats.Config.writeToParcel(mEnergyConsumerStatsConfig, out); 17148 EnergyConsumerStats.writeSummaryToParcel(mGlobalEnergyConsumerStats, out); 17149 17150 mScreenOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17151 mScreenDozeTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17152 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 17153 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17154 } 17155 final int numDisplays = mPerDisplayBatteryStats.length; 17156 out.writeInt(numDisplays); 17157 for (int i = 0; i < numDisplays; i++) { 17158 mPerDisplayBatteryStats[i].writeSummaryToParcel(out, nowRealtime); 17159 } 17160 mInteractiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17161 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17162 out.writeLong(mLongestLightIdleTimeMs); 17163 out.writeLong(mLongestFullIdleTimeMs); 17164 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17165 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17166 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17167 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17168 mPhoneOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17169 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 17170 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17171 } 17172 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17173 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 17174 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17175 } 17176 mNrNsaTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17177 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 17178 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 17179 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 17180 } 17181 final int numRat = mPerRatBatteryStats.length; 17182 out.writeInt(numRat); 17183 for (int i = 0; i < numRat; i++) { 17184 final RadioAccessTechnologyBatteryStats ratStat = mPerRatBatteryStats[i]; 17185 if (ratStat == null) { 17186 out.writeInt(0); 17187 continue; 17188 } 17189 out.writeInt(1); 17190 ratStat.writeSummaryToParcel(out, nowRealtime); 17191 } 17192 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17193 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17194 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 17195 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 17196 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 17197 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17198 mWifiOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17199 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17200 for (int i=0; i<NUM_WIFI_STATES; i++) { 17201 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17202 } 17203 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 17204 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17205 } 17206 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 17207 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17208 } 17209 mWifiActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17210 mWifiActivity.writeSummaryToParcel(out); 17211 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 17212 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17213 } 17214 mBluetoothActivity.writeSummaryToParcel(out); 17215 mModemActivity.writeSummaryToParcel(out); 17216 out.writeInt(mHasWifiReporting ? 1 : 0); 17217 out.writeInt(mHasBluetoothReporting ? 1 : 0); 17218 out.writeInt(mHasModemReporting ? 1 : 0); 17219 17220 out.writeInt(mNumConnectivityChange); 17221 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17222 mCameraOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17223 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17224 17225 out.writeInt(mRpmStats.size()); 17226 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 17227 Timer rpmt = ent.getValue(); 17228 if (rpmt != null) { 17229 out.writeInt(1); 17230 out.writeString(ent.getKey()); 17231 rpmt.writeSummaryFromParcelLocked(out, nowRealtime); 17232 } else { 17233 out.writeInt(0); 17234 } 17235 } 17236 out.writeInt(mScreenOffRpmStats.size()); 17237 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 17238 Timer rpmt = ent.getValue(); 17239 if (rpmt != null) { 17240 out.writeInt(1); 17241 out.writeString(ent.getKey()); 17242 rpmt.writeSummaryFromParcelLocked(out, nowRealtime); 17243 } else { 17244 out.writeInt(0); 17245 } 17246 } 17247 17248 out.writeInt(mKernelWakelockStats.size()); 17249 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 17250 Timer kwlt = ent.getValue(); 17251 if (kwlt != null) { 17252 out.writeInt(1); 17253 out.writeString(ent.getKey()); 17254 kwlt.writeSummaryFromParcelLocked(out, nowRealtime); 17255 } else { 17256 out.writeInt(0); 17257 } 17258 } 17259 17260 out.writeInt(mWakeupReasonStats.size()); 17261 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 17262 SamplingTimer timer = ent.getValue(); 17263 if (timer != null) { 17264 out.writeInt(1); 17265 out.writeString(ent.getKey()); 17266 timer.writeSummaryFromParcelLocked(out, nowRealtime); 17267 } else { 17268 out.writeInt(0); 17269 } 17270 } 17271 17272 out.writeInt(mKernelMemoryStats.size()); 17273 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 17274 Timer kmt = mKernelMemoryStats.valueAt(i); 17275 if (kmt != null) { 17276 out.writeInt(1); 17277 out.writeLong(mKernelMemoryStats.keyAt(i)); 17278 kmt.writeSummaryFromParcelLocked(out, nowRealtime); 17279 } else { 17280 out.writeInt(0); 17281 } 17282 } 17283 17284 final int NU = mUidStats.size(); 17285 out.writeInt(NU); 17286 for (int iu = 0; iu < NU; iu++) { 17287 out.writeInt(mUidStats.keyAt(iu)); 17288 Uid u = mUidStats.valueAt(iu); 17289 17290 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 17291 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, nowUptime, 17292 nowRealtime); 17293 17294 if (u.mWifiRunningTimer != null) { 17295 out.writeInt(1); 17296 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17297 } else { 17298 out.writeInt(0); 17299 } 17300 if (u.mFullWifiLockTimer != null) { 17301 out.writeInt(1); 17302 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17303 } else { 17304 out.writeInt(0); 17305 } 17306 if (u.mWifiScanTimer != null) { 17307 out.writeInt(1); 17308 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17309 } else { 17310 out.writeInt(0); 17311 } 17312 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 17313 if (u.mWifiBatchedScanTimer[i] != null) { 17314 out.writeInt(1); 17315 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17316 } else { 17317 out.writeInt(0); 17318 } 17319 } 17320 if (u.mWifiMulticastTimer != null) { 17321 out.writeInt(1); 17322 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17323 } else { 17324 out.writeInt(0); 17325 } 17326 if (u.mAudioTurnedOnTimer != null) { 17327 out.writeInt(1); 17328 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17329 } else { 17330 out.writeInt(0); 17331 } 17332 if (u.mVideoTurnedOnTimer != null) { 17333 out.writeInt(1); 17334 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17335 } else { 17336 out.writeInt(0); 17337 } 17338 if (u.mFlashlightTurnedOnTimer != null) { 17339 out.writeInt(1); 17340 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17341 } else { 17342 out.writeInt(0); 17343 } 17344 if (u.mCameraTurnedOnTimer != null) { 17345 out.writeInt(1); 17346 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17347 } else { 17348 out.writeInt(0); 17349 } 17350 if (u.mForegroundActivityTimer != null) { 17351 out.writeInt(1); 17352 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17353 } else { 17354 out.writeInt(0); 17355 } 17356 if (u.mForegroundServiceTimer != null) { 17357 out.writeInt(1); 17358 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17359 } else { 17360 out.writeInt(0); 17361 } 17362 if (u.mAggregatedPartialWakelockTimer != null) { 17363 out.writeInt(1); 17364 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17365 } else { 17366 out.writeInt(0); 17367 } 17368 if (u.mBluetoothScanTimer != null) { 17369 out.writeInt(1); 17370 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17371 } else { 17372 out.writeInt(0); 17373 } 17374 if (u.mBluetoothUnoptimizedScanTimer != null) { 17375 out.writeInt(1); 17376 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17377 } else { 17378 out.writeInt(0); 17379 } 17380 if (u.mBluetoothScanResultCounter != null) { 17381 out.writeInt(1); 17382 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 17383 } else { 17384 out.writeInt(0); 17385 } 17386 if (u.mBluetoothScanResultBgCounter != null) { 17387 out.writeInt(1); 17388 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 17389 } else { 17390 out.writeInt(0); 17391 } 17392 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 17393 if (u.mProcessStateTimer[i] != null) { 17394 out.writeInt(1); 17395 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17396 } else { 17397 out.writeInt(0); 17398 } 17399 } 17400 if (u.mVibratorOnTimer != null) { 17401 out.writeInt(1); 17402 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17403 } else { 17404 out.writeInt(0); 17405 } 17406 17407 if (u.mUserActivityCounters == null) { 17408 out.writeInt(0); 17409 } else { 17410 out.writeInt(1); 17411 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 17412 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 17413 } 17414 } 17415 17416 if (u.mNetworkByteActivityCounters == null) { 17417 out.writeInt(0); 17418 } else { 17419 out.writeInt(1); 17420 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 17421 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 17422 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 17423 } 17424 if (u.mMobileRadioActiveTime != null) { 17425 out.writeBoolean(true); 17426 u.mMobileRadioActiveTime.writeToParcel(out); 17427 } else { 17428 out.writeBoolean(false); 17429 } 17430 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 17431 } 17432 17433 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 17434 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 17435 17436 if (u.mCpuClusterSpeedTimesUs != null) { 17437 out.writeInt(1); 17438 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 17439 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 17440 if (cpuSpeeds != null) { 17441 out.writeInt(1); 17442 out.writeInt(cpuSpeeds.length); 17443 for (LongSamplingCounter c : cpuSpeeds) { 17444 if (c != null) { 17445 out.writeInt(1); 17446 c.writeSummaryFromParcelLocked(out); 17447 } else { 17448 out.writeInt(0); 17449 } 17450 } 17451 } else { 17452 out.writeInt(0); 17453 } 17454 } 17455 } else { 17456 out.writeInt(0); 17457 } 17458 17459 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 17460 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 17461 17462 if (u.mCpuActiveTimeMs != null) { 17463 out.writeInt(u.mCpuActiveTimeMs.getStateCount()); 17464 u.mCpuActiveTimeMs.writeToParcel(out); 17465 } else { 17466 out.writeInt(0); 17467 } 17468 17469 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 17470 17471 if (u.mProcStateTimeMs != null) { 17472 out.writeInt(u.mProcStateTimeMs.getStateCount()); 17473 u.mProcStateTimeMs.writeToParcel(out); 17474 } else { 17475 out.writeInt(0); 17476 } 17477 17478 if (u.mProcStateScreenOffTimeMs != null) { 17479 out.writeInt(u.mProcStateScreenOffTimeMs.getStateCount()); 17480 u.mProcStateScreenOffTimeMs.writeToParcel(out); 17481 } else { 17482 out.writeInt(0); 17483 } 17484 17485 if (u.mMobileRadioApWakeupCount != null) { 17486 out.writeInt(1); 17487 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 17488 } else { 17489 out.writeInt(0); 17490 } 17491 17492 if (u.mWifiRadioApWakeupCount != null) { 17493 out.writeInt(1); 17494 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 17495 } else { 17496 out.writeInt(0); 17497 } 17498 17499 EnergyConsumerStats.writeSummaryToParcel(u.mUidEnergyConsumerStats, out); 17500 17501 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 17502 int NW = wakeStats.size(); 17503 out.writeInt(NW); 17504 for (int iw=0; iw<NW; iw++) { 17505 out.writeString(wakeStats.keyAt(iw)); 17506 Uid.Wakelock wl = wakeStats.valueAt(iw); 17507 if (wl.mTimerFull != null) { 17508 out.writeInt(1); 17509 wl.mTimerFull.writeSummaryFromParcelLocked(out, nowRealtime); 17510 } else { 17511 out.writeInt(0); 17512 } 17513 if (wl.mTimerPartial != null) { 17514 out.writeInt(1); 17515 wl.mTimerPartial.writeSummaryFromParcelLocked(out, nowRealtime); 17516 } else { 17517 out.writeInt(0); 17518 } 17519 if (wl.mTimerWindow != null) { 17520 out.writeInt(1); 17521 wl.mTimerWindow.writeSummaryFromParcelLocked(out, nowRealtime); 17522 } else { 17523 out.writeInt(0); 17524 } 17525 if (wl.mTimerDraw != null) { 17526 out.writeInt(1); 17527 wl.mTimerDraw.writeSummaryFromParcelLocked(out, nowRealtime); 17528 } else { 17529 out.writeInt(0); 17530 } 17531 } 17532 17533 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 17534 int NS = syncStats.size(); 17535 out.writeInt(NS); 17536 for (int is=0; is<NS; is++) { 17537 out.writeString(syncStats.keyAt(is)); 17538 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, nowRealtime); 17539 } 17540 17541 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 17542 int NJ = jobStats.size(); 17543 out.writeInt(NJ); 17544 for (int ij=0; ij<NJ; ij++) { 17545 out.writeString(jobStats.keyAt(ij)); 17546 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, nowRealtime); 17547 } 17548 17549 u.writeJobCompletionsToParcelLocked(out); 17550 17551 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 17552 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 17553 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 17554 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 17555 if (u.mJobsFreshnessBuckets[i] != null) { 17556 out.writeInt(1); 17557 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 17558 } else { 17559 out.writeInt(0); 17560 } 17561 } 17562 17563 int NSE = u.mSensorStats.size(); 17564 out.writeInt(NSE); 17565 for (int ise=0; ise<NSE; ise++) { 17566 out.writeInt(u.mSensorStats.keyAt(ise)); 17567 Uid.Sensor se = u.mSensorStats.valueAt(ise); 17568 if (se.mTimer != null) { 17569 out.writeInt(1); 17570 se.mTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17571 } else { 17572 out.writeInt(0); 17573 } 17574 } 17575 17576 int NP = u.mProcessStats.size(); 17577 out.writeInt(NP); 17578 for (int ip=0; ip<NP; ip++) { 17579 out.writeString(u.mProcessStats.keyAt(ip)); 17580 Uid.Proc ps = u.mProcessStats.valueAt(ip); 17581 out.writeLong(ps.mUserTimeMs); 17582 out.writeLong(ps.mSystemTimeMs); 17583 out.writeLong(ps.mForegroundTimeMs); 17584 out.writeInt(ps.mStarts); 17585 out.writeInt(ps.mNumCrashes); 17586 out.writeInt(ps.mNumAnrs); 17587 ps.writeExcessivePowerToParcelLocked(out); 17588 } 17589 17590 NP = u.mPackageStats.size(); 17591 out.writeInt(NP); 17592 if (NP > 0) { 17593 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 17594 : u.mPackageStats.entrySet()) { 17595 out.writeString(ent.getKey()); 17596 Uid.Pkg ps = ent.getValue(); 17597 final int NWA = ps.mWakeupAlarms.size(); 17598 out.writeInt(NWA); 17599 for (int iwa=0; iwa<NWA; iwa++) { 17600 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 17601 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 17602 } 17603 NS = ps.mServiceStats.size(); 17604 out.writeInt(NS); 17605 for (int is=0; is<NS; is++) { 17606 out.writeString(ps.mServiceStats.keyAt(is)); 17607 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 17608 long time = ss.getStartTimeToNowLocked( 17609 mOnBatteryTimeBase.getUptime(nowUptime) / 1000); 17610 out.writeLong(time); 17611 out.writeInt(ss.mStarts); 17612 out.writeInt(ss.mLaunches); 17613 } 17614 } 17615 } 17616 } 17617 17618 if (!Flags.disableSystemServicePowerAttr()) { 17619 LongSamplingCounterArray.writeSummaryToParcelLocked(out, mBinderThreadCpuTimesUs); 17620 } 17621 } 17622 17623 /** 17624 * Persists the monotonic clock associated with battery stats. 17625 */ 17626 public void commitMonotonicClock() { 17627 mMonotonicClock.write(); 17628 } 17629 17630 @GuardedBy("this") 17631 public void prepareForDumpLocked() { 17632 // Need to retrieve current kernel wake lock stats before printing. 17633 pullPendingStateUpdatesLocked(); 17634 17635 // Pull the clock time. This may update the time and make a new history entry 17636 // if we had originally pulled a time before the RTC was set. 17637 getStartClockTime(); 17638 17639 if (!Flags.disableSystemServicePowerAttr()) { 17640 updateSystemServiceCallStats(); 17641 } 17642 } 17643 17644 @GuardedBy("this") 17645 public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart, 17646 BatteryStatsDumpHelper dumpHelper) { 17647 if (DEBUG) { 17648 pw.println("mOnBatteryTimeBase:"); 17649 mOnBatteryTimeBase.dump(pw, " "); 17650 pw.println("mOnBatteryScreenOffTimeBase:"); 17651 mOnBatteryScreenOffTimeBase.dump(pw, " "); 17652 Printer pr = new PrintWriterPrinter(pw); 17653 pr.println("*** Screen on timer:"); 17654 mScreenOnTimer.logState(pr, " "); 17655 pr.println("*** Screen doze timer:"); 17656 mScreenDozeTimer.logState(pr, " "); 17657 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 17658 pr.println("*** Screen brightness #" + i + ":"); 17659 mScreenBrightnessTimer[i].logState(pr, " "); 17660 } 17661 pr.println("*** Interactive timer:"); 17662 mInteractiveTimer.logState(pr, " "); 17663 pr.println("*** Power save mode timer:"); 17664 mPowerSaveModeEnabledTimer.logState(pr, " "); 17665 pr.println("*** Device idle mode light timer:"); 17666 mDeviceIdleModeLightTimer.logState(pr, " "); 17667 pr.println("*** Device idle mode full timer:"); 17668 mDeviceIdleModeFullTimer.logState(pr, " "); 17669 pr.println("*** Device light idling timer:"); 17670 mDeviceLightIdlingTimer.logState(pr, " "); 17671 pr.println("*** Device idling timer:"); 17672 mDeviceIdlingTimer.logState(pr, " "); 17673 pr.println("*** Phone timer:"); 17674 mPhoneOnTimer.logState(pr, " "); 17675 for (int i = 0; i < CELL_SIGNAL_STRENGTH_LEVEL_COUNT; i++) { 17676 pr.println("*** Phone signal strength #" + i + ":"); 17677 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 17678 } 17679 pr.println("*** Signal scanning :"); 17680 mPhoneSignalScanningTimer.logState(pr, " "); 17681 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 17682 pr.println("*** Data connection type #" + i + ":"); 17683 mPhoneDataConnectionsTimer[i].logState(pr, " "); 17684 } 17685 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 17686 pr.println("*** Mobile network active timer:"); 17687 mMobileRadioActiveTimer.logState(pr, " "); 17688 pr.println("*** Mobile network active adjusted timer:"); 17689 mMobileRadioActiveAdjustedTime.logState(pr, " "); 17690 pr.println("*** Wifi Multicast WakeLock Timer:"); 17691 mWifiMulticastWakelockTimer.logState(pr, " "); 17692 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 17693 pr.println("*** Wifi timer:"); 17694 mWifiOnTimer.logState(pr, " "); 17695 pr.println("*** WifiRunning timer:"); 17696 mGlobalWifiRunningTimer.logState(pr, " "); 17697 for (int i=0; i<NUM_WIFI_STATES; i++) { 17698 pr.println("*** Wifi state #" + i + ":"); 17699 mWifiStateTimer[i].logState(pr, " "); 17700 } 17701 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 17702 pr.println("*** Wifi suppl state #" + i + ":"); 17703 mWifiSupplStateTimer[i].logState(pr, " "); 17704 } 17705 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 17706 pr.println("*** Wifi signal strength #" + i + ":"); 17707 mWifiSignalStrengthsTimer[i].logState(pr, " "); 17708 } 17709 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 17710 pr.println("*** GPS signal quality #" + i + ":"); 17711 mGpsSignalQualityTimer[i].logState(pr, " "); 17712 } 17713 pr.println("*** Flashlight timer:"); 17714 mFlashlightOnTimer.logState(pr, " "); 17715 pr.println("*** Camera timer:"); 17716 mCameraOnTimer.logState(pr, " "); 17717 } 17718 super.dump(context, pw, flags, reqUid, histStart, dumpHelper); 17719 17720 synchronized (this) { 17721 pw.print("Per process state tracking available: "); 17722 pw.println(trackPerProcStateCpuTimes()); 17723 pw.print("Total cpu time reads: "); 17724 pw.println(mNumSingleUidCpuTimeReads); 17725 pw.print("Batching Duration (min): "); 17726 pw.println((mClock.uptimeMillis() - mCpuTimeReadsTrackingStartTimeMs) / (60 * 1000)); 17727 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 17728 pw.println(mNumAllUidCpuTimeReads); 17729 pw.print("UIDs removed since the later of device start or stats reset: "); 17730 pw.println(mNumUidsRemoved); 17731 17732 mPowerStatsUidResolver.dump(pw); 17733 17734 pw.println(); 17735 dumpConstantsLocked(pw); 17736 17737 pw.println(); 17738 mCpuPowerStatsCollector.dumpCpuPowerBracketsLocked(pw); 17739 17740 pw.println(); 17741 dumpEnergyConsumerStatsLocked(pw); 17742 } 17743 } 17744 } 17745