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.BatteryStatsManager.NUM_WIFI_STATES; 23 import static android.os.BatteryStatsManager.NUM_WIFI_SUPPL_STATES; 24 25 import android.annotation.IntDef; 26 import android.annotation.NonNull; 27 import android.annotation.Nullable; 28 import android.app.ActivityManager; 29 import android.app.AlarmManager; 30 import android.app.usage.NetworkStatsManager; 31 import android.bluetooth.BluetoothActivityEnergyInfo; 32 import android.bluetooth.UidTraffic; 33 import android.content.BroadcastReceiver; 34 import android.content.ContentResolver; 35 import android.content.Context; 36 import android.content.Intent; 37 import android.content.IntentFilter; 38 import android.database.ContentObserver; 39 import android.hardware.usb.UsbManager; 40 import android.location.GnssSignalQuality; 41 import android.net.NetworkStats; 42 import android.net.Uri; 43 import android.net.wifi.WifiManager; 44 import android.os.BatteryConsumer; 45 import android.os.BatteryManager; 46 import android.os.BatteryStats; 47 import android.os.BatteryUsageStats; 48 import android.os.BatteryUsageStatsQuery; 49 import android.os.Binder; 50 import android.os.BluetoothBatteryStats; 51 import android.os.Build; 52 import android.os.Handler; 53 import android.os.IBatteryPropertiesRegistrar; 54 import android.os.Looper; 55 import android.os.Message; 56 import android.os.OsProtoEnums; 57 import android.os.Parcel; 58 import android.os.ParcelFormatException; 59 import android.os.Parcelable; 60 import android.os.PowerManager; 61 import android.os.Process; 62 import android.os.RemoteException; 63 import android.os.ServiceManager; 64 import android.os.SystemClock; 65 import android.os.UserHandle; 66 import android.os.WakeLockStats; 67 import android.os.WorkSource; 68 import android.os.WorkSource.WorkChain; 69 import android.os.connectivity.CellularBatteryStats; 70 import android.os.connectivity.GpsBatteryStats; 71 import android.os.connectivity.WifiActivityEnergyInfo; 72 import android.os.connectivity.WifiBatteryStats; 73 import android.provider.Settings; 74 import android.telephony.AccessNetworkConstants; 75 import android.telephony.Annotation.NetworkType; 76 import android.telephony.CellSignalStrength; 77 import android.telephony.CellSignalStrengthLte; 78 import android.telephony.CellSignalStrengthNr; 79 import android.telephony.DataConnectionRealTimeInfo; 80 import android.telephony.ModemActivityInfo; 81 import android.telephony.ServiceState; 82 import android.telephony.ServiceState.RegState; 83 import android.telephony.SignalStrength; 84 import android.telephony.TelephonyManager; 85 import android.text.TextUtils; 86 import android.text.format.DateUtils; 87 import android.util.ArrayMap; 88 import android.util.ArraySet; 89 import android.util.AtomicFile; 90 import android.util.IndentingPrintWriter; 91 import android.util.KeyValueListParser; 92 import android.util.Log; 93 import android.util.LongSparseArray; 94 import android.util.LongSparseLongArray; 95 import android.util.MutableInt; 96 import android.util.PrintWriterPrinter; 97 import android.util.Printer; 98 import android.util.Slog; 99 import android.util.SparseArray; 100 import android.util.SparseDoubleArray; 101 import android.util.SparseIntArray; 102 import android.util.SparseLongArray; 103 import android.util.TimeUtils; 104 import android.util.Xml; 105 import android.view.Display; 106 107 import com.android.internal.annotations.GuardedBy; 108 import com.android.internal.annotations.VisibleForTesting; 109 import com.android.internal.os.BackgroundThread; 110 import com.android.internal.os.BatteryStatsHistory; 111 import com.android.internal.os.BatteryStatsHistory.HistoryStepDetailsCalculator; 112 import com.android.internal.os.BatteryStatsHistoryIterator; 113 import com.android.internal.os.BinderCallsStats; 114 import com.android.internal.os.BinderTransactionNameResolver; 115 import com.android.internal.os.Clock; 116 import com.android.internal.os.KernelCpuSpeedReader; 117 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; 118 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; 119 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 120 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; 121 import com.android.internal.os.KernelMemoryBandwidthStats; 122 import com.android.internal.os.KernelSingleUidTimeReader; 123 import com.android.internal.os.LongArrayMultiStateCounter; 124 import com.android.internal.os.LongMultiStateCounter; 125 import com.android.internal.os.PowerProfile; 126 import com.android.internal.os.RailStats; 127 import com.android.internal.os.RpmStats; 128 import com.android.internal.power.EnergyConsumerStats; 129 import com.android.internal.power.EnergyConsumerStats.StandardPowerBucket; 130 import com.android.internal.util.ArrayUtils; 131 import com.android.internal.util.FrameworkStatsLog; 132 import com.android.internal.util.XmlUtils; 133 import com.android.modules.utils.TypedXmlPullParser; 134 import com.android.modules.utils.TypedXmlSerializer; 135 import com.android.net.module.util.NetworkCapabilitiesUtils; 136 import com.android.server.power.stats.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes; 137 138 import libcore.util.EmptyArray; 139 140 import org.xmlpull.v1.XmlPullParser; 141 import org.xmlpull.v1.XmlPullParserException; 142 143 import java.io.ByteArrayOutputStream; 144 import java.io.File; 145 import java.io.FileInputStream; 146 import java.io.FileNotFoundException; 147 import java.io.FileOutputStream; 148 import java.io.IOException; 149 import java.io.PrintWriter; 150 import java.lang.annotation.Retention; 151 import java.lang.annotation.RetentionPolicy; 152 import java.util.ArrayList; 153 import java.util.Arrays; 154 import java.util.Calendar; 155 import java.util.Collection; 156 import java.util.HashMap; 157 import java.util.HashSet; 158 import java.util.Iterator; 159 import java.util.LinkedList; 160 import java.util.List; 161 import java.util.Map; 162 import java.util.Queue; 163 import java.util.concurrent.Future; 164 import java.util.concurrent.atomic.AtomicInteger; 165 import java.util.concurrent.locks.ReentrantLock; 166 167 /** 168 * All information we are collecting about things that can happen that impact 169 * battery life. All times are represented in microseconds except where indicated 170 * otherwise. 171 */ 172 public class BatteryStatsImpl extends BatteryStats { 173 private static final String TAG = "BatteryStatsImpl"; 174 private static final boolean DEBUG = false; 175 public static final boolean DEBUG_ENERGY = false; 176 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 177 private static final boolean DEBUG_BINDER_STATS = false; 178 private static final boolean DEBUG_MEMORY = false; 179 180 // TODO: remove "tcp" from network methods, since we measure total stats. 181 182 // Current on-disk Parcel version. Must be updated when the format of the parcelable changes 183 public static final int VERSION = 212; 184 185 // The maximum number of names wakelocks we will keep track of 186 // per uid; once the limit is reached, we batch the remaining wakelocks 187 // in to one common name. 188 private static final int MAX_WAKELOCKS_PER_UID; 189 190 static { 191 if (ActivityManager.isLowRamDeviceStatic()) { 192 MAX_WAKELOCKS_PER_UID = 40; 193 } else { 194 MAX_WAKELOCKS_PER_UID = 200; 195 } 196 } 197 198 // Number of transmit power states the Wifi controller can be in. 199 private static final int NUM_WIFI_TX_LEVELS = 1; 200 201 // Number of transmit power states the Bluetooth controller can be in. 202 private static final int NUM_BT_TX_LEVELS = 1; 203 204 /** 205 * Holding a wakelock costs more than just using the cpu. 206 * Currently, we assign only half the cpu time to an app that is running but 207 * not holding a wakelock. The apps holding wakelocks get the rest of the blame. 208 * If no app is holding a wakelock, then the distribution is normal. 209 */ 210 @VisibleForTesting 211 public static final int WAKE_LOCK_WEIGHT = 50; 212 213 public static final int RESET_REASON_CORRUPT_FILE = 1; 214 public static final int RESET_REASON_ADB_COMMAND = 2; 215 public static final int RESET_REASON_FULL_CHARGE = 3; 216 public static final int RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE = 4; 217 public static final int RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION = 5; 218 219 protected Clock mClock; 220 221 private final AtomicFile mStatsFile; 222 public final AtomicFile mCheckinFile; 223 public final AtomicFile mDailyFile; 224 225 static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1; 226 static final int MSG_REPORT_POWER_CHANGE = 2; 227 static final int MSG_REPORT_CHARGING = 3; 228 static final int MSG_REPORT_RESET_STATS = 4; 229 static final long DELAY_UPDATE_WAKELOCKS = 60 * 1000; 230 231 private static final double MILLISECONDS_IN_HOUR = 3600 * 1000; 232 private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L; 233 234 private static final LongCounter ZERO_LONG_COUNTER = new LongCounter() { 235 @Override 236 public long getCountLocked(int which) { 237 return 0; 238 } 239 240 @Override 241 public long getCountForProcessState(int procState) { 242 return 0; 243 } 244 245 @Override 246 public void logState(Printer pw, String prefix) { 247 pw.println(prefix + "mCount=0"); 248 } 249 }; 250 251 private static final LongCounter[] ZERO_LONG_COUNTER_ARRAY = 252 new LongCounter[]{ZERO_LONG_COUNTER}; 253 254 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); 255 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 256 257 @VisibleForTesting 258 protected KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader; 259 @VisibleForTesting 260 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 261 @VisibleForTesting 262 protected KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader; 263 @VisibleForTesting 264 protected KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader; 265 @VisibleForTesting 266 protected KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader; 267 @VisibleForTesting 268 protected KernelSingleUidTimeReader mKernelSingleUidTimeReader; 269 @VisibleForTesting 270 protected SystemServerCpuThreadReader mSystemServerCpuThreadReader = 271 SystemServerCpuThreadReader.create(); 272 273 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats 274 = new KernelMemoryBandwidthStats(); 275 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); 276 private int[] mCpuPowerBracketMap; 277 private final CpuUsageDetails mCpuUsageDetails = new CpuUsageDetails(); 278 getKernelMemoryStats()279 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 280 return mKernelMemoryStats; 281 } 282 283 private static final int[] SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS = { 284 EnergyConsumerStats.POWER_BUCKET_CPU, 285 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 286 EnergyConsumerStats.POWER_BUCKET_WIFI, 287 EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 288 }; 289 290 // TimeInState counters need NUM_PROCESS_STATE states in order to accommodate 291 // Uid.PROCESS_STATE_NONEXISTENT, which is outside the range of legitimate proc states. 292 private static final int PROC_STATE_TIME_COUNTER_STATE_COUNT = NUM_PROCESS_STATE + 1; 293 294 @GuardedBy("this") 295 public boolean mPerProcStateCpuTimesAvailable = true; 296 297 @GuardedBy("this") 298 private long mNumSingleUidCpuTimeReads; 299 @GuardedBy("this") 300 private long mCpuTimeReadsTrackingStartTimeMs = SystemClock.uptimeMillis(); 301 @GuardedBy("this") 302 private int mNumUidsRemoved; 303 @GuardedBy("this") 304 private int mNumAllUidCpuTimeReads; 305 306 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ 307 private RpmStats mTmpRpmStats = null; 308 /** The soonest the RPM stats can be updated after it was last updated. */ 309 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; 310 /** Last time that RPM stats were updated by updateRpmStatsLocked. */ 311 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS; 312 313 /** Container for Rail Energy Data stats. */ 314 private final RailStats mTmpRailStats = new RailStats(); 315 316 /** 317 * Estimate UID modem power usage based on their estimated mobile radio active time. 318 */ 319 public static final int PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME = 1; 320 /** 321 * Estimate UID modem power consumption by proportionally attributing estimated Rx and Tx 322 * power consumption individually. 323 * ModemActivityInfo must be available. 324 */ 325 public static final int PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX = 2; 326 @IntDef(flag = true, prefix = "PER_UID_MODEM_MODEL_", value = { 327 PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME, 328 PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX, 329 }) 330 @Retention(RetentionPolicy.SOURCE) 331 public @interface PerUidModemPowerModel { 332 } 333 334 /** 335 * Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader}, 336 * {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader}, 337 * {@link KernelCpuUidFreqTimeReader} and from the Kernel. 338 * 339 * Isolated and invalid UID info must be removed to conserve memory. However, STATSD and 340 * Batterystats both need to access UID cpu time. To resolve this race condition, only 341 * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is 342 * implemented so that STATSD can capture those UID times before they are deleted. 343 */ 344 @GuardedBy("this") 345 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 346 protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>(); 347 348 @NonNull copyHistory()349 BatteryStatsHistory copyHistory() { 350 return mHistory.copy(); 351 } 352 353 @VisibleForTesting 354 public final class UidToRemove { 355 private final int mStartUid; 356 private final int mEndUid; 357 private final long mUidRemovalTimestamp; 358 359 /** Remove just one UID */ UidToRemove(int uid, long timestamp)360 public UidToRemove(int uid, long timestamp) { 361 this(uid, uid, timestamp); 362 } 363 364 /** Remove a range of UIDs, startUid must be smaller than endUid. */ UidToRemove(int startUid, int endUid, long timestamp)365 public UidToRemove(int startUid, int endUid, long timestamp) { 366 mStartUid = startUid; 367 mEndUid = endUid; 368 mUidRemovalTimestamp = timestamp; 369 } 370 getUidRemovalTimestamp()371 public long getUidRemovalTimestamp() { 372 return mUidRemovalTimestamp; 373 } 374 375 @GuardedBy("BatteryStatsImpl.this") removeLocked()376 void removeLocked() { 377 removeCpuStatsForUidRangeLocked(mStartUid, mEndUid); 378 } 379 } 380 381 /** 382 * Listener for the battery stats reset. 383 */ 384 public interface BatteryResetListener { 385 386 /** 387 * Callback invoked immediately prior to resetting battery stats. 388 * @param resetReason One of the RESET_REASON_* constants. 389 */ prepareForBatteryStatsReset(int resetReason)390 void prepareForBatteryStatsReset(int resetReason); 391 } 392 393 private BatteryResetListener mBatteryResetListener; 394 395 public interface BatteryCallback { batteryNeedsCpuUpdate()396 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)397 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)398 public void batterySendBroadcast(Intent intent); batteryStatsReset()399 public void batteryStatsReset(); 400 } 401 402 public interface PlatformIdleStateCallback { fillLowPowerStats(RpmStats rpmStats)403 public void fillLowPowerStats(RpmStats rpmStats); getSubsystemLowPowerStats()404 public String getSubsystemLowPowerStats(); 405 } 406 407 /** interface to update rail information for power monitor */ 408 public interface EnergyStatsRetriever { 409 /** Function to fill the map for the rail data stats 410 * Used for power monitoring feature 411 * @param railStats 412 */ fillRailDataStats(RailStats railStats)413 void fillRailDataStats(RailStats railStats); 414 } 415 416 public static abstract class UserInfoProvider { 417 private int[] userIds; getUserIds()418 protected abstract @Nullable int[] getUserIds(); 419 @VisibleForTesting refreshUserIds()420 public final void refreshUserIds() { 421 userIds = getUserIds(); 422 } 423 @VisibleForTesting exists(int userId)424 public boolean exists(int userId) { 425 return userIds != null ? ArrayUtils.contains(userIds, userId) : true; 426 } 427 } 428 429 /** Provide BatteryStatsImpl configuration choices */ 430 public static class BatteryStatsConfig { 431 static final int RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG = 1 << 0; 432 static final int RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG = 1 << 1; 433 434 private final int mFlags; 435 BatteryStatsConfig(Builder builder)436 private BatteryStatsConfig(Builder builder) { 437 int flags = 0; 438 if (builder.mResetOnUnplugHighBatteryLevel) { 439 flags |= RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG; 440 } 441 if (builder.mResetOnUnplugAfterSignificantCharge) { 442 flags |= RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG; 443 } 444 mFlags = flags; 445 } 446 447 /** 448 * Returns whether a BatteryStats reset should occur on unplug when the battery level is 449 * high. 450 */ shouldResetOnUnplugHighBatteryLevel()451 boolean shouldResetOnUnplugHighBatteryLevel() { 452 return (mFlags & RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG) 453 == RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG; 454 } 455 456 /** 457 * Returns whether a BatteryStats reset should occur on unplug if the battery charge a 458 * significant amount since it has been plugged in. 459 */ shouldResetOnUnplugAfterSignificantCharge()460 boolean shouldResetOnUnplugAfterSignificantCharge() { 461 return (mFlags & RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG) 462 == RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG; 463 } 464 465 /** 466 * Builder for BatteryStatsConfig 467 */ 468 public static class Builder { 469 private boolean mResetOnUnplugHighBatteryLevel; 470 private boolean mResetOnUnplugAfterSignificantCharge; Builder()471 public Builder() { 472 mResetOnUnplugHighBatteryLevel = true; 473 mResetOnUnplugAfterSignificantCharge = true; 474 } 475 476 /** 477 * Build the BatteryStatsConfig. 478 */ build()479 public BatteryStatsConfig build() { 480 return new BatteryStatsConfig(this); 481 } 482 483 /** 484 * Set whether a BatteryStats reset should occur on unplug when the battery level is 485 * high. 486 */ setResetOnUnplugHighBatteryLevel(boolean reset)487 public Builder setResetOnUnplugHighBatteryLevel(boolean reset) { 488 mResetOnUnplugHighBatteryLevel = reset; 489 return this; 490 } 491 492 /** 493 * Set whether a BatteryStats reset should occur on unplug if the battery charge a 494 * significant amount since it has been plugged in. 495 */ setResetOnUnplugAfterSignificantCharge(boolean reset)496 public Builder setResetOnUnplugAfterSignificantCharge(boolean reset) { 497 mResetOnUnplugAfterSignificantCharge = reset; 498 return this; 499 } 500 } 501 502 } 503 504 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 505 506 private final Runnable mDeferSetCharging = new Runnable() { 507 @Override 508 public void run() { 509 synchronized (BatteryStatsImpl.this) { 510 if (mOnBattery) { 511 // if the device gets unplugged in the time between this runnable being 512 // executed and the lock being taken, we don't want to set charging state 513 return; 514 } 515 boolean changed = setChargingLocked(true); 516 if (changed) { 517 final long uptimeMs = mClock.uptimeMillis(); 518 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 519 mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs); 520 } 521 } 522 } 523 }; 524 525 public final EnergyStatsRetriever mEnergyConsumerRetriever; 526 527 /** 528 * This handler is running on {@link BackgroundThread}. 529 */ 530 final class MyHandler extends Handler { MyHandler(Looper looper)531 public MyHandler(Looper looper) { 532 super(looper, null, true); 533 } 534 535 @Override handleMessage(Message msg)536 public void handleMessage(Message msg) { 537 BatteryCallback cb = mCallback; 538 switch (msg.what) { 539 case MSG_REPORT_CPU_UPDATE_NEEDED: 540 if (cb != null) { 541 cb.batteryNeedsCpuUpdate(); 542 } 543 break; 544 case MSG_REPORT_POWER_CHANGE: 545 if (cb != null) { 546 cb.batteryPowerChanged(msg.arg1 != 0); 547 } 548 break; 549 case MSG_REPORT_CHARGING: 550 if (cb != null) { 551 final String action; 552 synchronized (BatteryStatsImpl.this) { 553 action = mCharging ? BatteryManager.ACTION_CHARGING 554 : BatteryManager.ACTION_DISCHARGING; 555 } 556 Intent intent = new Intent(action); 557 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 558 cb.batterySendBroadcast(intent); 559 } 560 break; 561 case MSG_REPORT_RESET_STATS: 562 if (cb != null) { 563 cb.batteryStatsReset(); 564 } 565 } 566 } 567 } 568 postBatteryNeedsCpuUpdateMsg()569 public void postBatteryNeedsCpuUpdateMsg() { 570 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); 571 } 572 573 /** 574 * Update per-freq cpu times for the supplied UID. 575 */ 576 @GuardedBy("this") 577 @SuppressWarnings("GuardedBy") // errorprone false positive on getProcStateTimeCounter 578 @VisibleForTesting updateProcStateCpuTimesLocked(int uid, long elapsedRealtimeMs, long uptimeMs)579 public void updateProcStateCpuTimesLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 580 if (!initKernelSingleUidTimeReaderLocked()) { 581 return; 582 } 583 584 final Uid u = getUidStatsLocked(uid); 585 586 mNumSingleUidCpuTimeReads++; 587 588 LongArrayMultiStateCounter onBatteryCounter = 589 u.getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 590 LongArrayMultiStateCounter onBatteryScreenOffCounter = 591 u.getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 592 593 if (isUsageHistoryEnabled()) { 594 LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 595 getCpuTimeInFreqContainer(); 596 mKernelSingleUidTimeReader.addDelta(uid, onBatteryCounter, elapsedRealtimeMs, 597 deltaContainer); 598 recordCpuUsage(uid, deltaContainer, elapsedRealtimeMs, uptimeMs); 599 } else { 600 mKernelSingleUidTimeReader.addDelta(uid, onBatteryCounter, elapsedRealtimeMs); 601 } 602 mKernelSingleUidTimeReader.addDelta(uid, onBatteryScreenOffCounter, elapsedRealtimeMs); 603 604 if (u.mChildUids != null) { 605 LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 606 getCpuTimeInFreqContainer(); 607 int childUidCount = u.mChildUids.size(); 608 for (int j = childUidCount - 1; j >= 0; --j) { 609 LongArrayMultiStateCounter cpuTimeInFreqCounter = 610 u.mChildUids.valueAt(j).cpuTimeInFreqCounter; 611 if (cpuTimeInFreqCounter != null) { 612 mKernelSingleUidTimeReader.addDelta(u.mChildUids.keyAt(j), 613 cpuTimeInFreqCounter, elapsedRealtimeMs, deltaContainer); 614 onBatteryCounter.addCounts(deltaContainer); 615 if (isUsageHistoryEnabled()) { 616 recordCpuUsage(uid, deltaContainer, elapsedRealtimeMs, uptimeMs); 617 } 618 onBatteryScreenOffCounter.addCounts(deltaContainer); 619 } 620 } 621 } 622 } 623 recordCpuUsage(int uid, LongArrayMultiStateCounter.LongArrayContainer cpuUsage, long elapsedRealtimeMs, long uptimeMs)624 private void recordCpuUsage(int uid, LongArrayMultiStateCounter.LongArrayContainer cpuUsage, 625 long elapsedRealtimeMs, long uptimeMs) { 626 if (!cpuUsage.combineValues(mCpuUsageDetails.cpuUsageMs, mCpuPowerBracketMap)) { 627 return; 628 } 629 630 mCpuUsageDetails.uid = uid; 631 mHistory.recordCpuUsage(elapsedRealtimeMs, uptimeMs, mCpuUsageDetails); 632 } 633 634 /** 635 * Removes kernel CPU stats for removed UIDs, in the order they were added to the 636 * mPendingRemovedUids queue. 637 */ 638 @GuardedBy("this") 639 @SuppressWarnings("GuardedBy") // errorprone false positive on removeLocked clearPendingRemovedUidsLocked()640 public void clearPendingRemovedUidsLocked() { 641 long cutOffTimeMs = mClock.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; 642 while (!mPendingRemovedUids.isEmpty() 643 && mPendingRemovedUids.peek().getUidRemovalTimestamp() < cutOffTimeMs) { 644 mPendingRemovedUids.poll().removeLocked(); 645 } 646 } 647 648 /** 649 * When the battery/screen state changes, we don't attribute the cpu times to any process 650 * but we still need to take snapshots of all uids to get correct deltas later on. 651 */ 652 @SuppressWarnings("GuardedBy") // errorprone false positive on getProcStateTimeCounter updateCpuTimesForAllUids()653 public void updateCpuTimesForAllUids() { 654 synchronized (BatteryStatsImpl.this) { 655 if (!trackPerProcStateCpuTimes()) { 656 return; 657 } 658 659 if(!initKernelSingleUidTimeReaderLocked()) { 660 return; 661 } 662 663 // TODO(b/197162116): just get a list of UIDs 664 final SparseArray<long[]> allUidCpuFreqTimesMs = 665 mCpuUidFreqTimeReader.getAllUidCpuFreqTimeMs(); 666 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) { 667 final int uid = allUidCpuFreqTimesMs.keyAt(i); 668 final int parentUid = mapUid(uid); 669 final Uid u = getAvailableUidStatsLocked(parentUid); 670 if (u == null) { 671 continue; 672 } 673 674 final int procState = u.mProcessState; 675 if (procState == Uid.PROCESS_STATE_NONEXISTENT) { 676 continue; 677 } 678 679 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 680 final long uptimeMs = mClock.uptimeMillis(); 681 final LongArrayMultiStateCounter onBatteryCounter = 682 u.getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 683 final LongArrayMultiStateCounter onBatteryScreenOffCounter = 684 u.getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 685 686 if (uid == parentUid || Process.isSdkSandboxUid(uid)) { 687 if (isUsageHistoryEnabled()) { 688 LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 689 getCpuTimeInFreqContainer(); 690 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryCounter, 691 elapsedRealtimeMs, deltaContainer); 692 recordCpuUsage(parentUid, deltaContainer, elapsedRealtimeMs, uptimeMs); 693 } else { 694 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryCounter, 695 elapsedRealtimeMs); 696 } 697 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryScreenOffCounter, 698 elapsedRealtimeMs); 699 } else { 700 Uid.ChildUid childUid = u.getChildUid(uid); 701 if (childUid != null) { 702 final LongArrayMultiStateCounter counter = childUid.cpuTimeInFreqCounter; 703 if (counter != null) { 704 final LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 705 getCpuTimeInFreqContainer(); 706 mKernelSingleUidTimeReader.addDelta(uid, counter, elapsedRealtimeMs, 707 deltaContainer); 708 onBatteryCounter.addCounts(deltaContainer); 709 if (isUsageHistoryEnabled()) { 710 recordCpuUsage(uid, deltaContainer, elapsedRealtimeMs, uptimeMs); 711 } 712 onBatteryScreenOffCounter.addCounts(deltaContainer); 713 } 714 } 715 } 716 } 717 } 718 } 719 720 @GuardedBy("this") initKernelSingleUidTimeReaderLocked()721 private boolean initKernelSingleUidTimeReaderLocked() { 722 if (mKernelSingleUidTimeReader == null) { 723 if (mPowerProfile == null) { 724 return false; 725 } 726 if (mCpuFreqs == null) { 727 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 728 } 729 if (mCpuFreqs != null) { 730 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader(mCpuFreqs.length); 731 } else { 732 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable(); 733 return false; 734 } 735 } 736 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable() 737 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable(); 738 return true; 739 } 740 741 public interface ExternalStatsSync { 742 int UPDATE_CPU = 0x01; 743 int UPDATE_WIFI = 0x02; 744 int UPDATE_RADIO = 0x04; 745 int UPDATE_BT = 0x08; 746 int UPDATE_RPM = 0x10; 747 int UPDATE_DISPLAY = 0x20; 748 int UPDATE_CAMERA = 0x40; 749 int RESET = 0x80; 750 751 int UPDATE_ALL = 752 UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM | UPDATE_DISPLAY 753 | UPDATE_CAMERA; 754 755 int UPDATE_ON_PROC_STATE_CHANGE = UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT; 756 757 int UPDATE_ON_RESET = UPDATE_ALL | RESET; 758 759 @IntDef(flag = true, prefix = "UPDATE_", value = { 760 UPDATE_CPU, 761 UPDATE_WIFI, 762 UPDATE_RADIO, 763 UPDATE_BT, 764 UPDATE_RPM, 765 UPDATE_DISPLAY, 766 UPDATE_CAMERA, 767 UPDATE_ALL, 768 }) 769 @Retention(RetentionPolicy.SOURCE) 770 public @interface ExternalUpdateFlag { 771 } 772 scheduleSync(String reason, int flags)773 Future<?> scheduleSync(String reason, int flags); scheduleCpuSyncDueToRemovedUid(int uid)774 Future<?> scheduleCpuSyncDueToRemovedUid(int uid); 775 776 /** 777 * Schedule a sync because of a screen state change. 778 */ scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates)779 Future<?> scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, 780 boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates); scheduleCpuSyncDueToWakelockChange(long delayMillis)781 Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); cancelCpuSyncDueToWakelockChange()782 void cancelCpuSyncDueToWakelockChange(); scheduleSyncDueToBatteryLevelChange(long delayMillis)783 Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); 784 /** Schedule removal of UIDs corresponding to a removed user */ scheduleCleanupDueToRemovedUser(int userId)785 Future<?> scheduleCleanupDueToRemovedUser(int userId); 786 /** Schedule a sync because of a process state change */ scheduleSyncDueToProcessStateChange(int flags, long delayMillis)787 void scheduleSyncDueToProcessStateChange(int flags, long delayMillis); 788 } 789 790 public Handler mHandler; 791 private ExternalStatsSync mExternalSync = null; 792 @VisibleForTesting 793 protected UserInfoProvider mUserInfoProvider = null; 794 795 private BatteryCallback mCallback; 796 797 /** 798 * Mapping isolated uids to the actual owning app uid. 799 */ 800 private final SparseIntArray mIsolatedUids = new SparseIntArray(); 801 /** 802 * Internal reference count of isolated uids. 803 */ 804 private final SparseIntArray mIsolatedUidRefCounts = new SparseIntArray(); 805 806 /** 807 * The statistics we have collected organized by uids. 808 */ 809 private final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 810 811 // A set of pools of currently active timers. When a timer is queried, we will divide the 812 // elapsed time by the number of active timers to arrive at that timer's share of the time. 813 // In order to do this, we must refresh each timer whenever the number of active timers 814 // changes. 815 @VisibleForTesting 816 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 817 private final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 818 private final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 819 private final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 820 private final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 821 private final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 822 private final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 823 private final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 824 private final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 825 private final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = 826 new SparseArray<>(); 827 private final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 828 private final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 829 private final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 830 private final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 831 private final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 832 833 // Last partial timers we use for distributing CPU usage. 834 @VisibleForTesting 835 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 836 837 // These are the objects that will want to do something when the device 838 // is unplugged from power. 839 protected final TimeBase mOnBatteryTimeBase = new TimeBase(true); 840 841 // These are the objects that will want to do something when the device 842 // is unplugged from power *and* the screen is off or doze. 843 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true); 844 845 private boolean mSystemReady; 846 private boolean mShuttingDown; 847 848 private final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 849 private final HistoryStepDetailsCalculatorImpl mStepDetailsCalculator = 850 new HistoryStepDetailsCalculatorImpl(); 851 852 private boolean mHaveBatteryLevel = false; 853 private boolean mBatteryPluggedIn; 854 private long mBatteryPluggedInRealTimeMs = 0; 855 private int mBatteryStatus; 856 private int mBatteryLevel; 857 private int mBatteryPlugType; 858 private int mBatteryChargeUah; 859 private int mBatteryHealth; 860 private int mBatteryTemperature; 861 private int mBatteryVoltageMv = -1; 862 863 @NonNull 864 private final BatteryStatsHistory mHistory; 865 866 int mStartCount; 867 868 /** 869 * Set to true when a reset occurs, informing us that the next time BatteryExternalStatsWorker 870 * gives us data, we mustn't process it since this data includes pre-reset-period data. 871 */ 872 @GuardedBy("this") 873 boolean mIgnoreNextExternalStats = false; 874 875 long mStartClockTimeMs; 876 String mStartPlatformVersion; 877 String mEndPlatformVersion; 878 879 long mUptimeUs; 880 long mUptimeStartUs; 881 long mRealtimeUs; 882 long mRealtimeStartUs; 883 884 int mWakeLockNesting; 885 boolean mWakeLockImportant; 886 public boolean mRecordAllHistory; 887 boolean mNoAutoReset; 888 889 /** 890 * Overall screen state. For multidisplay devices, this represents the current highest screen 891 * state of the displays. 892 */ 893 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 894 protected int mScreenState = Display.STATE_UNKNOWN; 895 /** 896 * Overall screen on timer. For multidisplay devices, this represents the time spent with at 897 * least one display in the screen on state. 898 */ 899 StopwatchTimer mScreenOnTimer; 900 /** 901 * Overall screen doze timer. For multidisplay devices, this represents the time spent with 902 * screen doze being the highest screen state. 903 */ 904 StopwatchTimer mScreenDozeTimer; 905 /** 906 * Overall screen brightness bin. For multidisplay devices, this represents the current 907 * brightest screen. 908 */ 909 int mScreenBrightnessBin = -1; 910 /** 911 * Overall screen brightness timers. For multidisplay devices, the {@link mScreenBrightnessBin} 912 * timer will be active at any given time 913 */ 914 final StopwatchTimer[] mScreenBrightnessTimer = 915 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 916 917 boolean mPretendScreenOff; 918 919 private static class DisplayBatteryStats { 920 /** 921 * Per display screen state. 922 */ 923 public int screenState = Display.STATE_UNKNOWN; 924 /** 925 * Per display screen on timers. 926 */ 927 public StopwatchTimer screenOnTimer; 928 /** 929 * Per display screen doze timers. 930 */ 931 public StopwatchTimer screenDozeTimer; 932 /** 933 * Per display screen brightness bins. 934 */ 935 public int screenBrightnessBin = -1; 936 /** 937 * Per display screen brightness timers. 938 */ 939 public StopwatchTimer[] screenBrightnessTimers = 940 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 941 /** 942 * Per display screen state the last time {@link #updateDisplayEnergyConsumerStatsLocked} 943 * was called. 944 */ 945 public int screenStateAtLastEnergyMeasurement = Display.STATE_UNKNOWN; 946 DisplayBatteryStats(Clock clock, TimeBase timeBase)947 DisplayBatteryStats(Clock clock, TimeBase timeBase) { 948 screenOnTimer = new StopwatchTimer(clock, null, -1, null, 949 timeBase); 950 screenDozeTimer = new StopwatchTimer(clock, null, -1, null, 951 timeBase); 952 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 953 screenBrightnessTimers[i] = new StopwatchTimer(clock, null, -100 - i, null, 954 timeBase); 955 } 956 } 957 958 /** 959 * Reset display timers. 960 */ reset(long elapsedRealtimeUs)961 public void reset(long elapsedRealtimeUs) { 962 screenOnTimer.reset(false, elapsedRealtimeUs); 963 screenDozeTimer.reset(false, elapsedRealtimeUs); 964 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 965 screenBrightnessTimers[i].reset(false, elapsedRealtimeUs); 966 } 967 } 968 969 /** 970 * Write data to summary parcel 971 */ writeSummaryToParcel(Parcel out, long elapsedRealtimeUs)972 public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { 973 screenOnTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 974 screenDozeTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 975 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 976 screenBrightnessTimers[i].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 977 } 978 } 979 980 /** 981 * Read data from summary parcel 982 */ readSummaryFromParcel(Parcel in)983 public void readSummaryFromParcel(Parcel in) { 984 screenOnTimer.readSummaryFromParcelLocked(in); 985 screenDozeTimer.readSummaryFromParcelLocked(in); 986 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 987 screenBrightnessTimers[i].readSummaryFromParcelLocked(in); 988 } 989 } 990 } 991 992 DisplayBatteryStats[] mPerDisplayBatteryStats; 993 994 private int mDisplayMismatchWtfCount = 0; 995 996 boolean mInteractive; 997 StopwatchTimer mInteractiveTimer; 998 999 boolean mPowerSaveModeEnabled; 1000 StopwatchTimer mPowerSaveModeEnabledTimer; 1001 1002 boolean mDeviceIdling; 1003 StopwatchTimer mDeviceIdlingTimer; 1004 1005 boolean mDeviceLightIdling; 1006 StopwatchTimer mDeviceLightIdlingTimer; 1007 1008 int mDeviceIdleMode; 1009 long mLastIdleTimeStartMs; 1010 long mLongestLightIdleTimeMs; 1011 long mLongestFullIdleTimeMs; 1012 StopwatchTimer mDeviceIdleModeLightTimer; 1013 StopwatchTimer mDeviceIdleModeFullTimer; 1014 1015 boolean mPhoneOn; 1016 StopwatchTimer mPhoneOnTimer; 1017 1018 int mAudioOnNesting; 1019 StopwatchTimer mAudioOnTimer; 1020 1021 int mVideoOnNesting; 1022 StopwatchTimer mVideoOnTimer; 1023 1024 int mFlashlightOnNesting; 1025 StopwatchTimer mFlashlightOnTimer; 1026 1027 int mCameraOnNesting; 1028 StopwatchTimer mCameraOnTimer; 1029 1030 private static final int USB_DATA_UNKNOWN = 0; 1031 private static final int USB_DATA_DISCONNECTED = 1; 1032 private static final int USB_DATA_CONNECTED = 2; 1033 int mUsbDataState = USB_DATA_UNKNOWN; 1034 1035 int mGpsSignalQualityBin = -1; 1036 final StopwatchTimer[] mGpsSignalQualityTimer = 1037 new StopwatchTimer[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS]; 1038 1039 int mPhoneSignalStrengthBin = -1; 1040 int mPhoneSignalStrengthBinRaw = -1; 1041 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 1042 new StopwatchTimer[CellSignalStrength.getNumSignalStrengthLevels()]; 1043 1044 StopwatchTimer mPhoneSignalScanningTimer; 1045 1046 int mPhoneDataConnectionType = -1; 1047 final StopwatchTimer[] mPhoneDataConnectionsTimer = 1048 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 1049 1050 @RadioAccessTechnology 1051 int mActiveRat = RADIO_ACCESS_TECHNOLOGY_OTHER; 1052 1053 private static class RadioAccessTechnologyBatteryStats { 1054 /** 1055 * This RAT is currently being used. 1056 */ 1057 private boolean mActive = false; 1058 /** 1059 * Current active frequency range for this RAT. 1060 */ 1061 @ServiceState.FrequencyRange 1062 private int mFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN; 1063 /** 1064 * Current signal strength for this RAT. 1065 */ 1066 private int mSignalStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1067 /** 1068 * Timers for each combination of frequency range and signal strength. 1069 */ 1070 public final StopwatchTimer[][] perStateTimers; 1071 /** 1072 * Counters tracking the time (in milliseconds) spent transmitting data in a given state. 1073 */ 1074 @Nullable 1075 private LongSamplingCounter[][] mPerStateTxDurationMs = null; 1076 /** 1077 * Counters tracking the time (in milliseconds) spent receiving data in at given frequency. 1078 */ 1079 @Nullable 1080 private LongSamplingCounter[] mPerFrequencyRxDurationMs = null; 1081 RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase)1082 RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase) { 1083 perStateTimers = 1084 new StopwatchTimer[freqCount][CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 1085 for (int i = 0; i < freqCount; i++) { 1086 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1087 perStateTimers[i][j] = new StopwatchTimer(clock, null, -1, null, timeBase); 1088 } 1089 } 1090 } 1091 1092 /** 1093 * Note this RAT is currently being used. 1094 */ noteActive(boolean active, long elapsedRealtimeMs)1095 public void noteActive(boolean active, long elapsedRealtimeMs) { 1096 if (mActive == active) return; 1097 mActive = active; 1098 if (mActive) { 1099 perStateTimers[mFrequencyRange][mSignalStrength].startRunningLocked( 1100 elapsedRealtimeMs); 1101 } else { 1102 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked( 1103 elapsedRealtimeMs); 1104 } 1105 } 1106 1107 /** 1108 * Note current frequency range has changed. 1109 */ noteFrequencyRange(@erviceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs)1110 public void noteFrequencyRange(@ServiceState.FrequencyRange int frequencyRange, 1111 long elapsedRealtimeMs) { 1112 if (mFrequencyRange == frequencyRange) return; 1113 1114 if (!mActive) { 1115 // RAT not in use, note the frequency change and move on. 1116 mFrequencyRange = frequencyRange; 1117 return; 1118 } 1119 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked(elapsedRealtimeMs); 1120 perStateTimers[frequencyRange][mSignalStrength].startRunningLocked(elapsedRealtimeMs); 1121 mFrequencyRange = frequencyRange; 1122 } 1123 1124 /** 1125 * Note current signal strength has changed. 1126 */ noteSignalStrength(int signalStrength, long elapsedRealtimeMs)1127 public void noteSignalStrength(int signalStrength, long elapsedRealtimeMs) { 1128 if (mSignalStrength == signalStrength) return; 1129 1130 if (!mActive) { 1131 // RAT not in use, note the signal strength change and move on. 1132 mSignalStrength = signalStrength; 1133 return; 1134 } 1135 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked(elapsedRealtimeMs); 1136 perStateTimers[mFrequencyRange][signalStrength].startRunningLocked(elapsedRealtimeMs); 1137 mSignalStrength = signalStrength; 1138 } 1139 1140 /** 1141 * Returns the duration in milliseconds spent in a given state since the last mark. 1142 */ getTimeSinceMark(@erviceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)1143 public long getTimeSinceMark(@ServiceState.FrequencyRange int frequencyRange, 1144 int signalStrength, long elapsedRealtimeMs) { 1145 return perStateTimers[frequencyRange][signalStrength].getTimeSinceMarkLocked( 1146 elapsedRealtimeMs * 1000) / 1000; 1147 } 1148 1149 /** 1150 * Set mark for all timers. 1151 */ setMark(long elapsedRealtimeMs)1152 public void setMark(long elapsedRealtimeMs) { 1153 final int size = perStateTimers.length; 1154 for (int i = 0; i < size; i++) { 1155 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1156 perStateTimers[i][j].setMark(elapsedRealtimeMs); 1157 } 1158 } 1159 } 1160 1161 /** 1162 * Returns numbers of frequencies tracked for this RAT. 1163 */ getFrequencyRangeCount()1164 public int getFrequencyRangeCount() { 1165 return perStateTimers.length; 1166 } 1167 1168 /** 1169 * Add TX time for a given state. 1170 */ incrementTxDuration(@erviceState.FrequencyRange int frequencyRange, int signalStrength, long durationMs)1171 public void incrementTxDuration(@ServiceState.FrequencyRange int frequencyRange, 1172 int signalStrength, long durationMs) { 1173 getTxDurationCounter(frequencyRange, signalStrength, true).addCountLocked(durationMs); 1174 } 1175 1176 /** 1177 * Add TX time for a given frequency. 1178 */ incrementRxDuration(@erviceState.FrequencyRange int frequencyRange, long durationMs)1179 public void incrementRxDuration(@ServiceState.FrequencyRange int frequencyRange, 1180 long durationMs) { 1181 getRxDurationCounter(frequencyRange, true).addCountLocked(durationMs); 1182 } 1183 1184 /** 1185 * Reset radio access technology timers and counts. 1186 */ reset(long elapsedRealtimeUs)1187 public void reset(long elapsedRealtimeUs) { 1188 final int size = perStateTimers.length; 1189 for (int i = 0; i < size; i++) { 1190 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1191 perStateTimers[i][j].reset(false, elapsedRealtimeUs); 1192 if (mPerStateTxDurationMs == null) continue; 1193 mPerStateTxDurationMs[i][j].reset(false, elapsedRealtimeUs); 1194 } 1195 if (mPerFrequencyRxDurationMs == null) continue; 1196 mPerFrequencyRxDurationMs[i].reset(false, elapsedRealtimeUs); 1197 } 1198 } 1199 1200 /** 1201 * Write data to summary parcel 1202 */ writeSummaryToParcel(Parcel out, long elapsedRealtimeUs)1203 public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { 1204 final int freqCount = perStateTimers.length; 1205 out.writeInt(freqCount); 1206 out.writeInt(CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS); 1207 for (int i = 0; i < freqCount; i++) { 1208 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1209 perStateTimers[i][j].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1210 } 1211 } 1212 1213 if (mPerStateTxDurationMs == null) { 1214 out.writeInt(0); 1215 } else { 1216 out.writeInt(1); 1217 for (int i = 0; i < freqCount; i++) { 1218 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1219 mPerStateTxDurationMs[i][j].writeSummaryFromParcelLocked(out); 1220 } 1221 } 1222 } 1223 1224 if (mPerFrequencyRxDurationMs == null) { 1225 out.writeInt(0); 1226 } else { 1227 out.writeInt(1); 1228 for (int i = 0; i < freqCount; i++) { 1229 mPerFrequencyRxDurationMs[i].writeSummaryFromParcelLocked(out); 1230 } 1231 } 1232 } 1233 1234 /** 1235 * Read data from summary parcel 1236 */ readSummaryFromParcel(Parcel in)1237 public void readSummaryFromParcel(Parcel in) { 1238 final int oldFreqCount = in.readInt(); 1239 final int oldSignalStrengthCount = in.readInt(); 1240 final int currFreqCount = perStateTimers.length; 1241 final int currSignalStrengthCount = CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; 1242 1243 for (int freq = 0; freq < oldFreqCount; freq++) { 1244 for (int strength = 0; strength < oldSignalStrengthCount; strength++) { 1245 if (freq >= currFreqCount || strength >= currSignalStrengthCount) { 1246 // Mismatch with the summary parcel. Consume the data but don't use it. 1247 final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, 1248 new TimeBase()); 1249 // Consume perStateTimers data. 1250 temp.readSummaryFromParcelLocked(in); 1251 } else { 1252 perStateTimers[freq][strength].readSummaryFromParcelLocked(in); 1253 } 1254 } 1255 } 1256 1257 if (in.readInt() == 1) { 1258 for (int freq = 0; freq < oldFreqCount; freq++) { 1259 for (int strength = 0; strength < oldSignalStrengthCount; strength++) { 1260 if (freq >= currFreqCount || strength >= currSignalStrengthCount) { 1261 // Mismatch with the summary parcel. Consume the data but don't use it. 1262 final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, 1263 new TimeBase()); 1264 // Consume mPerStateTxDurationMs data. 1265 temp.readSummaryFromParcelLocked(in); 1266 } 1267 getTxDurationCounter(freq, strength, true).readSummaryFromParcelLocked(in); 1268 } 1269 } 1270 } 1271 1272 if (in.readInt() == 1) { 1273 for (int freq = 0; freq < oldFreqCount; freq++) { 1274 if (freq >= currFreqCount) { 1275 // Mismatch with the summary parcel. Consume the data but don't use it. 1276 final StopwatchTimer 1277 temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); 1278 // Consume mPerFrequencyRxDurationMs data. 1279 temp.readSummaryFromParcelLocked(in); 1280 continue; 1281 } 1282 getRxDurationCounter(freq, true).readSummaryFromParcelLocked(in); 1283 } 1284 } 1285 } 1286 getTxDurationCounter( @erviceState.FrequencyRange int frequencyRange, int signalStrength, boolean make)1287 private LongSamplingCounter getTxDurationCounter( 1288 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, boolean make) { 1289 if (mPerStateTxDurationMs == null) { 1290 if (!make) return null; 1291 1292 final int freqCount = getFrequencyRangeCount(); 1293 final int signalStrengthCount = perStateTimers[0].length; 1294 final TimeBase timeBase = perStateTimers[0][0].mTimeBase; 1295 mPerStateTxDurationMs = new LongSamplingCounter[freqCount][signalStrengthCount]; 1296 for (int freq = 0; freq < freqCount; freq++) { 1297 for (int strength = 0; strength < signalStrengthCount; strength++) { 1298 mPerStateTxDurationMs[freq][strength] = new LongSamplingCounter(timeBase); 1299 } 1300 } 1301 } 1302 if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { 1303 Slog.w(TAG, "Unexpected frequency range (" + frequencyRange 1304 + ") requested in getTxDurationCounter"); 1305 return null; 1306 } 1307 if (signalStrength < 0 || signalStrength >= perStateTimers[0].length) { 1308 Slog.w(TAG, "Unexpected signal strength (" + signalStrength 1309 + ") requested in getTxDurationCounter"); 1310 return null; 1311 } 1312 return mPerStateTxDurationMs[frequencyRange][signalStrength]; 1313 } 1314 getRxDurationCounter( @erviceState.FrequencyRange int frequencyRange, boolean make)1315 private LongSamplingCounter getRxDurationCounter( 1316 @ServiceState.FrequencyRange int frequencyRange, boolean make) { 1317 if (mPerFrequencyRxDurationMs == null) { 1318 if (!make) return null; 1319 1320 final int freqCount = getFrequencyRangeCount(); 1321 final TimeBase timeBase = perStateTimers[0][0].mTimeBase; 1322 mPerFrequencyRxDurationMs = new LongSamplingCounter[freqCount]; 1323 for (int freq = 0; freq < freqCount; freq++) { 1324 mPerFrequencyRxDurationMs[freq] = new LongSamplingCounter(timeBase); 1325 } 1326 } 1327 if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { 1328 Slog.w(TAG, "Unexpected frequency range (" + frequencyRange 1329 + ") requested in getRxDurationCounter"); 1330 return null; 1331 } 1332 return mPerFrequencyRxDurationMs[frequencyRange]; 1333 } 1334 } 1335 1336 /** 1337 * Number of frequency ranges, keep in sync with {@link ServiceState.FrequencyRange} 1338 */ 1339 private static final int NR_FREQUENCY_COUNT = 5; 1340 1341 RadioAccessTechnologyBatteryStats[] mPerRatBatteryStats = 1342 new RadioAccessTechnologyBatteryStats[RADIO_ACCESS_TECHNOLOGY_COUNT]; 1343 1344 @GuardedBy("this") getRatBatteryStatsLocked( @adioAccessTechnology int rat)1345 private RadioAccessTechnologyBatteryStats getRatBatteryStatsLocked( 1346 @RadioAccessTechnology int rat) { 1347 RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 1348 if (stats == null) { 1349 final int freqCount = rat == RADIO_ACCESS_TECHNOLOGY_NR ? NR_FREQUENCY_COUNT : 1; 1350 stats = new RadioAccessTechnologyBatteryStats(freqCount, mClock, mOnBatteryTimeBase); 1351 mPerRatBatteryStats[rat] = stats; 1352 } 1353 return stats; 1354 } 1355 1356 final LongSamplingCounter[] mNetworkByteActivityCounters = 1357 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 1358 1359 final LongSamplingCounter[] mNetworkPacketActivityCounters = 1360 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 1361 1362 /** 1363 * The WiFi Overall wakelock timer 1364 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 1365 * since addition of per UID timers would not result in an accurate value due to overlapp of 1366 * per uid wakelock timers 1367 */ 1368 StopwatchTimer mWifiMulticastWakelockTimer; 1369 1370 /** 1371 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 1372 */ 1373 ControllerActivityCounterImpl mWifiActivity; 1374 1375 /** 1376 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 1377 */ 1378 ControllerActivityCounterImpl mBluetoothActivity; 1379 1380 /** 1381 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 1382 */ 1383 ControllerActivityCounterImpl mModemActivity; 1384 1385 /** 1386 * Whether the device supports WiFi controller energy reporting. This is set to true on 1387 * the first WiFi energy report. See {@link #mWifiActivity}. 1388 */ 1389 boolean mHasWifiReporting = false; 1390 1391 /** 1392 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 1393 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 1394 */ 1395 boolean mHasBluetoothReporting = false; 1396 1397 /** 1398 * Whether the device supports Modem controller energy reporting. This is set to true on 1399 * the first Modem energy report. See {@link #mModemActivity}. 1400 */ 1401 boolean mHasModemReporting = false; 1402 1403 boolean mWifiOn; 1404 StopwatchTimer mWifiOnTimer; 1405 1406 boolean mGlobalWifiRunning; 1407 StopwatchTimer mGlobalWifiRunningTimer; 1408 1409 int mWifiState = -1; 1410 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 1411 1412 int mWifiSupplState = -1; 1413 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 1414 1415 int mWifiSignalStrengthBin = -1; 1416 final StopwatchTimer[] mWifiSignalStrengthsTimer = 1417 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 1418 1419 StopwatchTimer mWifiActiveTimer; 1420 1421 int mBluetoothScanNesting; 1422 StopwatchTimer mBluetoothScanTimer; 1423 1424 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1425 long mMobileRadioActiveStartTimeMs; 1426 StopwatchTimer mMobileRadioActiveTimer; 1427 StopwatchTimer mMobileRadioActivePerAppTimer; 1428 LongSamplingCounter mMobileRadioActiveAdjustedTime; 1429 LongSamplingCounter mMobileRadioActiveUnknownTime; 1430 LongSamplingCounter mMobileRadioActiveUnknownCount; 1431 1432 /** 1433 * The soonest the Mobile Radio stats can be updated due to a mobile radio power state change 1434 * after it was last updated. 1435 */ 1436 @VisibleForTesting 1437 protected static final long MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS = 1000 * 60 * 10; 1438 1439 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1440 1441 @GuardedBy("this") 1442 @VisibleForTesting 1443 protected @Nullable EnergyConsumerStats.Config mEnergyConsumerStatsConfig; 1444 1445 /** 1446 * Accumulated global (generally, device-wide total) charge consumption of various consumers 1447 * while on battery. 1448 * Its '<b>custom</b> power buckets' correspond to the 1449 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 1450 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 1451 * 1452 * If energy consumer data is completely unavailable this will be null. 1453 */ 1454 @GuardedBy("this") 1455 @VisibleForTesting 1456 @Nullable 1457 protected EnergyConsumerStats mGlobalEnergyConsumerStats; 1458 /** Bluetooth Power calculator for attributing bluetooth EnergyConsumer to uids */ 1459 @Nullable BluetoothPowerCalculator mBluetoothPowerCalculator = null; 1460 /** Cpu Power calculator for attributing cpu EnergyConsumer to uids */ 1461 @Nullable CpuPowerCalculator mCpuPowerCalculator = null; 1462 /** Mobile Radio Power calculator for attributing radio EnergyConsumer to uids */ 1463 @Nullable MobileRadioPowerCalculator mMobileRadioPowerCalculator = null; 1464 /** Wifi Power calculator for attributing wifi EnergyConsumer to uids */ 1465 @Nullable WifiPowerCalculator mWifiPowerCalculator = null; 1466 1467 /** 1468 * These provide time bases that discount the time the device is plugged 1469 * in to power. 1470 */ 1471 boolean mOnBattery; 1472 @VisibleForTesting 1473 protected boolean mOnBatteryInternal; 1474 1475 /** 1476 * External reporting of whether the device is actually charging. 1477 */ 1478 boolean mCharging = true; 1479 1480 /* 1481 * These keep track of battery levels (1-100) at the last unplug event. 1482 */ 1483 int mDischargeUnplugLevel; 1484 int mDischargePlugLevel; 1485 int mDischargeCurrentLevel; 1486 int mLowDischargeAmountSinceCharge; 1487 int mHighDischargeAmountSinceCharge; 1488 int mDischargeScreenOnUnplugLevel; 1489 int mDischargeScreenOffUnplugLevel; 1490 int mDischargeScreenDozeUnplugLevel; 1491 int mDischargeAmountScreenOn; 1492 int mDischargeAmountScreenOnSinceCharge; 1493 int mDischargeAmountScreenOff; 1494 int mDischargeAmountScreenOffSinceCharge; 1495 int mDischargeAmountScreenDoze; 1496 int mDischargeAmountScreenDozeSinceCharge; 1497 1498 private LongSamplingCounter mDischargeScreenOffCounter; 1499 private LongSamplingCounter mDischargeScreenDozeCounter; 1500 private LongSamplingCounter mDischargeCounter; 1501 private LongSamplingCounter mDischargeLightDozeCounter; 1502 private LongSamplingCounter mDischargeDeepDozeCounter; 1503 1504 static final int MAX_LEVEL_STEPS = 200; 1505 1506 int mInitStepMode = 0; 1507 int mCurStepMode = 0; 1508 int mModStepMode = 0; 1509 1510 int mLastDischargeStepLevel; 1511 int mMinDischargeStepLevel; 1512 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1513 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1514 ArrayList<PackageChange> mDailyPackageChanges; 1515 1516 int mLastChargeStepLevel; 1517 int mMaxChargeStepLevel; 1518 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1519 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1520 1521 static final int MAX_DAILY_ITEMS = 10; 1522 1523 long mDailyStartTimeMs = 0; 1524 long mNextMinDailyDeadlineMs = 0; 1525 long mNextMaxDailyDeadlineMs = 0; 1526 1527 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 1528 1529 long mLastWriteTimeMs = 0; // Milliseconds 1530 1531 private int mPhoneServiceState = -1; 1532 private int mPhoneServiceStateRaw = -1; 1533 private int mPhoneSimStateRaw = -1; 1534 1535 private int mNumConnectivityChange; 1536 1537 private int mEstimatedBatteryCapacityMah = -1; 1538 1539 private int mLastLearnedBatteryCapacityUah = -1; 1540 private int mMinLearnedBatteryCapacityUah = -1; 1541 private int mMaxLearnedBatteryCapacityUah = -1; 1542 1543 private long mBatteryTimeToFullSeconds = -1; 1544 1545 private boolean mCpuFreqsInitialized; 1546 private long[] mCpuFreqs; 1547 private LongArrayMultiStateCounter.LongArrayContainer mTmpCpuTimeInFreq; 1548 1549 /** 1550 * Times spent by the system server threads handling incoming binder requests. 1551 */ 1552 private LongSamplingCounterArray mBinderThreadCpuTimesUs; 1553 1554 @VisibleForTesting 1555 protected PowerProfile mPowerProfile; 1556 1557 @VisibleForTesting 1558 @GuardedBy("this") 1559 protected final Constants mConstants; 1560 1561 @VisibleForTesting 1562 @GuardedBy("this") 1563 protected BatteryStatsConfig mBatteryStatsConfig = new BatteryStatsConfig.Builder().build(); 1564 1565 @GuardedBy("this") 1566 private AlarmManager mAlarmManager = null; 1567 1568 private final AlarmManager.OnAlarmListener mLongPlugInAlarmHandler = () -> 1569 mHandler.post(() -> { 1570 synchronized (BatteryStatsImpl.this) { 1571 maybeResetWhilePluggedInLocked(); 1572 } 1573 }); 1574 1575 /* 1576 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 1577 * recording their times when on-battery (regardless of screen state). 1578 */ 1579 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 1580 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 1581 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 1582 1583 @Override getRpmStats()1584 public Map<String, ? extends Timer> getRpmStats() { 1585 return mRpmStats; 1586 } 1587 1588 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 1589 @Override getScreenOffRpmStats()1590 public Map<String, ? extends Timer> getScreenOffRpmStats() { 1591 return mScreenOffRpmStats; 1592 } 1593 1594 /* 1595 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 1596 */ 1597 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 1598 getKernelWakelockStats()1599 public Map<String, ? extends Timer> getKernelWakelockStats() { 1600 return mKernelWakelockStats; 1601 } 1602 1603 @Override getWakeLockStats()1604 public WakeLockStats getWakeLockStats() { 1605 final long realtimeMs = mClock.elapsedRealtime(); 1606 final long realtimeUs = realtimeMs * 1000; 1607 List<WakeLockStats.WakeLock> uidWakeLockStats = new ArrayList<>(); 1608 for (int i = mUidStats.size() - 1; i >= 0; i--) { 1609 final Uid uid = mUidStats.valueAt(i); 1610 final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = 1611 uid.mWakelockStats.getMap(); 1612 for (int j = wakelockStats.size() - 1; j >= 0; j--) { 1613 final String name = wakelockStats.keyAt(j); 1614 final Uid.Wakelock wakelock = (Uid.Wakelock) wakelockStats.valueAt(j); 1615 final DualTimer timer = wakelock.mTimerPartial; 1616 if (timer != null) { 1617 final long totalTimeLockHeldMs = 1618 timer.getTotalTimeLocked(realtimeUs, STATS_SINCE_CHARGED) / 1000; 1619 if (totalTimeLockHeldMs != 0) { 1620 uidWakeLockStats.add( 1621 new WakeLockStats.WakeLock(uid.getUid(), name, 1622 timer.getCountLocked(STATS_SINCE_CHARGED), 1623 totalTimeLockHeldMs, 1624 timer.isRunningLocked() 1625 ? timer.getCurrentDurationMsLocked(realtimeMs) 1626 : 0)); 1627 } 1628 } 1629 } 1630 } 1631 return new WakeLockStats(uidWakeLockStats); 1632 } 1633 1634 @Override 1635 @GuardedBy("this") getBluetoothBatteryStats()1636 public BluetoothBatteryStats getBluetoothBatteryStats() { 1637 final long elapsedRealtimeUs = mClock.elapsedRealtime() * 1000; 1638 ArrayList<BluetoothBatteryStats.UidStats> uidStats = new ArrayList<>(); 1639 for (int i = mUidStats.size() - 1; i >= 0; i--) { 1640 final Uid uid = mUidStats.valueAt(i); 1641 final Timer scanTimer = uid.getBluetoothScanTimer(); 1642 final long scanTimeMs = 1643 scanTimer != null ? scanTimer.getTotalTimeLocked( 1644 elapsedRealtimeUs, STATS_SINCE_CHARGED) / 1000 : 0; 1645 1646 final Timer unoptimizedScanTimer = uid.getBluetoothUnoptimizedScanTimer(); 1647 final long unoptimizedScanTimeMs = 1648 unoptimizedScanTimer != null ? unoptimizedScanTimer.getTotalTimeLocked( 1649 elapsedRealtimeUs, STATS_SINCE_CHARGED) / 1000 : 0; 1650 1651 final Counter scanResultCounter = uid.getBluetoothScanResultCounter(); 1652 final int scanResultCount = 1653 scanResultCounter != null ? scanResultCounter.getCountLocked( 1654 STATS_SINCE_CHARGED) : 0; 1655 1656 final ControllerActivityCounter counter = uid.getBluetoothControllerActivity(); 1657 final long rxTimeMs = counter != null ? counter.getRxTimeCounter().getCountLocked( 1658 STATS_SINCE_CHARGED) : 0; 1659 final long txTimeMs = counter != null ? counter.getTxTimeCounters()[0].getCountLocked( 1660 STATS_SINCE_CHARGED) : 0; 1661 1662 if (scanTimeMs != 0 || unoptimizedScanTimeMs != 0 || scanResultCount != 0 1663 || rxTimeMs != 0 || txTimeMs != 0) { 1664 uidStats.add(new BluetoothBatteryStats.UidStats(uid.getUid(), 1665 scanTimeMs, 1666 unoptimizedScanTimeMs, 1667 scanResultCount, 1668 rxTimeMs, 1669 txTimeMs)); 1670 } 1671 } 1672 1673 return new BluetoothBatteryStats(uidStats); 1674 } 1675 1676 String mLastWakeupReason = null; 1677 long mLastWakeupUptimeMs = 0; 1678 long mLastWakeupElapsedTimeMs = 0; 1679 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 1680 getWakeupReasonStats()1681 public Map<String, ? extends Timer> getWakeupReasonStats() { 1682 return mWakeupReasonStats; 1683 } 1684 1685 @Override getUahDischarge(int which)1686 public long getUahDischarge(int which) { 1687 return mDischargeCounter.getCountLocked(which); 1688 } 1689 1690 @Override getUahDischargeScreenOff(int which)1691 public long getUahDischargeScreenOff(int which) { 1692 return mDischargeScreenOffCounter.getCountLocked(which); 1693 } 1694 1695 @Override getUahDischargeScreenDoze(int which)1696 public long getUahDischargeScreenDoze(int which) { 1697 return mDischargeScreenDozeCounter.getCountLocked(which); 1698 } 1699 1700 @Override getUahDischargeLightDoze(int which)1701 public long getUahDischargeLightDoze(int which) { 1702 return mDischargeLightDozeCounter.getCountLocked(which); 1703 } 1704 1705 @Override getUahDischargeDeepDoze(int which)1706 public long getUahDischargeDeepDoze(int which) { 1707 return mDischargeDeepDozeCounter.getCountLocked(which); 1708 } 1709 1710 @Override getEstimatedBatteryCapacity()1711 public int getEstimatedBatteryCapacity() { 1712 return mEstimatedBatteryCapacityMah; 1713 } 1714 1715 @Override getLearnedBatteryCapacity()1716 public int getLearnedBatteryCapacity() { 1717 return mLastLearnedBatteryCapacityUah; 1718 } 1719 1720 @Override getMinLearnedBatteryCapacity()1721 public int getMinLearnedBatteryCapacity() { 1722 return mMinLearnedBatteryCapacityUah; 1723 } 1724 1725 @Override getMaxLearnedBatteryCapacity()1726 public int getMaxLearnedBatteryCapacity() { 1727 return mMaxLearnedBatteryCapacityUah; 1728 } 1729 BatteryStatsImpl()1730 public BatteryStatsImpl() { 1731 this(Clock.SYSTEM_CLOCK); 1732 } 1733 BatteryStatsImpl(Clock clock)1734 public BatteryStatsImpl(Clock clock) { 1735 this(clock, null); 1736 } 1737 BatteryStatsImpl(Clock clock, File historyDirectory)1738 public BatteryStatsImpl(Clock clock, File historyDirectory) { 1739 init(clock); 1740 mHandler = null; 1741 mConstants = new Constants(mHandler); 1742 mStartClockTimeMs = clock.currentTimeMillis(); 1743 mDailyFile = null; 1744 if (historyDirectory == null) { 1745 mCheckinFile = null; 1746 mStatsFile = null; 1747 mHistory = new BatteryStatsHistory(mConstants.MAX_HISTORY_FILES, 1748 mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock); 1749 } else { 1750 mCheckinFile = new AtomicFile(new File(historyDirectory, "batterystats-checkin.bin")); 1751 mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin")); 1752 mHistory = new BatteryStatsHistory(historyDirectory, mConstants.MAX_HISTORY_FILES, 1753 mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock); 1754 } 1755 mPlatformIdleStateCallback = null; 1756 mEnergyConsumerRetriever = null; 1757 mUserInfoProvider = null; 1758 } 1759 init(Clock clock)1760 private void init(Clock clock) { 1761 mClock = clock; 1762 mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(true, clock); 1763 mCpuUidFreqTimeReader = new KernelCpuUidFreqTimeReader(true, clock); 1764 mCpuUidActiveTimeReader = new KernelCpuUidActiveTimeReader(true, clock); 1765 mCpuUidClusterTimeReader = new KernelCpuUidClusterTimeReader(true, clock); 1766 } 1767 1768 /** 1769 * TimeBase observer. 1770 */ 1771 public interface TimeBaseObs { onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1772 void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1773 void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); 1774 1775 /** 1776 * Reset the observer's state, returns true if the timer/counter is inactive 1777 * so it can be destroyed. 1778 * @param detachIfReset detach if true, no-op if false. 1779 * @return Returns true if the timer/counter is inactive and can be destroyed. 1780 */ reset(boolean detachIfReset)1781 default boolean reset(boolean detachIfReset) { 1782 return reset(detachIfReset, SystemClock.elapsedRealtime() * 1000); 1783 } 1784 1785 /** 1786 * @see #reset(boolean) 1787 * @param detachIfReset detach if true, no-op if false. 1788 * @param elapsedRealtimeUs the timestamp when this reset is actually reequested 1789 * @return Returns true if the timer/counter is inactive and can be destroyed. 1790 */ reset(boolean detachIfReset, long elapsedRealtimeUs)1791 boolean reset(boolean detachIfReset, long elapsedRealtimeUs); 1792 1793 /** 1794 * Detach the observer from TimeBase. 1795 */ detach()1796 void detach(); 1797 } 1798 1799 // methods are protected not private to be VisibleForTesting 1800 public static class TimeBase { 1801 protected final Collection<TimeBaseObs> mObservers; 1802 1803 // All below time metrics are in microseconds. 1804 protected long mUptimeUs; 1805 protected long mRealtimeUs; 1806 1807 protected boolean mRunning; 1808 1809 protected long mPastUptimeUs; 1810 protected long mUptimeStartUs; 1811 protected long mPastRealtimeUs; 1812 protected long mRealtimeStartUs; 1813 protected long mUnpluggedUptimeUs; 1814 protected long mUnpluggedRealtimeUs; 1815 dump(PrintWriter pw, String prefix)1816 public void dump(PrintWriter pw, String prefix) { 1817 StringBuilder sb = new StringBuilder(128); 1818 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 1819 sb.setLength(0); 1820 sb.append(prefix); 1821 sb.append("mUptime="); 1822 formatTimeMs(sb, mUptimeUs / 1000); 1823 pw.println(sb.toString()); 1824 sb.setLength(0); 1825 sb.append(prefix); 1826 sb.append("mRealtime="); 1827 formatTimeMs(sb, mRealtimeUs / 1000); 1828 pw.println(sb.toString()); 1829 sb.setLength(0); 1830 sb.append(prefix); 1831 sb.append("mPastUptime="); 1832 formatTimeMs(sb, mPastUptimeUs / 1000); sb.append("mUptimeStart="); 1833 formatTimeMs(sb, mUptimeStartUs / 1000); 1834 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptimeUs / 1000); 1835 pw.println(sb.toString()); 1836 sb.setLength(0); 1837 sb.append(prefix); 1838 sb.append("mPastRealtime="); 1839 formatTimeMs(sb, mPastRealtimeUs / 1000); sb.append("mRealtimeStart="); 1840 formatTimeMs(sb, mRealtimeStartUs / 1000); 1841 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtimeUs / 1000); 1842 pw.println(sb.toString()); 1843 } 1844 /** 1845 * The mObservers of TimeBase in BatteryStatsImpl object can contain up to 20k entries. 1846 * The mObservers of TimeBase in BatteryStatsImpl.Uid object only contains a few or tens of 1847 * entries. 1848 * mObservers must have good performance on add(), remove(), also be memory efficient. 1849 * This is why we provide isLongList parameter for long and short list user cases. 1850 * @param isLongList If true, use HashSet for mObservers list. 1851 * If false, use ArrayList for mObservers list. 1852 */ TimeBase(boolean isLongList)1853 public TimeBase(boolean isLongList) { 1854 mObservers = isLongList ? new HashSet<>() : new ArrayList<>(); 1855 } 1856 TimeBase()1857 public TimeBase() { 1858 this(false); 1859 } 1860 add(TimeBaseObs observer)1861 public void add(TimeBaseObs observer) { 1862 mObservers.add(observer); 1863 } 1864 remove(TimeBaseObs observer)1865 public void remove(TimeBaseObs observer) { 1866 mObservers.remove(observer); 1867 } 1868 hasObserver(TimeBaseObs observer)1869 public boolean hasObserver(TimeBaseObs observer) { 1870 return mObservers.contains(observer); 1871 } 1872 init(long uptimeUs, long elapsedRealtimeUs)1873 public void init(long uptimeUs, long elapsedRealtimeUs) { 1874 mRealtimeUs = 0; 1875 mUptimeUs = 0; 1876 mPastUptimeUs = 0; 1877 mPastRealtimeUs = 0; 1878 mUptimeStartUs = uptimeUs; 1879 mRealtimeStartUs = elapsedRealtimeUs; 1880 mUnpluggedUptimeUs = getUptime(mUptimeStartUs); 1881 mUnpluggedRealtimeUs = getRealtime(mRealtimeStartUs); 1882 } 1883 reset(long uptimeUs, long elapsedRealtimeUs)1884 public void reset(long uptimeUs, long elapsedRealtimeUs) { 1885 if (!mRunning) { 1886 mPastUptimeUs = 0; 1887 mPastRealtimeUs = 0; 1888 } else { 1889 mUptimeStartUs = uptimeUs; 1890 mRealtimeStartUs = elapsedRealtimeUs; 1891 // TODO: Since mUptimeStartUs was just reset and we are running, getUptime will 1892 // just return mPastUptimeUs. Also, are we sure we don't want to reset that? 1893 mUnpluggedUptimeUs = getUptime(uptimeUs); 1894 // TODO: likewise. 1895 mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 1896 } 1897 } 1898 computeUptime(long curTimeUs, int which)1899 public long computeUptime(long curTimeUs, int which) { 1900 return mUptimeUs + getUptime(curTimeUs); 1901 } 1902 computeRealtime(long curTimeUs, int which)1903 public long computeRealtime(long curTimeUs, int which) { 1904 return mRealtimeUs + getRealtime(curTimeUs); 1905 } 1906 getUptime(long curTimeUs)1907 public long getUptime(long curTimeUs) { 1908 long time = mPastUptimeUs; 1909 if (mRunning) { 1910 time += curTimeUs - mUptimeStartUs; 1911 } 1912 return time; 1913 } 1914 getRealtime(long curTimeUs)1915 public long getRealtime(long curTimeUs) { 1916 long time = mPastRealtimeUs; 1917 if (mRunning) { 1918 time += curTimeUs - mRealtimeStartUs; 1919 } 1920 return time; 1921 } 1922 getUptimeStart()1923 public long getUptimeStart() { 1924 return mUptimeStartUs; 1925 } 1926 getRealtimeStart()1927 public long getRealtimeStart() { 1928 return mRealtimeStartUs; 1929 } 1930 isRunning()1931 public boolean isRunning() { 1932 return mRunning; 1933 } 1934 setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs)1935 public boolean setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs) { 1936 if (mRunning != running) { 1937 mRunning = running; 1938 if (running) { 1939 mUptimeStartUs = uptimeUs; 1940 mRealtimeStartUs = elapsedRealtimeUs; 1941 long batteryUptimeUs = mUnpluggedUptimeUs = getUptime(uptimeUs); 1942 long batteryRealtimeUs = mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 1943 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1944 // Iterator object, here is an exception because mObservers' type is Collection 1945 // instead of list. 1946 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1947 while (iter.hasNext()) { 1948 iter.next().onTimeStarted( 1949 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 1950 } 1951 } else { 1952 mPastUptimeUs += uptimeUs - mUptimeStartUs; 1953 mPastRealtimeUs += elapsedRealtimeUs - mRealtimeStartUs; 1954 long batteryUptimeUs = getUptime(uptimeUs); 1955 long batteryRealtimeUs = getRealtime(elapsedRealtimeUs); 1956 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1957 // Iterator object, here is an exception because mObservers' type is Collection 1958 // instead of list. 1959 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1960 while (iter.hasNext()) { 1961 iter.next().onTimeStopped( 1962 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 1963 } 1964 } 1965 return true; 1966 } 1967 return false; 1968 } 1969 readSummaryFromParcel(Parcel in)1970 public void readSummaryFromParcel(Parcel in) { 1971 mUptimeUs = in.readLong(); 1972 mRealtimeUs = in.readLong(); 1973 } 1974 writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)1975 public void writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 1976 out.writeLong(computeUptime(uptimeUs, STATS_SINCE_CHARGED)); 1977 out.writeLong(computeRealtime(elapsedRealtimeUs, STATS_SINCE_CHARGED)); 1978 } 1979 readFromParcel(Parcel in)1980 public void readFromParcel(Parcel in) { 1981 mRunning = false; 1982 mUptimeUs = in.readLong(); 1983 mPastUptimeUs = in.readLong(); 1984 mUptimeStartUs = in.readLong(); 1985 mRealtimeUs = in.readLong(); 1986 mPastRealtimeUs = in.readLong(); 1987 mRealtimeStartUs = in.readLong(); 1988 mUnpluggedUptimeUs = in.readLong(); 1989 mUnpluggedRealtimeUs = in.readLong(); 1990 } 1991 writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)1992 public void writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 1993 final long runningUptime = getUptime(uptimeUs); 1994 final long runningRealtime = getRealtime(elapsedRealtimeUs); 1995 out.writeLong(mUptimeUs); 1996 out.writeLong(runningUptime); 1997 out.writeLong(mUptimeStartUs); 1998 out.writeLong(mRealtimeUs); 1999 out.writeLong(runningRealtime); 2000 out.writeLong(mRealtimeStartUs); 2001 out.writeLong(mUnpluggedUptimeUs); 2002 out.writeLong(mUnpluggedRealtimeUs); 2003 } 2004 } 2005 2006 /** 2007 * State for keeping track of counting information. 2008 */ 2009 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 2010 final AtomicInteger mCount = new AtomicInteger(); 2011 final TimeBase mTimeBase; 2012 Counter(TimeBase timeBase, Parcel in)2013 public Counter(TimeBase timeBase, Parcel in) { 2014 mTimeBase = timeBase; 2015 mCount.set(in.readInt()); 2016 timeBase.add(this); 2017 } 2018 Counter(TimeBase timeBase)2019 public Counter(TimeBase timeBase) { 2020 mTimeBase = timeBase; 2021 timeBase.add(this); 2022 } 2023 writeToParcel(Parcel out)2024 public void writeToParcel(Parcel out) { 2025 out.writeInt(mCount.get()); 2026 } 2027 2028 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2029 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2030 } 2031 2032 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2033 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2034 } 2035 2036 @Override getCountLocked(int which)2037 public int getCountLocked(int which) { 2038 return mCount.get(); 2039 } 2040 logState(Printer pw, String prefix)2041 public void logState(Printer pw, String prefix) { 2042 pw.println(prefix + "mCount=" + mCount.get()); 2043 } 2044 2045 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()2046 public void stepAtomic() { 2047 if (mTimeBase.isRunning()) { 2048 mCount.incrementAndGet(); 2049 } 2050 } 2051 addAtomic(int delta)2052 void addAtomic(int delta) { 2053 if (mTimeBase.isRunning()) { 2054 mCount.addAndGet(delta); 2055 } 2056 } 2057 2058 /** 2059 * Clear state of this counter. 2060 */ 2061 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2062 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2063 mCount.set(0); 2064 if (detachIfReset) { 2065 detach(); 2066 } 2067 return true; 2068 } 2069 2070 @Override detach()2071 public void detach() { 2072 mTimeBase.remove(this); 2073 } 2074 2075 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)2076 public void writeSummaryFromParcelLocked(Parcel out) { 2077 out.writeInt(mCount.get()); 2078 } 2079 2080 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)2081 public void readSummaryFromParcelLocked(Parcel in) { 2082 mCount.set(in.readInt()); 2083 } 2084 } 2085 2086 @VisibleForTesting 2087 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 2088 final TimeBase mTimeBase; 2089 public long[] mCounts; 2090 LongSamplingCounterArray(TimeBase timeBase, Parcel in)2091 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 2092 mTimeBase = timeBase; 2093 mCounts = in.createLongArray(); 2094 timeBase.add(this); 2095 } 2096 LongSamplingCounterArray(TimeBase timeBase)2097 public LongSamplingCounterArray(TimeBase timeBase) { 2098 mTimeBase = timeBase; 2099 timeBase.add(this); 2100 } 2101 writeToParcel(Parcel out)2102 private void writeToParcel(Parcel out) { 2103 out.writeLongArray(mCounts); 2104 } 2105 2106 @Override onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs)2107 public void onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs) { 2108 } 2109 2110 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2111 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2112 } 2113 2114 @Override getCountsLocked(int which)2115 public long[] getCountsLocked(int which) { 2116 return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); 2117 } 2118 2119 @Override logState(Printer pw, String prefix)2120 public void logState(Printer pw, String prefix) { 2121 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); 2122 } 2123 addCountLocked(long[] counts)2124 public void addCountLocked(long[] counts) { 2125 addCountLocked(counts, mTimeBase.isRunning()); 2126 } 2127 addCountLocked(long[] counts, boolean isRunning)2128 public void addCountLocked(long[] counts, boolean isRunning) { 2129 if (counts == null) { 2130 return; 2131 } 2132 if (isRunning) { 2133 if (mCounts == null) { 2134 mCounts = new long[counts.length]; 2135 } 2136 for (int i = 0; i < counts.length; ++i) { 2137 mCounts[i] += counts[i]; 2138 } 2139 } 2140 } 2141 getSize()2142 public int getSize() { 2143 return mCounts == null ? 0 : mCounts.length; 2144 } 2145 2146 /** 2147 * Clear state of this counter. 2148 */ 2149 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2150 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2151 if (mCounts != null) { 2152 Arrays.fill(mCounts, 0); 2153 } 2154 if (detachIfReset) { 2155 detach(); 2156 } 2157 return true; 2158 } 2159 2160 @Override detach()2161 public void detach() { 2162 mTimeBase.remove(this); 2163 } 2164 writeSummaryToParcelLocked(Parcel out)2165 private void writeSummaryToParcelLocked(Parcel out) { 2166 out.writeLongArray(mCounts); 2167 } 2168 readSummaryFromParcelLocked(Parcel in)2169 private void readSummaryFromParcelLocked(Parcel in) { 2170 mCounts = in.createLongArray(); 2171 } 2172 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)2173 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 2174 if (counterArray != null) { 2175 out.writeInt(1); 2176 counterArray.writeToParcel(out); 2177 } else { 2178 out.writeInt(0); 2179 } 2180 } 2181 readFromParcel(Parcel in, TimeBase timeBase)2182 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 2183 if (in.readInt() != 0) { 2184 return new LongSamplingCounterArray(timeBase, in); 2185 } else { 2186 return null; 2187 } 2188 } 2189 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)2190 public static void writeSummaryToParcelLocked(Parcel out, 2191 LongSamplingCounterArray counterArray) { 2192 if (counterArray != null) { 2193 out.writeInt(1); 2194 counterArray.writeSummaryToParcelLocked(out); 2195 } else { 2196 out.writeInt(0); 2197 } 2198 } 2199 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)2200 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 2201 TimeBase timeBase) { 2202 if (in.readInt() != 0) { 2203 final LongSamplingCounterArray counterArray 2204 = new LongSamplingCounterArray(timeBase); 2205 counterArray.readSummaryFromParcelLocked(in); 2206 return counterArray; 2207 } else { 2208 return null; 2209 } 2210 } 2211 } 2212 2213 private static class TimeMultiStateCounter extends LongCounter implements TimeBaseObs { 2214 private final TimeBase mTimeBase; 2215 private final LongMultiStateCounter mCounter; 2216 TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs)2217 private TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs) { 2218 this(timeBase, new LongMultiStateCounter(stateCount), timestampMs); 2219 } 2220 TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter, long timestampMs)2221 private TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter, 2222 long timestampMs) { 2223 mTimeBase = timeBase; 2224 mCounter = counter; 2225 mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); 2226 timeBase.add(this); 2227 } 2228 2229 @Nullable readFromParcel(Parcel in, TimeBase timeBase, int stateCount, long timestampMs)2230 private static TimeMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase, 2231 int stateCount, long timestampMs) { 2232 LongMultiStateCounter counter = LongMultiStateCounter.CREATOR.createFromParcel(in); 2233 if (counter.getStateCount() != stateCount) { 2234 return null; 2235 } 2236 return new TimeMultiStateCounter(timeBase, counter, timestampMs); 2237 } 2238 writeToParcel(Parcel out)2239 private void writeToParcel(Parcel out) { 2240 mCounter.writeToParcel(out, 0); 2241 } 2242 2243 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2244 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2245 mCounter.setEnabled(true, elapsedRealtimeUs / 1000); 2246 } 2247 2248 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2249 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2250 mCounter.setEnabled(false, elapsedRealtimeUs / 1000); 2251 } 2252 getStateCount()2253 public int getStateCount() { 2254 return mCounter.getStateCount(); 2255 } 2256 setState(@atteryConsumer.ProcessState int processState, long elapsedRealtimeMs)2257 private void setState(@BatteryConsumer.ProcessState int processState, 2258 long elapsedRealtimeMs) { 2259 mCounter.setState(processState, elapsedRealtimeMs); 2260 } 2261 update(long value, long timestampMs)2262 private long update(long value, long timestampMs) { 2263 return mCounter.updateValue(value, timestampMs); 2264 } 2265 increment(long increment, long timestampMs)2266 private void increment(long increment, long timestampMs) { 2267 mCounter.incrementValue(increment, timestampMs); 2268 } 2269 2270 /** 2271 * Returns accumulated count for the specified state. 2272 */ getCountForProcessState(@atteryConsumer.ProcessState int procState)2273 public long getCountForProcessState(@BatteryConsumer.ProcessState int procState) { 2274 return mCounter.getCount(procState); 2275 } 2276 getTotalCountLocked()2277 public long getTotalCountLocked() { 2278 return mCounter.getTotalCount(); 2279 } 2280 2281 @Override getCountLocked(int statsType)2282 public long getCountLocked(int statsType) { 2283 return getTotalCountLocked(); 2284 } 2285 2286 @Override logState(Printer pw, String prefix)2287 public void logState(Printer pw, String prefix) { 2288 pw.println(prefix + "mCounter=" + mCounter); 2289 } 2290 2291 /** 2292 * Clears state of this counter. 2293 */ 2294 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2295 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2296 mCounter.reset(); 2297 if (detachIfReset) { 2298 detach(); 2299 } 2300 return true; 2301 } 2302 2303 @Override detach()2304 public void detach() { 2305 mTimeBase.remove(this); 2306 } 2307 } 2308 2309 private static class TimeInFreqMultiStateCounter implements TimeBaseObs { 2310 private final TimeBase mTimeBase; 2311 private final LongArrayMultiStateCounter mCounter; 2312 TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount, long timestampMs)2313 private TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount, 2314 long timestampMs) { 2315 this(timeBase, new LongArrayMultiStateCounter(stateCount, cpuFreqCount), timestampMs); 2316 } 2317 TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter, long timestampMs)2318 private TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter, 2319 long timestampMs) { 2320 mTimeBase = timeBase; 2321 mCounter = counter; 2322 mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); 2323 timeBase.add(this); 2324 } 2325 writeToParcel(Parcel out)2326 private void writeToParcel(Parcel out) { 2327 mCounter.writeToParcel(out, 0); 2328 } 2329 2330 @Nullable readFromParcel(Parcel in, TimeBase timeBase, int stateCount, int cpuFreqCount, long timestampMs)2331 private static TimeInFreqMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase, 2332 int stateCount, int cpuFreqCount, long timestampMs) { 2333 // Read the object from the Parcel, whether it's usable or not 2334 LongArrayMultiStateCounter counter = 2335 LongArrayMultiStateCounter.CREATOR.createFromParcel(in); 2336 if (counter.getStateCount() != stateCount 2337 || counter.getArrayLength() != cpuFreqCount) { 2338 return null; 2339 } 2340 return new TimeInFreqMultiStateCounter(timeBase, counter, timestampMs); 2341 } 2342 2343 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2344 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2345 mCounter.setEnabled(true, elapsedRealtimeUs / 1000); 2346 } 2347 2348 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2349 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2350 mCounter.setEnabled(false, elapsedRealtimeUs / 1000); 2351 } 2352 getCounter()2353 public LongArrayMultiStateCounter getCounter() { 2354 return mCounter; 2355 } 2356 getStateCount()2357 public int getStateCount() { 2358 return mCounter.getStateCount(); 2359 } 2360 setTrackingEnabled(boolean enabled, long timestampMs)2361 public void setTrackingEnabled(boolean enabled, long timestampMs) { 2362 mCounter.setEnabled(enabled && mTimeBase.isRunning(), timestampMs); 2363 } 2364 setState(int uidRunningState, long elapsedRealtimeMs)2365 private void setState(int uidRunningState, long elapsedRealtimeMs) { 2366 mCounter.setState(uidRunningState, elapsedRealtimeMs); 2367 } 2368 2369 /** 2370 * Returns accumulated counts for the specified state, or false if all counts are zero. 2371 */ getCountsLocked(long[] counts, int procState)2372 public boolean getCountsLocked(long[] counts, int procState) { 2373 if (counts.length != mCounter.getArrayLength()) { 2374 return false; 2375 } 2376 2377 mCounter.getCounts(counts, procState); 2378 2379 // Return counts only if at least one of the elements is non-zero. 2380 for (int i = counts.length - 1; i >= 0; --i) { 2381 if (counts[i] != 0) { 2382 return true; 2383 } 2384 } 2385 return false; 2386 } 2387 logState(Printer pw, String prefix)2388 public void logState(Printer pw, String prefix) { 2389 pw.println(prefix + "mCounter=" + mCounter); 2390 } 2391 2392 /** 2393 * Clears state of this counter. 2394 */ 2395 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2396 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2397 mCounter.reset(); 2398 if (detachIfReset) { 2399 detach(); 2400 } 2401 return true; 2402 } 2403 2404 @Override detach()2405 public void detach() { 2406 mTimeBase.remove(this); 2407 } 2408 } 2409 2410 @VisibleForTesting 2411 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 2412 final TimeBase mTimeBase; 2413 private long mCount; 2414 LongSamplingCounter(TimeBase timeBase, Parcel in)2415 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 2416 mTimeBase = timeBase; 2417 mCount = in.readLong(); 2418 timeBase.add(this); 2419 } 2420 LongSamplingCounter(TimeBase timeBase)2421 public LongSamplingCounter(TimeBase timeBase) { 2422 mTimeBase = timeBase; 2423 timeBase.add(this); 2424 } 2425 writeToParcel(Parcel out)2426 public void writeToParcel(Parcel out) { 2427 out.writeLong(mCount); 2428 } 2429 2430 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2431 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2432 } 2433 2434 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2435 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2436 } 2437 getCountLocked(int which)2438 public long getCountLocked(int which) { 2439 return mCount; 2440 } 2441 2442 @Override getCountForProcessState(int procState)2443 public long getCountForProcessState(int procState) { 2444 if (procState == BatteryConsumer.PROCESS_STATE_ANY) { 2445 return getCountLocked(STATS_SINCE_CHARGED); 2446 } 2447 return 0; 2448 } 2449 2450 @Override logState(Printer pw, String prefix)2451 public void logState(Printer pw, String prefix) { 2452 pw.println(prefix + "mCount=" + mCount); 2453 } 2454 addCountLocked(long count)2455 public void addCountLocked(long count) { 2456 addCountLocked(count, mTimeBase.isRunning()); 2457 } 2458 addCountLocked(long count, boolean isRunning)2459 public void addCountLocked(long count, boolean isRunning) { 2460 if (isRunning) { 2461 mCount += count; 2462 } 2463 } 2464 2465 /** 2466 * Clear state of this counter. 2467 */ 2468 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2469 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2470 mCount = 0; 2471 if (detachIfReset) { 2472 detach(); 2473 } 2474 return true; 2475 } 2476 2477 @Override detach()2478 public void detach() { 2479 mTimeBase.remove(this); 2480 } 2481 writeSummaryFromParcelLocked(Parcel out)2482 public void writeSummaryFromParcelLocked(Parcel out) { 2483 out.writeLong(mCount); 2484 } 2485 readSummaryFromParcelLocked(Parcel in)2486 public void readSummaryFromParcelLocked(Parcel in) { 2487 mCount = in.readLong(); 2488 } 2489 } 2490 2491 /** 2492 * State for keeping track of timing information. 2493 */ 2494 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 2495 protected final Clock mClock; 2496 protected final int mType; 2497 protected final TimeBase mTimeBase; 2498 2499 protected int mCount; 2500 2501 // Times are in microseconds for better accuracy when dividing by the 2502 // lock count, and are in "battery realtime" units. 2503 2504 /** 2505 * The total time we have accumulated since the start of the original 2506 * boot, to the last time something interesting happened in the 2507 * current run. 2508 */ 2509 protected long mTotalTimeUs; 2510 2511 /** 2512 * The total time this timer has been running until the latest mark has been set. 2513 * Subtract this from mTotalTimeUs to get the time spent running since the mark was set. 2514 */ 2515 protected long mTimeBeforeMarkUs; 2516 2517 /** 2518 * Constructs from a parcel. 2519 * @param type 2520 * @param timeBase 2521 * @param in 2522 */ Timer(Clock clock, int type, TimeBase timeBase, Parcel in)2523 public Timer(Clock clock, int type, TimeBase timeBase, Parcel in) { 2524 mClock = clock; 2525 mType = type; 2526 mTimeBase = timeBase; 2527 2528 mCount = in.readInt(); 2529 mTotalTimeUs = in.readLong(); 2530 mTimeBeforeMarkUs = in.readLong(); 2531 timeBase.add(this); 2532 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTimeUs); 2533 } 2534 Timer(Clock clock, int type, TimeBase timeBase)2535 public Timer(Clock clock, int type, TimeBase timeBase) { 2536 mClock = clock; 2537 mType = type; 2538 mTimeBase = timeBase; 2539 timeBase.add(this); 2540 } 2541 writeToParcel(Parcel out, long elapsedRealtimeUs)2542 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2543 if (DEBUG) { 2544 Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 2545 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2546 elapsedRealtimeUs)); 2547 } 2548 out.writeInt(computeCurrentCountLocked()); 2549 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2550 elapsedRealtimeUs)); 2551 out.writeLong(mTimeBeforeMarkUs); 2552 } 2553 computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)2554 protected abstract long computeRunTimeLocked(long curBatteryRealtime, 2555 long elapsedRealtimeUs); 2556 computeCurrentCountLocked()2557 protected abstract int computeCurrentCountLocked(); 2558 2559 /** 2560 * Clear state of this timer. Returns true if the timer is inactive 2561 * so can be completely dropped. 2562 */ 2563 @Override reset(boolean detachIfReset)2564 public boolean reset(boolean detachIfReset) { 2565 return reset(detachIfReset, mClock.elapsedRealtime() * 1000); 2566 } 2567 2568 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2569 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2570 mTotalTimeUs = mTimeBeforeMarkUs = 0; 2571 mCount = 0; 2572 if (detachIfReset) { 2573 detach(); 2574 } 2575 return true; 2576 } 2577 2578 @Override detach()2579 public void detach() { 2580 mTimeBase.remove(this); 2581 } 2582 2583 @Override onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, long baseRealtimeUs)2584 public void onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, 2585 long baseRealtimeUs) { 2586 } 2587 2588 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2589 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2590 if (DEBUG && mType < 0) { 2591 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtimeUs 2592 + " old mTotalTime=" + mTotalTimeUs); 2593 } 2594 mTotalTimeUs = computeRunTimeLocked(baseRealtimeUs, elapsedRealtimeUs); 2595 mCount = computeCurrentCountLocked(); 2596 if (DEBUG && mType < 0) { 2597 Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTimeUs); 2598 } 2599 } 2600 2601 /** 2602 * Writes a possibly null Timer to a Parcel. 2603 * 2604 * @param out the Parcel to be written to. 2605 * @param timer a Timer, or null. 2606 */ writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)2607 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 2608 if (timer == null) { 2609 out.writeInt(0); // indicates null 2610 return; 2611 } 2612 out.writeInt(1); // indicates non-null 2613 timer.writeToParcel(out, elapsedRealtimeUs); 2614 } 2615 2616 @Override getTotalTimeLocked(long elapsedRealtimeUs, int which)2617 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 2618 return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2619 elapsedRealtimeUs); 2620 } 2621 2622 @Override getCountLocked(int which)2623 public int getCountLocked(int which) { 2624 return computeCurrentCountLocked(); 2625 } 2626 2627 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)2628 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 2629 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2630 elapsedRealtimeUs); 2631 return val - mTimeBeforeMarkUs; 2632 } 2633 2634 @Override logState(Printer pw, String prefix)2635 public void logState(Printer pw, String prefix) { 2636 pw.println(prefix + "mCount=" + mCount); 2637 pw.println(prefix + "mTotalTime=" + mTotalTimeUs); 2638 } 2639 2640 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2641 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2642 long runTimeUs = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2643 elapsedRealtimeUs); 2644 out.writeLong(runTimeUs); 2645 out.writeInt(computeCurrentCountLocked()); 2646 } 2647 readSummaryFromParcelLocked(Parcel in)2648 public void readSummaryFromParcelLocked(Parcel in) { 2649 // Multiply by 1000 for backwards compatibility 2650 mTotalTimeUs = in.readLong(); 2651 mCount = in.readInt(); 2652 // When reading the summary, we set the mark to be the latest information. 2653 mTimeBeforeMarkUs = mTotalTimeUs; 2654 } 2655 } 2656 2657 /** 2658 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 2659 * method. The state of the timer according to its {@link TimeBase} will determine how much 2660 * of the value is recorded. 2661 * 2662 * If the value being recorded resets, {@link #endSample()} can be called in order to 2663 * account for the change. If the value passed in to {@link #update(long, int)} decreased 2664 * between calls, the {@link #endSample()} is automatically called and the new value is 2665 * expected to increase monotonically from that point on. 2666 */ 2667 public static class SamplingTimer extends Timer { 2668 2669 /** 2670 * The most recent reported count from /proc/wakelocks. 2671 */ 2672 int mCurrentReportedCount; 2673 2674 /** 2675 * The reported count from /proc/wakelocks when unplug() was last 2676 * called. 2677 */ 2678 int mUnpluggedReportedCount; 2679 2680 /** 2681 * The most recent reported total_time from /proc/wakelocks. 2682 */ 2683 long mCurrentReportedTotalTimeUs; 2684 2685 2686 /** 2687 * The reported total_time from /proc/wakelocks when unplug() was last 2688 * called. 2689 */ 2690 long mUnpluggedReportedTotalTimeUs; 2691 2692 /** 2693 * Whether we are currently in a discharge cycle. 2694 */ 2695 boolean mTimeBaseRunning; 2696 2697 /** 2698 * Whether we are currently recording reported values. 2699 */ 2700 boolean mTrackingReportedValues; 2701 2702 /* 2703 * A sequence counter, incremented once for each update of the stats. 2704 */ 2705 int mUpdateVersion; 2706 2707 @VisibleForTesting SamplingTimer(Clock clock, TimeBase timeBase, Parcel in)2708 public SamplingTimer(Clock clock, TimeBase timeBase, Parcel in) { 2709 super(clock, 0, timeBase, in); 2710 mCurrentReportedCount = in.readInt(); 2711 mUnpluggedReportedCount = in.readInt(); 2712 mCurrentReportedTotalTimeUs = in.readLong(); 2713 mUnpluggedReportedTotalTimeUs = in.readLong(); 2714 mTrackingReportedValues = in.readInt() == 1; 2715 mTimeBaseRunning = timeBase.isRunning(); 2716 } 2717 2718 @VisibleForTesting SamplingTimer(Clock clock, TimeBase timeBase)2719 public SamplingTimer(Clock clock, TimeBase timeBase) { 2720 super(clock, 0, timeBase); 2721 mTrackingReportedValues = false; 2722 mTimeBaseRunning = timeBase.isRunning(); 2723 } 2724 2725 /** 2726 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 2727 * be less than the values used for a previous invocation. 2728 */ endSample()2729 public void endSample() { 2730 endSample(mClock.elapsedRealtime() * 1000); 2731 } 2732 2733 /** 2734 * @see #endSample() 2735 */ endSample(long elapsedRealtimeUs)2736 public void endSample(long elapsedRealtimeUs) { 2737 mTotalTimeUs = computeRunTimeLocked(0 /* unused by us */, elapsedRealtimeUs); 2738 mCount = computeCurrentCountLocked(); 2739 mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs = 0; 2740 mUnpluggedReportedCount = mCurrentReportedCount = 0; 2741 mTrackingReportedValues = false; 2742 } 2743 setUpdateVersion(int version)2744 public void setUpdateVersion(int version) { 2745 mUpdateVersion = version; 2746 } 2747 getUpdateVersion()2748 public int getUpdateVersion() { 2749 return mUpdateVersion; 2750 } 2751 2752 /** 2753 * Updates the current recorded values. These are meant to be monotonically increasing 2754 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 2755 * 2756 * If the values being recorded have been reset, the monotonically increasing requirement 2757 * will be broken. In this case, {@link #endSample()} is automatically called and 2758 * the total value of totalTimeUs and count are recorded, starting a new monotonically 2759 * increasing sample. 2760 * 2761 * @param totalTimeUs total time of sample in microseconds. 2762 * @param count total number of times the event being sampled occurred. 2763 */ update(long totalTimeUs, int count, long elapsedRealtimeUs)2764 public void update(long totalTimeUs, int count, long elapsedRealtimeUs) { 2765 if (mTimeBaseRunning && !mTrackingReportedValues) { 2766 // Updating the reported value for the first time. 2767 mUnpluggedReportedTotalTimeUs = totalTimeUs; 2768 mUnpluggedReportedCount = count; 2769 } 2770 2771 mTrackingReportedValues = true; 2772 2773 if (totalTimeUs < mCurrentReportedTotalTimeUs || count < mCurrentReportedCount) { 2774 endSample(elapsedRealtimeUs); 2775 } 2776 2777 mCurrentReportedTotalTimeUs = totalTimeUs; 2778 mCurrentReportedCount = count; 2779 } 2780 2781 /** 2782 * Adds deltaTime and deltaCount to the current sample. 2783 * 2784 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 2785 * @param deltaCount additional number of times the event being sampled occurred. 2786 */ add(long deltaTimeUs, int deltaCount)2787 public void add(long deltaTimeUs, int deltaCount) { 2788 add(deltaTimeUs, deltaCount, mClock.elapsedRealtime() * 1000); 2789 } 2790 2791 /** 2792 * @see #add(long, int) 2793 */ add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs)2794 public void add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs) { 2795 update(mCurrentReportedTotalTimeUs + deltaTimeUs, mCurrentReportedCount + deltaCount, 2796 elapsedRealtimeUs); 2797 } 2798 2799 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2800 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2801 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2802 if (mTrackingReportedValues) { 2803 mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs; 2804 mUnpluggedReportedCount = mCurrentReportedCount; 2805 } 2806 mTimeBaseRunning = true; 2807 } 2808 2809 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2810 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2811 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2812 mTimeBaseRunning = false; 2813 } 2814 2815 @Override logState(Printer pw, String prefix)2816 public void logState(Printer pw, String prefix) { 2817 super.logState(pw, prefix); 2818 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 2819 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 2820 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTimeUs 2821 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTimeUs); 2822 } 2823 2824 @Override computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)2825 protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) { 2826 return mTotalTimeUs + (mTimeBaseRunning && mTrackingReportedValues 2827 ? mCurrentReportedTotalTimeUs - mUnpluggedReportedTotalTimeUs : 0); 2828 } 2829 2830 @Override computeCurrentCountLocked()2831 protected int computeCurrentCountLocked() { 2832 return mCount + (mTimeBaseRunning && mTrackingReportedValues 2833 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 2834 } 2835 2836 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2837 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2838 super.writeToParcel(out, elapsedRealtimeUs); 2839 out.writeInt(mCurrentReportedCount); 2840 out.writeInt(mUnpluggedReportedCount); 2841 out.writeLong(mCurrentReportedTotalTimeUs); 2842 out.writeLong(mUnpluggedReportedTotalTimeUs); 2843 out.writeInt(mTrackingReportedValues ? 1 : 0); 2844 } 2845 2846 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2847 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2848 super.reset(detachIfReset, elapsedRealtimeUs); 2849 mTrackingReportedValues = false; 2850 mUnpluggedReportedTotalTimeUs = 0; 2851 mUnpluggedReportedCount = 0; 2852 return true; 2853 } 2854 } 2855 2856 /** 2857 * A timer that increments in batches. It does not run for durations, but just jumps 2858 * for a pre-determined amount. 2859 */ 2860 public static class BatchTimer extends Timer { 2861 final Uid mUid; 2862 2863 /** 2864 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 2865 */ 2866 long mLastAddedTimeUs; 2867 2868 /** 2869 * The last duration that we added to the timer. This is in microseconds. 2870 */ 2871 long mLastAddedDurationUs; 2872 2873 /** 2874 * Whether we are currently in a discharge cycle. 2875 */ 2876 boolean mInDischarge; 2877 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase, Parcel in)2878 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase, Parcel in) { 2879 super(clock, type, timeBase, in); 2880 mUid = uid; 2881 mLastAddedTimeUs = in.readLong(); 2882 mLastAddedDurationUs = in.readLong(); 2883 mInDischarge = timeBase.isRunning(); 2884 } 2885 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase)2886 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase) { 2887 super(clock, type, timeBase); 2888 mUid = uid; 2889 mInDischarge = timeBase.isRunning(); 2890 } 2891 2892 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2893 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2894 super.writeToParcel(out, elapsedRealtimeUs); 2895 out.writeLong(mLastAddedTimeUs); 2896 out.writeLong(mLastAddedDurationUs); 2897 } 2898 2899 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2900 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2901 recomputeLastDuration(elapsedRealtimeUs, false); 2902 mInDischarge = false; 2903 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2904 } 2905 2906 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2907 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2908 recomputeLastDuration(elapsedRealtimeUs, false); 2909 mInDischarge = true; 2910 // If we are still within the last added duration, then re-added whatever remains. 2911 if (mLastAddedTimeUs == elapsedRealtimeUs) { 2912 mTotalTimeUs += mLastAddedDurationUs; 2913 } 2914 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2915 } 2916 2917 @Override logState(Printer pw, String prefix)2918 public void logState(Printer pw, String prefix) { 2919 super.logState(pw, prefix); 2920 pw.println(prefix + "mLastAddedTime=" + mLastAddedTimeUs 2921 + " mLastAddedDuration=" + mLastAddedDurationUs); 2922 } 2923 computeOverage(long curTimeUs)2924 private long computeOverage(long curTimeUs) { 2925 if (mLastAddedTimeUs > 0) { 2926 return mLastAddedDurationUs - curTimeUs; 2927 } 2928 return 0; 2929 } 2930 recomputeLastDuration(long curTimeUs, boolean abort)2931 private void recomputeLastDuration(long curTimeUs, boolean abort) { 2932 final long overage = computeOverage(curTimeUs); 2933 if (overage > 0) { 2934 // Aborting before the duration ran out -- roll back the remaining 2935 // duration. Only do this if currently discharging; otherwise we didn't 2936 // actually add the time. 2937 if (mInDischarge) { 2938 mTotalTimeUs -= overage; 2939 } 2940 if (abort) { 2941 mLastAddedTimeUs = 0; 2942 } else { 2943 mLastAddedTimeUs = curTimeUs; 2944 mLastAddedDurationUs -= overage; 2945 } 2946 } 2947 } 2948 addDuration(long durationMs, long elapsedRealtimeMs)2949 public void addDuration(long durationMs, long elapsedRealtimeMs) { 2950 final long nowUs = elapsedRealtimeMs * 1000; 2951 recomputeLastDuration(nowUs, true); 2952 mLastAddedTimeUs = nowUs; 2953 mLastAddedDurationUs = durationMs * 1000; 2954 if (mInDischarge) { 2955 mTotalTimeUs += mLastAddedDurationUs; 2956 mCount++; 2957 } 2958 } 2959 abortLastDuration(long elapsedRealtimeMs)2960 public void abortLastDuration(long elapsedRealtimeMs) { 2961 final long nowUs = elapsedRealtimeMs * 1000; 2962 recomputeLastDuration(nowUs, true); 2963 } 2964 2965 @Override computeCurrentCountLocked()2966 protected int computeCurrentCountLocked() { 2967 return mCount; 2968 } 2969 2970 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)2971 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 2972 final long overage = computeOverage(elapsedRealtimeUs); 2973 if (overage > 0) { 2974 return mTotalTimeUs = overage; 2975 } 2976 return mTotalTimeUs; 2977 } 2978 2979 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2980 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2981 recomputeLastDuration(elapsedRealtimeUs, true); 2982 boolean stillActive = mLastAddedTimeUs == elapsedRealtimeUs; 2983 super.reset(!stillActive && detachIfReset, elapsedRealtimeUs); 2984 return !stillActive; 2985 } 2986 } 2987 2988 2989 /** 2990 * A StopwatchTimer that also tracks the total and max individual 2991 * time spent active according to the given timebase. Whereas 2992 * StopwatchTimer apportions the time amongst all in the pool, 2993 * the total and max durations are not apportioned. 2994 */ 2995 public static class DurationTimer extends StopwatchTimer { 2996 /** 2997 * The time (in ms) that the timer was last acquired or the time base 2998 * last (re-)started. Increasing the nesting depth does not reset this time. 2999 * 3000 * -1 if the timer is currently not running or the time base is not running. 3001 * 3002 * If written to a parcel, the start time is reset, as is mNesting in the base class 3003 * StopwatchTimer. 3004 */ 3005 long mStartTimeMs = -1; 3006 3007 /** 3008 * The longest time period (in ms) that the timer has been active. Not pooled. 3009 */ 3010 long mMaxDurationMs; 3011 3012 /** 3013 * The time (in ms) that that the timer has been active since most recent 3014 * stopRunningLocked() or reset(). Not pooled. 3015 */ 3016 long mCurrentDurationMs; 3017 3018 /** 3019 * The total time (in ms) that that the timer has been active since most recent reset() 3020 * prior to the current startRunningLocked. This is the sum of all past currentDurations 3021 * (but not including the present currentDuration) since reset. Not pooled. 3022 */ 3023 long mTotalDurationMs; 3024 DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)3025 public DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3026 TimeBase timeBase, Parcel in) { 3027 super(clock, uid, type, timerPool, timeBase, in); 3028 mMaxDurationMs = in.readLong(); 3029 mTotalDurationMs = in.readLong(); 3030 mCurrentDurationMs = in.readLong(); 3031 } 3032 DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)3033 public DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3034 TimeBase timeBase) { 3035 super(clock, uid, type, timerPool, timeBase); 3036 } 3037 3038 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3039 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3040 super.writeToParcel(out, elapsedRealtimeUs); 3041 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 3042 out.writeLong(mTotalDurationMs); 3043 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 3044 } 3045 3046 /** 3047 * Write the summary to the parcel. 3048 * 3049 * Since the time base is probably meaningless after we come back, reading 3050 * from this will have the effect of stopping the timer. So here all we write 3051 * is the max and total durations. 3052 */ 3053 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)3054 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 3055 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3056 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 3057 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 3058 } 3059 3060 /** 3061 * Read the summary parcel. 3062 * 3063 * Has the side effect of stopping the timer. 3064 */ 3065 @Override readSummaryFromParcelLocked(Parcel in)3066 public void readSummaryFromParcelLocked(Parcel in) { 3067 super.readSummaryFromParcelLocked(in); 3068 mMaxDurationMs = in.readLong(); 3069 mTotalDurationMs = in.readLong(); 3070 mStartTimeMs = -1; 3071 mCurrentDurationMs = 0; 3072 } 3073 3074 /** 3075 * The TimeBase time started (again). 3076 * 3077 * If the timer is also running, store the start time. 3078 */ onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3079 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3080 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3081 if (mNesting > 0) { 3082 mStartTimeMs = baseRealtimeUs / 1000; 3083 } 3084 } 3085 3086 /** 3087 * The TimeBase stopped running. 3088 * 3089 * If the timer is running, add the duration into mCurrentDurationMs. 3090 */ 3091 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3092 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3093 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3094 if (mNesting > 0) { 3095 // baseRealtimeUs has already been converted to the timebase's realtime. 3096 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 3097 } 3098 mStartTimeMs = -1; 3099 } 3100 3101 @Override logState(Printer pw, String prefix)3102 public void logState(Printer pw, String prefix) { 3103 super.logState(pw, prefix); 3104 } 3105 3106 @Override startRunningLocked(long elapsedRealtimeMs)3107 public void startRunningLocked(long elapsedRealtimeMs) { 3108 super.startRunningLocked(elapsedRealtimeMs); 3109 if (mNesting == 1 && mTimeBase.isRunning()) { 3110 // Just started 3111 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 3112 } 3113 } 3114 3115 /** 3116 * Decrements the mNesting ref-count on this timer. 3117 * 3118 * If it actually stopped (mNesting went to 0), then possibly update 3119 * mMaxDuration if the current duration was the longest ever. 3120 */ 3121 @Override stopRunningLocked(long elapsedRealtimeMs)3122 public void stopRunningLocked(long elapsedRealtimeMs) { 3123 if (mNesting == 1) { 3124 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 3125 mTotalDurationMs += durationMs; 3126 if (durationMs > mMaxDurationMs) { 3127 mMaxDurationMs = durationMs; 3128 } 3129 mStartTimeMs = -1; 3130 mCurrentDurationMs = 0; 3131 } 3132 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 3133 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 3134 super.stopRunningLocked(elapsedRealtimeMs); 3135 } 3136 3137 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3138 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3139 boolean result = super.reset(detachIfReset, elapsedRealtimeUs); 3140 mMaxDurationMs = 0; 3141 mTotalDurationMs = 0; 3142 mCurrentDurationMs = 0; 3143 if (mNesting > 0) { 3144 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeUs) / 1000; 3145 } else { 3146 mStartTimeMs = -1; 3147 } 3148 return result; 3149 } 3150 3151 /** 3152 * Returns the max duration that this timer has ever seen. 3153 * 3154 * Note that this time is NOT split between the timers in the timer group that 3155 * this timer is attached to. It is the TOTAL time. 3156 */ 3157 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)3158 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 3159 if (mNesting > 0) { 3160 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 3161 if (durationMs > mMaxDurationMs) { 3162 return durationMs; 3163 } 3164 } 3165 return mMaxDurationMs; 3166 } 3167 3168 /** 3169 * Returns the time since the timer was started. 3170 * Returns 0 if the timer is not currently running. 3171 * 3172 * Note that this time is NOT split between the timers in the timer group that 3173 * this timer is attached to. It is the TOTAL time. 3174 * 3175 * Note that if running timer is parceled and unparceled, this method will return 3176 * current duration value at the time of parceling even though timer may not be 3177 * currently running. 3178 */ 3179 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)3180 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 3181 long durationMs = mCurrentDurationMs; 3182 if (mNesting > 0 && mTimeBase.isRunning()) { 3183 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) 3184 - mStartTimeMs; 3185 } 3186 return durationMs; 3187 } 3188 3189 /** 3190 * Returns the total cumulative duration that this timer has been on since reset(). 3191 * If mTimerPool == null, this should be the same 3192 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 3193 * 3194 * Note that this time is NOT split between the timers in the timer group that 3195 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 3196 * the result will not be equivalent to getTotalTimeLocked. 3197 */ 3198 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)3199 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 3200 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 3201 } 3202 } 3203 3204 /** 3205 * State for keeping track of timing information. 3206 */ 3207 public static class StopwatchTimer extends Timer { 3208 final Uid mUid; 3209 final ArrayList<StopwatchTimer> mTimerPool; 3210 3211 int mNesting; 3212 3213 /** 3214 * The last time at which we updated the timer. If mNesting is > 0, 3215 * subtract this from the current battery time to find the amount of 3216 * time we have been running since we last computed an update. 3217 */ 3218 long mUpdateTimeUs; 3219 3220 /** 3221 * The total time at which the timer was acquired, to determine if it 3222 * was actually held for an interesting duration. If time base was not running when timer 3223 * was acquired, will be -1. 3224 */ 3225 long mAcquireTimeUs = -1; 3226 3227 long mTimeoutUs; 3228 3229 /** 3230 * For partial wake locks, keep track of whether we are in the list 3231 * to consume CPU cycles. 3232 */ 3233 @VisibleForTesting 3234 public boolean mInList; 3235 StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)3236 public StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3237 TimeBase timeBase, Parcel in) { 3238 super(clock, type, timeBase, in); 3239 mUid = uid; 3240 mTimerPool = timerPool; 3241 mUpdateTimeUs = in.readLong(); 3242 } 3243 StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)3244 public StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3245 TimeBase timeBase) { 3246 super(clock, type, timeBase); 3247 mUid = uid; 3248 mTimerPool = timerPool; 3249 } 3250 setTimeout(long timeoutUs)3251 public void setTimeout(long timeoutUs) { 3252 mTimeoutUs = timeoutUs; 3253 } 3254 writeToParcel(Parcel out, long elapsedRealtimeUs)3255 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3256 super.writeToParcel(out, elapsedRealtimeUs); 3257 out.writeLong(mUpdateTimeUs); 3258 } 3259 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3260 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3261 if (mNesting > 0) { 3262 if (DEBUG && mType < 0) { 3263 Log.v(TAG, "old mUpdateTime=" + mUpdateTimeUs); 3264 } 3265 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3266 mUpdateTimeUs = baseRealtimeUs; 3267 if (DEBUG && mType < 0) { 3268 Log.v(TAG, "new mUpdateTime=" + mUpdateTimeUs); 3269 } 3270 } 3271 } 3272 logState(Printer pw, String prefix)3273 public void logState(Printer pw, String prefix) { 3274 super.logState(pw, prefix); 3275 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTimeUs 3276 + " mAcquireTime=" + mAcquireTimeUs); 3277 } 3278 startRunningLocked(long elapsedRealtimeMs)3279 public void startRunningLocked(long elapsedRealtimeMs) { 3280 if (mNesting++ == 0) { 3281 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3282 mUpdateTimeUs = batteryRealtimeUs; 3283 if (mTimerPool != null) { 3284 // Accumulate time to all currently active timers before adding 3285 // this new one to the pool. 3286 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 3287 // Add this timer to the active pool 3288 mTimerPool.add(this); 3289 } 3290 if (mTimeBase.isRunning()) { 3291 // Increment the count 3292 mCount++; 3293 mAcquireTimeUs = mTotalTimeUs; 3294 } else { 3295 mAcquireTimeUs = -1; 3296 } 3297 if (DEBUG && mType < 0) { 3298 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTimeUs 3299 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 3300 + " mAcquireTime=" + mAcquireTimeUs); 3301 } 3302 } 3303 } 3304 isRunningLocked()3305 public boolean isRunningLocked() { 3306 return mNesting > 0; 3307 } 3308 stopRunningLocked(long elapsedRealtimeMs)3309 public void stopRunningLocked(long elapsedRealtimeMs) { 3310 // Ignore attempt to stop a timer that isn't running 3311 if (mNesting == 0) { 3312 return; 3313 } 3314 if (--mNesting == 0) { 3315 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3316 if (mTimerPool != null) { 3317 // Accumulate time to all active counters, scaled by the total 3318 // active in the pool, before taking this one out of the pool. 3319 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 3320 // Remove this timer from the active pool 3321 mTimerPool.remove(this); 3322 } else { 3323 mNesting = 1; 3324 mTotalTimeUs = computeRunTimeLocked(batteryRealtimeUs, 3325 elapsedRealtimeMs * 1000); 3326 mNesting = 0; 3327 } 3328 3329 if (DEBUG && mType < 0) { 3330 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTimeUs 3331 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 3332 + " mAcquireTime=" + mAcquireTimeUs); 3333 } 3334 3335 if (mAcquireTimeUs >= 0 && mTotalTimeUs == mAcquireTimeUs) { 3336 // If there was no change in the time, then discard this 3337 // count. A somewhat cheezy strategy, but hey. 3338 mCount--; 3339 } 3340 } 3341 } 3342 stopAllRunningLocked(long elapsedRealtimeMs)3343 public void stopAllRunningLocked(long elapsedRealtimeMs) { 3344 if (mNesting > 0) { 3345 mNesting = 1; 3346 stopRunningLocked(elapsedRealtimeMs); 3347 } 3348 } 3349 3350 // Update the total time for all other running Timers with the same type as this Timer 3351 // due to a change in timer count refreshTimersLocked(long batteryRealtimeUs, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)3352 private static long refreshTimersLocked(long batteryRealtimeUs, 3353 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 3354 long selfTimeUs = 0; 3355 final int N = pool.size(); 3356 for (int i=N-1; i>= 0; i--) { 3357 final StopwatchTimer t = pool.get(i); 3358 long heldTimeUs = batteryRealtimeUs - t.mUpdateTimeUs; 3359 if (heldTimeUs > 0) { 3360 final long myTimeUs = heldTimeUs / N; 3361 if (t == self) { 3362 selfTimeUs = myTimeUs; 3363 } 3364 t.mTotalTimeUs += myTimeUs; 3365 } 3366 t.mUpdateTimeUs = batteryRealtimeUs; 3367 } 3368 return selfTimeUs; 3369 } 3370 3371 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)3372 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 3373 if (mTimeoutUs > 0 && curBatteryRealtimeUs > mUpdateTimeUs + mTimeoutUs) { 3374 curBatteryRealtimeUs = mUpdateTimeUs + mTimeoutUs; 3375 } 3376 return mTotalTimeUs + (mNesting > 0 3377 ? (curBatteryRealtimeUs - mUpdateTimeUs) 3378 / (mTimerPool != null ? mTimerPool.size() : 1) 3379 : 0); 3380 } 3381 3382 @Override computeCurrentCountLocked()3383 protected int computeCurrentCountLocked() { 3384 return mCount; 3385 } 3386 3387 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3388 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3389 boolean canDetach = mNesting <= 0; 3390 super.reset(canDetach && detachIfReset, elapsedRealtimeUs); 3391 if (mNesting > 0) { 3392 mUpdateTimeUs = mTimeBase.getRealtime(elapsedRealtimeUs); 3393 } 3394 // To ensure mCount isn't decreased to -1 if timer is stopped later. 3395 mAcquireTimeUs = -1; 3396 return canDetach; 3397 } 3398 3399 @Override detach()3400 public void detach() { 3401 super.detach(); 3402 if (mTimerPool != null) { 3403 mTimerPool.remove(this); 3404 } 3405 } 3406 3407 @Override readSummaryFromParcelLocked(Parcel in)3408 public void readSummaryFromParcelLocked(Parcel in) { 3409 super.readSummaryFromParcelLocked(in); 3410 mNesting = 0; 3411 } 3412 3413 /** 3414 * Set the mark so that we can query later for the total time the timer has 3415 * accumulated since this point. The timer can be running or not. 3416 * 3417 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 3418 */ setMark(long elapsedRealtimeMs)3419 public void setMark(long elapsedRealtimeMs) { 3420 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3421 if (mNesting > 0) { 3422 // We are running. 3423 if (mTimerPool != null) { 3424 refreshTimersLocked(batteryRealtimeUs, mTimerPool, this); 3425 } else { 3426 mTotalTimeUs += batteryRealtimeUs - mUpdateTimeUs; 3427 mUpdateTimeUs = batteryRealtimeUs; 3428 } 3429 } 3430 mTimeBeforeMarkUs = mTotalTimeUs; 3431 } 3432 } 3433 3434 /** 3435 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 3436 * TimeBase is effectively a subset of the other. 3437 */ 3438 public static class DualTimer extends DurationTimer { 3439 // This class both is a DurationTimer and also holds a second DurationTimer. 3440 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 3441 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 3442 // STATS_SINCE_CHARGED). 3443 // mSubTimer typically tracks only part of the total time, such as background time, as 3444 // determined by a subTimeBase. It is NOT pooled. 3445 private final DurationTimer mSubTimer; 3446 3447 /** 3448 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 3449 * The main timer (this) is based on the given timeBase and timerPool. 3450 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 3451 * the main timer is. 3452 */ DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)3453 public DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3454 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 3455 super(clock, uid, type, timerPool, timeBase, in); 3456 mSubTimer = new DurationTimer(clock, uid, type, null, subTimeBase, in); 3457 } 3458 3459 /** 3460 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 3461 * The main timer (this) is based on the given timeBase and timerPool. 3462 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 3463 * the main timer is. 3464 */ DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)3465 public DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3466 TimeBase timeBase, TimeBase subTimeBase) { 3467 super(clock, uid, type, timerPool, timeBase); 3468 mSubTimer = new DurationTimer(clock, uid, type, null, subTimeBase); 3469 } 3470 3471 /** Get the secondary timer. */ 3472 @Override getSubTimer()3473 public DurationTimer getSubTimer() { 3474 return mSubTimer; 3475 } 3476 3477 @Override startRunningLocked(long elapsedRealtimeMs)3478 public void startRunningLocked(long elapsedRealtimeMs) { 3479 super.startRunningLocked(elapsedRealtimeMs); 3480 mSubTimer.startRunningLocked(elapsedRealtimeMs); 3481 } 3482 3483 @Override stopRunningLocked(long elapsedRealtimeMs)3484 public void stopRunningLocked(long elapsedRealtimeMs) { 3485 super.stopRunningLocked(elapsedRealtimeMs); 3486 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 3487 } 3488 3489 @Override stopAllRunningLocked(long elapsedRealtimeMs)3490 public void stopAllRunningLocked(long elapsedRealtimeMs) { 3491 super.stopAllRunningLocked(elapsedRealtimeMs); 3492 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 3493 } 3494 3495 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3496 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3497 boolean active = false; 3498 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 3499 active |= !mSubTimer.reset(false, elapsedRealtimeUs); 3500 active |= !super.reset(detachIfReset, elapsedRealtimeUs); 3501 return !active; 3502 } 3503 3504 @Override detach()3505 public void detach() { 3506 mSubTimer.detach(); 3507 super.detach(); 3508 } 3509 3510 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3511 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3512 super.writeToParcel(out, elapsedRealtimeUs); 3513 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 3514 } 3515 3516 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)3517 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 3518 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3519 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3520 } 3521 3522 @Override readSummaryFromParcelLocked(Parcel in)3523 public void readSummaryFromParcelLocked(Parcel in) { 3524 super.readSummaryFromParcelLocked(in); 3525 mSubTimer.readSummaryFromParcelLocked(in); 3526 } 3527 } 3528 3529 3530 public abstract class OverflowArrayMap<T> { 3531 private static final String OVERFLOW_NAME = "*overflow*"; 3532 3533 final int mUid; 3534 final ArrayMap<String, T> mMap = new ArrayMap<>(); 3535 T mCurOverflow; 3536 ArrayMap<String, MutableInt> mActiveOverflow; 3537 long mLastOverflowTimeMs; 3538 long mLastOverflowFinishTimeMs; 3539 long mLastClearTimeMs; 3540 long mLastCleanupTimeMs; 3541 OverflowArrayMap(int uid)3542 public OverflowArrayMap(int uid) { 3543 mUid = uid; 3544 } 3545 getMap()3546 public ArrayMap<String, T> getMap() { 3547 return mMap; 3548 } 3549 clear()3550 public void clear() { 3551 mLastClearTimeMs = SystemClock.elapsedRealtime(); 3552 mMap.clear(); 3553 mCurOverflow = null; 3554 mActiveOverflow = null; 3555 } 3556 add(String name, T obj)3557 public void add(String name, T obj) { 3558 if (name == null) { 3559 name = ""; 3560 } 3561 mMap.put(name, obj); 3562 if (OVERFLOW_NAME.equals(name)) { 3563 mCurOverflow = obj; 3564 } 3565 } 3566 cleanup(long elapsedRealtimeMs)3567 public void cleanup(long elapsedRealtimeMs) { 3568 mLastCleanupTimeMs = elapsedRealtimeMs; 3569 if (mActiveOverflow != null) { 3570 if (mActiveOverflow.size() == 0) { 3571 mActiveOverflow = null; 3572 } 3573 } 3574 if (mActiveOverflow == null) { 3575 // There is no currently active overflow, so we should no longer have 3576 // an overflow entry. 3577 if (mMap.containsKey(OVERFLOW_NAME)) { 3578 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 3579 + mMap.get(OVERFLOW_NAME)); 3580 mMap.remove(OVERFLOW_NAME); 3581 } 3582 mCurOverflow = null; 3583 } else { 3584 // There is currently active overflow, so we should still have an overflow entry. 3585 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 3586 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 3587 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 3588 } 3589 } 3590 } 3591 startObject(String name, long elapsedRealtimeMs)3592 public T startObject(String name, long elapsedRealtimeMs) { 3593 if (name == null) { 3594 name = ""; 3595 } 3596 T obj = mMap.get(name); 3597 if (obj != null) { 3598 return obj; 3599 } 3600 3601 // No object exists for the given name, but do we currently have it 3602 // running as part of the overflow? 3603 if (mActiveOverflow != null) { 3604 MutableInt over = mActiveOverflow.get(name); 3605 if (over != null) { 3606 // We are already actively counting this name in the overflow object. 3607 obj = mCurOverflow; 3608 if (obj == null) { 3609 // Shouldn't be here, but we'll try to recover. 3610 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 3611 obj = mCurOverflow = instantiateObject(); 3612 mMap.put(OVERFLOW_NAME, obj); 3613 } 3614 over.value++; 3615 return obj; 3616 } 3617 } 3618 3619 // No object exists for given name nor in the overflow; we need to make 3620 // a new one. 3621 final int N = mMap.size(); 3622 if (N >= MAX_WAKELOCKS_PER_UID) { 3623 // Went over the limit on number of objects to track; this one goes 3624 // in to the overflow. 3625 obj = mCurOverflow; 3626 if (obj == null) { 3627 // Need to start overflow now... 3628 obj = mCurOverflow = instantiateObject(); 3629 mMap.put(OVERFLOW_NAME, obj); 3630 } 3631 if (mActiveOverflow == null) { 3632 mActiveOverflow = new ArrayMap<>(); 3633 } 3634 mActiveOverflow.put(name, new MutableInt(1)); 3635 mLastOverflowTimeMs = elapsedRealtimeMs; 3636 return obj; 3637 } 3638 3639 // Normal case where we just need to make a new object. 3640 obj = instantiateObject(); 3641 mMap.put(name, obj); 3642 return obj; 3643 } 3644 stopObject(String name, long elapsedRealtimeMs)3645 public T stopObject(String name, long elapsedRealtimeMs) { 3646 if (name == null) { 3647 name = ""; 3648 } 3649 T obj = mMap.get(name); 3650 if (obj != null) { 3651 return obj; 3652 } 3653 3654 // No object exists for the given name, but do we currently have it 3655 // running as part of the overflow? 3656 if (mActiveOverflow != null) { 3657 MutableInt over = mActiveOverflow.get(name); 3658 if (over != null) { 3659 // We are already actively counting this name in the overflow object. 3660 obj = mCurOverflow; 3661 if (obj != null) { 3662 over.value--; 3663 if (over.value <= 0) { 3664 mActiveOverflow.remove(name); 3665 mLastOverflowFinishTimeMs = elapsedRealtimeMs; 3666 } 3667 return obj; 3668 } 3669 } 3670 } 3671 3672 // Huh, they are stopping an active operation but we can't find one! 3673 // That's not good. 3674 StringBuilder sb = new StringBuilder(); 3675 sb.append("Unable to find object for "); 3676 sb.append(name); 3677 sb.append(" in uid "); 3678 sb.append(mUid); 3679 sb.append(" mapsize="); 3680 sb.append(mMap.size()); 3681 sb.append(" activeoverflow="); 3682 sb.append(mActiveOverflow); 3683 sb.append(" curoverflow="); 3684 sb.append(mCurOverflow); 3685 long now = elapsedRealtimeMs; 3686 if (mLastOverflowTimeMs != 0) { 3687 sb.append(" lastOverflowTime="); 3688 TimeUtils.formatDuration(mLastOverflowTimeMs - now, sb); 3689 } 3690 if (mLastOverflowFinishTimeMs != 0) { 3691 sb.append(" lastOverflowFinishTime="); 3692 TimeUtils.formatDuration(mLastOverflowFinishTimeMs - now, sb); 3693 } 3694 if (mLastClearTimeMs != 0) { 3695 sb.append(" lastClearTime="); 3696 TimeUtils.formatDuration(mLastClearTimeMs - now, sb); 3697 } 3698 if (mLastCleanupTimeMs != 0) { 3699 sb.append(" lastCleanupTime="); 3700 TimeUtils.formatDuration(mLastCleanupTimeMs - now, sb); 3701 } 3702 Slog.wtf(TAG, sb.toString()); 3703 return null; 3704 } 3705 instantiateObject()3706 public abstract T instantiateObject(); 3707 } 3708 3709 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 3710 implements Parcelable { 3711 private final Clock mClock; 3712 private final TimeBase mTimeBase; 3713 private int mNumTxStates; 3714 private int mProcessState; 3715 private TimeMultiStateCounter mIdleTimeMillis; 3716 private final LongSamplingCounter mScanTimeMillis; 3717 private final LongSamplingCounter mSleepTimeMillis; 3718 private TimeMultiStateCounter mRxTimeMillis; 3719 private TimeMultiStateCounter[] mTxTimeMillis; 3720 private final LongSamplingCounter mPowerDrainMaMs; 3721 private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs; 3722 ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates)3723 public ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates) { 3724 mClock = clock; 3725 mTimeBase = timeBase; 3726 mNumTxStates = numTxStates; 3727 mScanTimeMillis = new LongSamplingCounter(timeBase); 3728 mSleepTimeMillis = new LongSamplingCounter(timeBase); 3729 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 3730 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase); 3731 } 3732 readSummaryFromParcel(Parcel in)3733 public void readSummaryFromParcel(Parcel in) { 3734 mIdleTimeMillis = readTimeMultiStateCounter(in, mTimeBase); 3735 mScanTimeMillis.readSummaryFromParcelLocked(in); 3736 mSleepTimeMillis.readSummaryFromParcelLocked(in); 3737 mRxTimeMillis = readTimeMultiStateCounter(in, mTimeBase); 3738 mTxTimeMillis = readTimeMultiStateCounters(in, mTimeBase, mNumTxStates); 3739 3740 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 3741 mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in); 3742 } 3743 3744 @Override describeContents()3745 public int describeContents() { 3746 return 0; 3747 } 3748 writeSummaryToParcel(Parcel dest)3749 public void writeSummaryToParcel(Parcel dest) { 3750 writeTimeMultiStateCounter(dest, mIdleTimeMillis); 3751 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 3752 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 3753 writeTimeMultiStateCounter(dest, mRxTimeMillis); 3754 writeTimeMultiStateCounters(dest, mTxTimeMillis); 3755 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 3756 mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest); 3757 } 3758 3759 @Override writeToParcel(Parcel dest, int flags)3760 public void writeToParcel(Parcel dest, int flags) { 3761 writeTimeMultiStateCounter(dest, mIdleTimeMillis); 3762 mScanTimeMillis.writeToParcel(dest); 3763 mSleepTimeMillis.writeToParcel(dest); 3764 writeTimeMultiStateCounter(dest, mRxTimeMillis); 3765 writeTimeMultiStateCounters(dest, mTxTimeMillis); 3766 mPowerDrainMaMs.writeToParcel(dest); 3767 mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); 3768 } 3769 readTimeMultiStateCounter(Parcel in, TimeBase timeBase)3770 private TimeMultiStateCounter readTimeMultiStateCounter(Parcel in, TimeBase timeBase) { 3771 if (in.readBoolean()) { 3772 return TimeMultiStateCounter.readFromParcel(in, timeBase, 3773 BatteryConsumer.PROCESS_STATE_COUNT, mClock.elapsedRealtime()); 3774 } 3775 return null; 3776 } 3777 writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter)3778 private void writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter) { 3779 if (counter != null) { 3780 dest.writeBoolean(true); 3781 counter.writeToParcel(dest); 3782 } else { 3783 dest.writeBoolean(false); 3784 } 3785 } 3786 readTimeMultiStateCounters(Parcel in, TimeBase timeBase, int expectedNumCounters)3787 private TimeMultiStateCounter[] readTimeMultiStateCounters(Parcel in, TimeBase timeBase, 3788 int expectedNumCounters) { 3789 if (in.readBoolean()) { 3790 final int numCounters = in.readInt(); 3791 boolean valid = (numCounters == expectedNumCounters); 3792 // Need to read counters out of the Parcel, even if all or some of them are 3793 // invalid. 3794 TimeMultiStateCounter[] counters = new TimeMultiStateCounter[numCounters]; 3795 for (int i = 0; i < numCounters; i++) { 3796 final TimeMultiStateCounter counter = TimeMultiStateCounter.readFromParcel(in, 3797 timeBase, BatteryConsumer.PROCESS_STATE_COUNT, 3798 mClock.elapsedRealtime()); 3799 if (counter != null) { 3800 counters[i] = counter; 3801 } else { 3802 valid = false; 3803 } 3804 } 3805 if (valid) { 3806 return counters; 3807 } 3808 } 3809 return null; 3810 } 3811 writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters)3812 private void writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters) { 3813 if (counters != null) { 3814 dest.writeBoolean(true); 3815 dest.writeInt(counters.length); 3816 for (TimeMultiStateCounter counter : counters) { 3817 counter.writeToParcel(dest); 3818 } 3819 } else { 3820 dest.writeBoolean(false); 3821 } 3822 } 3823 reset(boolean detachIfReset, long elapsedRealtimeUs)3824 public void reset(boolean detachIfReset, long elapsedRealtimeUs) { 3825 resetIfNotNull(mIdleTimeMillis, detachIfReset, elapsedRealtimeUs); 3826 mScanTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3827 mSleepTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3828 resetIfNotNull(mRxTimeMillis, detachIfReset, elapsedRealtimeUs); 3829 resetIfNotNull(mTxTimeMillis, detachIfReset, elapsedRealtimeUs); 3830 mPowerDrainMaMs.reset(detachIfReset, elapsedRealtimeUs); 3831 mMonitoredRailChargeConsumedMaMs.reset(detachIfReset, elapsedRealtimeUs); 3832 } 3833 detach()3834 public void detach() { 3835 detachIfNotNull(mIdleTimeMillis); 3836 mScanTimeMillis.detach(); 3837 mSleepTimeMillis.detach(); 3838 detachIfNotNull(mRxTimeMillis); 3839 detachIfNotNull(mTxTimeMillis); 3840 mPowerDrainMaMs.detach(); 3841 mMonitoredRailChargeConsumedMaMs.detach(); 3842 } 3843 3844 /** 3845 * @return a LongSamplingCounter, measuring time spent in the idle state in 3846 * milliseconds. 3847 */ 3848 @Override getIdleTimeCounter()3849 public LongCounter getIdleTimeCounter() { 3850 if (mIdleTimeMillis == null) { 3851 return ZERO_LONG_COUNTER; 3852 } 3853 return mIdleTimeMillis; 3854 } 3855 getOrCreateIdleTimeCounter()3856 private TimeMultiStateCounter getOrCreateIdleTimeCounter() { 3857 if (mIdleTimeMillis == null) { 3858 mIdleTimeMillis = createTimeMultiStateCounter(); 3859 } 3860 return mIdleTimeMillis; 3861 } 3862 3863 /** 3864 * @return a LongSamplingCounter, measuring time spent in the scan state in 3865 * milliseconds. 3866 */ 3867 @Override getScanTimeCounter()3868 public LongSamplingCounter getScanTimeCounter() { 3869 return mScanTimeMillis; 3870 } 3871 3872 /** 3873 * @return a LongSamplingCounter, measuring time spent in the sleep state in 3874 * milliseconds. 3875 */ 3876 @Override getSleepTimeCounter()3877 public LongSamplingCounter getSleepTimeCounter() { 3878 return mSleepTimeMillis; 3879 } 3880 3881 /** 3882 * @return a LongSamplingCounter, measuring time spent in the receive state in 3883 * milliseconds. 3884 */ 3885 @Override getRxTimeCounter()3886 public LongCounter getRxTimeCounter() { 3887 if (mRxTimeMillis == null) { 3888 return ZERO_LONG_COUNTER; 3889 } 3890 return mRxTimeMillis; 3891 } 3892 getOrCreateRxTimeCounter()3893 private TimeMultiStateCounter getOrCreateRxTimeCounter() { 3894 if (mRxTimeMillis == null) { 3895 mRxTimeMillis = createTimeMultiStateCounter(); 3896 } 3897 return mRxTimeMillis; 3898 } 3899 3900 /** 3901 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 3902 * milliseconds. 3903 */ 3904 @Override getTxTimeCounters()3905 public LongCounter[] getTxTimeCounters() { 3906 if (mTxTimeMillis == null) { 3907 return ZERO_LONG_COUNTER_ARRAY; 3908 } 3909 return mTxTimeMillis; 3910 } 3911 getOrCreateTxTimeCounters()3912 private TimeMultiStateCounter[] getOrCreateTxTimeCounters() { 3913 if (mTxTimeMillis == null) { 3914 mTxTimeMillis = new TimeMultiStateCounter[mNumTxStates]; 3915 for (int i = 0; i < mNumTxStates; i++) { 3916 mTxTimeMillis[i] = createTimeMultiStateCounter(); 3917 } 3918 } 3919 return mTxTimeMillis; 3920 } 3921 createTimeMultiStateCounter()3922 private TimeMultiStateCounter createTimeMultiStateCounter() { 3923 final long timestampMs = mClock.elapsedRealtime(); 3924 TimeMultiStateCounter counter = new TimeMultiStateCounter(mTimeBase, 3925 BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 3926 counter.setState(mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 3927 timestampMs); 3928 counter.update(0, timestampMs); 3929 return counter; 3930 } 3931 3932 /** 3933 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 3934 */ 3935 @Override getPowerCounter()3936 public LongSamplingCounter getPowerCounter() { 3937 return mPowerDrainMaMs; 3938 } 3939 3940 /** 3941 * @return a LongSamplingCounter, measuring actual monitored rail energy consumed 3942 * milli-ampere milli-seconds (mAmS). 3943 */ 3944 @Override getMonitoredRailChargeConsumedMaMs()3945 public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() { 3946 return mMonitoredRailChargeConsumedMaMs; 3947 } 3948 setState(int processState, long elapsedTimeMs)3949 private void setState(int processState, long elapsedTimeMs) { 3950 mProcessState = processState; 3951 if (mIdleTimeMillis != null) { 3952 mIdleTimeMillis.setState(processState, elapsedTimeMs); 3953 } 3954 if (mRxTimeMillis != null) { 3955 mRxTimeMillis.setState(processState, elapsedTimeMs); 3956 } 3957 if (mTxTimeMillis != null) { 3958 for (int i = 0; i < mTxTimeMillis.length; i++) { 3959 mTxTimeMillis[i].setState(processState, elapsedTimeMs); 3960 } 3961 } 3962 } 3963 } 3964 3965 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)3966 public SamplingTimer getRpmTimerLocked(String name) { 3967 SamplingTimer rpmt = mRpmStats.get(name); 3968 if (rpmt == null) { 3969 rpmt = new SamplingTimer(mClock, mOnBatteryTimeBase); 3970 mRpmStats.put(name, rpmt); 3971 } 3972 return rpmt; 3973 } 3974 3975 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)3976 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 3977 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 3978 if (rpmt == null) { 3979 rpmt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 3980 mScreenOffRpmStats.put(name, rpmt); 3981 } 3982 return rpmt; 3983 } 3984 3985 /* 3986 * Get the wakeup reason counter, and create a new one if one 3987 * doesn't already exist. 3988 */ getWakeupReasonTimerLocked(String name)3989 public SamplingTimer getWakeupReasonTimerLocked(String name) { 3990 SamplingTimer timer = mWakeupReasonStats.get(name); 3991 if (timer == null) { 3992 timer = new SamplingTimer(mClock, mOnBatteryTimeBase); 3993 mWakeupReasonStats.put(name, timer); 3994 } 3995 return timer; 3996 } 3997 3998 /* 3999 * Get the KernelWakelockTimer associated with name, and create a new one if one 4000 * doesn't already exist. 4001 */ getKernelWakelockTimerLocked(String name)4002 public SamplingTimer getKernelWakelockTimerLocked(String name) { 4003 SamplingTimer kwlt = mKernelWakelockStats.get(name); 4004 if (kwlt == null) { 4005 kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 4006 mKernelWakelockStats.put(name, kwlt); 4007 } 4008 return kwlt; 4009 } 4010 getKernelMemoryTimerLocked(long bucket)4011 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 4012 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 4013 if (kmt == null) { 4014 kmt = new SamplingTimer(mClock, mOnBatteryTimeBase); 4015 mKernelMemoryStats.put(bucket, kmt); 4016 } 4017 return kmt; 4018 } 4019 4020 private class HistoryStepDetailsCalculatorImpl implements HistoryStepDetailsCalculator { 4021 private final HistoryStepDetails mDetails = new HistoryStepDetails(); 4022 4023 private boolean mHasHistoryStepDetails; 4024 private boolean mUpdateRequested; 4025 4026 /** 4027 * Total time (in milliseconds) spent executing in user code. 4028 */ 4029 private long mLastStepCpuUserTimeMs; 4030 private long mCurStepCpuUserTimeMs; 4031 /** 4032 * Total time (in milliseconds) spent executing in kernel code. 4033 */ 4034 private long mLastStepCpuSystemTimeMs; 4035 private long mCurStepCpuSystemTimeMs; 4036 /** 4037 * Times from /proc/stat (but measured in milliseconds). 4038 */ 4039 private long mLastStepStatUserTimeMs; 4040 private long mLastStepStatSystemTimeMs; 4041 private long mLastStepStatIOWaitTimeMs; 4042 private long mLastStepStatIrqTimeMs; 4043 private long mLastStepStatSoftIrqTimeMs; 4044 private long mLastStepStatIdleTimeMs; 4045 private long mCurStepStatUserTimeMs; 4046 private long mCurStepStatSystemTimeMs; 4047 private long mCurStepStatIOWaitTimeMs; 4048 private long mCurStepStatIrqTimeMs; 4049 private long mCurStepStatSoftIrqTimeMs; 4050 private long mCurStepStatIdleTimeMs; 4051 4052 @Override getHistoryStepDetails()4053 public HistoryStepDetails getHistoryStepDetails() { 4054 if (!mUpdateRequested) { 4055 mUpdateRequested = true; 4056 // Perform a CPU update right after we do this collection, so we have started 4057 // collecting good data for the next step. 4058 requestImmediateCpuUpdate(); 4059 4060 if (mPlatformIdleStateCallback != null) { 4061 mDetails.statSubsystemPowerState = 4062 mPlatformIdleStateCallback.getSubsystemLowPowerStats(); 4063 if (DEBUG) { 4064 Slog.i(TAG, 4065 "WRITE SubsystemPowerState:" + mDetails.statSubsystemPowerState); 4066 } 4067 } 4068 } 4069 4070 if (!mHasHistoryStepDetails) { 4071 // We are not generating a delta, so all we need to do is reset the stats 4072 // we will later be doing a delta from. 4073 final int uidCount = mUidStats.size(); 4074 for (int i = 0; i < uidCount; i++) { 4075 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4076 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 4077 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 4078 } 4079 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 4080 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 4081 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 4082 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 4083 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 4084 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 4085 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 4086 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 4087 return null; 4088 } else { 4089 if (DEBUG) { 4090 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTimeMs + " sys=" 4091 + mLastStepStatSystemTimeMs + " io=" + mLastStepStatIOWaitTimeMs 4092 + " irq=" + mLastStepStatIrqTimeMs + " sirq=" 4093 + mLastStepStatSoftIrqTimeMs + " idle=" + mLastStepStatIdleTimeMs); 4094 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTimeMs + " sys=" 4095 + mCurStepStatSystemTimeMs + " io=" + mCurStepStatIOWaitTimeMs 4096 + " irq=" + mCurStepStatIrqTimeMs + " sirq=" 4097 + mCurStepStatSoftIrqTimeMs + " idle=" + mCurStepStatIdleTimeMs); 4098 } 4099 mDetails.userTime = (int) (mCurStepCpuUserTimeMs - mLastStepCpuUserTimeMs); 4100 mDetails.systemTime = (int) (mCurStepCpuSystemTimeMs - mLastStepCpuSystemTimeMs); 4101 mDetails.statUserTime = (int) (mCurStepStatUserTimeMs - mLastStepStatUserTimeMs); 4102 mDetails.statSystemTime = 4103 (int) (mCurStepStatSystemTimeMs - mLastStepStatSystemTimeMs); 4104 mDetails.statIOWaitTime = 4105 (int) (mCurStepStatIOWaitTimeMs - mLastStepStatIOWaitTimeMs); 4106 mDetails.statIrqTime = (int) (mCurStepStatIrqTimeMs - mLastStepStatIrqTimeMs); 4107 mDetails.statSoftIrqTime = 4108 (int) (mCurStepStatSoftIrqTimeMs - mLastStepStatSoftIrqTimeMs); 4109 mDetails.statIdlTime = (int) (mCurStepStatIdleTimeMs - mLastStepStatIdleTimeMs); 4110 mDetails.appCpuUid1 = mDetails.appCpuUid2 = mDetails.appCpuUid3 = -1; 4111 mDetails.appCpuUTime1 = mDetails.appCpuUTime2 = mDetails.appCpuUTime3 = 0; 4112 mDetails.appCpuSTime1 = mDetails.appCpuSTime2 = mDetails.appCpuSTime3 = 0; 4113 final int uidCount = mUidStats.size(); 4114 for (int i = 0; i < uidCount; i++) { 4115 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4116 final int totalUTimeMs = 4117 (int) (uid.mCurStepUserTimeMs - uid.mLastStepUserTimeMs); 4118 final int totalSTimeMs = 4119 (int) (uid.mCurStepSystemTimeMs - uid.mLastStepSystemTimeMs); 4120 final int totalTimeMs = totalUTimeMs + totalSTimeMs; 4121 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 4122 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 4123 if (totalTimeMs <= (mDetails.appCpuUTime3 + mDetails.appCpuSTime3)) { 4124 continue; 4125 } 4126 if (totalTimeMs <= (mDetails.appCpuUTime2 + mDetails.appCpuSTime2)) { 4127 mDetails.appCpuUid3 = uid.mUid; 4128 mDetails.appCpuUTime3 = totalUTimeMs; 4129 mDetails.appCpuSTime3 = totalSTimeMs; 4130 } else { 4131 mDetails.appCpuUid3 = mDetails.appCpuUid2; 4132 mDetails.appCpuUTime3 = mDetails.appCpuUTime2; 4133 mDetails.appCpuSTime3 = mDetails.appCpuSTime2; 4134 if (totalTimeMs <= (mDetails.appCpuUTime1 + mDetails.appCpuSTime1)) { 4135 mDetails.appCpuUid2 = uid.mUid; 4136 mDetails.appCpuUTime2 = totalUTimeMs; 4137 mDetails.appCpuSTime2 = totalSTimeMs; 4138 } else { 4139 mDetails.appCpuUid2 = mDetails.appCpuUid1; 4140 mDetails.appCpuUTime2 = mDetails.appCpuUTime1; 4141 mDetails.appCpuSTime2 = mDetails.appCpuSTime1; 4142 mDetails.appCpuUid1 = uid.mUid; 4143 mDetails.appCpuUTime1 = totalUTimeMs; 4144 mDetails.appCpuSTime1 = totalSTimeMs; 4145 } 4146 } 4147 } 4148 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 4149 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 4150 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 4151 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 4152 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 4153 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 4154 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 4155 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 4156 return mDetails; 4157 } 4158 } 4159 addCpuStats(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs)4160 public void addCpuStats(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, 4161 int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, 4162 int statSoftIrqTimeMs, int statIdleTimeMs) { 4163 if (DEBUG) { 4164 Slog.d(TAG, "Adding cpu: tuser=" + totalUTimeMs + " tsys=" + totalSTimeMs 4165 + " user=" + statUserTimeMs + " sys=" + statSystemTimeMs 4166 + " io=" + statIOWaitTimeMs + " irq=" + statIrqTimeMs 4167 + " sirq=" + statSoftIrqTimeMs + " idle=" + statIdleTimeMs); 4168 } 4169 mCurStepCpuUserTimeMs += totalUTimeMs; 4170 mCurStepCpuSystemTimeMs += totalSTimeMs; 4171 mCurStepStatUserTimeMs += statUserTimeMs; 4172 mCurStepStatSystemTimeMs += statSystemTimeMs; 4173 mCurStepStatIOWaitTimeMs += statIOWaitTimeMs; 4174 mCurStepStatIrqTimeMs += statIrqTimeMs; 4175 mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs; 4176 mCurStepStatIdleTimeMs += statIdleTimeMs; 4177 } 4178 finishAddingCpuLocked()4179 public void finishAddingCpuLocked() { 4180 mHasHistoryStepDetails = true; 4181 mUpdateRequested = false; 4182 } 4183 4184 @Override clear()4185 public void clear() { 4186 mHasHistoryStepDetails = false; 4187 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs = 0; 4188 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs = 0; 4189 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs = 0; 4190 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs = 0; 4191 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs = 0; 4192 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs = 0; 4193 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs = 0; 4194 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs = 0; 4195 } 4196 } 4197 4198 @GuardedBy("this") 4199 @Override commitCurrentHistoryBatchLocked()4200 public void commitCurrentHistoryBatchLocked() { 4201 mHistory.commitCurrentHistoryBatchLocked(); 4202 } 4203 4204 @GuardedBy("this") createFakeHistoryEvents(long numEvents)4205 public void createFakeHistoryEvents(long numEvents) { 4206 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 4207 final long uptimeMs = mClock.uptimeMillis(); 4208 for(long i = 0; i < numEvents; i++) { 4209 noteLongPartialWakelockStart("name1", "historyName1", 1000, 4210 elapsedRealtimeMs, uptimeMs); 4211 noteLongPartialWakelockFinish("name1", "historyName1", 1000, 4212 elapsedRealtimeMs, uptimeMs); 4213 } 4214 } 4215 4216 @GuardedBy("this") recordHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)4217 public void recordHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 4218 String name, int uid) { 4219 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid); 4220 } 4221 4222 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, long realtimeUs)4223 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, 4224 long realtimeUs) { 4225 final boolean screenOff = !Display.isOnState(screenState); 4226 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 4227 final boolean updateOnBatteryScreenOffTimeBase = 4228 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 4229 4230 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 4231 if (updateOnBatteryScreenOffTimeBase) { 4232 updateKernelWakelocksLocked(realtimeUs); 4233 updateBatteryPropertiesLocked(); 4234 } 4235 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 4236 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 4237 // improved, remove the surrounding if{}. 4238 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 4239 // if either OnBattery or OnBatteryScreenOfftimebase changes. 4240 updateRpmStatsLocked(realtimeUs); 4241 } 4242 if (DEBUG_ENERGY_CPU) { 4243 Slog.d(TAG, "Updating cpu time because screen is now " 4244 + Display.stateToString(screenState) 4245 + " and battery is " + (unplugged ? "on" : "off")); 4246 } 4247 4248 mOnBatteryTimeBase.setRunning(unplugged, uptimeUs, realtimeUs); 4249 if (updateOnBatteryTimeBase) { 4250 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4251 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptimeUs, realtimeUs); 4252 } 4253 } 4254 if (updateOnBatteryScreenOffTimeBase) { 4255 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, 4256 uptimeUs, realtimeUs); 4257 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4258 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptimeUs, realtimeUs); 4259 } 4260 } 4261 } 4262 } 4263 4264 @GuardedBy("this") updateBatteryPropertiesLocked()4265 private void updateBatteryPropertiesLocked() { 4266 try { 4267 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 4268 ServiceManager.getService("batteryproperties")); 4269 if (registrar != null) { 4270 registrar.scheduleUpdate(); 4271 } 4272 } catch (RemoteException e) { 4273 // Ignore. 4274 } 4275 } 4276 4277 @GuardedBy("this") addIsolatedUidLocked(int isolatedUid, int appUid)4278 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 4279 addIsolatedUidLocked(isolatedUid, appUid, 4280 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4281 } 4282 4283 @GuardedBy("this") 4284 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addIsolatedUid addIsolatedUidLocked(int isolatedUid, int appUid, long elapsedRealtimeMs, long uptimeMs)4285 public void addIsolatedUidLocked(int isolatedUid, int appUid, 4286 long elapsedRealtimeMs, long uptimeMs) { 4287 mIsolatedUids.put(isolatedUid, appUid); 4288 mIsolatedUidRefCounts.put(isolatedUid, 1); 4289 final Uid u = getUidStatsLocked(appUid, elapsedRealtimeMs, uptimeMs); 4290 u.addIsolatedUid(isolatedUid); 4291 } 4292 4293 /** 4294 * Schedules a read of the latest cpu times before removing the isolated UID. 4295 * @see #removeIsolatedUidLocked(int, int, int) 4296 */ scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid)4297 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { 4298 int curUid = mIsolatedUids.get(isolatedUid, -1); 4299 if (curUid == appUid) { 4300 if (mExternalSync != null) { 4301 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 4302 } 4303 } 4304 } 4305 4306 /** 4307 * Isolated uid should only be removed after all wakelocks associated with the uid are stopped 4308 * and the cpu time-in-state has been read one last time for the uid. 4309 * 4310 * @see #scheduleRemoveIsolatedUidLocked(int, int) 4311 * 4312 * @return true if the isolated uid is actually removed. 4313 */ 4314 @GuardedBy("this") maybeRemoveIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs)4315 public boolean maybeRemoveIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, 4316 long uptimeMs) { 4317 final int refCount = mIsolatedUidRefCounts.get(isolatedUid, 0) - 1; 4318 if (refCount > 0) { 4319 // Isolated uid is still being tracked 4320 mIsolatedUidRefCounts.put(isolatedUid, refCount); 4321 return false; 4322 } 4323 4324 final int idx = mIsolatedUids.indexOfKey(isolatedUid); 4325 if (idx >= 0) { 4326 final int ownerUid = mIsolatedUids.valueAt(idx); 4327 final Uid u = getUidStatsLocked(ownerUid, elapsedRealtimeMs, uptimeMs); 4328 u.removeIsolatedUid(isolatedUid); 4329 mIsolatedUids.removeAt(idx); 4330 mIsolatedUidRefCounts.delete(isolatedUid); 4331 } else { 4332 Slog.w(TAG, "Attempted to remove untracked isolated uid (" + isolatedUid + ")"); 4333 } 4334 mPendingRemovedUids.add(new UidToRemove(isolatedUid, elapsedRealtimeMs)); 4335 4336 return true; 4337 } 4338 4339 /** 4340 * Increment the ref count for an isolated uid. 4341 * call #maybeRemoveIsolatedUidLocked to decrement. 4342 */ incrementIsolatedUidRefCount(int uid)4343 public void incrementIsolatedUidRefCount(int uid) { 4344 final int refCount = mIsolatedUidRefCounts.get(uid, 0); 4345 if (refCount <= 0) { 4346 // Uid is not mapped or referenced 4347 Slog.w(TAG, 4348 "Attempted to increment ref counted of untracked isolated uid (" + uid + ")"); 4349 return; 4350 } 4351 mIsolatedUidRefCounts.put(uid, refCount + 1); 4352 } 4353 mapUid(int uid)4354 private int mapUid(int uid) { 4355 if (Process.isSdkSandboxUid(uid)) { 4356 return Process.getAppUidForSdkSandboxUid(uid); 4357 } 4358 return mapIsolatedUid(uid); 4359 } 4360 mapIsolatedUid(int uid)4361 private int mapIsolatedUid(int uid) { 4362 return mIsolatedUids.get(/*key=*/uid, /*valueIfKeyNotFound=*/uid); 4363 } 4364 4365 @GuardedBy("this") noteEventLocked(int code, String name, int uid, long elapsedRealtimeMs, long uptimeMs)4366 public void noteEventLocked(int code, String name, int uid, 4367 long elapsedRealtimeMs, long uptimeMs) { 4368 uid = mapUid(uid); 4369 if (!mActiveEvents.updateState(code, name, uid, 0)) { 4370 return; 4371 } 4372 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid); 4373 } 4374 4375 @GuardedBy("this") noteCurrentTimeChangedLocked(long currentTimeMs, long elapsedRealtimeMs, long uptimeMs)4376 public void noteCurrentTimeChangedLocked(long currentTimeMs, 4377 long elapsedRealtimeMs, long uptimeMs) { 4378 mHistory.recordCurrentTimeChange(elapsedRealtimeMs, uptimeMs, currentTimeMs); 4379 } 4380 4381 @GuardedBy("this") noteProcessStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4382 public void noteProcessStartLocked(String name, int uid, 4383 long elapsedRealtimeMs, long uptimeMs) { 4384 uid = mapUid(uid); 4385 if (isOnBattery()) { 4386 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4387 u.getProcessStatsLocked(name).incStartsLocked(); 4388 } 4389 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 4390 return; 4391 } 4392 if (!mRecordAllHistory) { 4393 return; 4394 } 4395 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid); 4396 } 4397 4398 @GuardedBy("this") noteProcessCrashLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4399 public void noteProcessCrashLocked(String name, int uid, 4400 long elapsedRealtimeMs, long uptimeMs) { 4401 uid = mapUid(uid); 4402 if (isOnBattery()) { 4403 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4404 u.getProcessStatsLocked(name).incNumCrashesLocked(); 4405 } 4406 } 4407 4408 @GuardedBy("this") noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4409 public void noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4410 uid = mapUid(uid); 4411 if (isOnBattery()) { 4412 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4413 u.getProcessStatsLocked(name).incNumAnrsLocked(); 4414 } 4415 } 4416 4417 @GuardedBy("this") noteUidProcessStateLocked(int uid, int state)4418 public void noteUidProcessStateLocked(int uid, int state) { 4419 noteUidProcessStateLocked(uid, state, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4420 } 4421 4422 @GuardedBy("this") 4423 @SuppressWarnings("GuardedBy") // errorprone false positive on u.updateUidProcessStateLocked noteUidProcessStateLocked(int uid, int state, long elapsedRealtimeMs, long uptimeMs)4424 public void noteUidProcessStateLocked(int uid, int state, 4425 long elapsedRealtimeMs, long uptimeMs) { 4426 int parentUid = mapUid(uid); 4427 if (uid != parentUid) { 4428 if (Process.isIsolated(uid)) { 4429 // Isolated UIDs process state is already rolled up into parent, so no need to track 4430 // Otherwise the parent's process state will get downgraded incorrectly 4431 return; 4432 } 4433 } 4434 // TODO(b/155216561): It is possible for isolated uids to be in a higher 4435 // state than its parent uid. We should track the highest state within the union of host 4436 // and isolated uids rather than only the parent uid. 4437 FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, 4438 ActivityManager.processStateAmToProto(state)); 4439 getUidStatsLocked(parentUid, elapsedRealtimeMs, uptimeMs) 4440 .updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs); 4441 } 4442 4443 @GuardedBy("this") noteProcessFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4444 public void noteProcessFinishLocked(String name, int uid, 4445 long elapsedRealtimeMs, long uptimeMs) { 4446 uid = mapUid(uid); 4447 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4448 return; 4449 } 4450 if (!mRecordAllHistory) { 4451 return; 4452 } 4453 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH, name, uid); 4454 } 4455 4456 @GuardedBy("this") noteSyncStartLocked(String name, int uid)4457 public void noteSyncStartLocked(String name, int uid) { 4458 noteSyncStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4459 } 4460 4461 @GuardedBy("this") noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4462 public void noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4463 uid = mapUid(uid); 4464 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4465 .noteStartSyncLocked(name, elapsedRealtimeMs); 4466 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4467 return; 4468 } 4469 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid); 4470 } 4471 4472 @GuardedBy("this") noteSyncFinishLocked(String name, int uid)4473 public void noteSyncFinishLocked(String name, int uid) { 4474 noteSyncFinishLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4475 } 4476 4477 @GuardedBy("this") noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4478 public void noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4479 uid = mapUid(uid); 4480 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4481 .noteStopSyncLocked(name, elapsedRealtimeMs); 4482 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4483 return; 4484 } 4485 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH, name, uid); 4486 } 4487 4488 @GuardedBy("this") noteJobStartLocked(String name, int uid)4489 public void noteJobStartLocked(String name, int uid) { 4490 noteJobStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4491 } 4492 4493 @GuardedBy("this") noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4494 public void noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4495 uid = mapUid(uid); 4496 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4497 .noteStartJobLocked(name, elapsedRealtimeMs); 4498 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4499 return; 4500 } 4501 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid); 4502 } 4503 4504 @GuardedBy("this") noteJobFinishLocked(String name, int uid, int stopReason)4505 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4506 noteJobFinishLocked(name, uid, stopReason, 4507 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4508 } 4509 4510 @GuardedBy("this") noteJobFinishLocked(String name, int uid, int stopReason, long elapsedRealtimeMs, long uptimeMs)4511 public void noteJobFinishLocked(String name, int uid, int stopReason, 4512 long elapsedRealtimeMs, long uptimeMs) { 4513 uid = mapUid(uid); 4514 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4515 .noteStopJobLocked(name, elapsedRealtimeMs, stopReason); 4516 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4517 return; 4518 } 4519 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid); 4520 } 4521 4522 @GuardedBy("this") noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, long elapsedRealtimeMs, long uptimeMs)4523 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, 4524 long elapsedRealtimeMs, long uptimeMs) { 4525 uid = mapUid(uid); 4526 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4527 .noteJobsDeferredLocked(numDeferred, sinceLast); 4528 } 4529 4530 @GuardedBy("this") noteAlarmStartLocked(String name, WorkSource workSource, int uid)4531 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4532 noteAlarmStartLocked(name, workSource, uid, 4533 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4534 } 4535 4536 @GuardedBy("this") noteAlarmStartLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4537 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid, 4538 long elapsedRealtimeMs, long uptimeMs) { 4539 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid, 4540 elapsedRealtimeMs, uptimeMs); 4541 } 4542 4543 @GuardedBy("this") noteAlarmFinishLocked(String name, WorkSource workSource, int uid)4544 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 4545 noteAlarmFinishLocked(name, workSource, uid, 4546 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4547 } 4548 4549 @GuardedBy("this") noteAlarmFinishLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4550 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid, 4551 long elapsedRealtimeMs, long uptimeMs) { 4552 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid, 4553 elapsedRealtimeMs, uptimeMs); 4554 } 4555 4556 @GuardedBy("this") noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4557 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4558 int uid, long elapsedRealtimeMs, long uptimeMs) { 4559 if (!mRecordAllHistory) { 4560 return; 4561 } 4562 4563 if (workSource != null) { 4564 for (int i = 0; i < workSource.size(); ++i) { 4565 uid = mapUid(workSource.getUid(i)); 4566 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4567 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4568 } 4569 } 4570 4571 List<WorkChain> workChains = workSource.getWorkChains(); 4572 if (workChains != null) { 4573 for (int i = 0; i < workChains.size(); ++i) { 4574 uid = mapUid(workChains.get(i).getAttributionUid()); 4575 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4576 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4577 } 4578 } 4579 } 4580 } else { 4581 uid = mapUid(uid); 4582 4583 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4584 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4585 } 4586 } 4587 } 4588 4589 @GuardedBy("this") noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)4590 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4591 String tag) { 4592 noteWakupAlarmLocked(packageName, uid, workSource, tag, 4593 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4594 } 4595 4596 @GuardedBy("this") noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag, long elapsedRealtimeMs, long uptimeMs)4597 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4598 String tag, long elapsedRealtimeMs, long uptimeMs) { 4599 if (workSource != null) { 4600 for (int i = 0; i < workSource.size(); ++i) { 4601 uid = workSource.getUid(i); 4602 final String workSourceName = workSource.getPackageName(i); 4603 4604 if (isOnBattery()) { 4605 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 4606 workSourceName != null ? workSourceName : packageName, 4607 elapsedRealtimeMs, uptimeMs); 4608 pkg.noteWakeupAlarmLocked(tag); 4609 } 4610 } 4611 4612 List<WorkChain> workChains = workSource.getWorkChains(); 4613 if (workChains != null) { 4614 for (int i = 0; i < workChains.size(); ++i) { 4615 final WorkChain wc = workChains.get(i); 4616 uid = wc.getAttributionUid(); 4617 4618 if (isOnBattery()) { 4619 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4620 elapsedRealtimeMs, uptimeMs); 4621 pkg.noteWakeupAlarmLocked(tag); 4622 } 4623 } 4624 } 4625 } else { 4626 if (isOnBattery()) { 4627 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4628 elapsedRealtimeMs, uptimeMs); 4629 pkg.noteWakeupAlarmLocked(tag); 4630 } 4631 } 4632 } 4633 requestWakelockCpuUpdate()4634 private void requestWakelockCpuUpdate() { 4635 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 4636 } 4637 requestImmediateCpuUpdate()4638 private void requestImmediateCpuUpdate() { 4639 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 4640 } 4641 4642 @GuardedBy("this") setRecordAllHistoryLocked(boolean enabled)4643 public void setRecordAllHistoryLocked(boolean enabled) { 4644 mRecordAllHistory = enabled; 4645 if (!enabled) { 4646 // Clear out any existing state. 4647 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 4648 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 4649 // Record the currently running processes as stopping, now that we are no 4650 // longer tracking them. 4651 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4652 HistoryItem.EVENT_PROC); 4653 if (active != null) { 4654 long mSecRealtime = mClock.elapsedRealtime(); 4655 final long mSecUptime = mClock.uptimeMillis(); 4656 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4657 SparseIntArray uids = ent.getValue(); 4658 for (int j=0; j<uids.size(); j++) { 4659 mHistory.recordEvent(mSecRealtime, mSecUptime, 4660 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 4661 } 4662 } 4663 } 4664 } else { 4665 // Record the currently running processes as starting, now that we are tracking them. 4666 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4667 HistoryItem.EVENT_PROC); 4668 if (active != null) { 4669 long mSecRealtime = mClock.elapsedRealtime(); 4670 final long mSecUptime = mClock.uptimeMillis(); 4671 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4672 SparseIntArray uids = ent.getValue(); 4673 for (int j=0; j<uids.size(); j++) { 4674 mHistory.recordEvent(mSecRealtime, mSecUptime, HistoryItem.EVENT_PROC_START, 4675 ent.getKey(), uids.keyAt(j)); 4676 } 4677 } 4678 } 4679 } 4680 } 4681 setNoAutoReset(boolean enabled)4682 public void setNoAutoReset(boolean enabled) { 4683 mNoAutoReset = enabled; 4684 } 4685 4686 @GuardedBy("this") setPretendScreenOff(boolean pretendScreenOff)4687 public void setPretendScreenOff(boolean pretendScreenOff) { 4688 if (mPretendScreenOff != pretendScreenOff) { 4689 mPretendScreenOff = pretendScreenOff; 4690 final int primaryScreenState = mPerDisplayBatteryStats[0].screenState; 4691 noteScreenStateLocked(0, primaryScreenState, 4692 mClock.elapsedRealtime(), mClock.uptimeMillis(), 4693 mClock.currentTimeMillis()); 4694 } 4695 } 4696 4697 @GuardedBy("this") noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging)4698 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4699 int type, boolean unimportantForLogging) { 4700 noteStartWakeLocked(uid, pid, wc, name, historyName, type, unimportantForLogging, 4701 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4702 } 4703 4704 @GuardedBy("this") noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)4705 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4706 int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs) { 4707 final int mappedUid = mapUid(uid); 4708 if (type == WAKE_TYPE_PARTIAL) { 4709 // Only care about partial wake locks, since full wake locks 4710 // will be canceled when the user puts the screen to sleep. 4711 aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs); 4712 if (historyName == null) { 4713 historyName = name; 4714 } 4715 if (mRecordAllHistory) { 4716 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 4717 mappedUid, 0)) { 4718 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, 4719 HistoryItem.EVENT_WAKE_LOCK_START, historyName, mappedUid); 4720 } 4721 } 4722 if (mWakeLockNesting == 0) { 4723 mWakeLockImportant = !unimportantForLogging; 4724 mHistory.recordWakelockStartEvent(elapsedRealtimeMs, uptimeMs, historyName, 4725 mappedUid); 4726 } else if (!mWakeLockImportant && !unimportantForLogging) { 4727 if (mHistory.maybeUpdateWakelockTag(elapsedRealtimeMs, uptimeMs, historyName, 4728 mappedUid)) { 4729 mWakeLockImportant = true; 4730 } 4731 } 4732 mWakeLockNesting++; 4733 } 4734 if (mappedUid >= 0) { 4735 if (mappedUid != uid) { 4736 // Prevent the isolated uid mapping from being removed while the wakelock is 4737 // being held. 4738 incrementIsolatedUidRefCount(uid); 4739 } 4740 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4741 // We only update the cpu time when a wake lock is acquired if the screen is off. 4742 // If the screen is on, we don't distribute the power amongst partial wakelocks. 4743 if (DEBUG_ENERGY_CPU) { 4744 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 4745 } 4746 requestWakelockCpuUpdate(); 4747 } 4748 4749 Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs); 4750 uidStats.noteStartWakeLocked(pid, name, type, elapsedRealtimeMs); 4751 4752 int procState = uidStats.mProcessState; 4753 4754 if (wc != null) { 4755 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 4756 wc.getTags(), getPowerManagerWakeLockLevel(type), name, 4757 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE, procState); 4758 } else { 4759 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, 4760 mapIsolatedUid(uid), null, getPowerManagerWakeLockLevel(type), name, 4761 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE, procState); 4762 } 4763 } 4764 } 4765 4766 @GuardedBy("this") noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type)4767 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4768 int type) { 4769 noteStopWakeLocked(uid, pid, wc, name, historyName, type, 4770 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4771 } 4772 4773 @GuardedBy("this") noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)4774 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4775 int type, long elapsedRealtimeMs, long uptimeMs) { 4776 final int mappedUid = mapUid(uid); 4777 if (type == WAKE_TYPE_PARTIAL) { 4778 mWakeLockNesting--; 4779 if (historyName == null) { 4780 historyName = name; 4781 } 4782 if (mRecordAllHistory) { 4783 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 4784 mappedUid, 0)) { 4785 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, 4786 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, mappedUid); 4787 } 4788 } 4789 if (mWakeLockNesting == 0) { 4790 mHistory.recordWakelockStopEvent(elapsedRealtimeMs, uptimeMs, historyName, 4791 mappedUid); 4792 } 4793 } 4794 if (mappedUid >= 0) { 4795 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4796 if (DEBUG_ENERGY_CPU) { 4797 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 4798 } 4799 requestWakelockCpuUpdate(); 4800 } 4801 4802 Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs); 4803 uidStats.noteStopWakeLocked(pid, name, type, elapsedRealtimeMs); 4804 4805 int procState = uidStats.mProcessState; 4806 if (wc != null) { 4807 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 4808 wc.getTags(), getPowerManagerWakeLockLevel(type), name, 4809 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE, procState); 4810 } else { 4811 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, 4812 mapIsolatedUid(uid), null, getPowerManagerWakeLockLevel(type), name, 4813 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE, procState); 4814 } 4815 4816 if (mappedUid != uid) { 4817 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 4818 maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 4819 } 4820 } 4821 } 4822 4823 /** 4824 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 4825 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 4826 * These are estimations, since batterystats loses some of the original data. 4827 * TODO: Delete this. Instead, FrameworkStatsLog.write should be called from 4828 * PowerManager's Notifier. 4829 */ getPowerManagerWakeLockLevel(int battertStatsWakelockType)4830 private int getPowerManagerWakeLockLevel(int battertStatsWakelockType) { 4831 switch (battertStatsWakelockType) { 4832 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 4833 case BatteryStats.WAKE_TYPE_PARTIAL: 4834 return PowerManager.PARTIAL_WAKE_LOCK; 4835 4836 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 4837 case BatteryStats.WAKE_TYPE_FULL: 4838 return PowerManager.FULL_WAKE_LOCK; 4839 4840 case BatteryStats.WAKE_TYPE_DRAW: 4841 return PowerManager.DRAW_WAKE_LOCK; 4842 4843 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 4844 case BatteryStats.WAKE_TYPE_WINDOW: 4845 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 4846 return -1; 4847 4848 default: 4849 Slog.e(TAG, "Illegal wakelock type in batterystats: " + battertStatsWakelockType); 4850 return -1; 4851 } 4852 } 4853 4854 @GuardedBy("this") noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)4855 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 4856 String historyName, int type, boolean unimportantForLogging, 4857 long elapsedRealtimeMs, long uptimeMs) { 4858 final int N = ws.size(); 4859 for (int i=0; i<N; i++) { 4860 noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type, 4861 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 4862 } 4863 4864 List<WorkChain> wcs = ws.getWorkChains(); 4865 if (wcs != null) { 4866 for (int i = 0; i < wcs.size(); ++i) { 4867 final WorkChain wc = wcs.get(i); 4868 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4869 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 4870 } 4871 } 4872 } 4873 4874 @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)4875 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 4876 String historyName, int type, WorkSource newWs, int newPid, String newName, 4877 String newHistoryName, int newType, boolean newUnimportantForLogging, 4878 long elapsedRealtimeMs, long uptimeMs) { 4879 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 4880 4881 // For correct semantics, we start the need worksources first, so that we won't 4882 // make inappropriate history items as if all wake locks went away and new ones 4883 // appeared. This is okay because tracking of wake locks allows nesting. 4884 // 4885 // First the starts : 4886 final int NN = newWs.size(); 4887 for (int i=0; i<NN; i++) { 4888 noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType, 4889 newUnimportantForLogging, elapsedRealtimeMs, uptimeMs); 4890 } 4891 if (wcs != null) { 4892 List<WorkChain> newChains = wcs[0]; 4893 if (newChains != null) { 4894 for (int i = 0; i < newChains.size(); ++i) { 4895 final WorkChain newChain = newChains.get(i); 4896 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 4897 newHistoryName, newType, newUnimportantForLogging, elapsedRealtimeMs, 4898 uptimeMs); 4899 } 4900 } 4901 } 4902 4903 // Then the stops : 4904 final int NO = ws.size(); 4905 for (int i=0; i<NO; i++) { 4906 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 4907 uptimeMs); 4908 } 4909 if (wcs != null) { 4910 List<WorkChain> goneChains = wcs[1]; 4911 if (goneChains != null) { 4912 for (int i = 0; i < goneChains.size(); ++i) { 4913 final WorkChain goneChain = goneChains.get(i); 4914 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 4915 historyName, type, elapsedRealtimeMs, uptimeMs); 4916 } 4917 } 4918 } 4919 } 4920 4921 @GuardedBy("this") noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)4922 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 4923 String historyName, int type, long elapsedRealtimeMs, long uptimeMs) { 4924 final int N = ws.size(); 4925 for (int i=0; i<N; i++) { 4926 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 4927 uptimeMs); 4928 } 4929 4930 List<WorkChain> wcs = ws.getWorkChains(); 4931 if (wcs != null) { 4932 for (int i = 0; i < wcs.size(); ++i) { 4933 final WorkChain wc = wcs.get(i); 4934 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4935 elapsedRealtimeMs, uptimeMs); 4936 } 4937 } 4938 } 4939 4940 @GuardedBy("this") noteLongPartialWakelockStart(String name, String historyName, int uid)4941 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 4942 noteLongPartialWakelockStart(name, historyName, uid, 4943 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4944 } 4945 4946 @GuardedBy("this") noteLongPartialWakelockStart(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)4947 public void noteLongPartialWakelockStart(String name, String historyName, int uid, 4948 long elapsedRealtimeMs, long uptimeMs) { 4949 noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 4950 } 4951 4952 @GuardedBy("this") noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)4953 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 4954 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 4955 final int N = workSource.size(); 4956 for (int i = 0; i < N; ++i) { 4957 final int uid = mapUid(workSource.getUid(i)); 4958 noteLongPartialWakeLockStartInternal(name, historyName, uid, 4959 elapsedRealtimeMs, uptimeMs); 4960 } 4961 4962 final List<WorkChain> workChains = workSource.getWorkChains(); 4963 if (workChains != null) { 4964 for (int i = 0; i < workChains.size(); ++i) { 4965 final WorkChain workChain = workChains.get(i); 4966 final int uid = workChain.getAttributionUid(); 4967 noteLongPartialWakeLockStartInternal(name, historyName, uid, 4968 elapsedRealtimeMs, uptimeMs); 4969 } 4970 } 4971 } 4972 4973 @GuardedBy("this") noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)4974 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, 4975 long elapsedRealtimeMs, long uptimeMs) { 4976 final int mappedUid = mapUid(uid); 4977 if (historyName == null) { 4978 historyName = name; 4979 } 4980 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, 4981 mappedUid, 0)) { 4982 return; 4983 } 4984 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 4985 historyName, mappedUid); 4986 if (mappedUid != uid) { 4987 // Prevent the isolated uid mapping from being removed while the wakelock is 4988 // being held. 4989 incrementIsolatedUidRefCount(uid); 4990 } 4991 } 4992 4993 @GuardedBy("this") noteLongPartialWakelockFinish(String name, String historyName, int uid)4994 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 4995 noteLongPartialWakelockFinish(name, historyName, uid, 4996 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4997 } 4998 4999 @GuardedBy("this") noteLongPartialWakelockFinish(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5000 public void noteLongPartialWakelockFinish(String name, String historyName, int uid, 5001 long elapsedRealtimeMs, long uptimeMs) { 5002 noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 5003 } 5004 5005 @GuardedBy("this") noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)5006 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 5007 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 5008 final int N = workSource.size(); 5009 for (int i = 0; i < N; ++i) { 5010 final int uid = mapUid(workSource.getUid(i)); 5011 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 5012 elapsedRealtimeMs, uptimeMs); 5013 } 5014 5015 final List<WorkChain> workChains = workSource.getWorkChains(); 5016 if (workChains != null) { 5017 for (int i = 0; i < workChains.size(); ++i) { 5018 final WorkChain workChain = workChains.get(i); 5019 final int uid = workChain.getAttributionUid(); 5020 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 5021 elapsedRealtimeMs, uptimeMs); 5022 } 5023 } 5024 } 5025 5026 @GuardedBy("this") noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5027 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, 5028 long elapsedRealtimeMs, long uptimeMs) { 5029 final int mappedUid = mapUid(uid); 5030 if (historyName == null) { 5031 historyName = name; 5032 } 5033 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, 5034 mappedUid, 0)) { 5035 return; 5036 } 5037 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 5038 historyName, mappedUid); 5039 if (mappedUid != uid) { 5040 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 5041 maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 5042 } 5043 } 5044 5045 @GuardedBy("this") aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs)5046 void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) { 5047 if (mLastWakeupReason != null) { 5048 long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs; 5049 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 5050 timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds 5051 FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, 5052 /* duration_usec */ deltaUptimeMs * 1000, mLastWakeupElapsedTimeMs); 5053 mLastWakeupReason = null; 5054 } 5055 } 5056 5057 @GuardedBy("this") noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs)5058 public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) { 5059 aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs); 5060 mHistory.recordWakeupEvent(elapsedRealtimeMs, uptimeMs, reason); 5061 mLastWakeupReason = reason; 5062 mLastWakeupUptimeMs = uptimeMs; 5063 mLastWakeupElapsedTimeMs = elapsedRealtimeMs; 5064 } 5065 5066 @GuardedBy("this") startAddingCpuStatsLocked()5067 public boolean startAddingCpuStatsLocked() { 5068 mExternalSync.cancelCpuSyncDueToWakelockChange(); 5069 return mOnBatteryInternal; 5070 } 5071 5072 @GuardedBy("this") addCpuStatsLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs)5073 public void addCpuStatsLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, 5074 int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, 5075 int statSoftIrqTimeMs, int statIdleTimeMs) { 5076 mStepDetailsCalculator.addCpuStats(totalUTimeMs, totalSTimeMs, statUserTimeMs, 5077 statSystemTimeMs, statIOWaitTimeMs, statIrqTimeMs, 5078 statSoftIrqTimeMs, statIdleTimeMs); 5079 } 5080 5081 /** 5082 * Called after {@link #addCpuStatsLocked} has been invoked for all active apps. 5083 */ 5084 @GuardedBy("this") finishAddingCpuStatsLocked()5085 public void finishAddingCpuStatsLocked() { 5086 mStepDetailsCalculator.finishAddingCpuLocked(); 5087 } 5088 noteProcessDiedLocked(int uid, int pid)5089 public void noteProcessDiedLocked(int uid, int pid) { 5090 uid = mapUid(uid); 5091 Uid u = mUidStats.get(uid); 5092 if (u != null) { 5093 u.mPids.remove(pid); 5094 } 5095 } 5096 reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs)5097 public void reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs) { 5098 uid = mapUid(uid); 5099 Uid u = mUidStats.get(uid); 5100 if (u != null) { 5101 u.reportExcessiveCpuLocked(proc, overTimeMs, usedTimeMs); 5102 } 5103 } 5104 5105 int mSensorNesting; 5106 5107 @GuardedBy("this") noteStartSensorLocked(int uid, int sensor)5108 public void noteStartSensorLocked(int uid, int sensor) { 5109 noteStartSensorLocked(uid, sensor, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5110 } 5111 5112 @GuardedBy("this") noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)5113 public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 5114 uid = mapUid(uid); 5115 if (mSensorNesting == 0) { 5116 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5117 HistoryItem.STATE_SENSOR_ON_FLAG); 5118 } 5119 mSensorNesting++; 5120 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5121 .noteStartSensor(sensor, elapsedRealtimeMs); 5122 } 5123 5124 @GuardedBy("this") noteStopSensorLocked(int uid, int sensor)5125 public void noteStopSensorLocked(int uid, int sensor) { 5126 noteStopSensorLocked(uid, sensor, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5127 } 5128 5129 @GuardedBy("this") noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)5130 public void noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 5131 uid = mapUid(uid); 5132 mSensorNesting--; 5133 if (mSensorNesting == 0) { 5134 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5135 HistoryItem.STATE_SENSOR_ON_FLAG); 5136 } 5137 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5138 .noteStopSensor(sensor, elapsedRealtimeMs); 5139 } 5140 5141 int mGpsNesting; 5142 5143 @GuardedBy("this") noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)5144 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 5145 noteGpsChangedLocked(oldWs, newWs, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5146 } 5147 5148 @GuardedBy("this") noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)5149 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, 5150 long elapsedRealtimeMs, long uptimeMs) { 5151 for (int i = 0; i < newWs.size(); ++i) { 5152 noteStartGpsLocked(newWs.getUid(i), null, elapsedRealtimeMs, uptimeMs); 5153 } 5154 5155 for (int i = 0; i < oldWs.size(); ++i) { 5156 noteStopGpsLocked((oldWs.getUid(i)), null, elapsedRealtimeMs, uptimeMs); 5157 } 5158 5159 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 5160 if (wcs != null) { 5161 if (wcs[0] != null) { 5162 final List<WorkChain> newChains = wcs[0]; 5163 for (int i = 0; i < newChains.size(); ++i) { 5164 noteStartGpsLocked(-1, newChains.get(i), elapsedRealtimeMs, uptimeMs); 5165 } 5166 } 5167 5168 if (wcs[1] != null) { 5169 final List<WorkChain> goneChains = wcs[1]; 5170 for (int i = 0; i < goneChains.size(); ++i) { 5171 noteStopGpsLocked(-1, goneChains.get(i), elapsedRealtimeMs, uptimeMs); 5172 } 5173 } 5174 } 5175 } 5176 5177 @GuardedBy("this") noteStartGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)5178 private void noteStartGpsLocked(int uid, WorkChain workChain, 5179 long elapsedRealtimeMs, long uptimeMs) { 5180 if (workChain != null) { 5181 uid = workChain.getAttributionUid(); 5182 } 5183 final int mappedUid = mapUid(uid); 5184 if (mGpsNesting == 0) { 5185 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5186 HistoryItem.STATE_GPS_ON_FLAG); 5187 } 5188 mGpsNesting++; 5189 5190 if (workChain == null) { 5191 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 5192 mapIsolatedUid(uid), null, FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 5193 } else { 5194 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 5195 workChain.getUids(), workChain.getTags(), 5196 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 5197 } 5198 5199 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs).noteStartGps(elapsedRealtimeMs); 5200 } 5201 5202 @GuardedBy("this") noteStopGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)5203 private void noteStopGpsLocked(int uid, WorkChain workChain, 5204 long elapsedRealtimeMs, long uptimeMs) { 5205 if (workChain != null) { 5206 uid = workChain.getAttributionUid(); 5207 } 5208 final int mappedUid = mapUid(uid); 5209 mGpsNesting--; 5210 if (mGpsNesting == 0) { 5211 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5212 HistoryItem.STATE_GPS_ON_FLAG); 5213 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 5214 mGpsSignalQualityBin = -1; 5215 } 5216 5217 if (workChain == null) { 5218 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 5219 mapIsolatedUid(uid), null, 5220 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 5221 } else { 5222 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, workChain.getUids(), 5223 workChain.getTags(), FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 5224 } 5225 5226 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs).noteStopGps(elapsedRealtimeMs); 5227 } 5228 5229 @GuardedBy("this") noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs)5230 public void noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs) { 5231 if (mGpsNesting == 0) { 5232 return; 5233 } 5234 if (signalLevel < 0 || signalLevel >= mGpsSignalQualityTimer.length) { 5235 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 5236 return; 5237 } 5238 if (mGpsSignalQualityBin != signalLevel) { 5239 if (mGpsSignalQualityBin >= 0) { 5240 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtimeMs); 5241 } 5242 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 5243 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs); 5244 } 5245 mHistory.recordGpsSignalQualityEvent(elapsedRealtimeMs, uptimeMs, signalLevel); 5246 mGpsSignalQualityBin = signalLevel; 5247 } 5248 } 5249 5250 @GuardedBy("this") noteScreenStateLocked(int display, int state)5251 public void noteScreenStateLocked(int display, int state) { 5252 noteScreenStateLocked(display, state, mClock.elapsedRealtime(), mClock.uptimeMillis(), 5253 mClock.currentTimeMillis()); 5254 } 5255 5256 @GuardedBy("this") noteScreenStateLocked(int display, int displayState, long elapsedRealtimeMs, long uptimeMs, long currentTimeMs)5257 public void noteScreenStateLocked(int display, int displayState, 5258 long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) { 5259 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 5260 // original 4 are mapped to one of the originals. 5261 if (displayState > MAX_TRACKED_SCREEN_STATE) { 5262 if (Display.isOnState(displayState)) { 5263 displayState = Display.STATE_ON; 5264 } else if (Display.isDozeState(displayState)) { 5265 if (Display.isSuspendedState(displayState)) { 5266 displayState = Display.STATE_DOZE_SUSPEND; 5267 } else { 5268 displayState = Display.STATE_DOZE; 5269 } 5270 } else if (Display.isOffState(displayState)) { 5271 displayState = Display.STATE_OFF; 5272 } else { 5273 Slog.wtf(TAG, "Unknown screen state (not mapped): " + displayState); 5274 displayState = Display.STATE_UNKNOWN; 5275 } 5276 } 5277 // As of this point, displayState should be mapped to one of: 5278 // - Display.STATE_ON, 5279 // - Display.STATE_DOZE 5280 // - Display.STATE_DOZE_SUSPEND 5281 // - Display.STATE_OFF 5282 // - Display.STATE_UNKNOWN 5283 5284 int state; 5285 int overallBin = mScreenBrightnessBin; 5286 int externalUpdateFlag = 0; 5287 boolean shouldScheduleSync = false; 5288 final int numDisplay = mPerDisplayBatteryStats.length; 5289 if (display < 0 || display >= numDisplay) { 5290 Slog.wtf(TAG, "Unexpected note screen state for display " + display + " (only " 5291 + mPerDisplayBatteryStats.length + " displays exist...)"); 5292 return; 5293 } 5294 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5295 final int oldDisplayState = displayStats.screenState; 5296 5297 if (oldDisplayState == displayState) { 5298 // Nothing changed 5299 state = mScreenState; 5300 } else { 5301 displayStats.screenState = displayState; 5302 5303 // Stop timer for previous display state. 5304 switch (oldDisplayState) { 5305 case Display.STATE_ON: 5306 displayStats.screenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5307 final int bin = displayStats.screenBrightnessBin; 5308 if (bin >= 0) { 5309 displayStats.screenBrightnessTimers[bin].stopRunningLocked( 5310 elapsedRealtimeMs); 5311 } 5312 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5313 shouldScheduleSync = true; 5314 break; 5315 case Display.STATE_DOZE: 5316 // Transition from doze to doze suspend can be ignored. 5317 if (displayState == Display.STATE_DOZE_SUSPEND) break; 5318 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5319 shouldScheduleSync = true; 5320 break; 5321 case Display.STATE_DOZE_SUSPEND: 5322 // Transition from doze suspend to doze can be ignored. 5323 if (displayState == Display.STATE_DOZE) break; 5324 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5325 shouldScheduleSync = true; 5326 break; 5327 case Display.STATE_OFF: // fallthrough 5328 case Display.STATE_UNKNOWN: 5329 // Not tracked by timers. 5330 break; 5331 default: 5332 Slog.wtf(TAG, 5333 "Attempted to stop timer for unexpected display state " + display); 5334 } 5335 5336 // Start timer for new display state. 5337 switch (displayState) { 5338 case Display.STATE_ON: 5339 displayStats.screenOnTimer.startRunningLocked(elapsedRealtimeMs); 5340 final int bin = displayStats.screenBrightnessBin; 5341 if (bin >= 0) { 5342 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5343 elapsedRealtimeMs); 5344 } 5345 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5346 shouldScheduleSync = true; 5347 break; 5348 case Display.STATE_DOZE: 5349 // Transition from doze suspend to doze can be ignored. 5350 if (oldDisplayState == Display.STATE_DOZE_SUSPEND) break; 5351 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5352 shouldScheduleSync = true; 5353 break; 5354 case Display.STATE_DOZE_SUSPEND: 5355 // Transition from doze to doze suspend can be ignored. 5356 if (oldDisplayState == Display.STATE_DOZE) break; 5357 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5358 shouldScheduleSync = true; 5359 break; 5360 case Display.STATE_OFF: // fallthrough 5361 case Display.STATE_UNKNOWN: 5362 // Not tracked by timers. 5363 break; 5364 default: 5365 Slog.wtf(TAG, 5366 "Attempted to start timer for unexpected display state " + displayState 5367 + " for display " + display); 5368 } 5369 5370 if (shouldScheduleSync 5371 && mGlobalEnergyConsumerStats != null 5372 && mGlobalEnergyConsumerStats.isStandardBucketSupported( 5373 EnergyConsumerStats.POWER_BUCKET_SCREEN_ON)) { 5374 // Display energy consumption stats is available. Prepare to schedule an 5375 // external sync. 5376 externalUpdateFlag |= ExternalStatsSync.UPDATE_DISPLAY; 5377 } 5378 5379 // Reevaluate most important display screen state. 5380 state = Display.STATE_UNKNOWN; 5381 for (int i = 0; i < numDisplay; i++) { 5382 final int tempState = mPerDisplayBatteryStats[i].screenState; 5383 if (tempState == Display.STATE_ON 5384 || state == Display.STATE_ON) { 5385 state = Display.STATE_ON; 5386 } else if (tempState == Display.STATE_DOZE 5387 || state == Display.STATE_DOZE) { 5388 state = Display.STATE_DOZE; 5389 } else if (tempState == Display.STATE_DOZE_SUSPEND 5390 || state == Display.STATE_DOZE_SUSPEND) { 5391 state = Display.STATE_DOZE_SUSPEND; 5392 } else if (tempState == Display.STATE_OFF 5393 || state == Display.STATE_OFF) { 5394 state = Display.STATE_OFF; 5395 } 5396 } 5397 } 5398 5399 final boolean batteryRunning = mOnBatteryTimeBase.isRunning(); 5400 final boolean batteryScreenOffRunning = mOnBatteryScreenOffTimeBase.isRunning(); 5401 5402 state = mPretendScreenOff ? Display.STATE_OFF : state; 5403 if (mScreenState != state) { 5404 recordDailyStatsIfNeededLocked(true, currentTimeMs); 5405 final int oldState = mScreenState; 5406 mScreenState = state; 5407 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 5408 + ", newState=" + Display.stateToString(state)); 5409 5410 if (state != Display.STATE_UNKNOWN) { 5411 int stepState = state-1; 5412 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 5413 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 5414 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 5415 } else { 5416 Slog.wtf(TAG, "Unexpected screen state: " + state); 5417 } 5418 } 5419 5420 int startStates = 0; 5421 int stopStates = 0; 5422 if (Display.isDozeState(state) && !Display.isDozeState(oldState)) { 5423 startStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 5424 mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5425 } else if (Display.isDozeState(oldState) && !Display.isDozeState(state)) { 5426 stopStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 5427 mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5428 } 5429 if (Display.isOnState(state)) { 5430 startStates |= HistoryItem.STATE_SCREEN_ON_FLAG; 5431 mScreenOnTimer.startRunningLocked(elapsedRealtimeMs); 5432 if (mScreenBrightnessBin >= 0) { 5433 mScreenBrightnessTimer[mScreenBrightnessBin] 5434 .startRunningLocked(elapsedRealtimeMs); 5435 } 5436 } else if (Display.isOnState(oldState)) { 5437 stopStates |= HistoryItem.STATE_SCREEN_ON_FLAG; 5438 mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5439 if (mScreenBrightnessBin >= 0) { 5440 mScreenBrightnessTimer[mScreenBrightnessBin] 5441 .stopRunningLocked(elapsedRealtimeMs); 5442 } 5443 } 5444 if (startStates != 0 || stopStates != 0) { 5445 mHistory.recordStateChangeEvent(elapsedRealtimeMs, uptimeMs, startStates, 5446 stopStates); 5447 } 5448 5449 // Per screen state Cpu stats needed. Prepare to schedule an external sync. 5450 externalUpdateFlag |= ExternalStatsSync.UPDATE_CPU; 5451 shouldScheduleSync = true; 5452 5453 if (Display.isOnState(state)) { 5454 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 5455 uptimeMs * 1000, elapsedRealtimeMs * 1000); 5456 // Fake a wake lock, so we consider the device waked as long as the screen is on. 5457 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 5458 elapsedRealtimeMs, uptimeMs); 5459 } else if (Display.isOnState(oldState)) { 5460 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 5461 elapsedRealtimeMs, uptimeMs); 5462 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 5463 uptimeMs * 1000, elapsedRealtimeMs * 1000); 5464 } 5465 // Update discharge amounts. 5466 if (mOnBatteryInternal) { 5467 updateDischargeScreenLevelsLocked(oldState, state); 5468 } 5469 } 5470 5471 // Changing display states might have changed the screen used to determine the overall 5472 // brightness. 5473 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 5474 5475 if (shouldScheduleSync) { 5476 final int numDisplays = mPerDisplayBatteryStats.length; 5477 final int[] displayStates = new int[numDisplays]; 5478 for (int i = 0; i < numDisplays; i++) { 5479 displayStates[i] = mPerDisplayBatteryStats[i].screenState; 5480 } 5481 mExternalSync.scheduleSyncDueToScreenStateChange(externalUpdateFlag, 5482 batteryRunning, batteryScreenOffRunning, state, displayStates); 5483 } 5484 } 5485 5486 /** 5487 * Note screen brightness change for a display. 5488 */ 5489 @GuardedBy("this") noteScreenBrightnessLocked(int display, int brightness)5490 public void noteScreenBrightnessLocked(int display, int brightness) { 5491 noteScreenBrightnessLocked(display, brightness, mClock.elapsedRealtime(), 5492 mClock.uptimeMillis()); 5493 } 5494 5495 5496 /** 5497 * Note screen brightness change for a display. 5498 */ 5499 @GuardedBy("this") noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, long uptimeMs)5500 public void noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, 5501 long uptimeMs) { 5502 // Bin the brightness. 5503 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 5504 if (bin < 0) bin = 0; 5505 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 5506 5507 final int overallBin; 5508 5509 final int numDisplays = mPerDisplayBatteryStats.length; 5510 if (display < 0 || display >= numDisplays) { 5511 Slog.wtf(TAG, "Unexpected note screen brightness for display " + display + " (only " 5512 + mPerDisplayBatteryStats.length + " displays exist...)"); 5513 return; 5514 } 5515 5516 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5517 final int oldBin = displayStats.screenBrightnessBin; 5518 if (oldBin == bin) { 5519 // Nothing changed 5520 overallBin = mScreenBrightnessBin; 5521 } else { 5522 displayStats.screenBrightnessBin = bin; 5523 if (displayStats.screenState == Display.STATE_ON) { 5524 if (oldBin >= 0) { 5525 displayStats.screenBrightnessTimers[oldBin].stopRunningLocked( 5526 elapsedRealtimeMs); 5527 } 5528 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5529 elapsedRealtimeMs); 5530 } 5531 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5532 } 5533 5534 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 5535 } 5536 5537 @GuardedBy("this") evaluateOverallScreenBrightnessBinLocked()5538 private int evaluateOverallScreenBrightnessBinLocked() { 5539 int overallBin = -1; 5540 final int numDisplays = getDisplayCount(); 5541 for (int display = 0; display < numDisplays; display++) { 5542 final int displayBrightnessBin; 5543 if (mPerDisplayBatteryStats[display].screenState == Display.STATE_ON) { 5544 displayBrightnessBin = mPerDisplayBatteryStats[display].screenBrightnessBin; 5545 } else { 5546 displayBrightnessBin = -1; 5547 } 5548 if (displayBrightnessBin > overallBin) { 5549 overallBin = displayBrightnessBin; 5550 } 5551 } 5552 return overallBin; 5553 } 5554 5555 @GuardedBy("this") maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, long uptimeMs)5556 private void maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, 5557 long uptimeMs) { 5558 if (mScreenBrightnessBin != overallBin) { 5559 if (overallBin >= 0) { 5560 mHistory.recordScreenBrightnessEvent(elapsedRealtimeMs, uptimeMs, overallBin); 5561 } 5562 if (mScreenState == Display.STATE_ON) { 5563 if (mScreenBrightnessBin >= 0) { 5564 mScreenBrightnessTimer[mScreenBrightnessBin] 5565 .stopRunningLocked(elapsedRealtimeMs); 5566 } 5567 if (overallBin >= 0) { 5568 mScreenBrightnessTimer[overallBin] 5569 .startRunningLocked(elapsedRealtimeMs); 5570 } 5571 } 5572 mScreenBrightnessBin = overallBin; 5573 } 5574 } 5575 5576 @GuardedBy("this") noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event, long elapsedRealtimeMs, long uptimeMs)5577 public void noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event, 5578 long elapsedRealtimeMs, long uptimeMs) { 5579 if (mOnBatteryInternal) { 5580 uid = mapUid(uid); 5581 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteUserActivityLocked(event); 5582 } 5583 } 5584 5585 @GuardedBy("this") noteWakeUpLocked(String reason, int reasonUid, long elapsedRealtimeMs, long uptimeMs)5586 public void noteWakeUpLocked(String reason, int reasonUid, 5587 long elapsedRealtimeMs, long uptimeMs) { 5588 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP, reason, 5589 reasonUid); 5590 } 5591 5592 @GuardedBy("this") noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs)5593 public void noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs) { 5594 if (mInteractive != interactive) { 5595 mInteractive = interactive; 5596 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 5597 if (interactive) { 5598 mInteractiveTimer.startRunningLocked(elapsedRealtimeMs); 5599 } else { 5600 mInteractiveTimer.stopRunningLocked(elapsedRealtimeMs); 5601 } 5602 } 5603 } 5604 5605 @GuardedBy("this") noteConnectivityChangedLocked(int type, String extra, long elapsedRealtimeMs, long uptimeMs)5606 public void noteConnectivityChangedLocked(int type, String extra, 5607 long elapsedRealtimeMs, long uptimeMs) { 5608 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 5609 extra, type); 5610 mNumConnectivityChange++; 5611 } 5612 5613 @GuardedBy("this") noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5614 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 5615 final long uptimeMillis, int uid) { 5616 uid = mapUid(uid); 5617 mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5618 uid); 5619 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked(); 5620 } 5621 5622 /** 5623 * Updates the radio power state and returns true if an external stats collection should occur. 5624 */ 5625 @GuardedBy("this") noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)5626 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 5627 return noteMobileRadioPowerStateLocked(powerState, timestampNs, uid, 5628 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5629 } 5630 5631 @GuardedBy("this") noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)5632 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, 5633 long elapsedRealtimeMs, long uptimeMs) { 5634 if (mMobileRadioPowerState != powerState) { 5635 long realElapsedRealtimeMs; 5636 final boolean active = isActiveRadioPowerState(powerState); 5637 if (active) { 5638 if (uid > 0) { 5639 noteMobileRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 5640 } 5641 5642 mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 5643 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 5644 HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG); 5645 } else { 5646 realElapsedRealtimeMs = timestampNs / (1000*1000); 5647 long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs; 5648 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 5649 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 5650 + " is before start time " + lastUpdateTimeMs); 5651 realElapsedRealtimeMs = elapsedRealtimeMs; 5652 } else if (realElapsedRealtimeMs < elapsedRealtimeMs) { 5653 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs 5654 - realElapsedRealtimeMs); 5655 } 5656 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 5657 HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG); 5658 } 5659 mMobileRadioPowerState = powerState; 5660 5661 // Inform current RatBatteryStats that the modem active state might have changed. 5662 getRatBatteryStatsLocked(mActiveRat).noteActive(active, elapsedRealtimeMs); 5663 5664 if (active) { 5665 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtimeMs); 5666 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtimeMs); 5667 } else { 5668 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 5669 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 5670 5671 if (mLastModemActivityInfo != null) { 5672 if (elapsedRealtimeMs < mLastModemActivityInfo.getTimestampMillis() 5673 + MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS) { 5674 // Modem Activity info has been collected recently, don't bother 5675 // triggering another update. 5676 return false; 5677 } 5678 } 5679 // Tell the caller to collect radio network/power stats. 5680 return true; 5681 } 5682 } 5683 return false; 5684 } 5685 isActiveRadioPowerState(int powerState)5686 private static boolean isActiveRadioPowerState(int powerState) { 5687 return powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5688 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5689 } 5690 5691 /** 5692 * Toggles the power save mode state. 5693 */ 5694 @GuardedBy("this") notePowerSaveModeLockedInit(boolean enabled, long elapsedRealtimeMs, long uptimeMs)5695 public void notePowerSaveModeLockedInit(boolean enabled, long elapsedRealtimeMs, 5696 long uptimeMs) { 5697 if (mPowerSaveModeEnabled != enabled) { 5698 notePowerSaveModeLocked(enabled, elapsedRealtimeMs, uptimeMs); 5699 } else { 5700 // Log an initial value for BATTERY_SAVER_MODE_STATE_CHANGED in order to 5701 // allow the atom to read all future state changes. 5702 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 5703 enabled 5704 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 5705 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 5706 } 5707 } 5708 5709 @GuardedBy("this") notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs)5710 public void notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs) { 5711 if (mPowerSaveModeEnabled != enabled) { 5712 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 5713 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 5714 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 5715 mPowerSaveModeEnabled = enabled; 5716 if (enabled) { 5717 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 5718 HistoryItem.STATE2_POWER_SAVE_FLAG); 5719 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs); 5720 } else { 5721 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 5722 HistoryItem.STATE2_POWER_SAVE_FLAG); 5723 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs); 5724 } 5725 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 5726 enabled 5727 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 5728 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 5729 } 5730 } 5731 5732 @GuardedBy("this") noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, long elapsedRealtimeMs, long uptimeMs)5733 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, 5734 long elapsedRealtimeMs, long uptimeMs) { 5735 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 5736 if (mDeviceIdling && !nowIdling && activeReason == null) { 5737 // We don't go out of general idling mode until explicitly taken out of 5738 // device idle through going active or significant motion. 5739 nowIdling = true; 5740 } 5741 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 5742 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 5743 // We don't go out of general light idling mode until explicitly taken out of 5744 // device idle through going active or significant motion. 5745 nowLightIdling = true; 5746 } 5747 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 5748 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE, 5749 activeReason, activeUid); 5750 } 5751 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 5752 int statsmode; 5753 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 5754 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 5755 else statsmode = DEVICE_IDLE_MODE_OFF; 5756 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, statsmode); 5757 } 5758 if (mDeviceIdling != nowIdling) { 5759 mDeviceIdling = nowIdling; 5760 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 5761 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 5762 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 5763 if (nowIdling) { 5764 mDeviceIdlingTimer.startRunningLocked(elapsedRealtimeMs); 5765 } else { 5766 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 5767 } 5768 } 5769 if (mDeviceLightIdling != nowLightIdling) { 5770 mDeviceLightIdling = nowLightIdling; 5771 if (nowLightIdling) { 5772 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtimeMs); 5773 } else { 5774 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 5775 } 5776 } 5777 if (mDeviceIdleMode != mode) { 5778 mHistory.recordDeviceIdleEvent(elapsedRealtimeMs, uptimeMs, mode); 5779 long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs; 5780 mLastIdleTimeStartMs = elapsedRealtimeMs; 5781 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 5782 if (lastDuration > mLongestLightIdleTimeMs) { 5783 mLongestLightIdleTimeMs = lastDuration; 5784 } 5785 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtimeMs); 5786 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 5787 if (lastDuration > mLongestFullIdleTimeMs) { 5788 mLongestFullIdleTimeMs = lastDuration; 5789 } 5790 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtimeMs); 5791 } 5792 if (mode == DEVICE_IDLE_MODE_LIGHT) { 5793 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtimeMs); 5794 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 5795 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtimeMs); 5796 } 5797 mDeviceIdleMode = mode; 5798 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 5799 } 5800 } 5801 5802 @GuardedBy("this") notePackageInstalledLocked(String pkgName, long versionCode, long elapsedRealtimeMs, long uptimeMs)5803 public void notePackageInstalledLocked(String pkgName, long versionCode, 5804 long elapsedRealtimeMs, long uptimeMs) { 5805 // XXX need to figure out what to do with long version codes. 5806 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED, 5807 pkgName, (int)versionCode); 5808 PackageChange pc = new PackageChange(); 5809 pc.mPackageName = pkgName; 5810 pc.mUpdate = true; 5811 pc.mVersionCode = versionCode; 5812 addPackageChange(pc); 5813 } 5814 5815 @GuardedBy("this") notePackageUninstalledLocked(String pkgName, long elapsedRealtimeMs, long uptimeMs)5816 public void notePackageUninstalledLocked(String pkgName, 5817 long elapsedRealtimeMs, long uptimeMs) { 5818 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_UNINSTALLED, 5819 pkgName, 0); 5820 PackageChange pc = new PackageChange(); 5821 pc.mPackageName = pkgName; 5822 pc.mUpdate = true; 5823 addPackageChange(pc); 5824 } 5825 addPackageChange(PackageChange pc)5826 private void addPackageChange(PackageChange pc) { 5827 if (mDailyPackageChanges == null) { 5828 mDailyPackageChanges = new ArrayList<>(); 5829 } 5830 mDailyPackageChanges.add(pc); 5831 } 5832 5833 @GuardedBy("this") stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs)5834 void stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs) { 5835 for (int i = 0; i < mGpsSignalQualityTimer.length; i++) { 5836 if (i == except) { 5837 continue; 5838 } 5839 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 5840 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtimeMs); 5841 } 5842 } 5843 } 5844 5845 @GuardedBy("this") notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs)5846 public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) { 5847 if (!mPhoneOn) { 5848 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 5849 HistoryItem.STATE2_PHONE_IN_CALL_FLAG); 5850 mPhoneOn = true; 5851 mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs); 5852 if (mConstants.PHONE_ON_EXTERNAL_STATS_COLLECTION) { 5853 scheduleSyncExternalStatsLocked("phone-on", ExternalStatsSync.UPDATE_RADIO); 5854 } 5855 } 5856 } 5857 5858 @GuardedBy("this") notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs)5859 public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) { 5860 if (mPhoneOn) { 5861 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 5862 HistoryItem.STATE2_PHONE_IN_CALL_FLAG); 5863 mPhoneOn = false; 5864 mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs); 5865 scheduleSyncExternalStatsLocked("phone-off", ExternalStatsSync.UPDATE_RADIO); 5866 } 5867 } 5868 5869 @GuardedBy("this") registerUsbStateReceiver(Context context)5870 private void registerUsbStateReceiver(Context context) { 5871 final IntentFilter usbStateFilter = new IntentFilter(); 5872 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 5873 context.registerReceiver(new BroadcastReceiver() { 5874 @Override 5875 public void onReceive(Context context, Intent intent) { 5876 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 5877 synchronized (BatteryStatsImpl.this) { 5878 noteUsbConnectionStateLocked(state, mClock.elapsedRealtime(), 5879 mClock.uptimeMillis()); 5880 } 5881 } 5882 }, usbStateFilter); 5883 synchronized (this) { 5884 if (mUsbDataState == USB_DATA_UNKNOWN) { 5885 final Intent usbState = context.registerReceiver(null, usbStateFilter); 5886 final boolean initState = usbState != null && usbState.getBooleanExtra( 5887 UsbManager.USB_CONNECTED, false); 5888 noteUsbConnectionStateLocked(initState, mClock.elapsedRealtime(), 5889 mClock.uptimeMillis()); 5890 } 5891 } 5892 } 5893 5894 @GuardedBy("this") noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, long uptimeMs)5895 private void noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, 5896 long uptimeMs) { 5897 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 5898 if (mUsbDataState != newState) { 5899 mUsbDataState = newState; 5900 if (connected) { 5901 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 5902 HistoryItem.STATE2_USB_DATA_LINK_FLAG); 5903 } else { 5904 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 5905 HistoryItem.STATE2_USB_DATA_LINK_FLAG); 5906 } 5907 } 5908 } 5909 5910 @GuardedBy("this") stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)5911 void stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 5912 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 5913 if (i == except) { 5914 continue; 5915 } 5916 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 5917 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 5918 } 5919 } 5920 } 5921 5922 @GuardedBy("this") updateAllPhoneStateLocked(int state, int simState, int strengthBin, long elapsedRealtimeMs, long uptimeMs)5923 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin, 5924 long elapsedRealtimeMs, long uptimeMs) { 5925 boolean scanning = false; 5926 boolean newHistory = false; 5927 int addStateFlag = 0; 5928 int removeStateFlag = 0; 5929 int newState = -1; 5930 int newSignalStrength = -1; 5931 5932 mPhoneServiceStateRaw = state; 5933 mPhoneSimStateRaw = simState; 5934 mPhoneSignalStrengthBinRaw = strengthBin; 5935 5936 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 5937 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5938 // to infer that we are scanning from other data. 5939 if (state == ServiceState.STATE_OUT_OF_SERVICE 5940 && strengthBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5941 state = ServiceState.STATE_IN_SERVICE; 5942 } 5943 } 5944 5945 // If the phone is powered off, stop all timers. 5946 if (state == ServiceState.STATE_POWER_OFF) { 5947 strengthBin = -1; 5948 5949 // If we are in service, make sure the correct signal string timer is running. 5950 } else if (state == ServiceState.STATE_IN_SERVICE) { 5951 // Bin will be changed below. 5952 5953 // If we're out of service, we are in the lowest signal strength 5954 // bin and have the scanning bit set. 5955 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 5956 scanning = true; 5957 strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 5958 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 5959 addStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG; 5960 newHistory = true; 5961 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtimeMs); 5962 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 5963 simState, strengthBin); 5964 } 5965 } 5966 5967 if (!scanning) { 5968 // If we are no longer scanning, then stop the scanning timer. 5969 if (mPhoneSignalScanningTimer.isRunningLocked()) { 5970 removeStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG; 5971 newHistory = true; 5972 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs); 5973 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 5974 simState, strengthBin); 5975 } 5976 } 5977 5978 if (mPhoneServiceState != state) { 5979 newState = state; 5980 newHistory = true; 5981 mPhoneServiceState = state; 5982 } 5983 5984 if (mPhoneSignalStrengthBin != strengthBin) { 5985 if (mPhoneSignalStrengthBin >= 0) { 5986 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 5987 elapsedRealtimeMs); 5988 } 5989 if (strengthBin >= 0) { 5990 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5991 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 5992 } 5993 newSignalStrength = strengthBin; 5994 newHistory = true; 5995 FrameworkStatsLog.write( 5996 FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 5997 } else { 5998 stopAllPhoneSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 5999 } 6000 mPhoneSignalStrengthBin = strengthBin; 6001 } 6002 6003 if (newHistory) { 6004 mHistory.recordPhoneStateChangeEvent(elapsedRealtimeMs, uptimeMs, 6005 addStateFlag, removeStateFlag, newState, newSignalStrength); 6006 } 6007 } 6008 6009 @GuardedBy("this") notePhoneStateLocked(int state, int simState, long elapsedRealtimeMs, long uptimeMs)6010 public void notePhoneStateLocked(int state, int simState, 6011 long elapsedRealtimeMs, long uptimeMs) { 6012 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw, 6013 elapsedRealtimeMs, uptimeMs); 6014 } 6015 6016 @GuardedBy("this") notePhoneSignalStrengthLocked(SignalStrength signalStrength, long elapsedRealtimeMs, long uptimeMs)6017 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength, 6018 long elapsedRealtimeMs, long uptimeMs) { 6019 final int overallSignalStrength = signalStrength.getLevel(); 6020 final SparseIntArray perRatSignalStrength = new SparseIntArray( 6021 BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT); 6022 6023 // Extract signal strength level for each RAT. 6024 final List<CellSignalStrength> cellSignalStrengths = 6025 signalStrength.getCellSignalStrengths(); 6026 final int size = cellSignalStrengths.size(); 6027 for (int i = 0; i < size; i++) { 6028 CellSignalStrength cellSignalStrength = cellSignalStrengths.get(i); 6029 // Map each CellSignalStrength to a BatteryStats.RadioAccessTechnology 6030 final int ratType; 6031 final int level; 6032 if (cellSignalStrength instanceof CellSignalStrengthNr) { 6033 ratType = RADIO_ACCESS_TECHNOLOGY_NR; 6034 level = cellSignalStrength.getLevel(); 6035 } else if (cellSignalStrength instanceof CellSignalStrengthLte) { 6036 ratType = RADIO_ACCESS_TECHNOLOGY_LTE; 6037 level = cellSignalStrength.getLevel(); 6038 } else { 6039 ratType = RADIO_ACCESS_TECHNOLOGY_OTHER; 6040 level = cellSignalStrength.getLevel(); 6041 } 6042 6043 // According to SignalStrength#getCellSignalStrengths(), multiple of the same 6044 // cellSignalStrength can be present. Just take the highest level one for each RAT. 6045 if (perRatSignalStrength.get(ratType, -1) < level) { 6046 perRatSignalStrength.put(ratType, level); 6047 } 6048 } 6049 6050 notePhoneSignalStrengthLocked(overallSignalStrength, perRatSignalStrength, 6051 elapsedRealtimeMs, uptimeMs); 6052 } 6053 6054 /** 6055 * Note phone signal strength change, including per RAT signal strength. 6056 * 6057 * @param signalStrength overall signal strength {@see SignalStrength#getLevel()} 6058 * @param perRatSignalStrength signal strength of available RATs 6059 */ 6060 @GuardedBy("this") notePhoneSignalStrengthLocked(int signalStrength, SparseIntArray perRatSignalStrength)6061 public void notePhoneSignalStrengthLocked(int signalStrength, 6062 SparseIntArray perRatSignalStrength) { 6063 notePhoneSignalStrengthLocked(signalStrength, perRatSignalStrength, 6064 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6065 } 6066 6067 /** 6068 * Note phone signal strength change, including per RAT signal strength. 6069 * 6070 * @param signalStrength overall signal strength {@see SignalStrength#getLevel()} 6071 * @param perRatSignalStrength signal strength of available RATs 6072 */ 6073 @GuardedBy("this") notePhoneSignalStrengthLocked(int signalStrength, SparseIntArray perRatSignalStrength, long elapsedRealtimeMs, long uptimeMs)6074 public void notePhoneSignalStrengthLocked(int signalStrength, 6075 SparseIntArray perRatSignalStrength, 6076 long elapsedRealtimeMs, long uptimeMs) { 6077 // Note each RAT's signal strength. 6078 final int size = perRatSignalStrength.size(); 6079 for (int i = 0; i < size; i++) { 6080 final int rat = perRatSignalStrength.keyAt(i); 6081 final int ratSignalStrength = perRatSignalStrength.valueAt(i); 6082 getRatBatteryStatsLocked(rat).noteSignalStrength(ratSignalStrength, elapsedRealtimeMs); 6083 } 6084 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, signalStrength, 6085 elapsedRealtimeMs, uptimeMs); 6086 } 6087 6088 @GuardedBy("this") notePhoneDataConnectionStateLocked(@etworkType int dataType, boolean hasData, @RegState int serviceType, @ServiceState.FrequencyRange int nrFrequency)6089 public void notePhoneDataConnectionStateLocked(@NetworkType int dataType, boolean hasData, 6090 @RegState int serviceType, @ServiceState.FrequencyRange int nrFrequency) { 6091 notePhoneDataConnectionStateLocked(dataType, hasData, serviceType, nrFrequency, 6092 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6093 } 6094 6095 @GuardedBy("this") notePhoneDataConnectionStateLocked(@etworkType int dataType, boolean hasData, @RegState int serviceType, @ServiceState.FrequencyRange int nrFrequency, long elapsedRealtimeMs, long uptimeMs)6096 public void notePhoneDataConnectionStateLocked(@NetworkType int dataType, boolean hasData, 6097 @RegState int serviceType, @ServiceState.FrequencyRange int nrFrequency, 6098 long elapsedRealtimeMs, long uptimeMs) { 6099 // BatteryStats uses 0 to represent no network type. 6100 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 6101 // Unknown is included in DATA_CONNECTION_OTHER. 6102 int bin = DATA_CONNECTION_OUT_OF_SERVICE; 6103 if (hasData) { 6104 if (dataType > 0 && dataType <= TelephonyManager.getAllNetworkTypes().length) { 6105 bin = dataType; 6106 } else { 6107 switch (serviceType) { 6108 case ServiceState.STATE_OUT_OF_SERVICE: 6109 bin = DATA_CONNECTION_OUT_OF_SERVICE; 6110 break; 6111 case ServiceState.STATE_EMERGENCY_ONLY: 6112 bin = DATA_CONNECTION_EMERGENCY_SERVICE; 6113 break; 6114 default: 6115 bin = DATA_CONNECTION_OTHER; 6116 break; 6117 } 6118 } 6119 } 6120 6121 final int newRat = mapNetworkTypeToRadioAccessTechnology(bin); 6122 if (newRat == RADIO_ACCESS_TECHNOLOGY_NR) { 6123 // Note possible frequency change for the NR RAT. 6124 getRatBatteryStatsLocked(newRat).noteFrequencyRange(nrFrequency, elapsedRealtimeMs); 6125 } 6126 6127 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 6128 if (mPhoneDataConnectionType != bin) { 6129 mHistory.recordDataConnectionTypeChangeEvent(elapsedRealtimeMs, uptimeMs, bin); 6130 if (mPhoneDataConnectionType >= 0) { 6131 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 6132 elapsedRealtimeMs); 6133 } 6134 mPhoneDataConnectionType = bin; 6135 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtimeMs); 6136 6137 if (mActiveRat != newRat) { 6138 getRatBatteryStatsLocked(mActiveRat).noteActive(false, elapsedRealtimeMs); 6139 mActiveRat = newRat; 6140 } 6141 final boolean modemActive = mMobileRadioActiveTimer.isRunningLocked(); 6142 getRatBatteryStatsLocked(newRat).noteActive(modemActive, elapsedRealtimeMs); 6143 } 6144 } 6145 6146 @RadioAccessTechnology mapNetworkTypeToRadioAccessTechnology(@etworkType int dataType)6147 private static int mapNetworkTypeToRadioAccessTechnology(@NetworkType int dataType) { 6148 switch (dataType) { 6149 case TelephonyManager.NETWORK_TYPE_NR: 6150 return RADIO_ACCESS_TECHNOLOGY_NR; 6151 case TelephonyManager.NETWORK_TYPE_LTE: 6152 return RADIO_ACCESS_TECHNOLOGY_LTE; 6153 case TelephonyManager.NETWORK_TYPE_UNKNOWN: //fallthrough 6154 case TelephonyManager.NETWORK_TYPE_GPRS: //fallthrough 6155 case TelephonyManager.NETWORK_TYPE_EDGE: //fallthrough 6156 case TelephonyManager.NETWORK_TYPE_UMTS: //fallthrough 6157 case TelephonyManager.NETWORK_TYPE_CDMA: //fallthrough 6158 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fallthrough 6159 case TelephonyManager.NETWORK_TYPE_EVDO_A: //fallthrough 6160 case TelephonyManager.NETWORK_TYPE_1xRTT: //fallthrough 6161 case TelephonyManager.NETWORK_TYPE_HSDPA: //fallthrough 6162 case TelephonyManager.NETWORK_TYPE_HSUPA: //fallthrough 6163 case TelephonyManager.NETWORK_TYPE_HSPA: //fallthrough 6164 case TelephonyManager.NETWORK_TYPE_IDEN: //fallthrough 6165 case TelephonyManager.NETWORK_TYPE_EVDO_B: //fallthrough 6166 case TelephonyManager.NETWORK_TYPE_EHRPD: //fallthrough 6167 case TelephonyManager.NETWORK_TYPE_HSPAP: //fallthrough 6168 case TelephonyManager.NETWORK_TYPE_GSM: //fallthrough 6169 case TelephonyManager.NETWORK_TYPE_TD_SCDMA: //fallthrough 6170 case TelephonyManager.NETWORK_TYPE_IWLAN: //fallthrough 6171 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6172 default: 6173 Slog.w(TAG, "Unhandled NetworkType (" + dataType + "), mapping to OTHER"); 6174 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6175 } 6176 } 6177 6178 @RadioAccessTechnology mapRadioAccessNetworkTypeToRadioAccessTechnology( @ccessNetworkConstants.RadioAccessNetworkType int dataType)6179 private static int mapRadioAccessNetworkTypeToRadioAccessTechnology( 6180 @AccessNetworkConstants.RadioAccessNetworkType int dataType) { 6181 switch (dataType) { 6182 case AccessNetworkConstants.AccessNetworkType.NGRAN: 6183 return RADIO_ACCESS_TECHNOLOGY_NR; 6184 case AccessNetworkConstants.AccessNetworkType.EUTRAN: 6185 return RADIO_ACCESS_TECHNOLOGY_LTE; 6186 case AccessNetworkConstants.AccessNetworkType.UNKNOWN: //fallthrough 6187 case AccessNetworkConstants.AccessNetworkType.GERAN: //fallthrough 6188 case AccessNetworkConstants.AccessNetworkType.UTRAN: //fallthrough 6189 case AccessNetworkConstants.AccessNetworkType.CDMA2000: //fallthrough 6190 case AccessNetworkConstants.AccessNetworkType.IWLAN: 6191 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6192 default: 6193 Slog.w(TAG, 6194 "Unhandled RadioAccessNetworkType (" + dataType + "), mapping to OTHER"); 6195 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6196 } 6197 } 6198 6199 @GuardedBy("this") noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs)6200 public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) { 6201 if (!mWifiOn) { 6202 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6203 HistoryItem.STATE2_WIFI_ON_FLAG); 6204 mWifiOn = true; 6205 mWifiOnTimer.startRunningLocked(elapsedRealtimeMs); 6206 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 6207 } 6208 } 6209 6210 @GuardedBy("this") noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs)6211 public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) { 6212 if (mWifiOn) { 6213 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6214 HistoryItem.STATE2_WIFI_ON_FLAG); 6215 mWifiOn = false; 6216 mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs); 6217 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 6218 } 6219 } 6220 6221 @GuardedBy("this") noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6222 public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6223 uid = mapUid(uid); 6224 if (mAudioOnNesting == 0) { 6225 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6226 HistoryItem.STATE_AUDIO_ON_FLAG); 6227 mAudioOnTimer.startRunningLocked(elapsedRealtimeMs); 6228 } 6229 mAudioOnNesting++; 6230 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6231 .noteAudioTurnedOnLocked(elapsedRealtimeMs); 6232 } 6233 6234 @GuardedBy("this") noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6235 public void noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6236 if (mAudioOnNesting == 0) { 6237 return; 6238 } 6239 uid = mapUid(uid); 6240 if (--mAudioOnNesting == 0) { 6241 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6242 HistoryItem.STATE_AUDIO_ON_FLAG); 6243 mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs); 6244 } 6245 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6246 .noteAudioTurnedOffLocked(elapsedRealtimeMs); 6247 } 6248 6249 @GuardedBy("this") noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6250 public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6251 uid = mapUid(uid); 6252 if (mVideoOnNesting == 0) { 6253 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6254 HistoryItem.STATE2_VIDEO_ON_FLAG); 6255 mVideoOnTimer.startRunningLocked(elapsedRealtimeMs); 6256 } 6257 mVideoOnNesting++; 6258 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6259 .noteVideoTurnedOnLocked(elapsedRealtimeMs); 6260 } 6261 6262 @GuardedBy("this") noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6263 public void noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6264 if (mVideoOnNesting == 0) { 6265 return; 6266 } 6267 uid = mapUid(uid); 6268 if (--mVideoOnNesting == 0) { 6269 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6270 HistoryItem.STATE2_VIDEO_ON_FLAG); 6271 mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs); 6272 } 6273 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6274 .noteVideoTurnedOffLocked(elapsedRealtimeMs); 6275 } 6276 6277 @GuardedBy("this") noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs)6278 public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) { 6279 if (mAudioOnNesting > 0) { 6280 mAudioOnNesting = 0; 6281 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6282 HistoryItem.STATE_AUDIO_ON_FLAG); 6283 mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6284 for (int i=0; i<mUidStats.size(); i++) { 6285 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6286 uid.noteResetAudioLocked(elapsedRealtimeMs); 6287 } 6288 } 6289 } 6290 6291 @GuardedBy("this") noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs)6292 public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) { 6293 if (mVideoOnNesting > 0) { 6294 mVideoOnNesting = 0; 6295 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6296 HistoryItem.STATE2_VIDEO_ON_FLAG); 6297 mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6298 for (int i=0; i<mUidStats.size(); i++) { 6299 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6300 uid.noteResetVideoLocked(elapsedRealtimeMs); 6301 } 6302 } 6303 } 6304 6305 @GuardedBy("this") noteActivityResumedLocked(int uid)6306 public void noteActivityResumedLocked(int uid) { 6307 noteActivityResumedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6308 } 6309 6310 @GuardedBy("this") noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6311 public void noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6312 uid = mapUid(uid); 6313 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6314 .noteActivityResumedLocked(elapsedRealtimeMs); 6315 } 6316 6317 @GuardedBy("this") noteActivityPausedLocked(int uid)6318 public void noteActivityPausedLocked(int uid) { 6319 noteActivityPausedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6320 } 6321 6322 @GuardedBy("this") noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6323 public void noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6324 uid = mapUid(uid); 6325 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6326 .noteActivityPausedLocked(elapsedRealtimeMs); 6327 } 6328 6329 @GuardedBy("this") noteVibratorOnLocked(int uid, long durationMillis, long elapsedRealtimeMs, long uptimeMs)6330 public void noteVibratorOnLocked(int uid, long durationMillis, 6331 long elapsedRealtimeMs, long uptimeMs) { 6332 uid = mapUid(uid); 6333 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6334 .noteVibratorOnLocked(durationMillis, elapsedRealtimeMs); 6335 } 6336 6337 @GuardedBy("this") noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6338 public void noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6339 uid = mapUid(uid); 6340 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6341 .noteVibratorOffLocked(elapsedRealtimeMs); 6342 } 6343 6344 @GuardedBy("this") noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6345 public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6346 uid = mapUid(uid); 6347 if (mFlashlightOnNesting++ == 0) { 6348 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6349 HistoryItem.STATE2_FLASHLIGHT_FLAG); 6350 mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs); 6351 } 6352 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6353 .noteFlashlightTurnedOnLocked(elapsedRealtimeMs); 6354 } 6355 6356 @GuardedBy("this") noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6357 public void noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6358 if (mFlashlightOnNesting == 0) { 6359 return; 6360 } 6361 uid = mapUid(uid); 6362 if (--mFlashlightOnNesting == 0) { 6363 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6364 HistoryItem.STATE2_FLASHLIGHT_FLAG); 6365 mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs); 6366 } 6367 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6368 .noteFlashlightTurnedOffLocked(elapsedRealtimeMs); 6369 } 6370 6371 @GuardedBy("this") noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6372 public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6373 uid = mapUid(uid); 6374 if (mCameraOnNesting++ == 0) { 6375 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6376 HistoryItem.STATE2_CAMERA_FLAG); 6377 mCameraOnTimer.startRunningLocked(elapsedRealtimeMs); 6378 } 6379 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6380 .noteCameraTurnedOnLocked(elapsedRealtimeMs); 6381 6382 scheduleSyncExternalStatsLocked("camera-on", ExternalStatsSync.UPDATE_CAMERA); 6383 } 6384 6385 @GuardedBy("this") noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6386 public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6387 if (mCameraOnNesting == 0) { 6388 return; 6389 } 6390 uid = mapUid(uid); 6391 if (--mCameraOnNesting == 0) { 6392 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6393 HistoryItem.STATE2_CAMERA_FLAG); 6394 mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs); 6395 } 6396 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6397 .noteCameraTurnedOffLocked(elapsedRealtimeMs); 6398 6399 scheduleSyncExternalStatsLocked("camera-off", ExternalStatsSync.UPDATE_CAMERA); 6400 } 6401 6402 @GuardedBy("this") noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs)6403 public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) { 6404 if (mCameraOnNesting > 0) { 6405 mCameraOnNesting = 0; 6406 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6407 HistoryItem.STATE2_CAMERA_FLAG); 6408 mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6409 for (int i=0; i<mUidStats.size(); i++) { 6410 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6411 uid.noteResetCameraLocked(elapsedRealtimeMs); 6412 } 6413 } 6414 6415 scheduleSyncExternalStatsLocked("camera-reset", ExternalStatsSync.UPDATE_CAMERA); 6416 } 6417 6418 @GuardedBy("this") noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs)6419 public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) { 6420 if (mFlashlightOnNesting > 0) { 6421 mFlashlightOnNesting = 0; 6422 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6423 HistoryItem.STATE2_FLASHLIGHT_FLAG); 6424 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6425 for (int i=0; i<mUidStats.size(); i++) { 6426 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6427 uid.noteResetFlashlightLocked(elapsedRealtimeMs); 6428 } 6429 } 6430 } 6431 6432 @GuardedBy("this") noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6433 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 6434 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 6435 if (workChain != null) { 6436 uid = workChain.getAttributionUid(); 6437 } 6438 uid = mapUid(uid); 6439 if (mBluetoothScanNesting == 0) { 6440 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6441 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6442 mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs); 6443 } 6444 mBluetoothScanNesting++; 6445 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6446 .noteBluetoothScanStartedLocked(elapsedRealtimeMs, isUnoptimized); 6447 } 6448 6449 @GuardedBy("this") noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)6450 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 6451 noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized, 6452 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6453 } 6454 6455 @GuardedBy("this") noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6456 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 6457 long elapsedRealtimeMs, long uptimeMs) { 6458 final int N = ws.size(); 6459 for (int i = 0; i < N; i++) { 6460 noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized, 6461 elapsedRealtimeMs, uptimeMs); 6462 } 6463 6464 final List<WorkChain> workChains = ws.getWorkChains(); 6465 if (workChains != null) { 6466 for (int i = 0; i < workChains.size(); ++i) { 6467 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized, 6468 elapsedRealtimeMs, uptimeMs); 6469 } 6470 } 6471 } 6472 6473 @GuardedBy("this") noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6474 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 6475 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 6476 if (workChain != null) { 6477 uid = workChain.getAttributionUid(); 6478 } 6479 uid = mapUid(uid); 6480 mBluetoothScanNesting--; 6481 if (mBluetoothScanNesting == 0) { 6482 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6483 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6484 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 6485 } 6486 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6487 .noteBluetoothScanStoppedLocked(elapsedRealtimeMs, isUnoptimized); 6488 } 6489 6490 @GuardedBy("this") noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)6491 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 6492 noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized, 6493 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6494 } 6495 6496 @GuardedBy("this") noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6497 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 6498 long elapsedRealtimeMs, long uptimeMs) { 6499 final int N = ws.size(); 6500 for (int i = 0; i < N; i++) { 6501 noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized, 6502 elapsedRealtimeMs, uptimeMs); 6503 } 6504 6505 final List<WorkChain> workChains = ws.getWorkChains(); 6506 if (workChains != null) { 6507 for (int i = 0; i < workChains.size(); ++i) { 6508 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized, 6509 elapsedRealtimeMs, uptimeMs); 6510 } 6511 } 6512 } 6513 6514 @GuardedBy("this") noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs)6515 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) { 6516 if (mBluetoothScanNesting > 0) { 6517 mBluetoothScanNesting = 0; 6518 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6519 HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG); 6520 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 6521 for (int i=0; i<mUidStats.size(); i++) { 6522 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6523 uid.noteResetBluetoothScanLocked(elapsedRealtimeMs); 6524 } 6525 } 6526 } 6527 6528 @GuardedBy("this") noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)6529 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 6530 noteBluetoothScanResultsFromSourceLocked(ws, numNewResults, 6531 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6532 } 6533 6534 @GuardedBy("this") noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, long elapsedRealtimeMs, long uptimeMs)6535 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, 6536 long elapsedRealtimeMs, long uptimeMs) { 6537 final int N = ws.size(); 6538 for (int i = 0; i < N; i++) { 6539 int uid = mapUid(ws.getUid(i)); 6540 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6541 .noteBluetoothScanResultsLocked(numNewResults); 6542 } 6543 6544 final List<WorkChain> workChains = ws.getWorkChains(); 6545 if (workChains != null) { 6546 for (int i = 0; i < workChains.size(); ++i) { 6547 final WorkChain wc = workChains.get(i); 6548 int uid = mapUid(wc.getAttributionUid()); 6549 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6550 .noteBluetoothScanResultsLocked(numNewResults); 6551 } 6552 } 6553 } 6554 6555 @GuardedBy("this") noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)6556 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 6557 final long uptimeMillis, int uid) { 6558 uid = mapUid(uid); 6559 mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 6560 uid); 6561 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked(); 6562 } 6563 6564 @GuardedBy("this") noteWifiRadioPowerState(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)6565 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid, 6566 long elapsedRealtimeMs, long uptimeMs) { 6567 if (mWifiRadioPowerState != powerState) { 6568 final boolean active = 6569 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 6570 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 6571 if (active) { 6572 if (uid > 0) { 6573 noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 6574 } 6575 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6576 HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG); 6577 mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs); 6578 } else { 6579 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6580 HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG); 6581 mWifiActiveTimer.stopRunningLocked(timestampNs / (1000 * 1000)); 6582 } 6583 mWifiRadioPowerState = powerState; 6584 } 6585 } 6586 6587 @GuardedBy("this") noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6588 public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6589 if (!mGlobalWifiRunning) { 6590 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 6591 HistoryItem.STATE2_WIFI_RUNNING_FLAG); 6592 mGlobalWifiRunning = true; 6593 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 6594 int N = ws.size(); 6595 for (int i=0; i<N; i++) { 6596 int uid = mapUid(ws.getUid(i)); 6597 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6598 .noteWifiRunningLocked(elapsedRealtimeMs); 6599 } 6600 6601 List<WorkChain> workChains = ws.getWorkChains(); 6602 if (workChains != null) { 6603 for (int i = 0; i < workChains.size(); ++i) { 6604 int uid = mapUid(workChains.get(i).getAttributionUid()); 6605 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6606 .noteWifiRunningLocked(elapsedRealtimeMs); 6607 } 6608 } 6609 6610 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 6611 } else { 6612 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 6613 } 6614 } 6615 6616 @GuardedBy("this") noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)6617 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, 6618 long elapsedRealtimeMs, long uptimeMs) { 6619 if (mGlobalWifiRunning) { 6620 int N = oldWs.size(); 6621 for (int i=0; i<N; i++) { 6622 int uid = mapUid(oldWs.getUid(i)); 6623 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6624 .noteWifiStoppedLocked(elapsedRealtimeMs); 6625 } 6626 6627 List<WorkChain> workChains = oldWs.getWorkChains(); 6628 if (workChains != null) { 6629 for (int i = 0; i < workChains.size(); ++i) { 6630 int uid = mapUid(workChains.get(i).getAttributionUid()); 6631 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6632 .noteWifiStoppedLocked(elapsedRealtimeMs); 6633 } 6634 } 6635 6636 N = newWs.size(); 6637 for (int i=0; i<N; i++) { 6638 int uid = mapUid(newWs.getUid(i)); 6639 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6640 .noteWifiRunningLocked(elapsedRealtimeMs); 6641 } 6642 6643 workChains = newWs.getWorkChains(); 6644 if (workChains != null) { 6645 for (int i = 0; i < workChains.size(); ++i) { 6646 int uid = mapUid(workChains.get(i).getAttributionUid()); 6647 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6648 .noteWifiRunningLocked(elapsedRealtimeMs); 6649 } 6650 } 6651 } else { 6652 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 6653 } 6654 } 6655 6656 @GuardedBy("this") noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6657 public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6658 if (mGlobalWifiRunning) { 6659 mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs, 6660 HistoryItem.STATE2_WIFI_RUNNING_FLAG); 6661 mGlobalWifiRunning = false; 6662 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 6663 int N = ws.size(); 6664 for (int i=0; i<N; i++) { 6665 int uid = mapUid(ws.getUid(i)); 6666 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6667 .noteWifiStoppedLocked(elapsedRealtimeMs); 6668 } 6669 6670 List<WorkChain> workChains = ws.getWorkChains(); 6671 if (workChains != null) { 6672 for (int i = 0; i < workChains.size(); ++i) { 6673 int uid = mapUid(workChains.get(i).getAttributionUid()); 6674 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6675 .noteWifiStoppedLocked(elapsedRealtimeMs); 6676 } 6677 } 6678 6679 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 6680 } else { 6681 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 6682 } 6683 } 6684 6685 @GuardedBy("this") noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs)6686 public void noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs) { 6687 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 6688 if (mWifiState != wifiState) { 6689 if (mWifiState >= 0) { 6690 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtimeMs); 6691 } 6692 mWifiState = wifiState; 6693 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtimeMs); 6694 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 6695 } 6696 } 6697 6698 @GuardedBy("this") noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, long elapsedRealtimeMs, long uptimeMs)6699 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, 6700 long elapsedRealtimeMs, long uptimeMs) { 6701 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 6702 if (mWifiSupplState != supplState) { 6703 if (mWifiSupplState >= 0) { 6704 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtimeMs); 6705 } 6706 mWifiSupplState = supplState; 6707 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs); 6708 mHistory.recordWifiSupplicantStateChangeEvent(elapsedRealtimeMs, uptimeMs, supplState); 6709 } 6710 } 6711 6712 @GuardedBy("this") stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)6713 void stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 6714 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 6715 if (i == except) { 6716 continue; 6717 } 6718 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 6719 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 6720 } 6721 } 6722 } 6723 6724 @GuardedBy("this") noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs)6725 public void noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs) { 6726 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 6727 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 6728 if (mWifiSignalStrengthBin != strengthBin) { 6729 if (mWifiSignalStrengthBin >= 0) { 6730 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 6731 elapsedRealtimeMs); 6732 } 6733 if (strengthBin >= 0) { 6734 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 6735 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 6736 } 6737 mHistory.recordWifiSignalStrengthChangeEvent(elapsedRealtimeMs, uptimeMs, 6738 strengthBin); 6739 } else { 6740 stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 6741 } 6742 mWifiSignalStrengthBin = strengthBin; 6743 } 6744 } 6745 6746 private int mWifiFullLockNesting = 0; 6747 6748 @GuardedBy("this") noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6749 public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6750 if (mWifiFullLockNesting == 0) { 6751 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6752 HistoryItem.STATE_WIFI_FULL_LOCK_FLAG); 6753 } 6754 mWifiFullLockNesting++; 6755 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6756 .noteFullWifiLockAcquiredLocked(elapsedRealtimeMs); 6757 } 6758 6759 @GuardedBy("this") noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6760 public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6761 mWifiFullLockNesting--; 6762 if (mWifiFullLockNesting == 0) { 6763 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6764 HistoryItem.STATE_WIFI_FULL_LOCK_FLAG); 6765 } 6766 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6767 .noteFullWifiLockReleasedLocked(elapsedRealtimeMs); 6768 } 6769 6770 int mWifiScanNesting = 0; 6771 6772 @GuardedBy("this") noteWifiScanStartedLocked(int uid)6773 public void noteWifiScanStartedLocked(int uid) { 6774 noteWifiScanStartedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6775 } 6776 6777 @GuardedBy("this") noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6778 public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6779 if (mWifiScanNesting == 0) { 6780 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6781 HistoryItem.STATE_WIFI_SCAN_FLAG); 6782 } 6783 mWifiScanNesting++; 6784 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6785 .noteWifiScanStartedLocked(elapsedRealtimeMs); 6786 } 6787 6788 @GuardedBy("this") noteWifiScanStoppedLocked(int uid)6789 public void noteWifiScanStoppedLocked(int uid) { 6790 noteWifiScanStoppedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6791 } 6792 6793 @GuardedBy("this") noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6794 public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6795 mWifiScanNesting--; 6796 if (mWifiScanNesting == 0) { 6797 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6798 HistoryItem.STATE_WIFI_SCAN_FLAG); 6799 } 6800 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6801 .noteWifiScanStoppedLocked(elapsedRealtimeMs); 6802 } 6803 noteWifiBatchedScanStartedLocked(int uid, int csph, long elapsedRealtimeMs, long uptimeMs)6804 public void noteWifiBatchedScanStartedLocked(int uid, int csph, 6805 long elapsedRealtimeMs, long uptimeMs) { 6806 uid = mapUid(uid); 6807 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6808 .noteWifiBatchedScanStartedLocked(csph, elapsedRealtimeMs); 6809 } 6810 noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6811 public void noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6812 uid = mapUid(uid); 6813 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6814 .noteWifiBatchedScanStoppedLocked(elapsedRealtimeMs); 6815 } 6816 6817 private int mWifiMulticastNesting = 0; 6818 6819 @GuardedBy("this") noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6820 public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6821 uid = mapUid(uid); 6822 if (mWifiMulticastNesting == 0) { 6823 mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs, 6824 HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG); 6825 // Start Wifi Multicast overall timer 6826 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 6827 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs); 6828 } 6829 } 6830 mWifiMulticastNesting++; 6831 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6832 .noteWifiMulticastEnabledLocked(elapsedRealtimeMs); 6833 } 6834 6835 @GuardedBy("this") noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6836 public void noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6837 uid = mapUid(uid); 6838 mWifiMulticastNesting--; 6839 if (mWifiMulticastNesting == 0) { 6840 mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs, 6841 HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG); 6842 6843 // Stop Wifi Multicast overall timer 6844 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 6845 if (DEBUG) Slog.v(TAG, "Multicast Overall Timer Stopped"); 6846 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 6847 } 6848 } 6849 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6850 .noteWifiMulticastDisabledLocked(elapsedRealtimeMs); 6851 } 6852 6853 @GuardedBy("this") noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6854 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, 6855 long elapsedRealtimeMs, long uptimeMs) { 6856 int N = ws.size(); 6857 for (int i=0; i<N; i++) { 6858 final int uid = mapUid(ws.getUid(i)); 6859 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 6860 } 6861 6862 final List<WorkChain> workChains = ws.getWorkChains(); 6863 if (workChains != null) { 6864 for (int i = 0; i < workChains.size(); ++i) { 6865 final WorkChain workChain = workChains.get(i); 6866 final int uid = mapUid(workChain.getAttributionUid()); 6867 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 6868 } 6869 } 6870 } 6871 6872 @GuardedBy("this") noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6873 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, 6874 long elapsedRealtimeMs, long uptimeMs) { 6875 int N = ws.size(); 6876 for (int i=0; i<N; i++) { 6877 final int uid = mapUid(ws.getUid(i)); 6878 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 6879 } 6880 6881 final List<WorkChain> workChains = ws.getWorkChains(); 6882 if (workChains != null) { 6883 for (int i = 0; i < workChains.size(); ++i) { 6884 final WorkChain workChain = workChains.get(i); 6885 final int uid = mapUid(workChain.getAttributionUid()); 6886 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 6887 } 6888 } 6889 } 6890 6891 @GuardedBy("this") noteWifiScanStartedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6892 public void noteWifiScanStartedFromSourceLocked(WorkSource ws, 6893 long elapsedRealtimeMs, long uptimeMs) { 6894 int N = ws.size(); 6895 for (int i=0; i<N; i++) { 6896 final int uid = mapUid(ws.getUid(i)); 6897 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 6898 } 6899 6900 final List<WorkChain> workChains = ws.getWorkChains(); 6901 if (workChains != null) { 6902 for (int i = 0; i < workChains.size(); ++i) { 6903 final WorkChain workChain = workChains.get(i); 6904 final int uid = mapUid(workChain.getAttributionUid()); 6905 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 6906 } 6907 } 6908 } 6909 6910 @GuardedBy("this") noteWifiScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6911 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws, 6912 long elapsedRealtimeMs, long uptimeMs) { 6913 int N = ws.size(); 6914 for (int i=0; i<N; i++) { 6915 final int uid = mapUid(ws.getUid(i)); 6916 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 6917 } 6918 6919 final List<WorkChain> workChains = ws.getWorkChains(); 6920 if (workChains != null) { 6921 for (int i = 0; i < workChains.size(); ++i) { 6922 final WorkChain workChain = workChains.get(i); 6923 final int uid = mapUid(workChain.getAttributionUid()); 6924 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 6925 } 6926 } 6927 } 6928 6929 @GuardedBy("this") noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, long elapsedRealtimeMs, long uptimeMs)6930 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, 6931 long elapsedRealtimeMs, long uptimeMs) { 6932 int N = ws.size(); 6933 for (int i=0; i<N; i++) { 6934 noteWifiBatchedScanStartedLocked(ws.getUid(i), csph, elapsedRealtimeMs, uptimeMs); 6935 } 6936 6937 final List<WorkChain> workChains = ws.getWorkChains(); 6938 if (workChains != null) { 6939 for (int i = 0; i < workChains.size(); ++i) { 6940 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph, 6941 elapsedRealtimeMs, uptimeMs); 6942 } 6943 } 6944 } 6945 6946 @GuardedBy("this") noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6947 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, 6948 long elapsedRealtimeMs, long uptimeMs) { 6949 int N = ws.size(); 6950 for (int i=0; i<N; i++) { 6951 noteWifiBatchedScanStoppedLocked(ws.getUid(i), elapsedRealtimeMs, uptimeMs); 6952 } 6953 6954 final List<WorkChain> workChains = ws.getWorkChains(); 6955 if (workChains != null) { 6956 for (int i = 0; i < workChains.size(); ++i) { 6957 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid(), 6958 elapsedRealtimeMs, uptimeMs); 6959 } 6960 } 6961 } 6962 includeInStringArray(String[] array, String str)6963 private static String[] includeInStringArray(String[] array, String str) { 6964 if (ArrayUtils.indexOf(array, str) >= 0) { 6965 return array; 6966 } 6967 String[] newArray = new String[array.length+1]; 6968 System.arraycopy(array, 0, newArray, 0, array.length); 6969 newArray[array.length] = str; 6970 return newArray; 6971 } 6972 excludeFromStringArray(String[] array, String str)6973 private static String[] excludeFromStringArray(String[] array, String str) { 6974 int index = ArrayUtils.indexOf(array, str); 6975 if (index >= 0) { 6976 String[] newArray = new String[array.length-1]; 6977 if (index > 0) { 6978 System.arraycopy(array, 0, newArray, 0, index); 6979 } 6980 if (index < array.length-1) { 6981 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 6982 } 6983 return newArray; 6984 } 6985 return array; 6986 } 6987 6988 /** @hide */ noteNetworkInterfaceForTransports(String iface, int[] transportTypes)6989 public void noteNetworkInterfaceForTransports(String iface, int[] transportTypes) { 6990 if (TextUtils.isEmpty(iface)) return; 6991 final int displayTransport = NetworkCapabilitiesUtils.getDisplayTransport(transportTypes); 6992 6993 synchronized (mModemNetworkLock) { 6994 if (displayTransport == TRANSPORT_CELLULAR) { 6995 mModemIfaces = includeInStringArray(mModemIfaces, iface); 6996 if (DEBUG) { 6997 Slog.d(TAG, "Note mobile iface " + iface + ": " 6998 + Arrays.toString(mModemIfaces)); 6999 } 7000 } else { 7001 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 7002 if (DEBUG) { 7003 Slog.d(TAG, "Note non-mobile iface " + iface + ": " 7004 + Arrays.toString(mModemIfaces)); 7005 } 7006 } 7007 } 7008 7009 synchronized (mWifiNetworkLock) { 7010 if (displayTransport == TRANSPORT_WIFI) { 7011 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 7012 if (DEBUG) { 7013 Slog.d(TAG, "Note wifi iface " + iface + ": " + Arrays.toString(mWifiIfaces)); 7014 } 7015 } else { 7016 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 7017 if (DEBUG) { 7018 Slog.d(TAG, "Note non-wifi iface " + iface + ": " 7019 + Arrays.toString(mWifiIfaces)); 7020 } 7021 } 7022 } 7023 } 7024 7025 /** 7026 * Records timing data related to an incoming Binder call in order to attribute 7027 * the power consumption to the calling app. 7028 */ noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)7029 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 7030 Collection<BinderCallsStats.CallStat> callStats) { 7031 noteBinderCallStats(workSourceUid, incrementalCallCount, callStats, 7032 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7033 } 7034 noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats, long elapsedRealtimeMs, long uptimeMs)7035 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 7036 Collection<BinderCallsStats.CallStat> callStats, 7037 long elapsedRealtimeMs, long uptimeMs) { 7038 synchronized (this) { 7039 getUidStatsLocked(workSourceUid, elapsedRealtimeMs, uptimeMs) 7040 .noteBinderCallStatsLocked(incrementalCallCount, callStats); 7041 } 7042 } 7043 7044 /** 7045 * Takes note of native IDs of threads taking incoming binder calls. The CPU time 7046 * of these threads is attributed to the apps making those binder calls. 7047 */ noteBinderThreadNativeIds(int[] binderThreadNativeTids)7048 public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) { 7049 mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids); 7050 } 7051 7052 /** 7053 * Estimates the proportion of system server CPU activity handling incoming binder calls 7054 * that can be attributed to each app 7055 */ 7056 @VisibleForTesting updateSystemServiceCallStats()7057 public void updateSystemServiceCallStats() { 7058 // Start off by computing the average duration of recorded binder calls, 7059 // regardless of which binder or transaction. We will use this as a fallback 7060 // for calls that were not sampled at all. 7061 int totalRecordedCallCount = 0; 7062 long totalRecordedCallTimeMicros = 0; 7063 for (int i = 0; i < mUidStats.size(); i++) { 7064 Uid uid = mUidStats.valueAt(i); 7065 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 7066 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 7067 BinderCallStats stats = binderCallStats.valueAt(j); 7068 totalRecordedCallCount += stats.recordedCallCount; 7069 totalRecordedCallTimeMicros += stats.recordedCpuTimeMicros; 7070 } 7071 } 7072 7073 long totalSystemServiceTimeMicros = 0; 7074 7075 // For every UID, use recorded durations of sampled binder calls to estimate 7076 // the total time the system server spent handling requests from this UID. 7077 for (int i = 0; i < mUidStats.size(); i++) { 7078 Uid uid = mUidStats.valueAt(i); 7079 7080 long totalTimeForUidUs = 0; 7081 int totalCallCountForUid = 0; 7082 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 7083 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 7084 BinderCallStats stats = binderCallStats.valueAt(j); 7085 totalCallCountForUid += stats.callCount; 7086 if (stats.recordedCallCount > 0) { 7087 totalTimeForUidUs += 7088 stats.callCount * stats.recordedCpuTimeMicros / stats.recordedCallCount; 7089 } else if (totalRecordedCallCount > 0) { 7090 totalTimeForUidUs += 7091 stats.callCount * totalRecordedCallTimeMicros / totalRecordedCallCount; 7092 } 7093 } 7094 7095 if (totalCallCountForUid < uid.mBinderCallCount && totalRecordedCallCount > 0) { 7096 // Estimate remaining calls, which were not tracked because of binder call 7097 // stats sampling 7098 totalTimeForUidUs += 7099 (uid.mBinderCallCount - totalCallCountForUid) * totalRecordedCallTimeMicros 7100 / totalRecordedCallCount; 7101 } 7102 7103 uid.mSystemServiceTimeUs = totalTimeForUidUs; 7104 totalSystemServiceTimeMicros += totalTimeForUidUs; 7105 } 7106 7107 for (int i = 0; i < mUidStats.size(); i++) { 7108 Uid uid = mUidStats.valueAt(i); 7109 if (totalSystemServiceTimeMicros > 0) { 7110 uid.mProportionalSystemServiceUsage = 7111 (double) uid.mSystemServiceTimeUs / totalSystemServiceTimeMicros; 7112 } else { 7113 uid.mProportionalSystemServiceUsage = 0; 7114 } 7115 } 7116 } 7117 getWifiIfaces()7118 public String[] getWifiIfaces() { 7119 synchronized (mWifiNetworkLock) { 7120 return mWifiIfaces; 7121 } 7122 } 7123 getMobileIfaces()7124 public String[] getMobileIfaces() { 7125 synchronized (mModemNetworkLock) { 7126 return mModemIfaces; 7127 } 7128 } 7129 getScreenOnTime(long elapsedRealtimeUs, int which)7130 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 7131 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7132 } 7133 getScreenOnCount(int which)7134 @Override public int getScreenOnCount(int which) { 7135 return mScreenOnTimer.getCountLocked(which); 7136 } 7137 getScreenDozeTime(long elapsedRealtimeUs, int which)7138 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 7139 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7140 } 7141 getScreenDozeCount(int which)7142 @Override public int getScreenDozeCount(int which) { 7143 return mScreenDozeTimer.getCountLocked(which); 7144 } 7145 getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)7146 @Override public long getScreenBrightnessTime(int brightnessBin, 7147 long elapsedRealtimeUs, int which) { 7148 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 7149 elapsedRealtimeUs, which); 7150 } 7151 getScreenBrightnessTimer(int brightnessBin)7152 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 7153 return mScreenBrightnessTimer[brightnessBin]; 7154 } 7155 7156 @Override getDisplayCount()7157 public int getDisplayCount() { 7158 return mPerDisplayBatteryStats.length; 7159 } 7160 7161 @Override getDisplayScreenOnTime(int display, long elapsedRealtimeUs)7162 public long getDisplayScreenOnTime(int display, long elapsedRealtimeUs) { 7163 return mPerDisplayBatteryStats[display].screenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, 7164 STATS_SINCE_CHARGED); 7165 } 7166 7167 @Override getDisplayScreenDozeTime(int display, long elapsedRealtimeUs)7168 public long getDisplayScreenDozeTime(int display, long elapsedRealtimeUs) { 7169 return mPerDisplayBatteryStats[display].screenDozeTimer.getTotalTimeLocked( 7170 elapsedRealtimeUs, STATS_SINCE_CHARGED); 7171 } 7172 7173 @Override getDisplayScreenBrightnessTime(int display, int brightnessBin, long elapsedRealtimeUs)7174 public long getDisplayScreenBrightnessTime(int display, int brightnessBin, 7175 long elapsedRealtimeUs) { 7176 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 7177 return displayStats.screenBrightnessTimers[brightnessBin].getTotalTimeLocked( 7178 elapsedRealtimeUs, STATS_SINCE_CHARGED); 7179 } 7180 getInteractiveTime(long elapsedRealtimeUs, int which)7181 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 7182 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7183 } 7184 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)7185 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 7186 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7187 } 7188 getPowerSaveModeEnabledCount(int which)7189 @Override public int getPowerSaveModeEnabledCount(int which) { 7190 return mPowerSaveModeEnabledTimer.getCountLocked(which); 7191 } 7192 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)7193 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 7194 int which) { 7195 switch (mode) { 7196 case DEVICE_IDLE_MODE_LIGHT: 7197 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7198 case DEVICE_IDLE_MODE_DEEP: 7199 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7200 } 7201 return 0; 7202 } 7203 getDeviceIdleModeCount(int mode, int which)7204 @Override public int getDeviceIdleModeCount(int mode, int which) { 7205 switch (mode) { 7206 case DEVICE_IDLE_MODE_LIGHT: 7207 return mDeviceIdleModeLightTimer.getCountLocked(which); 7208 case DEVICE_IDLE_MODE_DEEP: 7209 return mDeviceIdleModeFullTimer.getCountLocked(which); 7210 } 7211 return 0; 7212 } 7213 getLongestDeviceIdleModeTime(int mode)7214 @Override public long getLongestDeviceIdleModeTime(int mode) { 7215 switch (mode) { 7216 case DEVICE_IDLE_MODE_LIGHT: 7217 return mLongestLightIdleTimeMs; 7218 case DEVICE_IDLE_MODE_DEEP: 7219 return mLongestFullIdleTimeMs; 7220 } 7221 return 0; 7222 } 7223 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)7224 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 7225 switch (mode) { 7226 case DEVICE_IDLE_MODE_LIGHT: 7227 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7228 case DEVICE_IDLE_MODE_DEEP: 7229 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7230 } 7231 return 0; 7232 } 7233 getDeviceIdlingCount(int mode, int which)7234 @Override public int getDeviceIdlingCount(int mode, int which) { 7235 switch (mode) { 7236 case DEVICE_IDLE_MODE_LIGHT: 7237 return mDeviceLightIdlingTimer.getCountLocked(which); 7238 case DEVICE_IDLE_MODE_DEEP: 7239 return mDeviceIdlingTimer.getCountLocked(which); 7240 } 7241 return 0; 7242 } 7243 getNumConnectivityChange(int which)7244 @Override public int getNumConnectivityChange(int which) { 7245 return mNumConnectivityChange; 7246 } 7247 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)7248 @Override public long getGpsSignalQualityTime(int strengthBin, 7249 long elapsedRealtimeUs, int which) { 7250 if (strengthBin < 0 || strengthBin >= mGpsSignalQualityTimer.length) { 7251 return 0; 7252 } 7253 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 7254 elapsedRealtimeUs, which); 7255 } 7256 getGpsBatteryDrainMaMs()7257 @Override public long getGpsBatteryDrainMaMs() { 7258 final double opVolt = mPowerProfile.getAveragePower( 7259 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 7260 if (opVolt == 0) { 7261 return 0; 7262 } 7263 double energyUsedMaMs = 0.0; 7264 final int which = STATS_SINCE_CHARGED; 7265 final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000; 7266 for(int i=0; i < mGpsSignalQualityTimer.length; i++) { 7267 energyUsedMaMs 7268 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 7269 * (getGpsSignalQualityTime(i, rawRealtimeUs, which) / 1000); 7270 } 7271 return (long) energyUsedMaMs; 7272 } 7273 getPhoneOnTime(long elapsedRealtimeUs, int which)7274 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 7275 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7276 } 7277 getPhoneOnCount(int which)7278 @Override public int getPhoneOnCount(int which) { 7279 return mPhoneOnTimer.getCountLocked(which); 7280 } 7281 getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)7282 @Override public long getPhoneSignalStrengthTime(int strengthBin, 7283 long elapsedRealtimeUs, int which) { 7284 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 7285 elapsedRealtimeUs, which); 7286 } 7287 getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)7288 @Override public long getPhoneSignalScanningTime( 7289 long elapsedRealtimeUs, int which) { 7290 return mPhoneSignalScanningTimer.getTotalTimeLocked( 7291 elapsedRealtimeUs, which); 7292 } 7293 getPhoneSignalScanningTimer()7294 @Override public Timer getPhoneSignalScanningTimer() { 7295 return mPhoneSignalScanningTimer; 7296 } 7297 getPhoneSignalStrengthCount(int strengthBin, int which)7298 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 7299 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 7300 } 7301 getPhoneSignalStrengthTimer(int strengthBin)7302 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 7303 return mPhoneSignalStrengthsTimer[strengthBin]; 7304 } 7305 getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)7306 @Override public long getPhoneDataConnectionTime(int dataType, 7307 long elapsedRealtimeUs, int which) { 7308 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 7309 elapsedRealtimeUs, which); 7310 } 7311 getPhoneDataConnectionCount(int dataType, int which)7312 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 7313 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 7314 } 7315 getPhoneDataConnectionTimer(int dataType)7316 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 7317 return mPhoneDataConnectionsTimer[dataType]; 7318 } 7319 getActiveRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)7320 @Override public long getActiveRadioDurationMs(@RadioAccessTechnology int rat, 7321 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, 7322 long elapsedRealtimeMs) { 7323 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7324 if (stats == null) return 0L; 7325 7326 final int freqCount = stats.perStateTimers.length; 7327 if (frequencyRange < 0 || frequencyRange >= freqCount) return 0L; 7328 7329 final StopwatchTimer[] strengthTimers = stats.perStateTimers[frequencyRange]; 7330 final int strengthCount = strengthTimers.length; 7331 if (signalStrength < 0 || signalStrength >= strengthCount) return 0L; 7332 7333 return stats.perStateTimers[frequencyRange][signalStrength].getTotalTimeLocked( 7334 elapsedRealtimeMs * 1000, STATS_SINCE_CHARGED) / 1000; 7335 } 7336 7337 @Override getActiveTxRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)7338 public long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat, 7339 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, 7340 long elapsedRealtimeMs) { 7341 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7342 if (stats == null) return DURATION_UNAVAILABLE; 7343 7344 final LongSamplingCounter counter = stats.getTxDurationCounter(frequencyRange, 7345 signalStrength, false); 7346 if (counter == null) return DURATION_UNAVAILABLE; 7347 7348 return counter.getCountLocked(STATS_SINCE_CHARGED); 7349 } 7350 7351 @Override getActiveRxRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs)7352 public long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat, 7353 @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs) { 7354 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 7355 if (stats == null) return DURATION_UNAVAILABLE; 7356 7357 final LongSamplingCounter counter = stats.getRxDurationCounter(frequencyRange, false); 7358 if (counter == null) return DURATION_UNAVAILABLE; 7359 7360 return counter.getCountLocked(STATS_SINCE_CHARGED); 7361 } 7362 getMobileRadioActiveTime(long elapsedRealtimeUs, int which)7363 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 7364 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7365 } 7366 getMobileRadioActiveCount(int which)7367 @Override public int getMobileRadioActiveCount(int which) { 7368 return mMobileRadioActiveTimer.getCountLocked(which); 7369 } 7370 getMobileRadioActiveAdjustedTime(int which)7371 @Override public long getMobileRadioActiveAdjustedTime(int which) { 7372 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 7373 } 7374 getMobileRadioActiveUnknownTime(int which)7375 @Override public long getMobileRadioActiveUnknownTime(int which) { 7376 return mMobileRadioActiveUnknownTime.getCountLocked(which); 7377 } 7378 getMobileRadioActiveUnknownCount(int which)7379 @Override public int getMobileRadioActiveUnknownCount(int which) { 7380 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 7381 } 7382 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)7383 @Override public long getWifiMulticastWakelockTime( 7384 long elapsedRealtimeUs, int which) { 7385 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 7386 elapsedRealtimeUs, which); 7387 } 7388 getWifiMulticastWakelockCount(int which)7389 @Override public int getWifiMulticastWakelockCount(int which) { 7390 return mWifiMulticastWakelockTimer.getCountLocked(which); 7391 } 7392 getWifiOnTime(long elapsedRealtimeUs, int which)7393 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 7394 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7395 } 7396 getWifiActiveTime(long elapsedRealtimeUs, int which)7397 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 7398 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7399 } 7400 getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)7401 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 7402 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7403 } 7404 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)7405 @Override public long getWifiStateTime(int wifiState, 7406 long elapsedRealtimeUs, int which) { 7407 return mWifiStateTimer[wifiState].getTotalTimeLocked( 7408 elapsedRealtimeUs, which); 7409 } 7410 getWifiStateCount(int wifiState, int which)7411 @Override public int getWifiStateCount(int wifiState, int which) { 7412 return mWifiStateTimer[wifiState].getCountLocked(which); 7413 } 7414 getWifiStateTimer(int wifiState)7415 @Override public Timer getWifiStateTimer(int wifiState) { 7416 return mWifiStateTimer[wifiState]; 7417 } 7418 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)7419 @Override public long getWifiSupplStateTime(int state, 7420 long elapsedRealtimeUs, int which) { 7421 return mWifiSupplStateTimer[state].getTotalTimeLocked( 7422 elapsedRealtimeUs, which); 7423 } 7424 getWifiSupplStateCount(int state, int which)7425 @Override public int getWifiSupplStateCount(int state, int which) { 7426 return mWifiSupplStateTimer[state].getCountLocked(which); 7427 } 7428 getWifiSupplStateTimer(int state)7429 @Override public Timer getWifiSupplStateTimer(int state) { 7430 return mWifiSupplStateTimer[state]; 7431 } 7432 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)7433 @Override public long getWifiSignalStrengthTime(int strengthBin, 7434 long elapsedRealtimeUs, int which) { 7435 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 7436 elapsedRealtimeUs, which); 7437 } 7438 getWifiSignalStrengthCount(int strengthBin, int which)7439 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 7440 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 7441 } 7442 getWifiSignalStrengthTimer(int strengthBin)7443 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 7444 return mWifiSignalStrengthsTimer[strengthBin]; 7445 } 7446 7447 @Override getBluetoothControllerActivity()7448 public ControllerActivityCounter getBluetoothControllerActivity() { 7449 return mBluetoothActivity; 7450 } 7451 7452 @Override getWifiControllerActivity()7453 public ControllerActivityCounter getWifiControllerActivity() { 7454 return mWifiActivity; 7455 } 7456 7457 @Override getModemControllerActivity()7458 public ControllerActivityCounter getModemControllerActivity() { 7459 return mModemActivity; 7460 } 7461 7462 @Override hasBluetoothActivityReporting()7463 public boolean hasBluetoothActivityReporting() { 7464 return mHasBluetoothReporting; 7465 } 7466 7467 @Override hasWifiActivityReporting()7468 public boolean hasWifiActivityReporting() { 7469 return mHasWifiReporting; 7470 } 7471 7472 @Override hasModemActivityReporting()7473 public boolean hasModemActivityReporting() { 7474 return mHasModemReporting; 7475 } 7476 7477 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)7478 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 7479 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7480 } 7481 7482 @Override getFlashlightOnCount(int which)7483 public long getFlashlightOnCount(int which) { 7484 return mFlashlightOnTimer.getCountLocked(which); 7485 } 7486 7487 @Override getCameraOnTime(long elapsedRealtimeUs, int which)7488 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 7489 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7490 } 7491 7492 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)7493 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 7494 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7495 } 7496 7497 @Override getNetworkActivityBytes(int type, int which)7498 public long getNetworkActivityBytes(int type, int which) { 7499 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 7500 return mNetworkByteActivityCounters[type].getCountLocked(which); 7501 } else { 7502 return 0; 7503 } 7504 } 7505 7506 @Override getNetworkActivityPackets(int type, int which)7507 public long getNetworkActivityPackets(int type, int which) { 7508 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 7509 return mNetworkPacketActivityCounters[type].getCountLocked(which); 7510 } else { 7511 return 0; 7512 } 7513 } 7514 7515 @GuardedBy("this") 7516 @Override getBluetoothEnergyConsumptionUC()7517 public long getBluetoothEnergyConsumptionUC() { 7518 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH); 7519 } 7520 7521 @GuardedBy("this") 7522 @Override getCpuEnergyConsumptionUC()7523 public long getCpuEnergyConsumptionUC() { 7524 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU); 7525 } 7526 7527 @GuardedBy("this") 7528 @Override getGnssEnergyConsumptionUC()7529 public long getGnssEnergyConsumptionUC() { 7530 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_GNSS); 7531 } 7532 7533 @GuardedBy("this") 7534 @Override getMobileRadioEnergyConsumptionUC()7535 public long getMobileRadioEnergyConsumptionUC() { 7536 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 7537 } 7538 7539 @GuardedBy("this") 7540 @Override getPhoneEnergyConsumptionUC()7541 public long getPhoneEnergyConsumptionUC() { 7542 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_PHONE); 7543 } 7544 7545 @GuardedBy("this") 7546 @Override getScreenOnEnergyConsumptionUC()7547 public long getScreenOnEnergyConsumptionUC() { 7548 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON); 7549 } 7550 7551 @GuardedBy("this") 7552 @Override getScreenDozeEnergyConsumptionUC()7553 public long getScreenDozeEnergyConsumptionUC() { 7554 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_DOZE); 7555 } 7556 7557 @GuardedBy("this") 7558 @Override getWifiEnergyConsumptionUC()7559 public long getWifiEnergyConsumptionUC() { 7560 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI); 7561 } 7562 7563 @GuardedBy("this") 7564 @Override getCameraEnergyConsumptionUC()7565 public long getCameraEnergyConsumptionUC() { 7566 return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CAMERA); 7567 } 7568 7569 /** 7570 * Returns the consumption (in microcoulombs) that the given standard power bucket consumed. 7571 * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable 7572 * 7573 * @param bucket standard power bucket of interest 7574 * @return charge (in microcoulombs) used for this power bucket 7575 */ 7576 @GuardedBy("this") getPowerBucketConsumptionUC(@tandardPowerBucket int bucket)7577 private long getPowerBucketConsumptionUC(@StandardPowerBucket int bucket) { 7578 if (mGlobalEnergyConsumerStats == null) { 7579 return POWER_DATA_UNAVAILABLE; 7580 } 7581 return mGlobalEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket); 7582 } 7583 7584 @GuardedBy("this") 7585 @Override getCustomEnergyConsumerBatteryConsumptionUC()7586 public @Nullable long[] getCustomEnergyConsumerBatteryConsumptionUC() { 7587 if (mGlobalEnergyConsumerStats == null) { 7588 return null; 7589 } 7590 return mGlobalEnergyConsumerStats.getAccumulatedCustomBucketCharges(); 7591 } 7592 7593 /** 7594 * Returns the names of custom power components. 7595 */ 7596 @GuardedBy("this") 7597 @Override getCustomEnergyConsumerNames()7598 public @NonNull String[] getCustomEnergyConsumerNames() { 7599 if (mEnergyConsumerStatsConfig == null) { 7600 return new String[0]; 7601 } 7602 final String[] names = mEnergyConsumerStatsConfig.getCustomBucketNames(); 7603 for (int i = 0; i < names.length; i++) { 7604 if (TextUtils.isEmpty(names[i])) { 7605 names[i] = "CUSTOM_" + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i; 7606 } 7607 } 7608 return names; 7609 } 7610 7611 /** 7612 * Adds energy consumer delta to battery history. 7613 */ 7614 @GuardedBy("this") recordEnergyConsumerDetailsLocked(long elapsedRealtimeMs, long uptimeMs, EnergyConsumerDetails energyConsumerDetails)7615 public void recordEnergyConsumerDetailsLocked(long elapsedRealtimeMs, 7616 long uptimeMs, EnergyConsumerDetails energyConsumerDetails) { 7617 if (isUsageHistoryEnabled()) { 7618 mHistory.recordEnergyConsumerDetails(elapsedRealtimeMs, uptimeMs, 7619 energyConsumerDetails); 7620 } 7621 } 7622 7623 @GuardedBy("this") getStartClockTime()7624 @Override public long getStartClockTime() { 7625 final long currentTimeMs = mClock.currentTimeMillis(); 7626 if ((currentTimeMs > MILLISECONDS_IN_YEAR 7627 && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR)) 7628 || (mStartClockTimeMs > currentTimeMs)) { 7629 // If the start clock time has changed by more than a year, then presumably 7630 // the previous time was completely bogus. So we are going to figure out a 7631 // new time based on how much time has elapsed since we started counting. 7632 mHistory.recordCurrentTimeChange(mClock.elapsedRealtime(), mClock.uptimeMillis(), 7633 currentTimeMs 7634 ); 7635 return currentTimeMs - (mClock.elapsedRealtime() - (mRealtimeStartUs / 1000)); 7636 } 7637 return mStartClockTimeMs; 7638 } 7639 getStartPlatformVersion()7640 @Override public String getStartPlatformVersion() { 7641 return mStartPlatformVersion; 7642 } 7643 getEndPlatformVersion()7644 @Override public String getEndPlatformVersion() { 7645 return mEndPlatformVersion; 7646 } 7647 getParcelVersion()7648 @Override public int getParcelVersion() { 7649 return VERSION; 7650 } 7651 getIsOnBattery()7652 @Override public boolean getIsOnBattery() { 7653 return mOnBattery; 7654 } 7655 getStatsStartRealtime()7656 @Override public long getStatsStartRealtime() { 7657 return mRealtimeStartUs; 7658 } 7659 getUidStats()7660 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 7661 return mUidStats; 7662 } 7663 resetIfNotNull(T t, boolean detachIfReset, long elapsedRealtimeUs)7664 private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset, 7665 long elapsedRealtimeUs) { 7666 if (t != null) { 7667 return t.reset(detachIfReset, elapsedRealtimeUs); 7668 } 7669 return true; 7670 } 7671 resetIfNotNull(T[] t, boolean detachIfReset, long elapsedRealtimeUs)7672 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset, 7673 long elapsedRealtimeUs) { 7674 if (t != null) { 7675 boolean ret = true; 7676 for (int i = 0; i < t.length; i++) { 7677 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 7678 } 7679 return ret; 7680 } 7681 return true; 7682 } 7683 resetIfNotNull(T[][] t, boolean detachIfReset, long elapsedRealtimeUs)7684 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset, 7685 long elapsedRealtimeUs) { 7686 if (t != null) { 7687 boolean ret = true; 7688 for (int i = 0; i < t.length; i++) { 7689 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 7690 } 7691 return ret; 7692 } 7693 return true; 7694 } 7695 resetIfNotNull(ControllerActivityCounterImpl counter, boolean detachIfReset, long elapsedRealtimeUs)7696 private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, 7697 boolean detachIfReset, long elapsedRealtimeUs) { 7698 if (counter != null) { 7699 counter.reset(detachIfReset, elapsedRealtimeUs); 7700 } 7701 return true; 7702 } 7703 detachIfNotNull(T t)7704 private static <T extends TimeBaseObs> void detachIfNotNull(T t) { 7705 if (t != null) { 7706 t.detach(); 7707 } 7708 } 7709 detachIfNotNull(T[] t)7710 private static <T extends TimeBaseObs> void detachIfNotNull(T[] t) { 7711 if (t != null) { 7712 for (int i = 0; i < t.length; i++) { 7713 detachIfNotNull(t[i]); 7714 } 7715 } 7716 } 7717 detachIfNotNull(T[][] t)7718 private static <T extends TimeBaseObs> void detachIfNotNull(T[][] t) { 7719 if (t != null) { 7720 for (int i = 0; i < t.length; i++) { 7721 detachIfNotNull(t[i]); 7722 } 7723 } 7724 } 7725 detachIfNotNull(ControllerActivityCounterImpl counter)7726 private static void detachIfNotNull(ControllerActivityCounterImpl counter) { 7727 if (counter != null) { 7728 counter.detach(); 7729 } 7730 } 7731 7732 /** 7733 * Accumulates stats for a specific binder transaction. 7734 */ 7735 @VisibleForTesting 7736 protected static class BinderCallStats { 7737 public Class<? extends Binder> binderClass; 7738 public int transactionCode; 7739 public String methodName; 7740 7741 public long callCount; 7742 public long recordedCallCount; 7743 public long recordedCpuTimeMicros; 7744 7745 7746 @Override hashCode()7747 public int hashCode() { 7748 return binderClass.hashCode() * 31 + transactionCode; 7749 } 7750 7751 @Override equals(Object obj)7752 public boolean equals(Object obj) { 7753 if (!(obj instanceof BinderCallStats)) { 7754 return false; 7755 } 7756 BinderCallStats bcsk = (BinderCallStats) obj; 7757 return binderClass.equals(bcsk.binderClass) && transactionCode == bcsk.transactionCode; 7758 } 7759 getClassName()7760 public String getClassName() { 7761 return binderClass.getName(); 7762 } 7763 getMethodName()7764 public String getMethodName() { 7765 return methodName; 7766 } 7767 7768 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) ensureMethodName(BinderTransactionNameResolver resolver)7769 public void ensureMethodName(BinderTransactionNameResolver resolver) { 7770 if (methodName == null) { 7771 methodName = resolver.getMethodName(binderClass, transactionCode); 7772 } 7773 } 7774 7775 @Override toString()7776 public String toString() { 7777 return "BinderCallStats{" 7778 + binderClass 7779 + " transaction=" + transactionCode 7780 + " callCount=" + callCount 7781 + " recordedCallCount=" + recordedCallCount 7782 + " recorderCpuTimeMicros=" + recordedCpuTimeMicros 7783 + "}"; 7784 } 7785 } 7786 7787 /** 7788 * The statistics associated with a particular uid. 7789 */ 7790 public static class Uid extends BatteryStats.Uid { 7791 /** 7792 * BatteryStatsImpl that we are associated with. 7793 */ 7794 protected BatteryStatsImpl mBsi; 7795 7796 final int mUid; 7797 7798 /** TimeBase for when uid is in background and device is on battery. */ 7799 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 7800 public final TimeBase mOnBatteryBackgroundTimeBase; 7801 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 7802 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 7803 7804 boolean mWifiRunning; 7805 StopwatchTimer mWifiRunningTimer; 7806 7807 boolean mFullWifiLockOut; 7808 StopwatchTimer mFullWifiLockTimer; 7809 7810 boolean mWifiScanStarted; 7811 DualTimer mWifiScanTimer; 7812 7813 static final int NO_BATCHED_SCAN_STARTED = -1; 7814 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 7815 StopwatchTimer[] mWifiBatchedScanTimer; 7816 7817 int mWifiMulticastWakelockCount; 7818 StopwatchTimer mWifiMulticastTimer; 7819 7820 StopwatchTimer mAudioTurnedOnTimer; 7821 StopwatchTimer mVideoTurnedOnTimer; 7822 StopwatchTimer mFlashlightTurnedOnTimer; 7823 StopwatchTimer mCameraTurnedOnTimer; 7824 StopwatchTimer mForegroundActivityTimer; 7825 StopwatchTimer mForegroundServiceTimer; 7826 /** Total time spent by the uid holding any partial wakelocks. */ 7827 DualTimer mAggregatedPartialWakelockTimer; 7828 DualTimer mBluetoothScanTimer; 7829 DualTimer mBluetoothUnoptimizedScanTimer; 7830 Counter mBluetoothScanResultCounter; 7831 Counter mBluetoothScanResultBgCounter; 7832 7833 int mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 7834 StopwatchTimer[] mProcessStateTimer; 7835 7836 boolean mInForegroundService = false; 7837 7838 BatchTimer mVibratorOnTimer; 7839 7840 Counter[] mUserActivityCounters; 7841 7842 LongSamplingCounter[] mNetworkByteActivityCounters; 7843 LongSamplingCounter[] mNetworkPacketActivityCounters; 7844 TimeMultiStateCounter mMobileRadioActiveTime; 7845 LongSamplingCounter mMobileRadioActiveCount; 7846 7847 /** 7848 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 7849 */ 7850 private LongSamplingCounter mMobileRadioApWakeupCount; 7851 7852 /** 7853 * How many times this UID woke up the Application Processor due to a Wifi packet. 7854 */ 7855 private LongSamplingCounter mWifiRadioApWakeupCount; 7856 7857 /** 7858 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 7859 * Can be null if the UID has had no such activity. 7860 */ 7861 private ControllerActivityCounterImpl mWifiControllerActivity; 7862 7863 /** 7864 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 7865 * Can be null if the UID has had no such activity. 7866 */ 7867 private ControllerActivityCounterImpl mBluetoothControllerActivity; 7868 7869 /** 7870 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 7871 * Can be null if the UID has had no such activity. 7872 */ 7873 private ControllerActivityCounterImpl mModemControllerActivity; 7874 7875 /** 7876 * The CPU times we had at the last history details update. 7877 */ 7878 long mLastStepUserTimeMs; 7879 long mLastStepSystemTimeMs; 7880 long mCurStepUserTimeMs; 7881 long mCurStepSystemTimeMs; 7882 7883 LongSamplingCounter mUserCpuTime; 7884 LongSamplingCounter mSystemCpuTime; 7885 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 7886 TimeMultiStateCounter mCpuActiveTimeMs; 7887 7888 LongSamplingCounterArray mCpuFreqTimeMs; 7889 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 7890 LongSamplingCounterArray mCpuClusterTimesMs; 7891 7892 TimeInFreqMultiStateCounter mProcStateTimeMs; 7893 TimeInFreqMultiStateCounter mProcStateScreenOffTimeMs; 7894 7895 SparseArray<ChildUid> mChildUids; 7896 7897 /** 7898 * The statistics we have collected for this uid's wake locks. 7899 */ 7900 final OverflowArrayMap<Wakelock> mWakelockStats; 7901 7902 /** 7903 * The statistics we have collected for this uid's syncs. 7904 */ 7905 final OverflowArrayMap<DualTimer> mSyncStats; 7906 7907 /** 7908 * The statistics we have collected for this uid's jobs. 7909 */ 7910 final OverflowArrayMap<DualTimer> mJobStats; 7911 7912 /** 7913 * Count of the jobs that have completed and the reasons why they completed. 7914 */ 7915 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 7916 7917 /** 7918 * Count of app launch events that had associated deferred job counts or info about 7919 * last time a job was run. 7920 */ 7921 Counter mJobsDeferredEventCount; 7922 7923 /** 7924 * Count of deferred jobs that were pending when the app was launched or brought to 7925 * the foreground through a user interaction. 7926 */ 7927 Counter mJobsDeferredCount; 7928 7929 /** 7930 * Sum of time since the last time a job was run for this app before it was launched. 7931 */ 7932 LongSamplingCounter mJobsFreshnessTimeMs; 7933 7934 /** 7935 * Array of counts of instances where the time since the last job was run for the app 7936 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 7937 */ 7938 final Counter[] mJobsFreshnessBuckets; 7939 7940 /** 7941 * The statistics we have collected for this uid's sensor activations. 7942 */ 7943 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 7944 7945 /** 7946 * The statistics we have collected for this uid's processes. 7947 */ 7948 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 7949 7950 /** 7951 * The statistics we have collected for this uid's processes. 7952 */ 7953 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 7954 7955 /** 7956 * The transient wake stats we have collected for this uid's pids. 7957 */ 7958 final SparseArray<Pid> mPids = new SparseArray<>(); 7959 7960 /** 7961 * Grand total of system server binder calls made by this uid. 7962 */ 7963 private long mBinderCallCount; 7964 7965 /** 7966 * Detailed information about system server binder calls made by this uid. 7967 */ 7968 private final ArraySet<BinderCallStats> mBinderCallStats = new ArraySet<>(); 7969 7970 /** 7971 * EnergyConsumer consumption by this uid while on battery. 7972 * Its '<b>custom</b> power buckets' correspond to the 7973 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 7974 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 7975 * 7976 * Will be null if energy consumer data is completely unavailable (in which case 7977 * {@link #mGlobalEnergyConsumerStats} will also be null) or if the power usage by this uid 7978 * is 0 for every bucket. 7979 */ 7980 private EnergyConsumerStats mUidEnergyConsumerStats; 7981 7982 /** 7983 * Estimated total time spent by the system server handling requests from this uid. 7984 */ 7985 private long mSystemServiceTimeUs; 7986 7987 /** 7988 * Estimated proportion of system server binder call CPU cost for this uid. 7989 */ 7990 private double mProportionalSystemServiceUsage; 7991 Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs)7992 public Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs) { 7993 mBsi = bsi; 7994 mUid = uid; 7995 7996 /* Observer list of TimeBase object in Uid is short */ 7997 mOnBatteryBackgroundTimeBase = new TimeBase(false); 7998 mOnBatteryBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 7999 /* Observer list of TimeBase object in Uid is short */ 8000 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); 8001 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 8002 8003 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8004 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8005 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 8006 8007 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 8008 @Override public Wakelock instantiateObject() { 8009 return new Wakelock(mBsi, Uid.this); 8010 } 8011 }; 8012 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 8013 @Override public DualTimer instantiateObject() { 8014 return new DualTimer(mBsi.mClock, Uid.this, SYNC, null, 8015 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8016 } 8017 }; 8018 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 8019 @Override public DualTimer instantiateObject() { 8020 return new DualTimer(mBsi.mClock, Uid.this, JOB, null, 8021 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8022 } 8023 }; 8024 8025 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, this, WIFI_RUNNING, 8026 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 8027 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, this, FULL_WIFI_LOCK, 8028 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 8029 mWifiScanTimer = new DualTimer(mBsi.mClock, this, WIFI_SCAN, 8030 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8031 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 8032 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, this, WIFI_MULTICAST_ENABLED, 8033 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 8034 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 8035 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 8036 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 8037 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8038 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 8039 } 8040 8041 @GuardedBy("mBsi") 8042 @VisibleForTesting setProcessStateForTest(int procState, long elapsedTimeMs)8043 public void setProcessStateForTest(int procState, long elapsedTimeMs) { 8044 mProcessState = procState; 8045 getProcStateTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs); 8046 getProcStateScreenOffTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs); 8047 final int batteryConsumerProcessState = 8048 mapUidProcessStateToBatteryConsumerProcessState(procState); 8049 getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); 8050 getMobileRadioActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); 8051 final ControllerActivityCounterImpl wifiControllerActivity = 8052 getWifiControllerActivity(); 8053 if (wifiControllerActivity != null) { 8054 wifiControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs); 8055 } 8056 final ControllerActivityCounterImpl bluetoothControllerActivity = 8057 getBluetoothControllerActivity(); 8058 if (bluetoothControllerActivity != null) { 8059 bluetoothControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs); 8060 } 8061 final EnergyConsumerStats energyStats = 8062 getOrCreateEnergyConsumerStatsIfSupportedLocked(); 8063 if (energyStats != null) { 8064 energyStats.setState(batteryConsumerProcessState, elapsedTimeMs); 8065 } 8066 } 8067 8068 @Override getCpuFreqTimes(int which)8069 public long[] getCpuFreqTimes(int which) { 8070 return nullIfAllZeros(mCpuFreqTimeMs, which); 8071 } 8072 8073 @Override getScreenOffCpuFreqTimes(int which)8074 public long[] getScreenOffCpuFreqTimes(int which) { 8075 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 8076 } 8077 getCpuActiveTimeCounter()8078 private TimeMultiStateCounter getCpuActiveTimeCounter() { 8079 if (mCpuActiveTimeMs == null) { 8080 final long timestampMs = mBsi.mClock.elapsedRealtime(); 8081 mCpuActiveTimeMs = new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, 8082 BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 8083 mCpuActiveTimeMs.setState( 8084 mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 8085 timestampMs); 8086 } 8087 return mCpuActiveTimeMs; 8088 } 8089 8090 @Override getCpuActiveTime()8091 public long getCpuActiveTime() { 8092 if (mCpuActiveTimeMs == null) { 8093 return 0; 8094 } 8095 8096 long activeTime = 0; 8097 for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { 8098 activeTime += mCpuActiveTimeMs.getCountForProcessState(procState); 8099 } 8100 return activeTime; 8101 } 8102 8103 @Override getCpuActiveTime(int procState)8104 public long getCpuActiveTime(int procState) { 8105 if (mCpuActiveTimeMs == null 8106 || procState < 0 || procState >= BatteryConsumer.PROCESS_STATE_COUNT) { 8107 return 0; 8108 } 8109 8110 return mCpuActiveTimeMs.getCountForProcessState(procState); 8111 } 8112 8113 @Override getCpuClusterTimes()8114 public long[] getCpuClusterTimes() { 8115 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 8116 } 8117 8118 @GuardedBy("mBsi") 8119 @Override getCpuFreqTimes(long[] timesInFreqMs, int procState)8120 public boolean getCpuFreqTimes(long[] timesInFreqMs, int procState) { 8121 if (procState < 0 || procState >= NUM_PROCESS_STATE) { 8122 return false; 8123 } 8124 if (mProcStateTimeMs == null) { 8125 return false; 8126 } 8127 if (!mBsi.mPerProcStateCpuTimesAvailable) { 8128 mProcStateTimeMs = null; 8129 return false; 8130 } 8131 return mProcStateTimeMs.getCountsLocked(timesInFreqMs, procState); 8132 } 8133 8134 @GuardedBy("mBsi") 8135 @Override getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState)8136 public boolean getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState) { 8137 if (procState < 0 || procState >= NUM_PROCESS_STATE) { 8138 return false; 8139 } 8140 if (mProcStateScreenOffTimeMs == null) { 8141 return false; 8142 } 8143 if (!mBsi.mPerProcStateCpuTimesAvailable) { 8144 mProcStateScreenOffTimeMs = null; 8145 return false; 8146 } 8147 return mProcStateScreenOffTimeMs.getCountsLocked(timesInFreqMs, procState); 8148 } 8149 getBinderCallCount()8150 public long getBinderCallCount() { 8151 return mBinderCallCount; 8152 } 8153 8154 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) getBinderCallStats()8155 public ArraySet<BinderCallStats> getBinderCallStats() { 8156 return mBinderCallStats; 8157 } 8158 8159 @Override getProportionalSystemServiceUsage()8160 public double getProportionalSystemServiceUsage() { 8161 return mProportionalSystemServiceUsage; 8162 } 8163 8164 @GuardedBy("mBsi") addIsolatedUid(int isolatedUid)8165 public void addIsolatedUid(int isolatedUid) { 8166 if (mChildUids == null) { 8167 mChildUids = new SparseArray<>(); 8168 } else if (mChildUids.indexOfKey(isolatedUid) >= 0) { 8169 return; 8170 } 8171 mChildUids.put(isolatedUid, new ChildUid()); 8172 } 8173 removeIsolatedUid(int isolatedUid)8174 public void removeIsolatedUid(int isolatedUid) { 8175 final int idx = mChildUids == null ? -1 : mChildUids.indexOfKey(isolatedUid); 8176 if (idx < 0) { 8177 return; 8178 } 8179 mChildUids.remove(idx); 8180 } 8181 8182 @GuardedBy("mBsi") getChildUid(int childUid)8183 ChildUid getChildUid(int childUid) { 8184 return mChildUids == null ? null : mChildUids.get(childUid); 8185 } 8186 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)8187 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 8188 if (cpuTimesMs == null) { 8189 return null; 8190 } 8191 final long[] counts = cpuTimesMs.getCountsLocked(which); 8192 if (counts == null) { 8193 return null; 8194 } 8195 // Return counts only if at least one of the elements is non-zero. 8196 for (int i = counts.length - 1; i >= 0; --i) { 8197 if (counts[i] != 0) { 8198 return counts; 8199 } 8200 } 8201 return null; 8202 } 8203 8204 @GuardedBy("mBsi") ensureMultiStateCounters(long timestampMs)8205 private void ensureMultiStateCounters(long timestampMs) { 8206 if (mProcStateTimeMs != null) { 8207 return; 8208 } 8209 8210 mProcStateTimeMs = 8211 new TimeInFreqMultiStateCounter(mBsi.mOnBatteryTimeBase, 8212 PROC_STATE_TIME_COUNTER_STATE_COUNT, mBsi.getCpuFreqCount(), 8213 timestampMs); 8214 mProcStateScreenOffTimeMs = 8215 new TimeInFreqMultiStateCounter(mBsi.mOnBatteryScreenOffTimeBase, 8216 PROC_STATE_TIME_COUNTER_STATE_COUNT, mBsi.getCpuFreqCount(), 8217 timestampMs); 8218 } 8219 8220 @GuardedBy("mBsi") getProcStateTimeCounter(long timestampMs)8221 private TimeInFreqMultiStateCounter getProcStateTimeCounter(long timestampMs) { 8222 ensureMultiStateCounters(timestampMs); 8223 return mProcStateTimeMs; 8224 } 8225 8226 @GuardedBy("mBsi") getProcStateScreenOffTimeCounter(long timestampMs)8227 private TimeInFreqMultiStateCounter getProcStateScreenOffTimeCounter(long timestampMs) { 8228 ensureMultiStateCounters(timestampMs); 8229 return mProcStateScreenOffTimeMs; 8230 } 8231 8232 @Override getAggregatedPartialWakelockTimer()8233 public Timer getAggregatedPartialWakelockTimer() { 8234 return mAggregatedPartialWakelockTimer; 8235 } 8236 8237 @Override getWakelockStats()8238 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 8239 return mWakelockStats.getMap(); 8240 } 8241 8242 @Override getMulticastWakelockStats()8243 public Timer getMulticastWakelockStats() { 8244 return mWifiMulticastTimer; 8245 } 8246 8247 @Override getSyncStats()8248 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 8249 return mSyncStats.getMap(); 8250 } 8251 8252 @Override getJobStats()8253 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 8254 return mJobStats.getMap(); 8255 } 8256 8257 @Override getJobCompletionStats()8258 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 8259 return mJobCompletions; 8260 } 8261 8262 @Override getSensorStats()8263 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 8264 return mSensorStats; 8265 } 8266 8267 @Override getProcessStats()8268 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 8269 return mProcessStats; 8270 } 8271 8272 @Override getPackageStats()8273 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 8274 return mPackageStats; 8275 } 8276 8277 @Override getUid()8278 public int getUid() { 8279 return mUid; 8280 } 8281 8282 @Override noteWifiRunningLocked(long elapsedRealtimeMs)8283 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 8284 if (!mWifiRunning) { 8285 mWifiRunning = true; 8286 if (mWifiRunningTimer == null) { 8287 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, Uid.this, WIFI_RUNNING, 8288 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 8289 } 8290 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 8291 } 8292 } 8293 8294 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)8295 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 8296 if (mWifiRunning) { 8297 mWifiRunning = false; 8298 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 8299 } 8300 } 8301 8302 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)8303 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 8304 if (!mFullWifiLockOut) { 8305 mFullWifiLockOut = true; 8306 if (mFullWifiLockTimer == null) { 8307 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, Uid.this, FULL_WIFI_LOCK, 8308 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 8309 } 8310 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 8311 } 8312 } 8313 8314 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)8315 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 8316 if (mFullWifiLockOut) { 8317 mFullWifiLockOut = false; 8318 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 8319 } 8320 } 8321 8322 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)8323 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 8324 if (!mWifiScanStarted) { 8325 mWifiScanStarted = true; 8326 if (mWifiScanTimer == null) { 8327 mWifiScanTimer = new DualTimer(mBsi.mClock, Uid.this, WIFI_SCAN, 8328 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 8329 mOnBatteryBackgroundTimeBase); 8330 } 8331 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 8332 } 8333 } 8334 8335 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)8336 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 8337 if (mWifiScanStarted) { 8338 mWifiScanStarted = false; 8339 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 8340 } 8341 } 8342 8343 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)8344 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 8345 int bin = 0; 8346 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 8347 csph = csph >> 3; 8348 bin++; 8349 } 8350 8351 if (mWifiBatchedScanBinStarted == bin) return; 8352 8353 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 8354 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 8355 stopRunningLocked(elapsedRealtimeMs); 8356 } 8357 mWifiBatchedScanBinStarted = bin; 8358 if (mWifiBatchedScanTimer[bin] == null) { 8359 makeWifiBatchedScanBin(bin, null); 8360 } 8361 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 8362 } 8363 8364 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)8365 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 8366 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 8367 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 8368 stopRunningLocked(elapsedRealtimeMs); 8369 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8370 } 8371 } 8372 8373 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)8374 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 8375 if (mWifiMulticastWakelockCount == 0) { 8376 if (mWifiMulticastTimer == null) { 8377 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 8378 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 8379 } 8380 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 8381 } 8382 mWifiMulticastWakelockCount++; 8383 } 8384 8385 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)8386 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 8387 if (mWifiMulticastWakelockCount == 0) { 8388 return; 8389 } 8390 8391 mWifiMulticastWakelockCount--; 8392 if (mWifiMulticastWakelockCount == 0) { 8393 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 8394 } 8395 } 8396 8397 @Override getWifiControllerActivity()8398 public ControllerActivityCounterImpl getWifiControllerActivity() { 8399 return mWifiControllerActivity; 8400 } 8401 8402 @Override getBluetoothControllerActivity()8403 public ControllerActivityCounterImpl getBluetoothControllerActivity() { 8404 return mBluetoothControllerActivity; 8405 } 8406 8407 @Override getModemControllerActivity()8408 public ControllerActivityCounter getModemControllerActivity() { 8409 return mModemControllerActivity; 8410 } 8411 getOrCreateWifiControllerActivityLocked()8412 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 8413 if (mWifiControllerActivity == null) { 8414 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8415 mBsi.mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 8416 } 8417 return mWifiControllerActivity; 8418 } 8419 getOrCreateBluetoothControllerActivityLocked()8420 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 8421 if (mBluetoothControllerActivity == null) { 8422 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8423 mBsi.mOnBatteryTimeBase, NUM_BT_TX_LEVELS); 8424 } 8425 return mBluetoothControllerActivity; 8426 } 8427 getOrCreateModemControllerActivityLocked()8428 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 8429 if (mModemControllerActivity == null) { 8430 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 8431 mBsi.mOnBatteryTimeBase, ModemActivityInfo.getNumTxPowerLevels()); 8432 } 8433 return mModemControllerActivity; 8434 } 8435 8436 @GuardedBy("mBsi") getOrCreateEnergyConsumerStatsLocked()8437 private EnergyConsumerStats getOrCreateEnergyConsumerStatsLocked() { 8438 if (mUidEnergyConsumerStats == null) { 8439 mUidEnergyConsumerStats = new EnergyConsumerStats(mBsi.mEnergyConsumerStatsConfig); 8440 } 8441 return mUidEnergyConsumerStats; 8442 } 8443 8444 @GuardedBy("mBsi") getOrCreateEnergyConsumerStatsIfSupportedLocked()8445 private EnergyConsumerStats getOrCreateEnergyConsumerStatsIfSupportedLocked() { 8446 if (mUidEnergyConsumerStats == null && mBsi.mEnergyConsumerStatsConfig != null) { 8447 mUidEnergyConsumerStats = new EnergyConsumerStats(mBsi.mEnergyConsumerStatsConfig); 8448 } 8449 return mUidEnergyConsumerStats; 8450 } 8451 8452 /** Adds the given charge to the given standard power bucket for this uid. */ 8453 @GuardedBy("mBsi") addChargeToStandardBucketLocked(long chargeDeltaUC, @StandardPowerBucket int powerBucket, long timestampMs)8454 private void addChargeToStandardBucketLocked(long chargeDeltaUC, 8455 @StandardPowerBucket int powerBucket, long timestampMs) { 8456 final EnergyConsumerStats energyConsumerStats = 8457 getOrCreateEnergyConsumerStatsLocked(); 8458 energyConsumerStats.updateStandardBucket(powerBucket, chargeDeltaUC, timestampMs); 8459 } 8460 8461 /** Adds the given charge to the given custom power bucket for this uid. */ 8462 @GuardedBy("mBsi") addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket)8463 private void addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket) { 8464 getOrCreateEnergyConsumerStatsLocked().updateCustomBucket(powerBucket, chargeDeltaUC, 8465 mBsi.mClock.elapsedRealtime()); 8466 } 8467 8468 /** 8469 * Returns the battery consumption (in microcoulomb) of this uid for a standard power bucket 8470 * of interest. 8471 * @param bucket standard power bucket of interest 8472 * @return consumption (in microcolombs) used by this uid for this power bucket 8473 */ 8474 @GuardedBy("mBsi") getEnergyConsumptionUC(@tandardPowerBucket int bucket)8475 public long getEnergyConsumptionUC(@StandardPowerBucket int bucket) { 8476 if (mBsi.mGlobalEnergyConsumerStats == null 8477 || !mBsi.mGlobalEnergyConsumerStats.isStandardBucketSupported(bucket)) { 8478 return POWER_DATA_UNAVAILABLE; 8479 } 8480 if (mUidEnergyConsumerStats == null) { 8481 return 0L; // It is supported, but was never filled, so it must be 0 8482 } 8483 return mUidEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket); 8484 } 8485 8486 /** 8487 * Returns the battery consumption (in microcoulombs) of this uid for a standard power 8488 * bucket and a process state, such as Uid.PROCESS_STATE_TOP. 8489 */ 8490 @GuardedBy("mBsi") getEnergyConsumptionUC(@tandardPowerBucket int bucket, int processState)8491 public long getEnergyConsumptionUC(@StandardPowerBucket int bucket, 8492 int processState) { 8493 if (mBsi.mGlobalEnergyConsumerStats == null 8494 || !mBsi.mGlobalEnergyConsumerStats.isStandardBucketSupported(bucket)) { 8495 return POWER_DATA_UNAVAILABLE; 8496 } 8497 if (mUidEnergyConsumerStats == null) { 8498 return 0L; // It is supported, but was never filled, so it must be 0 8499 } 8500 return mUidEnergyConsumerStats.getAccumulatedStandardBucketCharge(bucket, processState); 8501 } 8502 8503 @GuardedBy("mBsi") 8504 @Override getCustomEnergyConsumerBatteryConsumptionUC()8505 public long[] getCustomEnergyConsumerBatteryConsumptionUC() { 8506 if (mBsi.mGlobalEnergyConsumerStats == null) { 8507 return null; 8508 } 8509 if (mUidEnergyConsumerStats == null) { 8510 // Custom buckets may exist. But all values for this uid are 0 so we report all 0s. 8511 return new long[mBsi.mGlobalEnergyConsumerStats.getNumberCustomPowerBuckets()]; 8512 } 8513 return mUidEnergyConsumerStats.getAccumulatedCustomBucketCharges(); 8514 } 8515 8516 @GuardedBy("mBsi") 8517 @Override getBluetoothEnergyConsumptionUC()8518 public long getBluetoothEnergyConsumptionUC() { 8519 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH); 8520 } 8521 8522 @GuardedBy("mBsi") 8523 @Override getBluetoothEnergyConsumptionUC( @atteryConsumer.ProcessState int processState)8524 public long getBluetoothEnergyConsumptionUC( 8525 @BatteryConsumer.ProcessState int processState) { 8526 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 8527 processState); 8528 } 8529 8530 @GuardedBy("mBsi") 8531 @Override getCpuEnergyConsumptionUC()8532 public long getCpuEnergyConsumptionUC() { 8533 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU); 8534 } 8535 8536 @GuardedBy("mBsi") 8537 @Override getCpuEnergyConsumptionUC( @atteryConsumer.ProcessState int processState)8538 public long getCpuEnergyConsumptionUC( 8539 @BatteryConsumer.ProcessState int processState) { 8540 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CPU, 8541 processState); 8542 } 8543 8544 @GuardedBy("mBsi") 8545 @Override getGnssEnergyConsumptionUC()8546 public long getGnssEnergyConsumptionUC() { 8547 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_GNSS); 8548 } 8549 8550 @GuardedBy("mBsi") 8551 @Override getMobileRadioEnergyConsumptionUC()8552 public long getMobileRadioEnergyConsumptionUC() { 8553 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 8554 } 8555 8556 @GuardedBy("mBsi") 8557 @Override getMobileRadioEnergyConsumptionUC(int processState)8558 public long getMobileRadioEnergyConsumptionUC(int processState) { 8559 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 8560 processState); 8561 } 8562 8563 @GuardedBy("mBsi") 8564 @Override getScreenOnEnergyConsumptionUC()8565 public long getScreenOnEnergyConsumptionUC() { 8566 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON); 8567 } 8568 8569 @GuardedBy("mBsi") 8570 @Override getWifiEnergyConsumptionUC()8571 public long getWifiEnergyConsumptionUC() { 8572 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI); 8573 } 8574 8575 @GuardedBy("mBsi") 8576 @Override getWifiEnergyConsumptionUC(int processState)8577 public long getWifiEnergyConsumptionUC(int processState) { 8578 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI, 8579 processState); 8580 } 8581 8582 @GuardedBy("mBsi") 8583 @Override getCameraEnergyConsumptionUC()8584 public long getCameraEnergyConsumptionUC() { 8585 return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CAMERA); 8586 } 8587 8588 /** 8589 * Gets the minimum of the uid's foreground activity time and its PROCESS_STATE_TOP time 8590 * since last marked. Also sets the mark time for both these timers. 8591 * 8592 * @see CpuPowerCalculator 8593 * 8594 * @param doCalc if true, then calculate the minimum; else don't bother and return 0. Either 8595 * way, the mark is set. 8596 */ markProcessForegroundTimeUs(long elapsedRealtimeMs, boolean doCalc)8597 private long markProcessForegroundTimeUs(long elapsedRealtimeMs, 8598 boolean doCalc) { 8599 long fgTimeUs = 0; 8600 final StopwatchTimer fgTimer = mForegroundActivityTimer; 8601 if (fgTimer != null) { 8602 if (doCalc) fgTimeUs = fgTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8603 fgTimer.setMark(elapsedRealtimeMs); 8604 } 8605 8606 long topTimeUs = 0; 8607 final StopwatchTimer topTimer = mProcessStateTimer[PROCESS_STATE_TOP]; 8608 if (topTimer != null) { 8609 if (doCalc) topTimeUs = topTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8610 topTimer.setMark(elapsedRealtimeMs); 8611 } 8612 8613 // Return the min of the two 8614 return (topTimeUs < fgTimeUs) ? topTimeUs : fgTimeUs; 8615 } 8616 8617 8618 /** 8619 * Gets the uid's time spent using the GNSS since last marked. Also sets the mark time for 8620 * the GNSS timer. 8621 */ markGnssTimeUs(long elapsedRealtimeMs)8622 private long markGnssTimeUs(long elapsedRealtimeMs) { 8623 final Sensor sensor = mSensorStats.get(Sensor.GPS); 8624 if (sensor == null) { 8625 return 0; 8626 } 8627 8628 final StopwatchTimer timer = sensor.mTimer; 8629 if (timer == null) { 8630 return 0; 8631 } 8632 8633 final long gnssTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8634 timer.setMark(elapsedRealtimeMs); 8635 return gnssTimeUs; 8636 } 8637 8638 /** 8639 * Gets the uid's time spent using the camera since last marked. Also sets the mark time for 8640 * the camera timer. 8641 */ markCameraTimeUs(long elapsedRealtimeMs)8642 private long markCameraTimeUs(long elapsedRealtimeMs) { 8643 final StopwatchTimer timer = mCameraTurnedOnTimer; 8644 if (timer == null) { 8645 return 0; 8646 } 8647 final long cameraTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8648 timer.setMark(elapsedRealtimeMs); 8649 return cameraTimeUs; 8650 } 8651 createAudioTurnedOnTimerLocked()8652 public StopwatchTimer createAudioTurnedOnTimerLocked() { 8653 if (mAudioTurnedOnTimer == null) { 8654 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, AUDIO_TURNED_ON, 8655 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 8656 } 8657 return mAudioTurnedOnTimer; 8658 } 8659 noteAudioTurnedOnLocked(long elapsedRealtimeMs)8660 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 8661 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 8662 } 8663 noteAudioTurnedOffLocked(long elapsedRealtimeMs)8664 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 8665 if (mAudioTurnedOnTimer != null) { 8666 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 8667 } 8668 } 8669 noteResetAudioLocked(long elapsedRealtimeMs)8670 public void noteResetAudioLocked(long elapsedRealtimeMs) { 8671 if (mAudioTurnedOnTimer != null) { 8672 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 8673 } 8674 } 8675 createVideoTurnedOnTimerLocked()8676 public StopwatchTimer createVideoTurnedOnTimerLocked() { 8677 if (mVideoTurnedOnTimer == null) { 8678 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, VIDEO_TURNED_ON, 8679 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 8680 } 8681 return mVideoTurnedOnTimer; 8682 } 8683 noteVideoTurnedOnLocked(long elapsedRealtimeMs)8684 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 8685 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 8686 } 8687 noteVideoTurnedOffLocked(long elapsedRealtimeMs)8688 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 8689 if (mVideoTurnedOnTimer != null) { 8690 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 8691 } 8692 } 8693 noteResetVideoLocked(long elapsedRealtimeMs)8694 public void noteResetVideoLocked(long elapsedRealtimeMs) { 8695 if (mVideoTurnedOnTimer != null) { 8696 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 8697 } 8698 } 8699 createFlashlightTurnedOnTimerLocked()8700 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 8701 if (mFlashlightTurnedOnTimer == null) { 8702 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 8703 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 8704 } 8705 return mFlashlightTurnedOnTimer; 8706 } 8707 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)8708 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 8709 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 8710 } 8711 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)8712 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 8713 if (mFlashlightTurnedOnTimer != null) { 8714 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 8715 } 8716 } 8717 noteResetFlashlightLocked(long elapsedRealtimeMs)8718 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 8719 if (mFlashlightTurnedOnTimer != null) { 8720 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 8721 } 8722 } 8723 createCameraTurnedOnTimerLocked()8724 public StopwatchTimer createCameraTurnedOnTimerLocked() { 8725 if (mCameraTurnedOnTimer == null) { 8726 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, CAMERA_TURNED_ON, 8727 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 8728 } 8729 return mCameraTurnedOnTimer; 8730 } 8731 noteCameraTurnedOnLocked(long elapsedRealtimeMs)8732 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 8733 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 8734 } 8735 noteCameraTurnedOffLocked(long elapsedRealtimeMs)8736 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 8737 if (mCameraTurnedOnTimer != null) { 8738 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 8739 } 8740 } 8741 noteResetCameraLocked(long elapsedRealtimeMs)8742 public void noteResetCameraLocked(long elapsedRealtimeMs) { 8743 if (mCameraTurnedOnTimer != null) { 8744 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 8745 } 8746 } 8747 createForegroundActivityTimerLocked()8748 public StopwatchTimer createForegroundActivityTimerLocked() { 8749 if (mForegroundActivityTimer == null) { 8750 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 8751 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 8752 } 8753 return mForegroundActivityTimer; 8754 } 8755 createForegroundServiceTimerLocked()8756 public StopwatchTimer createForegroundServiceTimerLocked() { 8757 if (mForegroundServiceTimer == null) { 8758 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 8759 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 8760 } 8761 return mForegroundServiceTimer; 8762 } 8763 createAggregatedPartialWakelockTimerLocked()8764 public DualTimer createAggregatedPartialWakelockTimerLocked() { 8765 if (mAggregatedPartialWakelockTimer == null) { 8766 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClock, this, 8767 AGGREGATED_WAKE_TYPE_PARTIAL, null, 8768 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 8769 } 8770 return mAggregatedPartialWakelockTimer; 8771 } 8772 createBluetoothScanTimerLocked()8773 public DualTimer createBluetoothScanTimerLocked() { 8774 if (mBluetoothScanTimer == null) { 8775 mBluetoothScanTimer = new DualTimer(mBsi.mClock, Uid.this, BLUETOOTH_SCAN_ON, 8776 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 8777 mOnBatteryBackgroundTimeBase); 8778 } 8779 return mBluetoothScanTimer; 8780 } 8781 createBluetoothUnoptimizedScanTimerLocked()8782 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 8783 if (mBluetoothUnoptimizedScanTimer == null) { 8784 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClock, Uid.this, 8785 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 8786 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8787 } 8788 return mBluetoothUnoptimizedScanTimer; 8789 } 8790 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)8791 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 8792 boolean isUnoptimized) { 8793 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 8794 if (isUnoptimized) { 8795 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 8796 } 8797 } 8798 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)8799 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 8800 if (mBluetoothScanTimer != null) { 8801 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 8802 } 8803 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 8804 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 8805 } 8806 } 8807 noteResetBluetoothScanLocked(long elapsedRealtimeMs)8808 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 8809 if (mBluetoothScanTimer != null) { 8810 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 8811 } 8812 if (mBluetoothUnoptimizedScanTimer != null) { 8813 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 8814 } 8815 } 8816 createBluetoothScanResultCounterLocked()8817 public Counter createBluetoothScanResultCounterLocked() { 8818 if (mBluetoothScanResultCounter == null) { 8819 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 8820 } 8821 return mBluetoothScanResultCounter; 8822 } 8823 createBluetoothScanResultBgCounterLocked()8824 public Counter createBluetoothScanResultBgCounterLocked() { 8825 if (mBluetoothScanResultBgCounter == null) { 8826 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 8827 } 8828 return mBluetoothScanResultBgCounter; 8829 } 8830 noteBluetoothScanResultsLocked(int numNewResults)8831 public void noteBluetoothScanResultsLocked(int numNewResults) { 8832 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 8833 // Uses background timebase, so the count will only be incremented if uid in background. 8834 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 8835 } 8836 8837 @Override noteActivityResumedLocked(long elapsedRealtimeMs)8838 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 8839 // We always start, since we want multiple foreground PIDs to nest 8840 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 8841 } 8842 8843 @Override noteActivityPausedLocked(long elapsedRealtimeMs)8844 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 8845 if (mForegroundActivityTimer != null) { 8846 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 8847 } 8848 } 8849 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)8850 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 8851 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 8852 } 8853 noteForegroundServicePausedLocked(long elapsedRealtimeMs)8854 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 8855 if (mForegroundServiceTimer != null) { 8856 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 8857 } 8858 } 8859 createVibratorOnTimerLocked()8860 public BatchTimer createVibratorOnTimerLocked() { 8861 if (mVibratorOnTimer == null) { 8862 mVibratorOnTimer = new BatchTimer(mBsi.mClock, Uid.this, VIBRATOR_ON, 8863 mBsi.mOnBatteryTimeBase); 8864 } 8865 return mVibratorOnTimer; 8866 } 8867 noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs)8868 public void noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs) { 8869 createVibratorOnTimerLocked().addDuration(durationMillis, elapsedRealtimeMs); 8870 } 8871 noteVibratorOffLocked(long elapsedRealtimeMs)8872 public void noteVibratorOffLocked(long elapsedRealtimeMs) { 8873 if (mVibratorOnTimer != null) { 8874 mVibratorOnTimer.abortLastDuration(elapsedRealtimeMs); 8875 } 8876 } 8877 8878 @Override getWifiRunningTime(long elapsedRealtimeUs, int which)8879 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 8880 if (mWifiRunningTimer == null) { 8881 return 0; 8882 } 8883 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8884 } 8885 8886 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)8887 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 8888 if (mFullWifiLockTimer == null) { 8889 return 0; 8890 } 8891 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8892 } 8893 8894 @Override getWifiScanTime(long elapsedRealtimeUs, int which)8895 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 8896 if (mWifiScanTimer == null) { 8897 return 0; 8898 } 8899 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8900 } 8901 8902 @Override getWifiScanCount(int which)8903 public int getWifiScanCount(int which) { 8904 if (mWifiScanTimer == null) { 8905 return 0; 8906 } 8907 return mWifiScanTimer.getCountLocked(which); 8908 } 8909 8910 @Override getWifiScanTimer()8911 public Timer getWifiScanTimer() { 8912 return mWifiScanTimer; 8913 } 8914 8915 @Override getWifiScanBackgroundCount(int which)8916 public int getWifiScanBackgroundCount(int which) { 8917 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 8918 return 0; 8919 } 8920 return mWifiScanTimer.getSubTimer().getCountLocked(which); 8921 } 8922 8923 @Override getWifiScanActualTime(final long elapsedRealtimeUs)8924 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 8925 if (mWifiScanTimer == null) { 8926 return 0; 8927 } 8928 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 8929 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 8930 } 8931 8932 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)8933 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 8934 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 8935 return 0; 8936 } 8937 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 8938 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 8939 } 8940 8941 @Override getWifiScanBackgroundTimer()8942 public Timer getWifiScanBackgroundTimer() { 8943 if (mWifiScanTimer == null) { 8944 return null; 8945 } 8946 return mWifiScanTimer.getSubTimer(); 8947 } 8948 8949 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)8950 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 8951 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 8952 if (mWifiBatchedScanTimer[csphBin] == null) { 8953 return 0; 8954 } 8955 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 8956 } 8957 8958 @Override getWifiBatchedScanCount(int csphBin, int which)8959 public int getWifiBatchedScanCount(int csphBin, int which) { 8960 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 8961 if (mWifiBatchedScanTimer[csphBin] == null) { 8962 return 0; 8963 } 8964 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 8965 } 8966 8967 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)8968 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 8969 if (mWifiMulticastTimer == null) { 8970 return 0; 8971 } 8972 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8973 } 8974 8975 @Override getAudioTurnedOnTimer()8976 public Timer getAudioTurnedOnTimer() { 8977 return mAudioTurnedOnTimer; 8978 } 8979 8980 @Override getVideoTurnedOnTimer()8981 public Timer getVideoTurnedOnTimer() { 8982 return mVideoTurnedOnTimer; 8983 } 8984 8985 @Override getFlashlightTurnedOnTimer()8986 public Timer getFlashlightTurnedOnTimer() { 8987 return mFlashlightTurnedOnTimer; 8988 } 8989 8990 @Override getCameraTurnedOnTimer()8991 public Timer getCameraTurnedOnTimer() { 8992 return mCameraTurnedOnTimer; 8993 } 8994 8995 @Override getForegroundActivityTimer()8996 public Timer getForegroundActivityTimer() { 8997 return mForegroundActivityTimer; 8998 } 8999 9000 @Override getForegroundServiceTimer()9001 public Timer getForegroundServiceTimer() { 9002 return mForegroundServiceTimer; 9003 } 9004 9005 @Override getBluetoothScanTimer()9006 public Timer getBluetoothScanTimer() { 9007 return mBluetoothScanTimer; 9008 } 9009 9010 @Override getBluetoothScanBackgroundTimer()9011 public Timer getBluetoothScanBackgroundTimer() { 9012 if (mBluetoothScanTimer == null) { 9013 return null; 9014 } 9015 return mBluetoothScanTimer.getSubTimer(); 9016 } 9017 9018 @Override getBluetoothUnoptimizedScanTimer()9019 public Timer getBluetoothUnoptimizedScanTimer() { 9020 return mBluetoothUnoptimizedScanTimer; 9021 } 9022 9023 @Override getBluetoothUnoptimizedScanBackgroundTimer()9024 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 9025 if (mBluetoothUnoptimizedScanTimer == null) { 9026 return null; 9027 } 9028 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 9029 } 9030 9031 @Override getBluetoothScanResultCounter()9032 public Counter getBluetoothScanResultCounter() { 9033 return mBluetoothScanResultCounter; 9034 } 9035 9036 @Override getBluetoothScanResultBgCounter()9037 public Counter getBluetoothScanResultBgCounter() { 9038 return mBluetoothScanResultBgCounter; 9039 } 9040 makeProcessState(int i, Parcel in)9041 void makeProcessState(int i, Parcel in) { 9042 if (i < 0 || i >= NUM_PROCESS_STATE) return; 9043 9044 detachIfNotNull(mProcessStateTimer[i]); 9045 if (in == null) { 9046 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClock, this, PROCESS_STATE, null, 9047 mBsi.mOnBatteryTimeBase); 9048 } else { 9049 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClock, this, PROCESS_STATE, null, 9050 mBsi.mOnBatteryTimeBase, in); 9051 } 9052 } 9053 9054 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)9055 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 9056 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 9057 if (mProcessStateTimer[state] == null) { 9058 return 0; 9059 } 9060 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 9061 } 9062 9063 @Override getProcessStateTimer(int state)9064 public Timer getProcessStateTimer(int state) { 9065 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 9066 return mProcessStateTimer[state]; 9067 } 9068 9069 @Override getVibratorOnTimer()9070 public Timer getVibratorOnTimer() { 9071 return mVibratorOnTimer; 9072 } 9073 9074 @Override noteUserActivityLocked(@owerManager.UserActivityEvent int event)9075 public void noteUserActivityLocked(@PowerManager.UserActivityEvent int event) { 9076 if (mUserActivityCounters == null) { 9077 initUserActivityLocked(); 9078 } 9079 if (event >= 0 && event < NUM_USER_ACTIVITY_TYPES) { 9080 mUserActivityCounters[event].stepAtomic(); 9081 } else { 9082 Slog.w(TAG, "Unknown user activity type " + event + " was specified.", 9083 new Throwable()); 9084 } 9085 } 9086 9087 @Override hasUserActivity()9088 public boolean hasUserActivity() { 9089 return mUserActivityCounters != null; 9090 } 9091 9092 @Override getUserActivityCount(int type, int which)9093 public int getUserActivityCount(int type, int which) { 9094 if (mUserActivityCounters == null) { 9095 return 0; 9096 } 9097 return mUserActivityCounters[type].getCountLocked(which); 9098 } 9099 makeWifiBatchedScanBin(int i, Parcel in)9100 void makeWifiBatchedScanBin(int i, Parcel in) { 9101 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 9102 9103 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 9104 if (collected == null) { 9105 collected = new ArrayList<StopwatchTimer>(); 9106 mBsi.mWifiBatchedScanTimers.put(i, collected); 9107 } 9108 detachIfNotNull(mWifiBatchedScanTimer[i]); 9109 if (in == null) { 9110 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClock, this, WIFI_BATCHED_SCAN, 9111 collected, mBsi.mOnBatteryTimeBase); 9112 } else { 9113 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClock, this, WIFI_BATCHED_SCAN, 9114 collected, mBsi.mOnBatteryTimeBase, in); 9115 } 9116 } 9117 9118 initUserActivityLocked()9119 void initUserActivityLocked() { 9120 detachIfNotNull(mUserActivityCounters); 9121 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 9122 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 9123 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 9124 } 9125 } 9126 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)9127 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 9128 ensureNetworkActivityLocked(); 9129 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 9130 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 9131 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 9132 } else { 9133 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 9134 new Throwable()); 9135 } 9136 } 9137 noteMobileRadioActiveTimeLocked(long batteryUptimeDeltaUs, long elapsedTimeMs)9138 void noteMobileRadioActiveTimeLocked(long batteryUptimeDeltaUs, long elapsedTimeMs) { 9139 ensureNetworkActivityLocked(); 9140 getMobileRadioActiveTimeCounter().increment(batteryUptimeDeltaUs, elapsedTimeMs); 9141 mMobileRadioActiveCount.addCountLocked(1); 9142 } 9143 getMobileRadioActiveTimeCounter()9144 private TimeMultiStateCounter getMobileRadioActiveTimeCounter() { 9145 if (mMobileRadioActiveTime == null) { 9146 final long timestampMs = mBsi.mClock.elapsedRealtime(); 9147 mMobileRadioActiveTime = new TimeMultiStateCounter( 9148 mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 9149 mMobileRadioActiveTime.setState( 9150 mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 9151 timestampMs); 9152 mMobileRadioActiveTime.update(0, timestampMs); 9153 } 9154 return mMobileRadioActiveTime; 9155 } 9156 9157 @Override hasNetworkActivity()9158 public boolean hasNetworkActivity() { 9159 return mNetworkByteActivityCounters != null; 9160 } 9161 9162 @Override getNetworkActivityBytes(int type, int which)9163 public long getNetworkActivityBytes(int type, int which) { 9164 if (mNetworkByteActivityCounters != null && type >= 0 9165 && type < mNetworkByteActivityCounters.length) { 9166 return mNetworkByteActivityCounters[type].getCountLocked(which); 9167 } else { 9168 return 0; 9169 } 9170 } 9171 9172 @Override getNetworkActivityPackets(int type, int which)9173 public long getNetworkActivityPackets(int type, int which) { 9174 if (mNetworkPacketActivityCounters != null && type >= 0 9175 && type < mNetworkPacketActivityCounters.length) { 9176 return mNetworkPacketActivityCounters[type].getCountLocked(which); 9177 } else { 9178 return 0; 9179 } 9180 } 9181 9182 @Override getMobileRadioActiveTime(int which)9183 public long getMobileRadioActiveTime(int which) { 9184 return getMobileRadioActiveTimeInProcessState(BatteryConsumer.PROCESS_STATE_ANY); 9185 } 9186 9187 @Override getMobileRadioActiveTimeInProcessState( @atteryConsumer.ProcessState int processState)9188 public long getMobileRadioActiveTimeInProcessState( 9189 @BatteryConsumer.ProcessState int processState) { 9190 if (mMobileRadioActiveTime == null) { 9191 return 0; 9192 } 9193 if (processState == BatteryConsumer.PROCESS_STATE_ANY) { 9194 return mMobileRadioActiveTime.getTotalCountLocked(); 9195 } else { 9196 return mMobileRadioActiveTime.getCountForProcessState(processState); 9197 } 9198 } 9199 9200 @Override getMobileRadioActiveCount(int which)9201 public int getMobileRadioActiveCount(int which) { 9202 return mMobileRadioActiveCount != null 9203 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 9204 } 9205 9206 @Override getUserCpuTimeUs(int which)9207 public long getUserCpuTimeUs(int which) { 9208 return mUserCpuTime.getCountLocked(which); 9209 } 9210 9211 @Override getSystemCpuTimeUs(int which)9212 public long getSystemCpuTimeUs(int which) { 9213 return mSystemCpuTime.getCountLocked(which); 9214 } 9215 9216 @Override getTimeAtCpuSpeed(int cluster, int step, int which)9217 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 9218 if (mCpuClusterSpeedTimesUs != null) { 9219 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 9220 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 9221 if (cpuSpeedTimesUs != null) { 9222 if (step >= 0 && step < cpuSpeedTimesUs.length) { 9223 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 9224 if (c != null) { 9225 return c.getCountLocked(which); 9226 } 9227 } 9228 } 9229 } 9230 } 9231 return 0; 9232 } 9233 noteMobileRadioApWakeupLocked()9234 public void noteMobileRadioApWakeupLocked() { 9235 if (mMobileRadioApWakeupCount == null) { 9236 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9237 } 9238 mMobileRadioApWakeupCount.addCountLocked(1); 9239 } 9240 9241 @Override getMobileRadioApWakeupCount(int which)9242 public long getMobileRadioApWakeupCount(int which) { 9243 if (mMobileRadioApWakeupCount != null) { 9244 return mMobileRadioApWakeupCount.getCountLocked(which); 9245 } 9246 return 0; 9247 } 9248 noteWifiRadioApWakeupLocked()9249 public void noteWifiRadioApWakeupLocked() { 9250 if (mWifiRadioApWakeupCount == null) { 9251 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9252 } 9253 mWifiRadioApWakeupCount.addCountLocked(1); 9254 } 9255 9256 @Override getWifiRadioApWakeupCount(int which)9257 public long getWifiRadioApWakeupCount(int which) { 9258 if (mWifiRadioApWakeupCount != null) { 9259 return mWifiRadioApWakeupCount.getCountLocked(which); 9260 } 9261 return 0; 9262 } 9263 9264 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)9265 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 9266 sb.setLength(0); 9267 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 9268 if (deferredEventCount == 0) { 9269 return; 9270 } 9271 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 9272 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 9273 sb.append(deferredEventCount); sb.append(','); 9274 sb.append(deferredCount); sb.append(','); 9275 sb.append(totalLatency); 9276 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9277 if (mJobsFreshnessBuckets[i] == null) { 9278 sb.append(",0"); 9279 } else { 9280 sb.append(","); 9281 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 9282 } 9283 } 9284 } 9285 9286 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)9287 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 9288 sb.setLength(0); 9289 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 9290 if (deferredEventCount == 0) { 9291 return; 9292 } 9293 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 9294 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 9295 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 9296 sb.append("count="); sb.append(deferredCount); sb.append(", "); 9297 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 9298 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9299 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 9300 if (mJobsFreshnessBuckets[i] == null) { 9301 sb.append("0"); 9302 } else { 9303 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 9304 } 9305 sb.append(" "); 9306 } 9307 } 9308 ensureNetworkActivityLocked()9309 void ensureNetworkActivityLocked() { 9310 if (mNetworkByteActivityCounters != null) { 9311 return; 9312 } 9313 9314 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9315 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9316 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9317 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9318 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9319 } 9320 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 9321 } 9322 9323 /** 9324 * Clear all stats for this uid. Returns true if the uid is completely 9325 * inactive so can be dropped. 9326 */ 9327 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptimeUs, long realtimeUs, int resetReason)9328 public boolean reset(long uptimeUs, long realtimeUs, int resetReason) { 9329 boolean active = false; 9330 9331 mOnBatteryBackgroundTimeBase.init(uptimeUs, realtimeUs); 9332 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeUs, realtimeUs); 9333 9334 if (mWifiRunningTimer != null) { 9335 active |= !mWifiRunningTimer.reset(false, realtimeUs); 9336 active |= mWifiRunning; 9337 } 9338 if (mFullWifiLockTimer != null) { 9339 active |= !mFullWifiLockTimer.reset(false, realtimeUs); 9340 active |= mFullWifiLockOut; 9341 } 9342 if (mWifiScanTimer != null) { 9343 active |= !mWifiScanTimer.reset(false, realtimeUs); 9344 active |= mWifiScanStarted; 9345 } 9346 if (mWifiBatchedScanTimer != null) { 9347 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 9348 if (mWifiBatchedScanTimer[i] != null) { 9349 active |= !mWifiBatchedScanTimer[i].reset(false, realtimeUs); 9350 } 9351 } 9352 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 9353 } 9354 if (mWifiMulticastTimer != null) { 9355 active |= !mWifiMulticastTimer.reset(false, realtimeUs); 9356 active |= (mWifiMulticastWakelockCount > 0); 9357 } 9358 9359 active |= !resetIfNotNull(mAudioTurnedOnTimer, false, realtimeUs); 9360 active |= !resetIfNotNull(mVideoTurnedOnTimer, false, realtimeUs); 9361 active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false, realtimeUs); 9362 active |= !resetIfNotNull(mCameraTurnedOnTimer, false, realtimeUs); 9363 active |= !resetIfNotNull(mForegroundActivityTimer, false, realtimeUs); 9364 active |= !resetIfNotNull(mForegroundServiceTimer, false, realtimeUs); 9365 active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false, realtimeUs); 9366 active |= !resetIfNotNull(mBluetoothScanTimer, false, realtimeUs); 9367 active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false, realtimeUs); 9368 9369 resetIfNotNull(mBluetoothScanResultCounter, false, realtimeUs); 9370 resetIfNotNull(mBluetoothScanResultBgCounter, false, realtimeUs); 9371 9372 if (mProcessStateTimer != null) { 9373 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 9374 active |= !resetIfNotNull(mProcessStateTimer[i], false, realtimeUs); 9375 } 9376 active |= (mProcessState != Uid.PROCESS_STATE_NONEXISTENT); 9377 } 9378 if (mVibratorOnTimer != null) { 9379 if (mVibratorOnTimer.reset(false, realtimeUs)) { 9380 mVibratorOnTimer.detach(); 9381 mVibratorOnTimer = null; 9382 } else { 9383 active = true; 9384 } 9385 } 9386 9387 resetIfNotNull(mUserActivityCounters, false, realtimeUs); 9388 9389 resetIfNotNull(mNetworkByteActivityCounters, false, realtimeUs); 9390 resetIfNotNull(mNetworkPacketActivityCounters, false, realtimeUs); 9391 resetIfNotNull(mMobileRadioActiveTime, false, realtimeUs); 9392 resetIfNotNull(mMobileRadioActiveCount, false, realtimeUs); 9393 9394 resetIfNotNull(mWifiControllerActivity, false, realtimeUs); 9395 resetIfNotNull(mBluetoothControllerActivity, false, realtimeUs); 9396 resetIfNotNull(mModemControllerActivity, false, realtimeUs); 9397 9398 if (resetReason == RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE) { 9399 mUidEnergyConsumerStats = null; 9400 } else { 9401 EnergyConsumerStats.resetIfNotNull(mUidEnergyConsumerStats); 9402 } 9403 9404 resetIfNotNull(mUserCpuTime, false, realtimeUs); 9405 resetIfNotNull(mSystemCpuTime, false, realtimeUs); 9406 9407 resetIfNotNull(mCpuClusterSpeedTimesUs, false, realtimeUs); 9408 9409 resetIfNotNull(mCpuFreqTimeMs, false, realtimeUs /* unused */); 9410 resetIfNotNull(mScreenOffCpuFreqTimeMs, false, realtimeUs /* unused */); 9411 9412 9413 resetIfNotNull(mCpuActiveTimeMs, false, realtimeUs /* unused */); 9414 resetIfNotNull(mCpuClusterTimesMs, false, realtimeUs /* unused */); 9415 9416 resetIfNotNull(mProcStateTimeMs, false, realtimeUs /* unused */); 9417 9418 resetIfNotNull(mProcStateScreenOffTimeMs, false, realtimeUs /* unused */); 9419 9420 resetIfNotNull(mMobileRadioApWakeupCount, false, realtimeUs); 9421 9422 resetIfNotNull(mWifiRadioApWakeupCount, false, realtimeUs); 9423 9424 9425 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9426 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 9427 Wakelock wl = wakeStats.valueAt(iw); 9428 if (wl.reset(realtimeUs)) { 9429 wakeStats.removeAt(iw); 9430 } else { 9431 active = true; 9432 } 9433 } 9434 final long realtimeMs = realtimeUs / 1000; 9435 mWakelockStats.cleanup(realtimeMs); 9436 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9437 for (int is=syncStats.size()-1; is>=0; is--) { 9438 DualTimer timer = syncStats.valueAt(is); 9439 if (timer.reset(false, realtimeUs)) { 9440 syncStats.removeAt(is); 9441 timer.detach(); 9442 } else { 9443 active = true; 9444 } 9445 } 9446 mSyncStats.cleanup(realtimeMs); 9447 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9448 for (int ij=jobStats.size()-1; ij>=0; ij--) { 9449 DualTimer timer = jobStats.valueAt(ij); 9450 if (timer.reset(false, realtimeUs)) { 9451 jobStats.removeAt(ij); 9452 timer.detach(); 9453 } else { 9454 active = true; 9455 } 9456 } 9457 mJobStats.cleanup(realtimeMs); 9458 mJobCompletions.clear(); 9459 9460 resetIfNotNull(mJobsDeferredEventCount, false, realtimeUs); 9461 resetIfNotNull(mJobsDeferredCount, false, realtimeUs); 9462 resetIfNotNull(mJobsFreshnessTimeMs, false, realtimeUs /* unused */); 9463 resetIfNotNull(mJobsFreshnessBuckets, false, realtimeUs); 9464 9465 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 9466 Sensor s = mSensorStats.valueAt(ise); 9467 if (s.reset(realtimeUs)) { 9468 mSensorStats.removeAt(ise); 9469 } else { 9470 active = true; 9471 } 9472 } 9473 9474 for (int ip = mProcessStats.size() - 1; ip >= 0; ip--) { 9475 Proc proc = mProcessStats.valueAt(ip); 9476 proc.detach(); 9477 } 9478 mProcessStats.clear(); 9479 9480 for (int i = mPids.size() - 1; i >= 0; i--) { 9481 Pid pid = mPids.valueAt(i); 9482 if (pid.mWakeNesting > 0) { 9483 active = true; 9484 } else { 9485 mPids.removeAt(i); 9486 } 9487 } 9488 9489 9490 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 9491 Pkg p = mPackageStats.valueAt(i); 9492 p.detach(); 9493 } 9494 mPackageStats.clear(); 9495 9496 mBinderCallCount = 0; 9497 mBinderCallStats.clear(); 9498 9499 mProportionalSystemServiceUsage = 0; 9500 9501 mLastStepUserTimeMs = mLastStepSystemTimeMs = 0; 9502 mCurStepUserTimeMs = mCurStepSystemTimeMs = 0; 9503 9504 9505 return !active; 9506 } 9507 9508 /** 9509 * This method MUST be called whenever the Uid object is destructed, otherwise it is a 9510 * memory leak in {@link TimeBase#mObservers} list. 9511 * Typically the Uid object is destructed when it is removed from 9512 * {@link BatteryStatsImpl#mUidStats} 9513 */ detachFromTimeBase()9514 void detachFromTimeBase() { 9515 detachIfNotNull(mWifiRunningTimer); 9516 detachIfNotNull(mFullWifiLockTimer); 9517 detachIfNotNull(mWifiScanTimer); 9518 detachIfNotNull(mWifiBatchedScanTimer); 9519 detachIfNotNull(mWifiMulticastTimer); 9520 detachIfNotNull(mAudioTurnedOnTimer); 9521 detachIfNotNull(mVideoTurnedOnTimer); 9522 detachIfNotNull(mFlashlightTurnedOnTimer); 9523 9524 detachIfNotNull(mCameraTurnedOnTimer); 9525 detachIfNotNull(mForegroundActivityTimer); 9526 detachIfNotNull(mForegroundServiceTimer); 9527 9528 detachIfNotNull(mAggregatedPartialWakelockTimer); 9529 9530 detachIfNotNull(mBluetoothScanTimer); 9531 detachIfNotNull(mBluetoothUnoptimizedScanTimer); 9532 detachIfNotNull(mBluetoothScanResultCounter); 9533 detachIfNotNull(mBluetoothScanResultBgCounter); 9534 9535 detachIfNotNull(mProcessStateTimer); 9536 9537 detachIfNotNull(mVibratorOnTimer); 9538 9539 detachIfNotNull(mUserActivityCounters); 9540 9541 detachIfNotNull(mNetworkByteActivityCounters); 9542 detachIfNotNull(mNetworkPacketActivityCounters); 9543 9544 detachIfNotNull(mMobileRadioActiveTime); 9545 detachIfNotNull(mMobileRadioActiveCount); 9546 detachIfNotNull(mMobileRadioApWakeupCount); 9547 detachIfNotNull(mWifiRadioApWakeupCount); 9548 9549 detachIfNotNull(mWifiControllerActivity); 9550 detachIfNotNull(mBluetoothControllerActivity); 9551 detachIfNotNull(mModemControllerActivity); 9552 9553 mPids.clear(); 9554 9555 detachIfNotNull(mUserCpuTime); 9556 detachIfNotNull(mSystemCpuTime); 9557 9558 detachIfNotNull(mCpuClusterSpeedTimesUs); 9559 9560 detachIfNotNull(mCpuActiveTimeMs); 9561 detachIfNotNull(mCpuFreqTimeMs); 9562 9563 detachIfNotNull(mScreenOffCpuFreqTimeMs); 9564 9565 detachIfNotNull(mCpuClusterTimesMs); 9566 9567 detachIfNotNull(mProcStateTimeMs); 9568 9569 detachIfNotNull(mProcStateScreenOffTimeMs); 9570 9571 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9572 for (int iw = wakeStats.size() - 1; iw >= 0; iw--) { 9573 Wakelock wl = wakeStats.valueAt(iw); 9574 wl.detachFromTimeBase(); 9575 } 9576 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9577 for (int is = syncStats.size() - 1; is >= 0; is--) { 9578 DualTimer timer = syncStats.valueAt(is); 9579 detachIfNotNull(timer); 9580 } 9581 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9582 for (int ij = jobStats.size() - 1; ij >= 0; ij--) { 9583 DualTimer timer = jobStats.valueAt(ij); 9584 detachIfNotNull(timer); 9585 } 9586 9587 detachIfNotNull(mJobsDeferredEventCount); 9588 detachIfNotNull(mJobsDeferredCount); 9589 detachIfNotNull(mJobsFreshnessTimeMs); 9590 detachIfNotNull(mJobsFreshnessBuckets); 9591 9592 9593 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 9594 Sensor s = mSensorStats.valueAt(ise); 9595 s.detachFromTimeBase(); 9596 } 9597 9598 for (int ip= mProcessStats.size() - 1; ip >= 0; ip--) { 9599 Proc proc = mProcessStats.valueAt(ip); 9600 proc.detach(); 9601 } 9602 mProcessStats.clear(); 9603 9604 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 9605 Pkg p = mPackageStats.valueAt(i); 9606 p.detach(); 9607 } 9608 mPackageStats.clear(); 9609 } 9610 writeJobCompletionsToParcelLocked(Parcel out)9611 void writeJobCompletionsToParcelLocked(Parcel out) { 9612 int NJC = mJobCompletions.size(); 9613 out.writeInt(NJC); 9614 for (int ijc=0; ijc<NJC; ijc++) { 9615 out.writeString(mJobCompletions.keyAt(ijc)); 9616 SparseIntArray types = mJobCompletions.valueAt(ijc); 9617 int NT = types.size(); 9618 out.writeInt(NT); 9619 for (int it=0; it<NT; it++) { 9620 out.writeInt(types.keyAt(it)); 9621 out.writeInt(types.valueAt(it)); 9622 } 9623 } 9624 } 9625 readJobCompletionsFromParcelLocked(Parcel in)9626 void readJobCompletionsFromParcelLocked(Parcel in) { 9627 int numJobCompletions = in.readInt(); 9628 mJobCompletions.clear(); 9629 for (int j = 0; j < numJobCompletions; j++) { 9630 String jobName = in.readString(); 9631 int numTypes = in.readInt(); 9632 if (numTypes > 0) { 9633 SparseIntArray types = new SparseIntArray(); 9634 for (int k = 0; k < numTypes; k++) { 9635 int type = in.readInt(); 9636 int count = in.readInt(); 9637 types.put(type, count); 9638 } 9639 mJobCompletions.put(jobName, types); 9640 } 9641 } 9642 } 9643 noteJobsDeferredLocked(int numDeferred, long sinceLast)9644 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 9645 mJobsDeferredEventCount.addAtomic(1); 9646 mJobsDeferredCount.addAtomic(numDeferred); 9647 if (sinceLast != 0) { 9648 // Add the total time, which can be divided by the event count to get an average 9649 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 9650 // Also keep track of how many times there were in these different buckets. 9651 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9652 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 9653 if (mJobsFreshnessBuckets[i] == null) { 9654 mJobsFreshnessBuckets[i] = new Counter( 9655 mBsi.mOnBatteryTimeBase); 9656 } 9657 mJobsFreshnessBuckets[i].addAtomic(1); 9658 break; 9659 } 9660 } 9661 } 9662 } 9663 9664 // Reusable object used as a key to lookup values in mBinderCallStats 9665 private static BinderCallStats sTempBinderCallStats = new BinderCallStats(); 9666 9667 /** 9668 * Notes incoming binder call stats associated with this work source UID. 9669 */ noteBinderCallStatsLocked(long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)9670 public void noteBinderCallStatsLocked(long incrementalCallCount, 9671 Collection<BinderCallsStats.CallStat> callStats) { 9672 if (DEBUG) { 9673 Slog.d(TAG, "noteBinderCalls() workSourceUid = [" + mUid + "], " 9674 + " incrementalCallCount: " + incrementalCallCount + " callStats = [" 9675 + new ArrayList<>(callStats) + "]"); 9676 } 9677 mBinderCallCount += incrementalCallCount; 9678 for (BinderCallsStats.CallStat stat : callStats) { 9679 BinderCallStats bcs; 9680 sTempBinderCallStats.binderClass = stat.binderClass; 9681 sTempBinderCallStats.transactionCode = stat.transactionCode; 9682 int index = mBinderCallStats.indexOf(sTempBinderCallStats); 9683 if (index >= 0) { 9684 bcs = mBinderCallStats.valueAt(index); 9685 } else { 9686 bcs = new BinderCallStats(); 9687 bcs.binderClass = stat.binderClass; 9688 bcs.transactionCode = stat.transactionCode; 9689 mBinderCallStats.add(bcs); 9690 } 9691 9692 bcs.callCount += stat.incrementalCallCount; 9693 bcs.recordedCallCount = stat.recordedCallCount; 9694 bcs.recordedCpuTimeMicros = stat.cpuTimeMicros; 9695 } 9696 } 9697 9698 /** 9699 * The statistics associated with a particular wake lock. 9700 */ 9701 public static class Wakelock extends BatteryStats.Uid.Wakelock { 9702 /** 9703 * BatteryStatsImpl that we are associated with. 9704 */ 9705 protected BatteryStatsImpl mBsi; 9706 9707 /** 9708 * BatteryStatsImpl that we are associated with. 9709 */ 9710 protected Uid mUid; 9711 9712 /** 9713 * How long (in ms) this uid has been keeping the device partially awake. 9714 * Tracks both the total time and the time while the app was in the background. 9715 */ 9716 DualTimer mTimerPartial; 9717 9718 /** 9719 * How long (in ms) this uid has been keeping the device fully awake. 9720 */ 9721 StopwatchTimer mTimerFull; 9722 9723 /** 9724 * How long (in ms) this uid has had a window keeping the device awake. 9725 */ 9726 StopwatchTimer mTimerWindow; 9727 9728 /** 9729 * How long (in ms) this uid has had a draw wake lock. 9730 */ 9731 StopwatchTimer mTimerDraw; 9732 Wakelock(BatteryStatsImpl bsi, Uid uid)9733 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 9734 mBsi = bsi; 9735 mUid = uid; 9736 } 9737 9738 /** 9739 * Reads a possibly null Timer from a Parcel. The timer is associated with the 9740 * proper timer pool from the given BatteryStatsImpl object. 9741 * 9742 * @param in the Parcel to be read from. 9743 * return a new Timer, or null. 9744 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)9745 private StopwatchTimer readStopwatchTimerFromParcel(int type, 9746 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 9747 if (in.readInt() == 0) { 9748 return null; 9749 } 9750 9751 return new StopwatchTimer(mBsi.mClock, mUid, type, pool, timeBase, in); 9752 } 9753 9754 /** 9755 * Reads a possibly null Timer from a Parcel. The timer is associated with the 9756 * proper timer pool from the given BatteryStatsImpl object. 9757 * 9758 * @param in the Parcel to be read from. 9759 * return a new Timer, or null. 9760 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)9761 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 9762 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 9763 if (in.readInt() == 0) { 9764 return null; 9765 } 9766 9767 return new DualTimer(mBsi.mClock, mUid, type, pool, timeBase, bgTimeBase, in); 9768 } 9769 reset(long elapsedRealtimeUs)9770 boolean reset(long elapsedRealtimeUs) { 9771 boolean wlactive = false; 9772 9773 wlactive |= !resetIfNotNull(mTimerFull, false, elapsedRealtimeUs); 9774 wlactive |= !resetIfNotNull(mTimerPartial, false, elapsedRealtimeUs); 9775 wlactive |= !resetIfNotNull(mTimerWindow, false, elapsedRealtimeUs); 9776 wlactive |= !resetIfNotNull(mTimerDraw, false, elapsedRealtimeUs); 9777 9778 if (!wlactive) { 9779 detachIfNotNull(mTimerFull); 9780 mTimerFull = null; 9781 9782 detachIfNotNull(mTimerPartial); 9783 mTimerPartial = null; 9784 9785 detachIfNotNull(mTimerWindow); 9786 mTimerWindow = null; 9787 9788 detachIfNotNull(mTimerDraw); 9789 mTimerDraw = null; 9790 } 9791 return !wlactive; 9792 } 9793 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)9794 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 9795 TimeBase screenOffBgTimeBase, Parcel in) { 9796 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 9797 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 9798 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 9799 mBsi.mFullTimers, timeBase, in); 9800 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 9801 mBsi.mWindowTimers, timeBase, in); 9802 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 9803 mBsi.mDrawTimers, timeBase, in); 9804 } 9805 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)9806 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 9807 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 9808 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 9809 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 9810 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 9811 } 9812 9813 @Override getWakeTime(int type)9814 public Timer getWakeTime(int type) { 9815 switch (type) { 9816 case WAKE_TYPE_FULL: return mTimerFull; 9817 case WAKE_TYPE_PARTIAL: return mTimerPartial; 9818 case WAKE_TYPE_WINDOW: return mTimerWindow; 9819 case WAKE_TYPE_DRAW: return mTimerDraw; 9820 default: throw new IllegalArgumentException("type = " + type); 9821 } 9822 } 9823 detachFromTimeBase()9824 public void detachFromTimeBase() { 9825 detachIfNotNull(mTimerPartial); 9826 detachIfNotNull(mTimerFull); 9827 detachIfNotNull(mTimerWindow); 9828 detachIfNotNull(mTimerDraw); 9829 } 9830 } 9831 9832 public static class Sensor extends BatteryStats.Uid.Sensor { 9833 /** 9834 * BatteryStatsImpl that we are associated with. 9835 */ 9836 protected BatteryStatsImpl mBsi; 9837 9838 /** 9839 * Uid that we are associated with. 9840 */ 9841 protected Uid mUid; 9842 9843 final int mHandle; 9844 DualTimer mTimer; 9845 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)9846 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 9847 mBsi = bsi; 9848 mUid = uid; 9849 mHandle = handle; 9850 } 9851 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)9852 private DualTimer readTimersFromParcel( 9853 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 9854 if (in.readInt() == 0) { 9855 return null; 9856 } 9857 9858 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 9859 if (pool == null) { 9860 pool = new ArrayList<StopwatchTimer>(); 9861 mBsi.mSensorTimers.put(mHandle, pool); 9862 } 9863 return new DualTimer(mBsi.mClock, mUid, 0, pool, timeBase, bgTimeBase, in); 9864 } 9865 reset(long elapsedRealtimeUs)9866 boolean reset(long elapsedRealtimeUs) { 9867 if (mTimer.reset(true, elapsedRealtimeUs)) { 9868 mTimer = null; 9869 return true; 9870 } 9871 return false; 9872 } 9873 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)9874 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 9875 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 9876 } 9877 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)9878 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 9879 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 9880 } 9881 9882 @Override getSensorTime()9883 public Timer getSensorTime() { 9884 return mTimer; 9885 } 9886 9887 @Override getSensorBackgroundTime()9888 public Timer getSensorBackgroundTime() { 9889 if (mTimer == null) { 9890 return null; 9891 } 9892 return mTimer.getSubTimer(); 9893 } 9894 9895 @Override getHandle()9896 public int getHandle() { 9897 return mHandle; 9898 } 9899 detachFromTimeBase()9900 public void detachFromTimeBase() { 9901 detachIfNotNull(mTimer); 9902 } 9903 } 9904 9905 /** 9906 * The statistics associated with a particular process. 9907 */ 9908 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 9909 /** 9910 * BatteryStatsImpl that we are associated with. 9911 */ 9912 protected BatteryStatsImpl mBsi; 9913 9914 /** 9915 * The name of this process. 9916 */ 9917 final String mName; 9918 9919 /** 9920 * Remains true until removed from the stats. 9921 */ 9922 boolean mActive = true; 9923 9924 /** 9925 * Total time (in ms) spent executing in user code. 9926 */ 9927 long mUserTimeMs; 9928 9929 /** 9930 * Total time (in ms) spent executing in kernel code. 9931 */ 9932 long mSystemTimeMs; 9933 9934 /** 9935 * Amount of time (in ms) the process was running in the foreground. 9936 */ 9937 long mForegroundTimeMs; 9938 9939 /** 9940 * Number of times the process has been started. 9941 */ 9942 int mStarts; 9943 9944 /** 9945 * Number of times the process has crashed. 9946 */ 9947 int mNumCrashes; 9948 9949 /** 9950 * Number of times the process has had an ANR. 9951 */ 9952 int mNumAnrs; 9953 9954 ArrayList<ExcessivePower> mExcessivePower; 9955 Proc(BatteryStatsImpl bsi, String name)9956 public Proc(BatteryStatsImpl bsi, String name) { 9957 mBsi = bsi; 9958 mName = name; 9959 mBsi.mOnBatteryTimeBase.add(this); 9960 } 9961 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)9962 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 9963 long baseRealtimeUs) { 9964 } 9965 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)9966 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 9967 long baseRealtimeUs) { 9968 } 9969 9970 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)9971 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 9972 if (detachIfReset) { 9973 this.detach(); 9974 } 9975 return true; 9976 } 9977 9978 @Override detach()9979 public void detach() { 9980 mActive = false; 9981 mBsi.mOnBatteryTimeBase.remove(this); 9982 } 9983 countExcessivePowers()9984 public int countExcessivePowers() { 9985 return mExcessivePower != null ? mExcessivePower.size() : 0; 9986 } 9987 getExcessivePower(int i)9988 public ExcessivePower getExcessivePower(int i) { 9989 if (mExcessivePower != null) { 9990 return mExcessivePower.get(i); 9991 } 9992 return null; 9993 } 9994 addExcessiveCpu(long overTimeMs, long usedTimeMs)9995 public void addExcessiveCpu(long overTimeMs, long usedTimeMs) { 9996 if (mExcessivePower == null) { 9997 mExcessivePower = new ArrayList<ExcessivePower>(); 9998 } 9999 ExcessivePower ew = new ExcessivePower(); 10000 ew.type = ExcessivePower.TYPE_CPU; 10001 ew.overTime = overTimeMs; 10002 ew.usedTime = usedTimeMs; 10003 mExcessivePower.add(ew); 10004 } 10005 writeExcessivePowerToParcelLocked(Parcel out)10006 void writeExcessivePowerToParcelLocked(Parcel out) { 10007 if (mExcessivePower == null) { 10008 out.writeInt(0); 10009 return; 10010 } 10011 10012 final int N = mExcessivePower.size(); 10013 out.writeInt(N); 10014 for (int i=0; i<N; i++) { 10015 ExcessivePower ew = mExcessivePower.get(i); 10016 out.writeInt(ew.type); 10017 out.writeLong(ew.overTime); 10018 out.writeLong(ew.usedTime); 10019 } 10020 } 10021 readExcessivePowerFromParcelLocked(Parcel in)10022 void readExcessivePowerFromParcelLocked(Parcel in) { 10023 final int N = in.readInt(); 10024 if (N == 0) { 10025 mExcessivePower = null; 10026 return; 10027 } 10028 10029 if (N > 10000) { 10030 throw new ParcelFormatException( 10031 "File corrupt: too many excessive power entries " + N); 10032 } 10033 10034 mExcessivePower = new ArrayList<>(); 10035 for (int i=0; i<N; i++) { 10036 ExcessivePower ew = new ExcessivePower(); 10037 ew.type = in.readInt(); 10038 ew.overTime = in.readLong(); 10039 ew.usedTime = in.readLong(); 10040 mExcessivePower.add(ew); 10041 } 10042 } 10043 writeToParcelLocked(Parcel out)10044 void writeToParcelLocked(Parcel out) { 10045 out.writeLong(mUserTimeMs); 10046 out.writeLong(mSystemTimeMs); 10047 out.writeLong(mForegroundTimeMs); 10048 out.writeInt(mStarts); 10049 out.writeInt(mNumCrashes); 10050 out.writeInt(mNumAnrs); 10051 writeExcessivePowerToParcelLocked(out); 10052 } 10053 readFromParcelLocked(Parcel in)10054 void readFromParcelLocked(Parcel in) { 10055 mUserTimeMs = in.readLong(); 10056 mSystemTimeMs = in.readLong(); 10057 mForegroundTimeMs = in.readLong(); 10058 mStarts = in.readInt(); 10059 mNumCrashes = in.readInt(); 10060 mNumAnrs = in.readInt(); 10061 readExcessivePowerFromParcelLocked(in); 10062 } 10063 addCpuTimeLocked(int utimeMs, int stimeMs)10064 public void addCpuTimeLocked(int utimeMs, int stimeMs) { 10065 addCpuTimeLocked(utimeMs, stimeMs, mBsi.mOnBatteryTimeBase.isRunning()); 10066 } 10067 addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning)10068 public void addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning) { 10069 if (isRunning) { 10070 mUserTimeMs += utimeMs; 10071 mSystemTimeMs += stimeMs; 10072 } 10073 } 10074 addForegroundTimeLocked(long ttimeMs)10075 public void addForegroundTimeLocked(long ttimeMs) { 10076 mForegroundTimeMs += ttimeMs; 10077 } 10078 incStartsLocked()10079 public void incStartsLocked() { 10080 mStarts++; 10081 } 10082 incNumCrashesLocked()10083 public void incNumCrashesLocked() { 10084 mNumCrashes++; 10085 } 10086 incNumAnrsLocked()10087 public void incNumAnrsLocked() { 10088 mNumAnrs++; 10089 } 10090 10091 @Override isActive()10092 public boolean isActive() { 10093 return mActive; 10094 } 10095 10096 @Override getUserTime(int which)10097 public long getUserTime(int which) { 10098 return mUserTimeMs; 10099 } 10100 10101 @Override getSystemTime(int which)10102 public long getSystemTime(int which) { 10103 return mSystemTimeMs; 10104 } 10105 10106 @Override getForegroundTime(int which)10107 public long getForegroundTime(int which) { 10108 return mForegroundTimeMs; 10109 } 10110 10111 @Override getStarts(int which)10112 public int getStarts(int which) { 10113 return mStarts; 10114 } 10115 10116 @Override getNumCrashes(int which)10117 public int getNumCrashes(int which) { 10118 return mNumCrashes; 10119 } 10120 10121 @Override getNumAnrs(int which)10122 public int getNumAnrs(int which) { 10123 return mNumAnrs; 10124 } 10125 } 10126 10127 /** 10128 * The statistics associated with a particular package. 10129 */ 10130 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 10131 /** 10132 * BatteryStatsImpl that we are associated with. 10133 */ 10134 protected BatteryStatsImpl mBsi; 10135 10136 /** 10137 * Number of times wakeup alarms have occurred for this app. 10138 * On screen-off timebase starting in report v25. 10139 */ 10140 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 10141 10142 /** 10143 * The statics we have collected for this package's services. 10144 */ 10145 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 10146 Pkg(BatteryStatsImpl bsi)10147 public Pkg(BatteryStatsImpl bsi) { 10148 mBsi = bsi; 10149 mBsi.mOnBatteryScreenOffTimeBase.add(this); 10150 } 10151 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10152 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10153 long baseRealtimeUs) { 10154 } 10155 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10156 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10157 long baseRealtimeUs) { 10158 } 10159 10160 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10161 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10162 if (detachIfReset) { 10163 this.detach(); 10164 } 10165 return true; 10166 } 10167 10168 @Override detach()10169 public void detach() { 10170 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 10171 for (int j = mWakeupAlarms.size() - 1; j >= 0; j--) { 10172 detachIfNotNull(mWakeupAlarms.valueAt(j)); 10173 } 10174 for (int j = mServiceStats.size() - 1; j >= 0; j--) { 10175 detachIfNotNull(mServiceStats.valueAt(j)); 10176 } 10177 } 10178 readFromParcelLocked(Parcel in)10179 void readFromParcelLocked(Parcel in) { 10180 int numWA = in.readInt(); 10181 mWakeupAlarms.clear(); 10182 for (int i=0; i<numWA; i++) { 10183 String tag = in.readString(); 10184 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 10185 } 10186 10187 int numServs = in.readInt(); 10188 mServiceStats.clear(); 10189 for (int m = 0; m < numServs; m++) { 10190 String serviceName = in.readString(); 10191 Uid.Pkg.Serv serv = new Serv(mBsi); 10192 mServiceStats.put(serviceName, serv); 10193 10194 serv.readFromParcelLocked(in); 10195 } 10196 } 10197 writeToParcelLocked(Parcel out)10198 void writeToParcelLocked(Parcel out) { 10199 int numWA = mWakeupAlarms.size(); 10200 out.writeInt(numWA); 10201 for (int i=0; i<numWA; i++) { 10202 out.writeString(mWakeupAlarms.keyAt(i)); 10203 mWakeupAlarms.valueAt(i).writeToParcel(out); 10204 } 10205 10206 final int NS = mServiceStats.size(); 10207 out.writeInt(NS); 10208 for (int i=0; i<NS; i++) { 10209 out.writeString(mServiceStats.keyAt(i)); 10210 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 10211 serv.writeToParcelLocked(out); 10212 } 10213 } 10214 10215 @Override getWakeupAlarmStats()10216 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 10217 return mWakeupAlarms; 10218 } 10219 noteWakeupAlarmLocked(String tag)10220 public void noteWakeupAlarmLocked(String tag) { 10221 Counter c = mWakeupAlarms.get(tag); 10222 if (c == null) { 10223 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 10224 mWakeupAlarms.put(tag, c); 10225 } 10226 c.stepAtomic(); 10227 } 10228 10229 @Override getServiceStats()10230 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 10231 return mServiceStats; 10232 } 10233 10234 /** 10235 * The statistics associated with a particular service. 10236 */ 10237 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 10238 /** 10239 * BatteryStatsImpl that we are associated with. 10240 */ 10241 protected BatteryStatsImpl mBsi; 10242 10243 /** 10244 * The android package in which this service resides. 10245 */ 10246 protected Pkg mPkg; 10247 10248 /** 10249 * Total time (ms in battery uptime) the service has been left started. 10250 */ 10251 protected long mStartTimeMs; 10252 10253 /** 10254 * If service has been started and not yet stopped, this is 10255 * when it was started. 10256 */ 10257 protected long mRunningSinceMs; 10258 10259 /** 10260 * True if we are currently running. 10261 */ 10262 protected boolean mRunning; 10263 10264 /** 10265 * Total number of times startService() has been called. 10266 */ 10267 protected int mStarts; 10268 10269 /** 10270 * Total time (ms in battery uptime) the service has been left launched. 10271 */ 10272 protected long mLaunchedTimeMs; 10273 10274 /** 10275 * If service has been launched and not yet exited, this is 10276 * when it was launched (ms in battery uptime). 10277 */ 10278 protected long mLaunchedSinceMs; 10279 10280 /** 10281 * True if we are currently launched. 10282 */ 10283 protected boolean mLaunched; 10284 10285 /** 10286 * Total number times the service has been launched. 10287 */ 10288 protected int mLaunches; 10289 10290 /** 10291 * Construct a Serv. Also adds it to the on-battery time base as a listener. 10292 */ Serv(BatteryStatsImpl bsi)10293 public Serv(BatteryStatsImpl bsi) { 10294 mBsi = bsi; 10295 mBsi.mOnBatteryTimeBase.add(this); 10296 } 10297 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10298 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10299 long baseRealtimeUs) { 10300 } 10301 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10302 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10303 long baseRealtimeUs) { 10304 } 10305 10306 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10307 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10308 if (detachIfReset) { 10309 this.detach(); 10310 } 10311 return true; 10312 } 10313 10314 /** 10315 * Remove this Serv as a listener from the time base. 10316 Ms*/ 10317 @Override detach()10318 public void detach() { 10319 mBsi.mOnBatteryTimeBase.remove(this); 10320 } 10321 readFromParcelLocked(Parcel in)10322 public void readFromParcelLocked(Parcel in) { 10323 mStartTimeMs = in.readLong(); 10324 mRunningSinceMs = in.readLong(); 10325 mRunning = in.readInt() != 0; 10326 mStarts = in.readInt(); 10327 mLaunchedTimeMs = in.readLong(); 10328 mLaunchedSinceMs = in.readLong(); 10329 mLaunched = in.readInt() != 0; 10330 mLaunches = in.readInt(); 10331 } 10332 writeToParcelLocked(Parcel out)10333 public void writeToParcelLocked(Parcel out) { 10334 out.writeLong(mStartTimeMs); 10335 out.writeLong(mRunningSinceMs); 10336 out.writeInt(mRunning ? 1 : 0); 10337 out.writeInt(mStarts); 10338 out.writeLong(mLaunchedTimeMs); 10339 out.writeLong(mLaunchedSinceMs); 10340 out.writeInt(mLaunched ? 1 : 0); 10341 out.writeInt(mLaunches); 10342 } 10343 getLaunchTimeToNowLocked(long batteryUptimeMs)10344 public long getLaunchTimeToNowLocked(long batteryUptimeMs) { 10345 if (!mLaunched) return mLaunchedTimeMs; 10346 return mLaunchedTimeMs + batteryUptimeMs - mLaunchedSinceMs; 10347 } 10348 getStartTimeToNowLocked(long batteryUptimeMs)10349 public long getStartTimeToNowLocked(long batteryUptimeMs) { 10350 if (!mRunning) return mStartTimeMs; 10351 return mStartTimeMs + batteryUptimeMs - mRunningSinceMs; 10352 } 10353 startLaunchedLocked()10354 public void startLaunchedLocked() { 10355 startLaunchedLocked(mBsi.mClock.uptimeMillis()); 10356 } 10357 startLaunchedLocked(long uptimeMs)10358 public void startLaunchedLocked(long uptimeMs) { 10359 if (!mLaunched) { 10360 mLaunches++; 10361 mLaunchedSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10362 mLaunched = true; 10363 } 10364 } 10365 stopLaunchedLocked()10366 public void stopLaunchedLocked() { 10367 stopLaunchedLocked(mBsi.mClock.uptimeMillis()); 10368 } 10369 stopLaunchedLocked(long uptimeMs)10370 public void stopLaunchedLocked(long uptimeMs) { 10371 if (mLaunched) { 10372 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10373 - mLaunchedSinceMs; 10374 if (timeMs > 0) { 10375 mLaunchedTimeMs += timeMs; 10376 } else { 10377 mLaunches--; 10378 } 10379 mLaunched = false; 10380 } 10381 } 10382 startRunningLocked()10383 public void startRunningLocked() { 10384 startRunningLocked(mBsi.mClock.uptimeMillis()); 10385 } 10386 startRunningLocked(long uptimeMs)10387 public void startRunningLocked(long uptimeMs) { 10388 if (!mRunning) { 10389 mStarts++; 10390 mRunningSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10391 mRunning = true; 10392 } 10393 } 10394 stopRunningLocked()10395 public void stopRunningLocked() { 10396 stopRunningLocked(mBsi.mClock.uptimeMillis()); 10397 } 10398 stopRunningLocked(long uptimeMs)10399 public void stopRunningLocked(long uptimeMs) { 10400 if (mRunning) { 10401 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10402 - mRunningSinceMs; 10403 if (timeMs > 0) { 10404 mStartTimeMs += timeMs; 10405 } else { 10406 mStarts--; 10407 } 10408 mRunning = false; 10409 } 10410 } 10411 getBatteryStats()10412 public BatteryStatsImpl getBatteryStats() { 10413 return mBsi; 10414 } 10415 10416 @Override getLaunches(int which)10417 public int getLaunches(int which) { 10418 return mLaunches; 10419 } 10420 10421 @Override getStartTime(long now, int which)10422 public long getStartTime(long now, int which) { 10423 return getStartTimeToNowLocked(now); 10424 } 10425 10426 @Override getStarts(int which)10427 public int getStarts(int which) { 10428 return mStarts; 10429 } 10430 } 10431 newServiceStatsLocked()10432 final Serv newServiceStatsLocked() { 10433 return new Serv(mBsi); 10434 } 10435 } 10436 10437 private class ChildUid { 10438 public final TimeMultiStateCounter cpuActiveCounter; 10439 public final LongArrayMultiStateCounter cpuTimeInFreqCounter; 10440 ChildUid()10441 ChildUid() { 10442 final long timestampMs = mBsi.mClock.elapsedRealtime(); 10443 cpuActiveCounter = 10444 new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, 1, timestampMs); 10445 cpuActiveCounter.setState(0, timestampMs); 10446 10447 if (mBsi.trackPerProcStateCpuTimes()) { 10448 final int cpuFreqCount = mBsi.getCpuFreqCount(); 10449 10450 cpuTimeInFreqCounter = new LongArrayMultiStateCounter(1, cpuFreqCount); 10451 10452 // Set initial values to all 0. This is a child UID and we want to include 10453 // the entirety of its CPU time-in-freq stats into the parent's stats. 10454 cpuTimeInFreqCounter.updateValues( 10455 new LongArrayMultiStateCounter.LongArrayContainer(cpuFreqCount), 10456 timestampMs); 10457 } else { 10458 cpuTimeInFreqCounter = null; 10459 } 10460 } 10461 } 10462 10463 /** 10464 * Retrieve the statistics object for a particular process, creating 10465 * if needed. 10466 */ getProcessStatsLocked(String name)10467 public Proc getProcessStatsLocked(String name) { 10468 Proc ps = mProcessStats.get(name); 10469 if (ps == null) { 10470 ps = new Proc(mBsi, name); 10471 mProcessStats.put(name, ps); 10472 } 10473 10474 return ps; 10475 } 10476 10477 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState, long elapsedRealtimeMs, long uptimeMs)10478 public void updateUidProcessStateLocked(int procState, 10479 long elapsedRealtimeMs, long uptimeMs) { 10480 int uidRunningState; 10481 // Make special note of Foreground Services 10482 final boolean userAwareService = 10483 (ActivityManager.isForegroundService(procState)); 10484 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 10485 10486 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 10487 return; 10488 } 10489 10490 if (mProcessState != uidRunningState) { 10491 if (mProcessState != Uid.PROCESS_STATE_NONEXISTENT) { 10492 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 10493 } 10494 if (uidRunningState != Uid.PROCESS_STATE_NONEXISTENT) { 10495 if (mProcessStateTimer[uidRunningState] == null) { 10496 makeProcessState(uidRunningState, null); 10497 } 10498 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 10499 } 10500 10501 if (mBsi.trackPerProcStateCpuTimes()) { 10502 mBsi.updateProcStateCpuTimesLocked(mUid, elapsedRealtimeMs, uptimeMs); 10503 10504 LongArrayMultiStateCounter onBatteryCounter = 10505 getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 10506 LongArrayMultiStateCounter onBatteryScreenOffCounter = 10507 getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 10508 10509 onBatteryCounter.setState(uidRunningState, elapsedRealtimeMs); 10510 onBatteryScreenOffCounter.setState(uidRunningState, elapsedRealtimeMs); 10511 } 10512 10513 final int prevBatteryConsumerProcessState = 10514 mapUidProcessStateToBatteryConsumerProcessState(mProcessState); 10515 10516 mProcessState = uidRunningState; 10517 10518 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10519 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10520 10521 final int batteryConsumerProcessState = 10522 mapUidProcessStateToBatteryConsumerProcessState(uidRunningState); 10523 getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedRealtimeMs); 10524 10525 getMobileRadioActiveTimeCounter() 10526 .setState(batteryConsumerProcessState, elapsedRealtimeMs); 10527 10528 final ControllerActivityCounterImpl wifiControllerActivity = 10529 getWifiControllerActivity(); 10530 if (wifiControllerActivity != null) { 10531 wifiControllerActivity.setState(batteryConsumerProcessState, elapsedRealtimeMs); 10532 } 10533 10534 final ControllerActivityCounterImpl bluetoothControllerActivity = 10535 getBluetoothControllerActivity(); 10536 if (bluetoothControllerActivity != null) { 10537 bluetoothControllerActivity.setState(batteryConsumerProcessState, 10538 elapsedRealtimeMs); 10539 } 10540 10541 final EnergyConsumerStats energyStats = 10542 getOrCreateEnergyConsumerStatsIfSupportedLocked(); 10543 if (energyStats != null) { 10544 energyStats.setState(batteryConsumerProcessState, elapsedRealtimeMs); 10545 } 10546 maybeScheduleExternalStatsSync(prevBatteryConsumerProcessState, 10547 batteryConsumerProcessState); 10548 } 10549 10550 if (userAwareService != mInForegroundService) { 10551 if (userAwareService) { 10552 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 10553 } else { 10554 noteForegroundServicePausedLocked(elapsedRealtimeMs); 10555 } 10556 mInForegroundService = userAwareService; 10557 } 10558 } 10559 10560 @GuardedBy("mBsi") maybeScheduleExternalStatsSync( @atteryConsumer.ProcessState int oldProcessState, @BatteryConsumer.ProcessState int newProcessState)10561 private void maybeScheduleExternalStatsSync( 10562 @BatteryConsumer.ProcessState int oldProcessState, 10563 @BatteryConsumer.ProcessState int newProcessState) { 10564 if (oldProcessState == newProcessState) { 10565 return; 10566 } 10567 // Transitions between BACKGROUND and such non-foreground states like cached 10568 // or nonexistent do not warrant doing a sync. If some of the stats for those 10569 // proc states bleed into the PROCESS_STATE_BACKGROUND, that's ok. 10570 if ((oldProcessState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED 10571 && newProcessState == BatteryConsumer.PROCESS_STATE_BACKGROUND) 10572 || (oldProcessState == BatteryConsumer.PROCESS_STATE_BACKGROUND 10573 && newProcessState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED)) { 10574 return; 10575 } 10576 10577 int flags = ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE; 10578 // Skip querying for inactive radio, where power usage is probably negligible. 10579 if (!BatteryStatsImpl.isActiveRadioPowerState(mBsi.mMobileRadioPowerState)) { 10580 flags &= ~ExternalStatsSync.UPDATE_RADIO; 10581 } 10582 10583 mBsi.mExternalSync.scheduleSyncDueToProcessStateChange(flags, 10584 mBsi.mConstants.PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 10585 } 10586 10587 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()10588 public boolean isInBackground() { 10589 // Note that PROCESS_STATE_CACHED and Uid.PROCESS_STATE_NONEXISTENT is 10590 // also considered to be 'background' for our purposes, because it's not foreground. 10591 return mProcessState >= PROCESS_STATE_BACKGROUND; 10592 } 10593 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)10594 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 10595 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 10596 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 10597 } 10598 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)10599 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 10600 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 10601 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 10602 } 10603 getPidStats()10604 public SparseArray<? extends Pid> getPidStats() { 10605 return mPids; 10606 } 10607 getPidStatsLocked(int pid)10608 public Pid getPidStatsLocked(int pid) { 10609 Pid p = mPids.get(pid); 10610 if (p == null) { 10611 p = new Pid(); 10612 mPids.put(pid, p); 10613 } 10614 return p; 10615 } 10616 10617 /** 10618 * Retrieve the statistics object for a particular service, creating 10619 * if needed. 10620 */ getPackageStatsLocked(String name)10621 public Pkg getPackageStatsLocked(String name) { 10622 Pkg ps = mPackageStats.get(name); 10623 if (ps == null) { 10624 ps = new Pkg(mBsi); 10625 mPackageStats.put(name, ps); 10626 } 10627 10628 return ps; 10629 } 10630 10631 /** 10632 * Retrieve the statistics object for a particular service, creating 10633 * if needed. 10634 */ getServiceStatsLocked(String pkg, String serv)10635 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 10636 Pkg ps = getPackageStatsLocked(pkg); 10637 Pkg.Serv ss = ps.mServiceStats.get(serv); 10638 if (ss == null) { 10639 ss = ps.newServiceStatsLocked(); 10640 ps.mServiceStats.put(serv, ss); 10641 } 10642 10643 return ss; 10644 } 10645 readSyncSummaryFromParcelLocked(String name, Parcel in)10646 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 10647 DualTimer timer = mSyncStats.instantiateObject(); 10648 timer.readSummaryFromParcelLocked(in); 10649 mSyncStats.add(name, timer); 10650 } 10651 readJobSummaryFromParcelLocked(String name, Parcel in)10652 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 10653 DualTimer timer = mJobStats.instantiateObject(); 10654 timer.readSummaryFromParcelLocked(in); 10655 mJobStats.add(name, timer); 10656 } 10657 readWakeSummaryFromParcelLocked(String wlName, Parcel in)10658 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 10659 Wakelock wl = new Wakelock(mBsi, this); 10660 mWakelockStats.add(wlName, wl); 10661 if (in.readInt() != 0) { 10662 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 10663 } 10664 if (in.readInt() != 0) { 10665 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 10666 } 10667 if (in.readInt() != 0) { 10668 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 10669 } 10670 if (in.readInt() != 0) { 10671 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 10672 } 10673 } 10674 getSensorTimerLocked(int sensor, boolean create)10675 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 10676 Sensor se = mSensorStats.get(sensor); 10677 if (se == null) { 10678 if (!create) { 10679 return null; 10680 } 10681 se = new Sensor(mBsi, this, sensor); 10682 mSensorStats.put(sensor, se); 10683 } 10684 DualTimer t = se.mTimer; 10685 if (t != null) { 10686 return t; 10687 } 10688 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 10689 if (timers == null) { 10690 timers = new ArrayList<StopwatchTimer>(); 10691 mBsi.mSensorTimers.put(sensor, timers); 10692 } 10693 t = new DualTimer(mBsi.mClock, this, BatteryStats.SENSOR, timers, 10694 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 10695 se.mTimer = t; 10696 return t; 10697 } 10698 noteStartSyncLocked(String name, long elapsedRealtimeMs)10699 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 10700 DualTimer t = mSyncStats.startObject(name, elapsedRealtimeMs); 10701 if (t != null) { 10702 t.startRunningLocked(elapsedRealtimeMs); 10703 } 10704 } 10705 noteStopSyncLocked(String name, long elapsedRealtimeMs)10706 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 10707 DualTimer t = mSyncStats.stopObject(name, elapsedRealtimeMs); 10708 if (t != null) { 10709 t.stopRunningLocked(elapsedRealtimeMs); 10710 } 10711 } 10712 noteStartJobLocked(String name, long elapsedRealtimeMs)10713 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 10714 DualTimer t = mJobStats.startObject(name, elapsedRealtimeMs); 10715 if (t != null) { 10716 t.startRunningLocked(elapsedRealtimeMs); 10717 } 10718 } 10719 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)10720 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 10721 DualTimer t = mJobStats.stopObject(name, elapsedRealtimeMs); 10722 if (t != null) { 10723 t.stopRunningLocked(elapsedRealtimeMs); 10724 } 10725 if (mBsi.mOnBatteryTimeBase.isRunning()) { 10726 SparseIntArray types = mJobCompletions.get(name); 10727 if (types == null) { 10728 types = new SparseIntArray(); 10729 mJobCompletions.put(name, types); 10730 } 10731 int last = types.get(stopReason, 0); 10732 types.put(stopReason, last + 1); 10733 } 10734 } 10735 getWakelockTimerLocked(Wakelock wl, int type)10736 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 10737 if (wl == null) { 10738 return null; 10739 } 10740 switch (type) { 10741 case WAKE_TYPE_PARTIAL: { 10742 DualTimer t = wl.mTimerPartial; 10743 if (t == null) { 10744 t = new DualTimer(mBsi.mClock, this, WAKE_TYPE_PARTIAL, 10745 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 10746 mOnBatteryScreenOffBackgroundTimeBase); 10747 wl.mTimerPartial = t; 10748 } 10749 return t; 10750 } 10751 case WAKE_TYPE_FULL: { 10752 StopwatchTimer t = wl.mTimerFull; 10753 if (t == null) { 10754 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_FULL, 10755 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 10756 wl.mTimerFull = t; 10757 } 10758 return t; 10759 } 10760 case WAKE_TYPE_WINDOW: { 10761 StopwatchTimer t = wl.mTimerWindow; 10762 if (t == null) { 10763 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_WINDOW, 10764 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 10765 wl.mTimerWindow = t; 10766 } 10767 return t; 10768 } 10769 case WAKE_TYPE_DRAW: { 10770 StopwatchTimer t = wl.mTimerDraw; 10771 if (t == null) { 10772 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_DRAW, 10773 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 10774 wl.mTimerDraw = t; 10775 } 10776 return t; 10777 } 10778 default: 10779 throw new IllegalArgumentException("type=" + type); 10780 } 10781 } 10782 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)10783 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 10784 Wakelock wl = mWakelockStats.startObject(name, elapsedRealtimeMs); 10785 if (wl != null) { 10786 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 10787 } 10788 if (type == WAKE_TYPE_PARTIAL) { 10789 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 10790 if (pid >= 0) { 10791 Pid p = getPidStatsLocked(pid); 10792 if (p.mWakeNesting++ == 0) { 10793 p.mWakeStartMs = elapsedRealtimeMs; 10794 } 10795 } 10796 } 10797 } 10798 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)10799 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 10800 Wakelock wl = mWakelockStats.stopObject(name, elapsedRealtimeMs); 10801 if (wl != null) { 10802 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 10803 wlt.stopRunningLocked(elapsedRealtimeMs); 10804 } 10805 if (type == WAKE_TYPE_PARTIAL) { 10806 if (mAggregatedPartialWakelockTimer != null) { 10807 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 10808 } 10809 if (pid >= 0) { 10810 Pid p = mPids.get(pid); 10811 if (p != null && p.mWakeNesting > 0) { 10812 if (p.mWakeNesting-- == 1) { 10813 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 10814 p.mWakeStartMs = 0; 10815 } 10816 } 10817 } 10818 } 10819 } 10820 reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs)10821 public void reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs) { 10822 Proc p = getProcessStatsLocked(proc); 10823 if (p != null) { 10824 p.addExcessiveCpu(overTimeMs, usedTimeMs); 10825 } 10826 } 10827 noteStartSensor(int sensor, long elapsedRealtimeMs)10828 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 10829 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 10830 t.startRunningLocked(elapsedRealtimeMs); 10831 } 10832 noteStopSensor(int sensor, long elapsedRealtimeMs)10833 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 10834 // Don't create a timer if one doesn't already exist 10835 DualTimer t = getSensorTimerLocked(sensor, false); 10836 if (t != null) { 10837 t.stopRunningLocked(elapsedRealtimeMs); 10838 } 10839 } 10840 noteStartGps(long elapsedRealtimeMs)10841 public void noteStartGps(long elapsedRealtimeMs) { 10842 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 10843 } 10844 noteStopGps(long elapsedRealtimeMs)10845 public void noteStopGps(long elapsedRealtimeMs) { 10846 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 10847 } 10848 } 10849 10850 @GuardedBy("this") 10851 @Override getCpuFreqs()10852 public long[] getCpuFreqs() { 10853 if (!mCpuFreqsInitialized) { 10854 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 10855 mCpuFreqsInitialized = true; 10856 } 10857 return mCpuFreqs; 10858 } 10859 10860 @GuardedBy("this") 10861 @Override getCpuFreqCount()10862 public int getCpuFreqCount() { 10863 final long[] cpuFreqs = getCpuFreqs(); 10864 return cpuFreqs != null ? cpuFreqs.length : 0; 10865 } 10866 10867 @GuardedBy("this") getCpuTimeInFreqContainer()10868 private LongArrayMultiStateCounter.LongArrayContainer getCpuTimeInFreqContainer() { 10869 if (mTmpCpuTimeInFreq == null) { 10870 mTmpCpuTimeInFreq = 10871 new LongArrayMultiStateCounter.LongArrayContainer(getCpuFreqCount()); 10872 } 10873 return mTmpCpuTimeInFreq; 10874 } 10875 BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, EnergyStatsRetriever energyStatsCb, UserInfoProvider userInfoProvider)10876 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, 10877 EnergyStatsRetriever energyStatsCb, UserInfoProvider userInfoProvider) { 10878 this(Clock.SYSTEM_CLOCK, systemDir, handler, cb, energyStatsCb, userInfoProvider); 10879 } 10880 BatteryStatsImpl(Clock clock, File systemDir, Handler handler, PlatformIdleStateCallback cb, EnergyStatsRetriever energyStatsCb, UserInfoProvider userInfoProvider)10881 private BatteryStatsImpl(Clock clock, File systemDir, Handler handler, 10882 PlatformIdleStateCallback cb, EnergyStatsRetriever energyStatsCb, 10883 UserInfoProvider userInfoProvider) { 10884 init(clock); 10885 10886 mHandler = new MyHandler(handler.getLooper()); 10887 mConstants = new Constants(mHandler); 10888 10889 if (systemDir == null) { 10890 mStatsFile = null; 10891 mCheckinFile = null; 10892 mDailyFile = null; 10893 mHistory = new BatteryStatsHistory(mConstants.MAX_HISTORY_FILES, 10894 mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock); 10895 } else { 10896 mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); 10897 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 10898 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 10899 mHistory = new BatteryStatsHistory(systemDir, mConstants.MAX_HISTORY_FILES, 10900 mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock); 10901 } 10902 mStartCount++; 10903 initTimersAndCounters(); 10904 mOnBattery = mOnBatteryInternal = false; 10905 long uptimeUs = mClock.uptimeMillis() * 1000; 10906 long realtimeUs = mClock.elapsedRealtime() * 1000; 10907 initTimes(uptimeUs, realtimeUs); 10908 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 10909 initDischarge(realtimeUs); 10910 updateDailyDeadlineLocked(); 10911 mPlatformIdleStateCallback = cb; 10912 mEnergyConsumerRetriever = energyStatsCb; 10913 mUserInfoProvider = userInfoProvider; 10914 10915 // Notify statsd that the system is initially not in doze. 10916 mDeviceIdleMode = DEVICE_IDLE_MODE_OFF; 10917 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mDeviceIdleMode); 10918 } 10919 10920 @VisibleForTesting initTimersAndCounters()10921 protected void initTimersAndCounters() { 10922 mScreenOnTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase); 10923 mScreenDozeTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase); 10924 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10925 mScreenBrightnessTimer[i] = new StopwatchTimer(mClock, null, -100 - i, null, 10926 mOnBatteryTimeBase); 10927 } 10928 10929 mPerDisplayBatteryStats = new DisplayBatteryStats[1]; 10930 mPerDisplayBatteryStats[0] = new DisplayBatteryStats(mClock, mOnBatteryTimeBase); 10931 10932 mInteractiveTimer = new StopwatchTimer(mClock, null, -10, null, mOnBatteryTimeBase); 10933 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClock, null, -2, null, 10934 mOnBatteryTimeBase); 10935 mDeviceIdleModeLightTimer = new StopwatchTimer(mClock, null, -11, null, 10936 mOnBatteryTimeBase); 10937 mDeviceIdleModeFullTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase); 10938 mDeviceLightIdlingTimer = new StopwatchTimer(mClock, null, -15, null, mOnBatteryTimeBase); 10939 mDeviceIdlingTimer = new StopwatchTimer(mClock, null, -12, null, mOnBatteryTimeBase); 10940 mPhoneOnTimer = new StopwatchTimer(mClock, null, -3, null, mOnBatteryTimeBase); 10941 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 10942 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -200 - i, null, 10943 mOnBatteryTimeBase); 10944 } 10945 mPhoneSignalScanningTimer = new StopwatchTimer(mClock, null, -200 + 1, null, 10946 mOnBatteryTimeBase); 10947 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10948 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClock, null, -300 - i, null, 10949 mOnBatteryTimeBase); 10950 } 10951 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10952 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 10953 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 10954 } 10955 mWifiActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 10956 NUM_WIFI_TX_LEVELS); 10957 mBluetoothActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 10958 NUM_BT_TX_LEVELS); 10959 mModemActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 10960 ModemActivityInfo.getNumTxPowerLevels()); 10961 mMobileRadioActiveTimer = new StopwatchTimer(mClock, null, -400, null, mOnBatteryTimeBase); 10962 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClock, null, -401, null, 10963 mOnBatteryTimeBase); 10964 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 10965 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 10966 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 10967 mWifiMulticastWakelockTimer = new StopwatchTimer(mClock, null, 10968 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 10969 mWifiOnTimer = new StopwatchTimer(mClock, null, -4, null, mOnBatteryTimeBase); 10970 mGlobalWifiRunningTimer = new StopwatchTimer(mClock, null, -5, null, mOnBatteryTimeBase); 10971 for (int i=0; i<NUM_WIFI_STATES; i++) { 10972 mWifiStateTimer[i] = new StopwatchTimer(mClock, null, -600 - i, null, 10973 mOnBatteryTimeBase); 10974 } 10975 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10976 mWifiSupplStateTimer[i] = new StopwatchTimer(mClock, null, -700 - i, null, 10977 mOnBatteryTimeBase); 10978 } 10979 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10980 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -800 - i, null, 10981 mOnBatteryTimeBase); 10982 } 10983 mWifiActiveTimer = new StopwatchTimer(mClock, null, -900, null, mOnBatteryTimeBase); 10984 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 10985 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClock, null, -1000 - i, null, 10986 mOnBatteryTimeBase); 10987 } 10988 mAudioOnTimer = new StopwatchTimer(mClock, null, -7, null, mOnBatteryTimeBase); 10989 mVideoOnTimer = new StopwatchTimer(mClock, null, -8, null, mOnBatteryTimeBase); 10990 mFlashlightOnTimer = new StopwatchTimer(mClock, null, -9, null, mOnBatteryTimeBase); 10991 mCameraOnTimer = new StopwatchTimer(mClock, null, -13, null, mOnBatteryTimeBase); 10992 mBluetoothScanTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase); 10993 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 10994 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10995 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10996 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10997 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10998 mDischargeUnplugLevel = 0; 10999 mDischargePlugLevel = -1; 11000 mDischargeCurrentLevel = 0; 11001 mBatteryLevel = 0; 11002 } 11003 11004 /** 11005 * Injects a power profile. 11006 */ 11007 @GuardedBy("this") setPowerProfileLocked(PowerProfile profile)11008 public void setPowerProfileLocked(PowerProfile profile) { 11009 mPowerProfile = profile; 11010 11011 int totalSpeedStepCount = 0; 11012 11013 // We need to initialize the KernelCpuSpeedReaders to read from 11014 // the first cpu of each core. Once we have the PowerProfile, we have access to this 11015 // information. 11016 final int numClusters = mPowerProfile.getNumCpuClusters(); 11017 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 11018 int firstCpuOfCluster = 0; 11019 for (int i = 0; i < numClusters; i++) { 11020 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 11021 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 11022 numSpeedSteps); 11023 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 11024 totalSpeedStepCount += numSpeedSteps; 11025 } 11026 11027 // Initialize CPU power bracket map, which combines CPU states (cluster/freq pairs) 11028 // into a small number of brackets 11029 mCpuPowerBracketMap = new int[totalSpeedStepCount]; 11030 int index = 0; 11031 int numCpuClusters = mPowerProfile.getNumCpuClusters(); 11032 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 11033 int steps = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 11034 for (int step = 0; step < steps; step++) { 11035 mCpuPowerBracketMap[index++] = 11036 mPowerProfile.getPowerBracketForCpuCore(cluster, step); 11037 } 11038 } 11039 11040 int cpuPowerBracketCount = mPowerProfile.getCpuPowerBracketCount(); 11041 mCpuUsageDetails.cpuBracketDescriptions = new String[cpuPowerBracketCount]; 11042 mCpuUsageDetails.cpuUsageMs = new long[cpuPowerBracketCount]; 11043 for (int i = 0; i < cpuPowerBracketCount; i++) { 11044 mCpuUsageDetails.cpuBracketDescriptions[i] = 11045 mPowerProfile.getCpuPowerBracketDescription(i); 11046 } 11047 11048 if (mEstimatedBatteryCapacityMah == -1) { 11049 // Initialize the estimated battery capacity to a known preset one. 11050 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 11051 } 11052 11053 setDisplayCountLocked(mPowerProfile.getNumDisplays()); 11054 } 11055 getPowerProfile()11056 PowerProfile getPowerProfile() { 11057 return mPowerProfile; 11058 } 11059 11060 /** 11061 * Injects BatteryStatsConfig 11062 */ setBatteryStatsConfig(BatteryStatsConfig config)11063 public void setBatteryStatsConfig(BatteryStatsConfig config) { 11064 synchronized (this) { 11065 mBatteryStatsConfig = config; 11066 } 11067 } 11068 11069 /** 11070 * Starts tracking CPU time-in-state for threads of the system server process, 11071 * keeping a separate account of threads receiving incoming binder calls. 11072 */ startTrackingSystemServerCpuTime()11073 public void startTrackingSystemServerCpuTime() { 11074 mSystemServerCpuThreadReader.startTrackingThreadCpuTime(); 11075 } 11076 getSystemServiceCpuThreadTimes()11077 public SystemServiceCpuThreadTimes getSystemServiceCpuThreadTimes() { 11078 return mSystemServerCpuThreadReader.readAbsolute(); 11079 } 11080 setCallback(BatteryCallback cb)11081 public void setCallback(BatteryCallback cb) { 11082 mCallback = cb; 11083 } 11084 setRadioScanningTimeoutLocked(long timeoutUs)11085 public void setRadioScanningTimeoutLocked(long timeoutUs) { 11086 if (mPhoneSignalScanningTimer != null) { 11087 mPhoneSignalScanningTimer.setTimeout(timeoutUs); 11088 } 11089 } 11090 setExternalStatsSyncLocked(ExternalStatsSync sync)11091 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 11092 mExternalSync = sync; 11093 } 11094 11095 /** 11096 * Initialize and set multi display timers and states. 11097 */ setDisplayCountLocked(int numDisplays)11098 public void setDisplayCountLocked(int numDisplays) { 11099 mPerDisplayBatteryStats = new DisplayBatteryStats[numDisplays]; 11100 for (int i = 0; i < numDisplays; i++) { 11101 mPerDisplayBatteryStats[i] = new DisplayBatteryStats(mClock, mOnBatteryTimeBase); 11102 } 11103 } 11104 updateDailyDeadlineLocked()11105 public void updateDailyDeadlineLocked() { 11106 // Get the current time. 11107 long currentTimeMs = mDailyStartTimeMs = mClock.currentTimeMillis(); 11108 Calendar calDeadline = Calendar.getInstance(); 11109 calDeadline.setTimeInMillis(currentTimeMs); 11110 11111 // Move time up to the next day, ranging from 1am to 3pm. 11112 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 11113 calDeadline.set(Calendar.MILLISECOND, 0); 11114 calDeadline.set(Calendar.SECOND, 0); 11115 calDeadline.set(Calendar.MINUTE, 0); 11116 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 11117 mNextMinDailyDeadlineMs = calDeadline.getTimeInMillis(); 11118 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 11119 mNextMaxDailyDeadlineMs = calDeadline.getTimeInMillis(); 11120 } 11121 recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs)11122 public void recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs) { 11123 if (currentTimeMs >= mNextMaxDailyDeadlineMs) { 11124 recordDailyStatsLocked(); 11125 } else if (settled && currentTimeMs >= mNextMinDailyDeadlineMs) { 11126 recordDailyStatsLocked(); 11127 } else if (currentTimeMs < (mDailyStartTimeMs - (1000 * 60 * 60 * 24))) { 11128 recordDailyStatsLocked(); 11129 } 11130 } 11131 recordDailyStatsLocked()11132 public void recordDailyStatsLocked() { 11133 DailyItem item = new DailyItem(); 11134 item.mStartTime = mDailyStartTimeMs; 11135 item.mEndTime = mClock.currentTimeMillis(); 11136 boolean hasData = false; 11137 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 11138 hasData = true; 11139 item.mDischargeSteps = new LevelStepTracker( 11140 mDailyDischargeStepTracker.mNumStepDurations, 11141 mDailyDischargeStepTracker.mStepDurations); 11142 } 11143 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 11144 hasData = true; 11145 item.mChargeSteps = new LevelStepTracker( 11146 mDailyChargeStepTracker.mNumStepDurations, 11147 mDailyChargeStepTracker.mStepDurations); 11148 } 11149 if (mDailyPackageChanges != null) { 11150 hasData = true; 11151 item.mPackageChanges = mDailyPackageChanges; 11152 mDailyPackageChanges = null; 11153 } 11154 mDailyDischargeStepTracker.init(); 11155 mDailyChargeStepTracker.init(); 11156 updateDailyDeadlineLocked(); 11157 11158 if (hasData) { 11159 final long startTimeMs = SystemClock.uptimeMillis(); 11160 mDailyItems.add(item); 11161 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 11162 mDailyItems.remove(0); 11163 } 11164 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 11165 try { 11166 TypedXmlSerializer out = Xml.resolveSerializer(memStream); 11167 writeDailyItemsLocked(out); 11168 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 11169 BackgroundThread.getHandler().post(new Runnable() { 11170 @Override 11171 public void run() { 11172 synchronized (mCheckinFile) { 11173 final long startTimeMs2 = SystemClock.uptimeMillis(); 11174 FileOutputStream stream = null; 11175 try { 11176 stream = mDailyFile.startWrite(); 11177 memStream.writeTo(stream); 11178 stream.flush(); 11179 mDailyFile.finishWrite(stream); 11180 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 11181 "batterystats-daily", 11182 initialTimeMs + SystemClock.uptimeMillis() - startTimeMs2); 11183 } catch (IOException e) { 11184 Slog.w("BatteryStats", 11185 "Error writing battery daily items", e); 11186 mDailyFile.failWrite(stream); 11187 } 11188 } 11189 } 11190 }); 11191 } catch (IOException e) { 11192 } 11193 } 11194 } 11195 writeDailyItemsLocked(TypedXmlSerializer out)11196 private void writeDailyItemsLocked(TypedXmlSerializer out) throws IOException { 11197 StringBuilder sb = new StringBuilder(64); 11198 out.startDocument(null, true); 11199 out.startTag(null, "daily-items"); 11200 for (int i=0; i<mDailyItems.size(); i++) { 11201 final DailyItem dit = mDailyItems.get(i); 11202 out.startTag(null, "item"); 11203 out.attributeLong(null, "start", dit.mStartTime); 11204 out.attributeLong(null, "end", dit.mEndTime); 11205 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 11206 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 11207 if (dit.mPackageChanges != null) { 11208 for (int j=0; j<dit.mPackageChanges.size(); j++) { 11209 PackageChange pc = dit.mPackageChanges.get(j); 11210 if (pc.mUpdate) { 11211 out.startTag(null, "upd"); 11212 out.attribute(null, "pkg", pc.mPackageName); 11213 out.attributeLong(null, "ver", pc.mVersionCode); 11214 out.endTag(null, "upd"); 11215 } else { 11216 out.startTag(null, "rem"); 11217 out.attribute(null, "pkg", pc.mPackageName); 11218 out.endTag(null, "rem"); 11219 } 11220 } 11221 } 11222 out.endTag(null, "item"); 11223 } 11224 out.endTag(null, "daily-items"); 11225 out.endDocument(); 11226 } 11227 writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)11228 private void writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, 11229 StringBuilder tmpBuilder) throws IOException { 11230 if (steps != null) { 11231 out.startTag(null, tag); 11232 out.attributeInt(null, "n", steps.mNumStepDurations); 11233 for (int i=0; i<steps.mNumStepDurations; i++) { 11234 out.startTag(null, "s"); 11235 tmpBuilder.setLength(0); 11236 steps.encodeEntryAt(i, tmpBuilder); 11237 out.attribute(null, "v", tmpBuilder.toString()); 11238 out.endTag(null, "s"); 11239 } 11240 out.endTag(null, tag); 11241 } 11242 } 11243 11244 @GuardedBy("this") readDailyStatsLocked()11245 public void readDailyStatsLocked() { 11246 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 11247 mDailyItems.clear(); 11248 FileInputStream stream; 11249 try { 11250 stream = mDailyFile.openRead(); 11251 } catch (FileNotFoundException e) { 11252 return; 11253 } 11254 try { 11255 TypedXmlPullParser parser = Xml.resolvePullParser(stream); 11256 readDailyItemsLocked(parser); 11257 } catch (IOException e) { 11258 } finally { 11259 try { 11260 stream.close(); 11261 } catch (IOException e) { 11262 } 11263 } 11264 } 11265 readDailyItemsLocked(TypedXmlPullParser parser)11266 private void readDailyItemsLocked(TypedXmlPullParser parser) { 11267 try { 11268 int type; 11269 while ((type = parser.next()) != XmlPullParser.START_TAG 11270 && type != XmlPullParser.END_DOCUMENT) { 11271 ; 11272 } 11273 11274 if (type != XmlPullParser.START_TAG) { 11275 throw new IllegalStateException("no start tag found"); 11276 } 11277 11278 int outerDepth = parser.getDepth(); 11279 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11280 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11281 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11282 continue; 11283 } 11284 11285 String tagName = parser.getName(); 11286 if (tagName.equals("item")) { 11287 readDailyItemTagLocked(parser); 11288 } else { 11289 Slog.w(TAG, "Unknown element under <daily-items>: " 11290 + parser.getName()); 11291 XmlUtils.skipCurrentTag(parser); 11292 } 11293 } 11294 11295 } catch (IllegalStateException e) { 11296 Slog.w(TAG, "Failed parsing daily " + e); 11297 } catch (NullPointerException e) { 11298 Slog.w(TAG, "Failed parsing daily " + e); 11299 } catch (NumberFormatException e) { 11300 Slog.w(TAG, "Failed parsing daily " + e); 11301 } catch (XmlPullParserException e) { 11302 Slog.w(TAG, "Failed parsing daily " + e); 11303 } catch (IOException e) { 11304 Slog.w(TAG, "Failed parsing daily " + e); 11305 } catch (IndexOutOfBoundsException e) { 11306 Slog.w(TAG, "Failed parsing daily " + e); 11307 } 11308 } 11309 readDailyItemTagLocked(TypedXmlPullParser parser)11310 void readDailyItemTagLocked(TypedXmlPullParser parser) throws NumberFormatException, 11311 XmlPullParserException, IOException { 11312 DailyItem dit = new DailyItem(); 11313 dit.mStartTime = parser.getAttributeLong(null, "start", 0); 11314 dit.mEndTime = parser.getAttributeLong(null, "end", 0); 11315 int outerDepth = parser.getDepth(); 11316 int type; 11317 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11318 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11319 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11320 continue; 11321 } 11322 11323 String tagName = parser.getName(); 11324 if (tagName.equals("dis")) { 11325 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 11326 } else if (tagName.equals("chg")) { 11327 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 11328 } else if (tagName.equals("upd")) { 11329 if (dit.mPackageChanges == null) { 11330 dit.mPackageChanges = new ArrayList<>(); 11331 } 11332 PackageChange pc = new PackageChange(); 11333 pc.mUpdate = true; 11334 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11335 pc.mVersionCode = parser.getAttributeLong(null, "ver", 0); 11336 dit.mPackageChanges.add(pc); 11337 XmlUtils.skipCurrentTag(parser); 11338 } else if (tagName.equals("rem")) { 11339 if (dit.mPackageChanges == null) { 11340 dit.mPackageChanges = new ArrayList<>(); 11341 } 11342 PackageChange pc = new PackageChange(); 11343 pc.mUpdate = false; 11344 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11345 dit.mPackageChanges.add(pc); 11346 XmlUtils.skipCurrentTag(parser); 11347 } else { 11348 Slog.w(TAG, "Unknown element under <item>: " 11349 + parser.getName()); 11350 XmlUtils.skipCurrentTag(parser); 11351 } 11352 } 11353 mDailyItems.add(dit); 11354 } 11355 readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, String tag)11356 void readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, 11357 String tag) 11358 throws NumberFormatException, XmlPullParserException, IOException { 11359 final int num = parser.getAttributeInt(null, "n", -1); 11360 if (num == -1) { 11361 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 11362 XmlUtils.skipCurrentTag(parser); 11363 return; 11364 } 11365 LevelStepTracker steps = new LevelStepTracker(num); 11366 if (isCharge) { 11367 dit.mChargeSteps = steps; 11368 } else { 11369 dit.mDischargeSteps = steps; 11370 } 11371 int i = 0; 11372 int outerDepth = parser.getDepth(); 11373 int type; 11374 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11375 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11376 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11377 continue; 11378 } 11379 11380 String tagName = parser.getName(); 11381 if ("s".equals(tagName)) { 11382 if (i < num) { 11383 String valueAttr = parser.getAttributeValue(null, "v"); 11384 if (valueAttr != null) { 11385 steps.decodeEntryAt(i, valueAttr); 11386 i++; 11387 } 11388 } 11389 } else { 11390 Slog.w(TAG, "Unknown element under <" + tag + ">: " 11391 + parser.getName()); 11392 XmlUtils.skipCurrentTag(parser); 11393 } 11394 } 11395 steps.mNumStepDurations = i; 11396 } 11397 11398 @Override getDailyItemLocked(int daysAgo)11399 public DailyItem getDailyItemLocked(int daysAgo) { 11400 int index = mDailyItems.size()-1-daysAgo; 11401 return index >= 0 ? mDailyItems.get(index) : null; 11402 } 11403 11404 @Override getCurrentDailyStartTime()11405 public long getCurrentDailyStartTime() { 11406 return mDailyStartTimeMs; 11407 } 11408 11409 @Override getNextMinDailyDeadline()11410 public long getNextMinDailyDeadline() { 11411 return mNextMinDailyDeadlineMs; 11412 } 11413 11414 @Override getNextMaxDailyDeadline()11415 public long getNextMaxDailyDeadline() { 11416 return mNextMaxDailyDeadlineMs; 11417 } 11418 11419 @GuardedBy("this") getHistoryTotalSize()11420 public int getHistoryTotalSize() { 11421 return mConstants.MAX_HISTORY_BUFFER * mConstants.MAX_HISTORY_FILES; 11422 } 11423 getHistoryUsedSize()11424 public int getHistoryUsedSize() { 11425 return mHistory.getHistoryUsedSize(); 11426 } 11427 11428 /** 11429 * Creates an iterator for battery stats history. 11430 */ 11431 @Override iterateBatteryStatsHistory()11432 public BatteryStatsHistoryIterator iterateBatteryStatsHistory() { 11433 return mHistory.copy().iterate(); 11434 } 11435 11436 @Override getHistoryStringPoolSize()11437 public int getHistoryStringPoolSize() { 11438 return mHistory.getHistoryStringPoolSize(); 11439 } 11440 11441 @Override getHistoryStringPoolBytes()11442 public int getHistoryStringPoolBytes() { 11443 return mHistory.getHistoryStringPoolBytes(); 11444 } 11445 11446 @Override getHistoryTagPoolString(int index)11447 public String getHistoryTagPoolString(int index) { 11448 return mHistory.getHistoryTagPoolString(index); 11449 } 11450 11451 @Override getHistoryTagPoolUid(int index)11452 public int getHistoryTagPoolUid(int index) { 11453 return mHistory.getHistoryTagPoolUid(index); 11454 } 11455 11456 @Override getStartCount()11457 public int getStartCount() { 11458 return mStartCount; 11459 } 11460 isOnBattery()11461 public boolean isOnBattery() { 11462 return mOnBattery; 11463 } 11464 isCharging()11465 public boolean isCharging() { 11466 return mCharging; 11467 } 11468 initTimes(long uptimeUs, long realtimeUs)11469 void initTimes(long uptimeUs, long realtimeUs) { 11470 mStartClockTimeMs = mClock.currentTimeMillis(); 11471 mOnBatteryTimeBase.init(uptimeUs, realtimeUs); 11472 mOnBatteryScreenOffTimeBase.init(uptimeUs, realtimeUs); 11473 mRealtimeUs = 0; 11474 mUptimeUs = 0; 11475 mRealtimeStartUs = realtimeUs; 11476 mUptimeStartUs = uptimeUs; 11477 } 11478 initDischarge(long elapsedRealtimeUs)11479 void initDischarge(long elapsedRealtimeUs) { 11480 mLowDischargeAmountSinceCharge = 0; 11481 mHighDischargeAmountSinceCharge = 0; 11482 mDischargeAmountScreenOn = 0; 11483 mDischargeAmountScreenOnSinceCharge = 0; 11484 mDischargeAmountScreenOff = 0; 11485 mDischargeAmountScreenOffSinceCharge = 0; 11486 mDischargeAmountScreenDoze = 0; 11487 mDischargeAmountScreenDozeSinceCharge = 0; 11488 mDischargeStepTracker.init(); 11489 mChargeStepTracker.init(); 11490 mDischargeScreenOffCounter.reset(false, elapsedRealtimeUs); 11491 mDischargeScreenDozeCounter.reset(false, elapsedRealtimeUs); 11492 mDischargeLightDozeCounter.reset(false, elapsedRealtimeUs); 11493 mDischargeDeepDozeCounter.reset(false, elapsedRealtimeUs); 11494 mDischargeCounter.reset(false, elapsedRealtimeUs); 11495 } 11496 setBatteryResetListener(BatteryResetListener batteryResetListener)11497 public void setBatteryResetListener(BatteryResetListener batteryResetListener) { 11498 mBatteryResetListener = batteryResetListener; 11499 } 11500 11501 @GuardedBy("this") resetAllStatsAndHistoryLocked(int reason)11502 public void resetAllStatsAndHistoryLocked(int reason) { 11503 final long mSecUptime = mClock.uptimeMillis(); 11504 long uptimeUs = mSecUptime * 1000; 11505 long mSecRealtime = mClock.elapsedRealtime(); 11506 long realtimeUs = mSecRealtime * 1000; 11507 resetAllStatsLocked(mSecUptime, mSecRealtime, reason); 11508 pullPendingStateUpdatesLocked(); 11509 mHistory.writeHistoryItem(mSecRealtime, mSecUptime); 11510 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel = mBatteryLevel; 11511 mOnBatteryTimeBase.reset(uptimeUs, realtimeUs); 11512 mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs); 11513 if (!mBatteryPluggedIn) { 11514 if (Display.isOnState(mScreenState)) { 11515 mDischargeScreenOnUnplugLevel = mBatteryLevel; 11516 mDischargeScreenDozeUnplugLevel = 0; 11517 mDischargeScreenOffUnplugLevel = 0; 11518 } else if (Display.isDozeState(mScreenState)) { 11519 mDischargeScreenOnUnplugLevel = 0; 11520 mDischargeScreenDozeUnplugLevel = mBatteryLevel; 11521 mDischargeScreenOffUnplugLevel = 0; 11522 } else { 11523 mDischargeScreenOnUnplugLevel = 0; 11524 mDischargeScreenDozeUnplugLevel = 0; 11525 mDischargeScreenOffUnplugLevel = mBatteryLevel; 11526 } 11527 mDischargeAmountScreenOn = 0; 11528 mDischargeAmountScreenOff = 0; 11529 mDischargeAmountScreenDoze = 0; 11530 } 11531 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 11532 } 11533 11534 @GuardedBy("this") resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, int resetReason)11535 private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, 11536 int resetReason) { 11537 if (mBatteryResetListener != null) { 11538 mBatteryResetListener.prepareForBatteryStatsReset(resetReason); 11539 } 11540 11541 final long uptimeUs = uptimeMillis * 1000; 11542 final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000; 11543 mStartCount = 0; 11544 initTimes(uptimeUs, elapsedRealtimeUs); 11545 mScreenOnTimer.reset(false, elapsedRealtimeUs); 11546 mScreenDozeTimer.reset(false, elapsedRealtimeUs); 11547 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11548 mScreenBrightnessTimer[i].reset(false, elapsedRealtimeUs); 11549 } 11550 11551 final int numDisplays = mPerDisplayBatteryStats.length; 11552 for (int i = 0; i < numDisplays; i++) { 11553 mPerDisplayBatteryStats[i].reset(elapsedRealtimeUs); 11554 } 11555 11556 if (mPowerProfile != null) { 11557 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 11558 } else { 11559 mEstimatedBatteryCapacityMah = -1; 11560 } 11561 mLastLearnedBatteryCapacityUah = -1; 11562 mMinLearnedBatteryCapacityUah = -1; 11563 mMaxLearnedBatteryCapacityUah = -1; 11564 mInteractiveTimer.reset(false, elapsedRealtimeUs); 11565 mPowerSaveModeEnabledTimer.reset(false, elapsedRealtimeUs); 11566 mLastIdleTimeStartMs = elapsedRealtimeMillis; 11567 mLongestLightIdleTimeMs = 0; 11568 mLongestFullIdleTimeMs = 0; 11569 mDeviceIdleModeLightTimer.reset(false, elapsedRealtimeUs); 11570 mDeviceIdleModeFullTimer.reset(false, elapsedRealtimeUs); 11571 mDeviceLightIdlingTimer.reset(false, elapsedRealtimeUs); 11572 mDeviceIdlingTimer.reset(false, elapsedRealtimeUs); 11573 mPhoneOnTimer.reset(false, elapsedRealtimeUs); 11574 mAudioOnTimer.reset(false, elapsedRealtimeUs); 11575 mVideoOnTimer.reset(false, elapsedRealtimeUs); 11576 mFlashlightOnTimer.reset(false, elapsedRealtimeUs); 11577 mCameraOnTimer.reset(false, elapsedRealtimeUs); 11578 mBluetoothScanTimer.reset(false, elapsedRealtimeUs); 11579 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 11580 mPhoneSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 11581 } 11582 mPhoneSignalScanningTimer.reset(false, elapsedRealtimeUs); 11583 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11584 mPhoneDataConnectionsTimer[i].reset(false, elapsedRealtimeUs); 11585 } 11586 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11587 mNetworkByteActivityCounters[i].reset(false, elapsedRealtimeUs); 11588 mNetworkPacketActivityCounters[i].reset(false, elapsedRealtimeUs); 11589 } 11590 for (int i = 0; i < RADIO_ACCESS_TECHNOLOGY_COUNT; i++) { 11591 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[i]; 11592 if (stats == null) continue; 11593 stats.reset(elapsedRealtimeUs); 11594 } 11595 mMobileRadioActiveTimer.reset(false, elapsedRealtimeUs); 11596 mMobileRadioActivePerAppTimer.reset(false, elapsedRealtimeUs); 11597 mMobileRadioActiveAdjustedTime.reset(false, elapsedRealtimeUs); 11598 mMobileRadioActiveUnknownTime.reset(false, elapsedRealtimeUs); 11599 mMobileRadioActiveUnknownCount.reset(false, elapsedRealtimeUs); 11600 mWifiOnTimer.reset(false, elapsedRealtimeUs); 11601 mGlobalWifiRunningTimer.reset(false, elapsedRealtimeUs); 11602 for (int i=0; i<NUM_WIFI_STATES; i++) { 11603 mWifiStateTimer[i].reset(false, elapsedRealtimeUs); 11604 } 11605 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11606 mWifiSupplStateTimer[i].reset(false, elapsedRealtimeUs); 11607 } 11608 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11609 mWifiSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 11610 } 11611 mWifiMulticastWakelockTimer.reset(false, elapsedRealtimeUs); 11612 mWifiActiveTimer.reset(false, elapsedRealtimeUs); 11613 mWifiActivity.reset(false, elapsedRealtimeUs); 11614 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 11615 mGpsSignalQualityTimer[i].reset(false, elapsedRealtimeUs); 11616 } 11617 mBluetoothActivity.reset(false, elapsedRealtimeUs); 11618 mModemActivity.reset(false, elapsedRealtimeUs); 11619 mNumConnectivityChange = 0; 11620 11621 for (int i=0; i<mUidStats.size(); i++) { 11622 if (mUidStats.valueAt(i).reset(uptimeUs, elapsedRealtimeUs, resetReason)) { 11623 mUidStats.valueAt(i).detachFromTimeBase(); 11624 mUidStats.remove(mUidStats.keyAt(i)); 11625 i--; 11626 } 11627 } 11628 11629 if (mRpmStats.size() > 0) { 11630 for (SamplingTimer timer : mRpmStats.values()) { 11631 mOnBatteryTimeBase.remove(timer); 11632 } 11633 mRpmStats.clear(); 11634 } 11635 if (mScreenOffRpmStats.size() > 0) { 11636 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 11637 mOnBatteryScreenOffTimeBase.remove(timer); 11638 } 11639 mScreenOffRpmStats.clear(); 11640 } 11641 11642 if (mKernelWakelockStats.size() > 0) { 11643 for (SamplingTimer timer : mKernelWakelockStats.values()) { 11644 mOnBatteryScreenOffTimeBase.remove(timer); 11645 } 11646 mKernelWakelockStats.clear(); 11647 } 11648 11649 if (mKernelMemoryStats.size() > 0) { 11650 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 11651 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 11652 } 11653 mKernelMemoryStats.clear(); 11654 } 11655 11656 if (mWakeupReasonStats.size() > 0) { 11657 for (SamplingTimer timer : mWakeupReasonStats.values()) { 11658 mOnBatteryTimeBase.remove(timer); 11659 } 11660 mWakeupReasonStats.clear(); 11661 } 11662 11663 mTmpRailStats.reset(); 11664 11665 EnergyConsumerStats.resetIfNotNull(mGlobalEnergyConsumerStats); 11666 11667 resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs); 11668 11669 mNumAllUidCpuTimeReads = 0; 11670 mNumUidsRemoved = 0; 11671 11672 initDischarge(elapsedRealtimeUs); 11673 11674 mHistory.reset(); 11675 11676 // Store the empty state to disk to ensure consistency 11677 writeSyncLocked(); 11678 11679 // Flush external data, gathering snapshots, but don't process it since it is pre-reset data 11680 mIgnoreNextExternalStats = true; 11681 mExternalSync.scheduleSync("reset", ExternalStatsSync.UPDATE_ON_RESET); 11682 11683 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 11684 } 11685 11686 @GuardedBy("this") initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)11687 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 11688 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 11689 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 11690 // Not recording process starts/stops. 11691 continue; 11692 } 11693 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 11694 if (active == null) { 11695 continue; 11696 } 11697 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 11698 SparseIntArray uids = ent.getValue(); 11699 for (int j=0; j<uids.size(); j++) { 11700 mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 11701 uids.keyAt(j)); 11702 } 11703 } 11704 } 11705 } 11706 11707 @GuardedBy("this") updateDischargeScreenLevelsLocked(int oldState, int newState)11708 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 11709 updateOldDischargeScreenLevelLocked(oldState); 11710 updateNewDischargeScreenLevelLocked(newState); 11711 } 11712 11713 @GuardedBy("this") updateOldDischargeScreenLevelLocked(int state)11714 private void updateOldDischargeScreenLevelLocked(int state) { 11715 if (Display.isOnState(state)) { 11716 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 11717 if (diff > 0) { 11718 mDischargeAmountScreenOn += diff; 11719 mDischargeAmountScreenOnSinceCharge += diff; 11720 } 11721 } else if (Display.isDozeState(state)) { 11722 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 11723 if (diff > 0) { 11724 mDischargeAmountScreenDoze += diff; 11725 mDischargeAmountScreenDozeSinceCharge += diff; 11726 } 11727 } else if (Display.isOffState(state)) { 11728 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 11729 if (diff > 0) { 11730 mDischargeAmountScreenOff += diff; 11731 mDischargeAmountScreenOffSinceCharge += diff; 11732 } 11733 } 11734 } 11735 11736 @GuardedBy("this") updateNewDischargeScreenLevelLocked(int state)11737 private void updateNewDischargeScreenLevelLocked(int state) { 11738 if (Display.isOnState(state)) { 11739 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 11740 mDischargeScreenOffUnplugLevel = 0; 11741 mDischargeScreenDozeUnplugLevel = 0; 11742 } else if (Display.isDozeState(state)) { 11743 mDischargeScreenOnUnplugLevel = 0; 11744 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 11745 mDischargeScreenOffUnplugLevel = 0; 11746 } else if (Display.isOffState(state)) { 11747 mDischargeScreenOnUnplugLevel = 0; 11748 mDischargeScreenDozeUnplugLevel = 0; 11749 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 11750 } 11751 } 11752 11753 @GuardedBy("this") pullPendingStateUpdatesLocked()11754 public void pullPendingStateUpdatesLocked() { 11755 if (mOnBatteryInternal) { 11756 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 11757 } 11758 } 11759 11760 private final Object mWifiNetworkLock = new Object(); 11761 11762 @GuardedBy("mWifiNetworkLock") 11763 private String[] mWifiIfaces = EmptyArray.STRING; 11764 11765 @GuardedBy("mWifiNetworkLock") 11766 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1); 11767 11768 private final Object mModemNetworkLock = new Object(); 11769 11770 @GuardedBy("mModemNetworkLock") 11771 private String[] mModemIfaces = EmptyArray.STRING; 11772 11773 @GuardedBy("mModemNetworkLock") 11774 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1); 11775 11776 @VisibleForTesting readMobileNetworkStatsLocked( @onNull NetworkStatsManager networkStatsManager)11777 protected NetworkStats readMobileNetworkStatsLocked( 11778 @NonNull NetworkStatsManager networkStatsManager) { 11779 return networkStatsManager.getMobileUidStats(); 11780 } 11781 11782 @VisibleForTesting readWifiNetworkStatsLocked( @onNull NetworkStatsManager networkStatsManager)11783 protected NetworkStats readWifiNetworkStatsLocked( 11784 @NonNull NetworkStatsManager networkStatsManager) { 11785 return networkStatsManager.getWifiUidStats(); 11786 } 11787 11788 /** 11789 * Distribute WiFi energy info and network traffic to apps. 11790 * @param info The energy information from the WiFi controller. 11791 */ 11792 @GuardedBy("this") updateWifiState(@ullable final WifiActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, @NonNull NetworkStatsManager networkStatsManager)11793 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info, 11794 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, 11795 @NonNull NetworkStatsManager networkStatsManager) { 11796 if (DEBUG_ENERGY) { 11797 synchronized (mWifiNetworkLock) { 11798 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 11799 } 11800 } 11801 11802 // Grab a separate lock to acquire the network stats, which may do I/O. 11803 NetworkStats delta = null; 11804 synchronized (mWifiNetworkLock) { 11805 final NetworkStats latestStats = readWifiNetworkStatsLocked(networkStatsManager); 11806 if (latestStats != null) { 11807 delta = latestStats.subtract(mLastWifiNetworkStats); 11808 mLastWifiNetworkStats = latestStats; 11809 } 11810 } 11811 11812 synchronized (this) { 11813 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 11814 if (mIgnoreNextExternalStats) { 11815 // TODO: Strictly speaking, we should re-mark all 5 timers for each uid (and the 11816 // global one) here like we do for display. But I'm not sure it's worth the 11817 // complicated code for a codepath that shouldn't ever actually happen in real 11818 // life. 11819 } 11820 return; 11821 } 11822 11823 final SparseDoubleArray uidEstimatedConsumptionMah = 11824 (mGlobalEnergyConsumerStats != null 11825 && mWifiPowerCalculator != null && consumedChargeUC > 0) ? 11826 new SparseDoubleArray() : null; 11827 double totalEstimatedConsumptionMah = 0; 11828 11829 SparseLongArray rxPackets = new SparseLongArray(); 11830 SparseLongArray txPackets = new SparseLongArray(); 11831 SparseLongArray rxTimesMs = new SparseLongArray(); 11832 SparseLongArray txTimesMs = new SparseLongArray(); 11833 long totalTxPackets = 0; 11834 long totalRxPackets = 0; 11835 if (delta != null) { 11836 for (NetworkStats.Entry entry : delta) { 11837 if (DEBUG_ENERGY) { 11838 Slog.d(TAG, "Wifi uid " + entry.getUid() 11839 + ": delta rx=" + entry.getRxBytes() 11840 + " tx=" + entry.getTxBytes() 11841 + " rxPackets=" + entry.getRxPackets() 11842 + " txPackets=" + entry.getTxPackets()); 11843 } 11844 11845 if (entry.getRxBytes() == 0 && entry.getTxBytes() == 0) { 11846 // Skip the lookup below since there is no work to do. 11847 continue; 11848 } 11849 11850 final int uid = mapUid(entry.getUid()); 11851 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 11852 if (entry.getRxBytes() != 0) { 11853 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.getRxBytes(), 11854 entry.getRxPackets()); 11855 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 11856 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.getRxBytes(), 11857 entry.getRxPackets()); 11858 } 11859 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 11860 entry.getRxBytes()); 11861 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 11862 entry.getRxPackets()); 11863 11864 rxPackets.incrementValue(uid, entry.getRxPackets()); 11865 11866 // Sum the total number of packets so that the Rx Power can 11867 // be evenly distributed amongst the apps. 11868 totalRxPackets += entry.getRxPackets(); 11869 } 11870 11871 if (entry.getTxBytes() != 0) { 11872 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.getTxBytes(), 11873 entry.getTxPackets()); 11874 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 11875 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.getTxBytes(), 11876 entry.getTxPackets()); 11877 } 11878 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 11879 entry.getTxBytes()); 11880 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 11881 entry.getTxPackets()); 11882 11883 txPackets.incrementValue(uid, entry.getTxPackets()); 11884 11885 // Sum the total number of packets so that the Tx Power can 11886 // be evenly distributed amongst the apps. 11887 totalTxPackets += entry.getTxPackets(); 11888 } 11889 11890 // Calculate consumed energy for this uid. Only do so if WifiReporting isn't 11891 // enabled (if it is, we'll do it later instead using info). 11892 if (uidEstimatedConsumptionMah != null && info == null && !mHasWifiReporting) { 11893 final long uidRunningMs = u.mWifiRunningTimer 11894 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 11895 if (uidRunningMs > 0) u.mWifiRunningTimer.setMark(elapsedRealtimeMs); 11896 11897 final long uidScanMs = u.mWifiScanTimer 11898 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 11899 if (uidScanMs > 0) u.mWifiScanTimer.setMark(elapsedRealtimeMs); 11900 11901 long uidBatchScanMs = 0; 11902 for (int bn = 0; bn < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bn++) { 11903 if (u.mWifiBatchedScanTimer[bn] != null) { 11904 long bnMs = u.mWifiBatchedScanTimer[bn] 11905 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 11906 if (bnMs > 0) { 11907 u.mWifiBatchedScanTimer[bn].setMark(elapsedRealtimeMs); 11908 } 11909 uidBatchScanMs += bnMs; 11910 } 11911 } 11912 11913 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 11914 mWifiPowerCalculator.calcPowerWithoutControllerDataMah( 11915 entry.getRxPackets(), entry.getTxPackets(), 11916 uidRunningMs, uidScanMs, uidBatchScanMs)); 11917 } 11918 } 11919 delta = null; 11920 } 11921 11922 if (info != null) { 11923 mHasWifiReporting = true; 11924 11925 // Measured in mAms 11926 final long txTimeMs = info.getControllerTxDurationMillis(); 11927 final long rxTimeMs = info.getControllerRxDurationMillis(); 11928 final long scanTimeMs = info.getControllerScanDurationMillis(); 11929 final long idleTimeMs = info.getControllerIdleDurationMillis(); 11930 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 11931 11932 long leftOverRxTimeMs = rxTimeMs; 11933 long leftOverTxTimeMs = txTimeMs; 11934 11935 if (DEBUG_ENERGY) { 11936 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 11937 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 11938 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 11939 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 11940 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 11941 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 11942 } 11943 11944 long totalWifiLockTimeMs = 0; 11945 long totalScanTimeMs = 0; 11946 11947 // On the first pass, collect some totals so that we can normalize power 11948 // calculations if we need to. 11949 final int uidStatsSize = mUidStats.size(); 11950 for (int i = 0; i < uidStatsSize; i++) { 11951 final Uid uid = mUidStats.valueAt(i); 11952 11953 // Sum the total scan power for all apps. 11954 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 11955 elapsedRealtimeMs * 1000) / 1000; 11956 11957 // Sum the total time holding wifi lock for all apps. 11958 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 11959 elapsedRealtimeMs * 1000) / 1000; 11960 } 11961 11962 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 11963 Slog.d(TAG, 11964 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 11965 + rxTimeMs + " ms). Normalizing scan time."); 11966 } 11967 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 11968 Slog.d(TAG, 11969 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 11970 + txTimeMs + " ms). Normalizing scan time."); 11971 } 11972 11973 // Actually assign and distribute power usage to apps. 11974 for (int i = 0; i < uidStatsSize; i++) { 11975 final Uid uid = mUidStats.valueAt(i); 11976 11977 final long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 11978 elapsedRealtimeMs * 1000) / 1000; 11979 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 11980 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 11981 if (scanTimeSinceMarkMs > 0) { 11982 // Set the new mark so that next time we get new data since this point. 11983 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 11984 11985 // Our total scan time is more than the reported Tx/Rx time. 11986 // This is possible because the cost of a scan is approximate. 11987 // Let's normalize the result so that we evenly blame each app 11988 // scanning. 11989 // 11990 // This means that we may have apps that transmitted/received packets not be 11991 // blamed for this, but this is fine as scans are relatively more expensive. 11992 if (totalScanTimeMs > rxTimeMs) { 11993 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 11994 totalScanTimeMs; 11995 } 11996 if (totalScanTimeMs > txTimeMs) { 11997 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 11998 totalScanTimeMs; 11999 } 12000 12001 if (DEBUG_ENERGY) { 12002 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 12003 + scanRxTimeSinceMarkMs + " ms Tx:" 12004 + scanTxTimeSinceMarkMs + " ms)"); 12005 } 12006 12007 rxTimesMs.incrementValue(uid.getUid(), scanRxTimeSinceMarkMs); 12008 txTimesMs.incrementValue(uid.getUid(), scanTxTimeSinceMarkMs); 12009 12010 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 12011 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 12012 } 12013 12014 // Distribute evenly the power consumed while Idle to each app holding a WiFi 12015 // lock. 12016 long myIdleTimeMs = 0; 12017 final long wifiLockTimeSinceMarkMs = 12018 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 12019 elapsedRealtimeMs * 1000) / 1000; 12020 if (wifiLockTimeSinceMarkMs > 0) { 12021 // Set the new mark so that next time we get new data since this point. 12022 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 12023 12024 myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) / totalWifiLockTimeMs; 12025 if (DEBUG_ENERGY) { 12026 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 12027 + myIdleTimeMs + " ms"); 12028 } 12029 uid.getOrCreateWifiControllerActivityLocked().getOrCreateIdleTimeCounter() 12030 .increment(myIdleTimeMs, elapsedRealtimeMs); 12031 } 12032 12033 if (uidEstimatedConsumptionMah != null) { 12034 double uidEstMah = mWifiPowerCalculator.calcPowerFromControllerDataMah( 12035 scanRxTimeSinceMarkMs, scanTxTimeSinceMarkMs, myIdleTimeMs); 12036 uidEstimatedConsumptionMah.incrementValue(uid.getUid(), uidEstMah); 12037 } 12038 } 12039 12040 if (DEBUG_ENERGY) { 12041 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 12042 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 12043 } 12044 12045 // Distribute the remaining Tx power appropriately between all apps that transmitted 12046 // packets. 12047 for (int i = 0; i < txPackets.size(); i++) { 12048 final int uid = txPackets.keyAt(i); 12049 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 12050 / totalTxPackets; 12051 txTimesMs.incrementValue(uid, myTxTimeMs); 12052 } 12053 12054 // Distribute the remaining Rx power appropriately between all apps that received 12055 // packets. 12056 for (int i = 0; i < rxPackets.size(); i++) { 12057 final int uid = rxPackets.keyAt(i); 12058 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 12059 / totalRxPackets; 12060 rxTimesMs.incrementValue(uid, myRxTimeMs); 12061 } 12062 12063 for (int i = 0; i < txTimesMs.size(); i++) { 12064 final int uid = txTimesMs.keyAt(i); 12065 final long myTxTimeMs = txTimesMs.valueAt(i); 12066 if (DEBUG_ENERGY) { 12067 Slog.d(TAG, " TxTime for UID " + uid + ": " + myTxTimeMs + " ms"); 12068 } 12069 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 12070 .getOrCreateWifiControllerActivityLocked() 12071 .getOrCreateTxTimeCounters()[0] 12072 .increment(myTxTimeMs, elapsedRealtimeMs); 12073 if (uidEstimatedConsumptionMah != null) { 12074 uidEstimatedConsumptionMah.incrementValue(uid, 12075 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12076 0, myTxTimeMs, 0)); 12077 } 12078 } 12079 12080 for (int i = 0; i < rxTimesMs.size(); i++) { 12081 final int uid = rxTimesMs.keyAt(i); 12082 final long myRxTimeMs = rxTimesMs.valueAt(i); 12083 if (DEBUG_ENERGY) { 12084 Slog.d(TAG, " RxTime for UID " + uid + ": " + myRxTimeMs + " ms"); 12085 } 12086 12087 getUidStatsLocked(rxTimesMs.keyAt(i), elapsedRealtimeMs, uptimeMs) 12088 .getOrCreateWifiControllerActivityLocked() 12089 .getOrCreateRxTimeCounter() 12090 .increment(myRxTimeMs, elapsedRealtimeMs); 12091 if (uidEstimatedConsumptionMah != null) { 12092 uidEstimatedConsumptionMah.incrementValue(uid, 12093 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12094 myRxTimeMs, 0, 0)); 12095 } 12096 } 12097 12098 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 12099 12100 // Update WiFi controller stats. 12101 mWifiActivity.getOrCreateRxTimeCounter().increment( 12102 info.getControllerRxDurationMillis(), elapsedRealtimeMs); 12103 mWifiActivity.getOrCreateTxTimeCounters()[0].increment( 12104 info.getControllerTxDurationMillis(), elapsedRealtimeMs); 12105 mWifiActivity.getScanTimeCounter().addCountLocked( 12106 info.getControllerScanDurationMillis()); 12107 mWifiActivity.getOrCreateIdleTimeCounter().increment( 12108 info.getControllerIdleDurationMillis(), elapsedRealtimeMs); 12109 12110 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12111 final double opVolt = mPowerProfile.getAveragePower( 12112 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12113 double controllerMaMs = 0; 12114 if (opVolt != 0) { 12115 // We store the power drain as mAms. 12116 controllerMaMs = info.getControllerEnergyUsedMicroJoules() / opVolt; 12117 mWifiActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 12118 } 12119 // Converting uWs to mAms. 12120 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 12121 long monitoredRailChargeConsumedMaMs = 12122 (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt); 12123 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 12124 monitoredRailChargeConsumedMaMs); 12125 mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs, 12126 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR)); 12127 mTmpRailStats.resetWifiTotalEnergyUsed(); 12128 12129 if (uidEstimatedConsumptionMah != null) { 12130 totalEstimatedConsumptionMah = Math.max(controllerMaMs / MILLISECONDS_IN_HOUR, 12131 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12132 rxTimeMs, txTimeMs, idleTimeMs)); 12133 } 12134 } 12135 12136 // Update the EnergyConsumerStats information. 12137 if (uidEstimatedConsumptionMah != null) { 12138 mGlobalEnergyConsumerStats.updateStandardBucket( 12139 EnergyConsumerStats.POWER_BUCKET_WIFI, consumedChargeUC); 12140 12141 // Now calculate the consumption for each uid, according to its proportional usage. 12142 if (!mHasWifiReporting) { 12143 final long globalTimeMs = mGlobalWifiRunningTimer 12144 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12145 mGlobalWifiRunningTimer.setMark(elapsedRealtimeMs); 12146 totalEstimatedConsumptionMah = mWifiPowerCalculator 12147 .calcGlobalPowerWithoutControllerDataMah(globalTimeMs); 12148 } 12149 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_WIFI, 12150 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedConsumptionMah, 12151 elapsedRealtimeMs); 12152 } 12153 } 12154 } 12155 12156 private ModemActivityInfo mLastModemActivityInfo = null; 12157 12158 /** 12159 * Distribute Cell radio energy info and network traffic to apps. 12160 */ noteModemControllerActivity(@ullable final ModemActivityInfo activityInfo, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, @NonNull NetworkStatsManager networkStatsManager)12161 public void noteModemControllerActivity(@Nullable final ModemActivityInfo activityInfo, 12162 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, 12163 @NonNull NetworkStatsManager networkStatsManager) { 12164 if (DEBUG_ENERGY) { 12165 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 12166 } 12167 ModemActivityInfo deltaInfo = mLastModemActivityInfo == null 12168 ? (activityInfo == null ? null : activityInfo.getDelta(activityInfo)) 12169 : mLastModemActivityInfo.getDelta(activityInfo); 12170 mLastModemActivityInfo = activityInfo; 12171 12172 // Add modem tx power to history. 12173 addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs); 12174 12175 // Grab a separate lock to acquire the network stats, which may do I/O. 12176 NetworkStats delta = null; 12177 synchronized (mModemNetworkLock) { 12178 final NetworkStats latestStats = readMobileNetworkStatsLocked(networkStatsManager); 12179 if (latestStats != null) { 12180 delta = latestStats.subtract(mLastModemNetworkStats); 12181 mLastModemNetworkStats = latestStats; 12182 } 12183 } 12184 12185 synchronized (this) { 12186 final long totalRadioDurationMs = 12187 mMobileRadioActiveTimer.getTimeSinceMarkLocked( 12188 elapsedRealtimeMs * 1000) / 1000; 12189 mMobileRadioActiveTimer.setMark(elapsedRealtimeMs); 12190 final long phoneOnDurationMs = Math.min(totalRadioDurationMs, 12191 mPhoneOnTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000); 12192 mPhoneOnTimer.setMark(elapsedRealtimeMs); 12193 12194 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12195 return; 12196 } 12197 12198 final SparseDoubleArray uidEstimatedConsumptionMah; 12199 final long dataConsumedChargeUC; 12200 if (consumedChargeUC > 0 && isMobileRadioEnergyConsumerSupportedLocked()) { 12201 final long phoneConsumedChargeUC; 12202 if (totalRadioDurationMs == 0) { 12203 phoneConsumedChargeUC = 0; 12204 } else { 12205 // Crudely attribute power consumption. Added (totalRadioDurationMs / 2) to the 12206 // numerator for long rounding. 12207 phoneConsumedChargeUC = 12208 (consumedChargeUC * phoneOnDurationMs + totalRadioDurationMs / 2) 12209 / totalRadioDurationMs; 12210 } 12211 dataConsumedChargeUC = consumedChargeUC - phoneConsumedChargeUC; 12212 12213 mGlobalEnergyConsumerStats.updateStandardBucket( 12214 EnergyConsumerStats.POWER_BUCKET_PHONE, phoneConsumedChargeUC); 12215 mGlobalEnergyConsumerStats.updateStandardBucket( 12216 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, dataConsumedChargeUC); 12217 uidEstimatedConsumptionMah = new SparseDoubleArray(); 12218 } else { 12219 uidEstimatedConsumptionMah = null; 12220 dataConsumedChargeUC = POWER_DATA_UNAVAILABLE; 12221 } 12222 12223 RxTxConsumption rxTxConsumption = null; 12224 boolean attributeWithModemActivityInfo = false; 12225 if (deltaInfo != null) { 12226 mHasModemReporting = true; 12227 mModemActivity.getOrCreateIdleTimeCounter() 12228 .increment(deltaInfo.getIdleTimeMillis(), elapsedRealtimeMs); 12229 mModemActivity.getSleepTimeCounter().addCountLocked( 12230 deltaInfo.getSleepTimeMillis()); 12231 mModemActivity.getOrCreateRxTimeCounter() 12232 .increment(deltaInfo.getReceiveTimeMillis(), elapsedRealtimeMs); 12233 for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); lvl++) { 12234 mModemActivity.getOrCreateTxTimeCounters()[lvl] 12235 .increment(deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl), 12236 elapsedRealtimeMs); 12237 } 12238 12239 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12240 final double opVolt = mPowerProfile.getAveragePower( 12241 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12242 if (opVolt != 0) { 12243 double energyUsed = 12244 deltaInfo.getSleepTimeMillis() * 12245 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 12246 + deltaInfo.getIdleTimeMillis() * 12247 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 12248 + deltaInfo.getReceiveTimeMillis() * 12249 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 12250 for (int i = 0; i < Math.min(ModemActivityInfo.getNumTxPowerLevels(), 12251 CellSignalStrength.getNumSignalStrengthLevels()); i++) { 12252 energyUsed += deltaInfo.getTransmitDurationMillisAtPowerLevel(i) 12253 * mPowerProfile.getAveragePower( 12254 PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 12255 } 12256 12257 // We store the power drain as mAms. 12258 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 12259 // Converting uWs to mAms. 12260 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 12261 long monitoredRailChargeConsumedMaMs = 12262 (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt); 12263 mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 12264 monitoredRailChargeConsumedMaMs); 12265 mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs, 12266 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR)); 12267 mTmpRailStats.resetCellularTotalEnergyUsed(); 12268 } 12269 12270 rxTxConsumption = incrementPerRatDataLocked(deltaInfo, elapsedRealtimeMs); 12271 12272 attributeWithModemActivityInfo = mConstants.PER_UID_MODEM_MODEL 12273 == PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX 12274 && rxTxConsumption != null; 12275 } 12276 long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 12277 elapsedRealtimeMs * 1000); 12278 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 12279 12280 long totalRxPackets = 0; 12281 long totalTxPackets = 0; 12282 if (delta != null) { 12283 for (NetworkStats.Entry entry : delta) { 12284 if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { 12285 continue; 12286 } 12287 12288 if (DEBUG_ENERGY) { 12289 Slog.d(TAG, "Mobile uid " + entry.getUid() + ": delta rx=" 12290 + entry.getRxBytes() + " tx=" + entry.getTxBytes() 12291 + " rxPackets=" + entry.getRxPackets() 12292 + " txPackets=" + entry.getTxPackets()); 12293 } 12294 12295 totalRxPackets += entry.getRxPackets(); 12296 totalTxPackets += entry.getTxPackets(); 12297 12298 final Uid u = getUidStatsLocked( 12299 mapUid(entry.getUid()), elapsedRealtimeMs, uptimeMs); 12300 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.getRxBytes(), 12301 entry.getRxPackets()); 12302 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.getTxBytes(), 12303 entry.getTxPackets()); 12304 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 12305 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 12306 entry.getRxBytes(), entry.getRxPackets()); 12307 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 12308 entry.getTxBytes(), entry.getTxPackets()); 12309 } 12310 12311 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 12312 entry.getRxBytes()); 12313 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12314 entry.getTxBytes()); 12315 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 12316 entry.getRxPackets()); 12317 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12318 entry.getTxPackets()); 12319 } 12320 12321 // Now distribute proportional blame to the apps that did networking. 12322 long totalPackets = totalRxPackets + totalTxPackets; 12323 if (totalPackets > 0) { 12324 for (NetworkStats.Entry entry : delta) { 12325 if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { 12326 continue; 12327 } 12328 12329 final Uid u = getUidStatsLocked(mapUid(entry.getUid()), 12330 elapsedRealtimeMs, uptimeMs); 12331 12332 // Distribute total radio active time in to this app. 12333 final long appPackets = entry.getRxPackets() + entry.getTxPackets(); 12334 final long appRadioTimeUs = 12335 (totalAppRadioTimeUs * appPackets) / totalPackets; 12336 u.noteMobileRadioActiveTimeLocked(appRadioTimeUs, elapsedRealtimeMs); 12337 12338 if (uidEstimatedConsumptionMah != null) { 12339 final double uidConsumptionMah; 12340 if (attributeWithModemActivityInfo) { 12341 // Distribute measured mobile radio charge consumption based on 12342 // rx/tx packets and estimated rx/tx charge consumption. 12343 uidConsumptionMah = smearModemActivityInfoRxTxConsumptionMah( 12344 rxTxConsumption, entry.getRxPackets(), entry.getTxPackets(), 12345 totalRxPackets, totalTxPackets); 12346 } else { 12347 // Distribute mobile radio charge consumption based on app radio 12348 // active time 12349 uidConsumptionMah = 12350 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12351 appRadioTimeUs / 1000); 12352 } 12353 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 12354 uidConsumptionMah); 12355 } 12356 12357 // Remove this app from the totals, so that we don't lose any time 12358 // due to rounding. 12359 totalAppRadioTimeUs -= appRadioTimeUs; 12360 totalPackets -= appPackets; 12361 12362 if (deltaInfo != null) { 12363 ControllerActivityCounterImpl activityCounter = 12364 u.getOrCreateModemControllerActivityLocked(); 12365 if (totalRxPackets > 0 && entry.getRxPackets() > 0) { 12366 final long rxMs = (entry.getRxPackets() 12367 * deltaInfo.getReceiveTimeMillis()) / totalRxPackets; 12368 activityCounter.getOrCreateRxTimeCounter() 12369 .increment(rxMs, elapsedRealtimeMs); 12370 } 12371 12372 if (totalTxPackets > 0 && entry.getTxPackets() > 0) { 12373 for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); 12374 lvl++) { 12375 long txMs = entry.getTxPackets() 12376 * deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl); 12377 txMs /= totalTxPackets; 12378 activityCounter.getOrCreateTxTimeCounters()[lvl] 12379 .increment(txMs, elapsedRealtimeMs); 12380 } 12381 } 12382 } 12383 } 12384 } 12385 12386 if (totalAppRadioTimeUs > 0) { 12387 // Whoops, there is some radio time we can't blame on an app! 12388 mMobileRadioActiveUnknownTime.addCountLocked(totalAppRadioTimeUs); 12389 mMobileRadioActiveUnknownCount.addCountLocked(1); 12390 } 12391 12392 // Update the EnergyConsumerStats information. 12393 if (uidEstimatedConsumptionMah != null) { 12394 double totalEstimatedConsumptionMah = 0.0; 12395 if (attributeWithModemActivityInfo) { 12396 // Estimate inactive modem power consumption and combine with previously 12397 // estimated active power consumption for an estimate of total modem 12398 // power consumption. 12399 final long sleepTimeMs = deltaInfo.getSleepTimeMillis(); 12400 final long idleTimeMs = deltaInfo.getIdleTimeMillis(); 12401 final double inactiveConsumptionMah = 12402 mMobileRadioPowerCalculator.calcInactiveStatePowerMah(sleepTimeMs, 12403 idleTimeMs); 12404 totalEstimatedConsumptionMah += inactiveConsumptionMah; 12405 totalEstimatedConsumptionMah += rxTxConsumption.rxConsumptionMah; 12406 totalEstimatedConsumptionMah += rxTxConsumption.txConsumptionMah; 12407 } else { 12408 // Estimate total active radio power consumption since last mark. 12409 totalEstimatedConsumptionMah += 12410 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12411 totalRadioDurationMs); 12412 12413 // Estimate idle power consumption at each signal strength level 12414 final int numSignalStrengthLevels = mPhoneSignalStrengthsTimer.length; 12415 for (int lvl = 0; lvl < numSignalStrengthLevels; lvl++) { 12416 final long strengthLevelDurationMs = 12417 mPhoneSignalStrengthsTimer[lvl].getTimeSinceMarkLocked( 12418 elapsedRealtimeMs * 1000) / 1000; 12419 mPhoneSignalStrengthsTimer[lvl].setMark(elapsedRealtimeMs); 12420 12421 totalEstimatedConsumptionMah += 12422 mMobileRadioPowerCalculator.calcIdlePowerAtSignalStrengthMah( 12423 strengthLevelDurationMs, lvl); 12424 } 12425 12426 // Estimate total active radio power consumption since last mark. 12427 final long scanTimeMs = mPhoneSignalScanningTimer.getTimeSinceMarkLocked( 12428 elapsedRealtimeMs * 1000) / 1000; 12429 mPhoneSignalScanningTimer.setMark(elapsedRealtimeMs); 12430 totalEstimatedConsumptionMah += 12431 mMobileRadioPowerCalculator.calcScanTimePowerMah(scanTimeMs); 12432 } 12433 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO, 12434 dataConsumedChargeUC, uidEstimatedConsumptionMah, 12435 totalEstimatedConsumptionMah, elapsedRealtimeMs); 12436 } 12437 } 12438 } 12439 } 12440 12441 private static class RxTxConsumption { 12442 public final double rxConsumptionMah; 12443 public final long rxDurationMs; 12444 public final double txConsumptionMah; 12445 public final long txDurationMs; 12446 12447 /** 12448 * Represents the ratio between time spent transmitting and the total active time. 12449 */ 12450 public final double txToTotalRatio; 12451 RxTxConsumption(double rxMah, long rxMs, double txMah, long txMs)12452 RxTxConsumption(double rxMah, long rxMs, double txMah, long txMs) { 12453 rxConsumptionMah = rxMah; 12454 rxDurationMs = rxMs; 12455 txConsumptionMah = txMah; 12456 txDurationMs = txMs; 12457 12458 final long activeDurationMs = txDurationMs + rxDurationMs; 12459 if (activeDurationMs == 0) { 12460 txToTotalRatio = 0.0; 12461 } else { 12462 txToTotalRatio = ((double) txDurationMs) / activeDurationMs; 12463 } 12464 } 12465 } 12466 12467 @GuardedBy("this") 12468 @Nullable incrementPerRatDataLocked(ModemActivityInfo deltaInfo, long elapsedRealtimeMs)12469 private RxTxConsumption incrementPerRatDataLocked(ModemActivityInfo deltaInfo, 12470 long elapsedRealtimeMs) { 12471 double rxConsumptionMah = 0.0; 12472 long rxDurationMs = 0; 12473 double txConsumptionMah = 0.0; 12474 long txDurationMs = 0; 12475 12476 final int infoSize = deltaInfo.getSpecificInfoLength(); 12477 if (infoSize == 1 && deltaInfo.getSpecificInfoRat(0) 12478 == AccessNetworkConstants.AccessNetworkType.UNKNOWN 12479 && deltaInfo.getSpecificInfoFrequencyRange(0) 12480 == ServiceState.FREQUENCY_RANGE_UNKNOWN) { 12481 // Specific info data unavailable. Proportionally smear Rx and Tx times across each RAT. 12482 final int levelCount = CellSignalStrength.getNumSignalStrengthLevels(); 12483 long[] perSignalStrengthActiveTimeMs = new long[levelCount]; 12484 long totalActiveTimeMs = 0; 12485 12486 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 12487 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 12488 if (ratStats == null) continue; 12489 12490 final int freqCount = ratStats.getFrequencyRangeCount(); 12491 for (int freq = 0; freq < freqCount; freq++) { 12492 for (int level = 0; level < levelCount; level++) { 12493 final long durationMs = ratStats.getTimeSinceMark(freq, level, 12494 elapsedRealtimeMs); 12495 perSignalStrengthActiveTimeMs[level] += durationMs; 12496 totalActiveTimeMs += durationMs; 12497 } 12498 } 12499 } 12500 if (totalActiveTimeMs != 0) { 12501 // Smear the provided Tx/Rx durations across each RAT, frequency, and signal 12502 // strength. 12503 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 12504 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 12505 if (ratStats == null) continue; 12506 12507 final int freqCount = ratStats.getFrequencyRangeCount(); 12508 for (int freq = 0; freq < freqCount; freq++) { 12509 long frequencyDurationMs = 0; 12510 for (int level = 0; level < levelCount; level++) { 12511 final long durationMs = ratStats.getTimeSinceMark(freq, level, 12512 elapsedRealtimeMs); 12513 final long totalLvlDurationMs = 12514 perSignalStrengthActiveTimeMs[level]; 12515 if (totalLvlDurationMs == 0) continue; 12516 final long totalTxLvlDurations = 12517 deltaInfo.getTransmitDurationMillisAtPowerLevel(level); 12518 // Smear HAL provided Tx power level duration based on active modem 12519 // duration in a given state. (Add totalLvlDurationMs / 2 before 12520 // the integer division with totalLvlDurationMs for rounding.) 12521 final long proportionalTxDurationMs = 12522 (durationMs * totalTxLvlDurations 12523 + (totalLvlDurationMs / 2)) / totalLvlDurationMs; 12524 ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs); 12525 frequencyDurationMs += durationMs; 12526 12527 if (isMobileRadioEnergyConsumerSupportedLocked()) { 12528 // Accumulate the power cost of time spent transmitting in a 12529 // particular state. 12530 final double txStatePowerConsumptionMah = 12531 mMobileRadioPowerCalculator.calcTxStatePowerMah(rat, freq, 12532 level, proportionalTxDurationMs); 12533 txConsumptionMah += txStatePowerConsumptionMah; 12534 txDurationMs += proportionalTxDurationMs; 12535 } 12536 } 12537 final long totalRxDuration = deltaInfo.getReceiveTimeMillis(); 12538 // Smear HAL provided Rx power duration based on active modem 12539 // duration in a given state. (Add totalActiveTimeMs / 2 before the 12540 // integer division with totalActiveTimeMs for rounding.) 12541 final long proportionalRxDurationMs = 12542 (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs 12543 / 2)) / totalActiveTimeMs; 12544 ratStats.incrementRxDuration(freq, proportionalRxDurationMs); 12545 12546 if (isMobileRadioEnergyConsumerSupportedLocked()) { 12547 // Accumulate the power cost of time spent receiving in a particular 12548 // state. 12549 final double rxStatePowerConsumptionMah = 12550 mMobileRadioPowerCalculator.calcRxStatePowerMah(rat, freq, 12551 proportionalRxDurationMs); 12552 rxConsumptionMah += rxStatePowerConsumptionMah; 12553 rxDurationMs += proportionalRxDurationMs; 12554 } 12555 } 12556 12557 } 12558 } 12559 } else { 12560 // Specific data available. 12561 for (int index = 0; index < infoSize; index++) { 12562 final int rat = deltaInfo.getSpecificInfoRat(index); 12563 final int freq = deltaInfo.getSpecificInfoFrequencyRange(index); 12564 12565 // Map RadioAccessNetworkType to course grain RadioAccessTechnology. 12566 final int ratBucket = mapRadioAccessNetworkTypeToRadioAccessTechnology(rat); 12567 final RadioAccessTechnologyBatteryStats ratStats = getRatBatteryStatsLocked( 12568 ratBucket); 12569 12570 final long rxTimeMs = deltaInfo.getReceiveTimeMillis(rat, freq); 12571 final int[] txTimesMs = deltaInfo.getTransmitTimeMillis(rat, freq); 12572 12573 ratStats.incrementRxDuration(freq, rxTimeMs); 12574 if (isMobileRadioEnergyConsumerSupportedLocked()) { 12575 // Accumulate the power cost of time spent receiving in a particular state. 12576 final double rxStatePowerConsumptionMah = 12577 mMobileRadioPowerCalculator.calcRxStatePowerMah(ratBucket, freq, 12578 rxTimeMs); 12579 rxConsumptionMah += rxStatePowerConsumptionMah; 12580 rxDurationMs += rxTimeMs; 12581 } 12582 12583 final int numTxLvl = txTimesMs.length; 12584 for (int lvl = 0; lvl < numTxLvl; lvl++) { 12585 final long txTimeMs = txTimesMs[lvl]; 12586 ratStats.incrementTxDuration(freq, lvl, txTimeMs); 12587 if (isMobileRadioEnergyConsumerSupportedLocked()) { 12588 // Accumulate the power cost of time spent transmitting in a particular 12589 // state. 12590 final double txStatePowerConsumptionMah = 12591 mMobileRadioPowerCalculator.calcTxStatePowerMah(ratBucket, freq, 12592 lvl, txTimeMs); 12593 txConsumptionMah += txStatePowerConsumptionMah; 12594 txDurationMs += txTimeMs; 12595 } 12596 } 12597 } 12598 } 12599 12600 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 12601 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 12602 if (ratStats == null) continue; 12603 ratStats.setMark(elapsedRealtimeMs); 12604 } 12605 12606 if (isMobileRadioEnergyConsumerSupportedLocked()) { 12607 return new RxTxConsumption(rxConsumptionMah, rxDurationMs, txConsumptionMah, 12608 txDurationMs); 12609 } else { 12610 return null; 12611 } 12612 } 12613 12614 /** 12615 * Smear modem Rx/Tx power consumption calculated from {@link ModemActivityInfo} using Rx/Tx 12616 * packets. 12617 * 12618 * @return the combine Rx/Tx smeared power consumption in milliamp-hours. 12619 */ smearModemActivityInfoRxTxConsumptionMah(RxTxConsumption rxTxConsumption, long rxPackets, long txPackets, long totalRxPackets, long totalTxPackets)12620 private double smearModemActivityInfoRxTxConsumptionMah(RxTxConsumption rxTxConsumption, 12621 long rxPackets, long txPackets, long totalRxPackets, long totalTxPackets) { 12622 // Distribute measured mobile radio charge consumption based on 12623 // rx/tx packets and estimated rx/tx charge consumption. 12624 double consumptionMah = 0.0; 12625 if (totalRxPackets != 0) { 12626 // Proportionally distribute receive battery consumption. 12627 consumptionMah += rxTxConsumption.rxConsumptionMah * rxPackets 12628 / totalRxPackets; 12629 } 12630 if (totalTxPackets != 0 || (totalRxPackets != 0 && rxTxConsumption.txToTotalRatio != 0.0)) { 12631 // ModemActivityInfo Tx time represents time spent both transmitting and receiving. 12632 // There is currently no way to distinguish how many Rx packets were received during 12633 // Rx time vs Tx time. 12634 // Assumption: The number of packets received while transmitting is proportional 12635 // to the time spent transmitting over total active time. 12636 final double totalPacketsDuringTxTime = 12637 totalTxPackets + rxTxConsumption.txToTotalRatio * totalRxPackets; 12638 final double packetsDuringTxTime = 12639 txPackets + rxTxConsumption.txToTotalRatio * rxPackets; 12640 consumptionMah += rxTxConsumption.txConsumptionMah * packetsDuringTxTime 12641 / totalPacketsDuringTxTime; 12642 } 12643 return consumptionMah; 12644 } 12645 12646 /** 12647 * Add modem tx power to history 12648 * Device is said to be in high cellular transmit power when it has spent most of the transmit 12649 * time at the highest power level. 12650 * @param activityInfo 12651 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo, long elapsedRealtimeMs, long uptimeMs)12652 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo, 12653 long elapsedRealtimeMs, long uptimeMs) { 12654 if (activityInfo == null) { 12655 return; 12656 } 12657 int levelMaxTimeSpent = 0; 12658 for (int i = 1; i < ModemActivityInfo.getNumTxPowerLevels(); i++) { 12659 if (activityInfo.getTransmitDurationMillisAtPowerLevel(i) 12660 > activityInfo.getTransmitDurationMillisAtPowerLevel(levelMaxTimeSpent)) { 12661 levelMaxTimeSpent = i; 12662 } 12663 } 12664 if (levelMaxTimeSpent == ModemActivityInfo.getNumTxPowerLevels() - 1) { 12665 mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs, 12666 HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG); 12667 } 12668 } 12669 12670 private final class BluetoothActivityInfoCache { 12671 long idleTimeMs; 12672 long rxTimeMs; 12673 long txTimeMs; 12674 long energy; 12675 12676 SparseLongArray uidRxBytes = new SparseLongArray(); 12677 SparseLongArray uidTxBytes = new SparseLongArray(); 12678 set(BluetoothActivityEnergyInfo info)12679 void set(BluetoothActivityEnergyInfo info) { 12680 idleTimeMs = info.getControllerIdleTimeMillis(); 12681 rxTimeMs = info.getControllerRxTimeMillis(); 12682 txTimeMs = info.getControllerTxTimeMillis(); 12683 energy = info.getControllerEnergyUsed(); 12684 if (!info.getUidTraffic().isEmpty()) { 12685 for (UidTraffic traffic : info.getUidTraffic()) { 12686 uidRxBytes.put(traffic.getUid(), traffic.getRxBytes()); 12687 uidTxBytes.put(traffic.getUid(), traffic.getTxBytes()); 12688 } 12689 } 12690 } 12691 reset()12692 void reset() { 12693 idleTimeMs = 0; 12694 rxTimeMs = 0; 12695 txTimeMs = 0; 12696 energy = 0; 12697 uidRxBytes.clear(); 12698 uidTxBytes.clear(); 12699 } 12700 } 12701 12702 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 12703 = new BluetoothActivityInfoCache(); 12704 12705 /** 12706 * Distribute Bluetooth energy info and network traffic to apps. 12707 * 12708 * @param info The accumulated energy information from the bluetooth controller. 12709 */ 12710 @GuardedBy("this") updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)12711 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info, 12712 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 12713 if (DEBUG_ENERGY) { 12714 Slog.d(TAG, "Updating bluetooth stats: " + info); 12715 } 12716 12717 if (info == null) { 12718 return; 12719 } 12720 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12721 mLastBluetoothActivityInfo.set(info); 12722 return; 12723 } 12724 12725 mHasBluetoothReporting = true; 12726 12727 if (info.getControllerRxTimeMillis() < mLastBluetoothActivityInfo.rxTimeMs 12728 || info.getControllerTxTimeMillis() < mLastBluetoothActivityInfo.txTimeMs 12729 || info.getControllerIdleTimeMillis() < mLastBluetoothActivityInfo.idleTimeMs 12730 || info.getControllerEnergyUsed() < mLastBluetoothActivityInfo.energy) { 12731 // A drop in accumulated Bluetooth stats is a sign of a Bluetooth crash. 12732 // Reset the preserved previous snapshot in order to restart accumulating deltas. 12733 mLastBluetoothActivityInfo.reset(); 12734 } 12735 12736 final long rxTimeMs = 12737 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 12738 final long txTimeMs = 12739 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 12740 final long idleTimeMs = 12741 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 12742 12743 if (DEBUG_ENERGY) { 12744 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 12745 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 12746 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 12747 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 12748 } 12749 12750 final SparseDoubleArray uidEstimatedConsumptionMah = 12751 (mGlobalEnergyConsumerStats != null 12752 && mBluetoothPowerCalculator != null && consumedChargeUC > 0) ? 12753 new SparseDoubleArray() : null; 12754 12755 long totalScanTimeMs = 0; 12756 12757 final int uidCount = mUidStats.size(); 12758 for (int i = 0; i < uidCount; i++) { 12759 final Uid u = mUidStats.valueAt(i); 12760 if (u.mBluetoothScanTimer == null) { 12761 continue; 12762 } 12763 12764 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 12765 elapsedRealtimeMs * 1000) / 1000; 12766 } 12767 12768 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 12769 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 12770 12771 if (DEBUG_ENERGY) { 12772 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 12773 + " TX=" + normalizeScanTxTime); 12774 } 12775 12776 long leftOverRxTimeMs = rxTimeMs; 12777 long leftOverTxTimeMs = txTimeMs; 12778 12779 final SparseLongArray rxTimesMs = new SparseLongArray(uidCount); 12780 final SparseLongArray txTimesMs = new SparseLongArray(uidCount); 12781 12782 for (int i = 0; i < uidCount; i++) { 12783 final Uid u = mUidStats.valueAt(i); 12784 if (u.mBluetoothScanTimer == null) { 12785 continue; 12786 } 12787 12788 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 12789 elapsedRealtimeMs * 1000) / 1000; 12790 if (scanTimeSinceMarkMs > 0) { 12791 // Set the new mark so that next time we get new data since this point. 12792 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 12793 12794 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 12795 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 12796 12797 if (normalizeScanRxTime) { 12798 // Scan time is longer than the total rx time in the controller, 12799 // so distribute the scan time proportionately. This means regular traffic 12800 // will not blamed, but scans are more expensive anyways. 12801 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 12802 } 12803 12804 if (normalizeScanTxTime) { 12805 // Scan time is longer than the total tx time in the controller, 12806 // so distribute the scan time proportionately. This means regular traffic 12807 // will not blamed, but scans are more expensive anyways. 12808 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 12809 } 12810 12811 rxTimesMs.incrementValue(u.getUid(), scanTimeRxSinceMarkMs); 12812 txTimesMs.incrementValue(u.getUid(), scanTimeTxSinceMarkMs); 12813 12814 if (uidEstimatedConsumptionMah != null) { 12815 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 12816 mBluetoothPowerCalculator.calculatePowerMah( 12817 scanTimeRxSinceMarkMs, scanTimeTxSinceMarkMs, 0)); 12818 } 12819 12820 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 12821 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 12822 } 12823 } 12824 12825 if (DEBUG_ENERGY) { 12826 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 12827 + leftOverTxTimeMs); 12828 } 12829 12830 // 12831 // Now distribute blame to apps that did bluetooth traffic. 12832 // 12833 12834 long totalTxBytes = 0; 12835 long totalRxBytes = 0; 12836 12837 final List<UidTraffic> uidTraffic = info.getUidTraffic(); 12838 final int numUids = uidTraffic.size(); 12839 for (int i = 0; i < numUids; i++) { 12840 final UidTraffic traffic = uidTraffic.get(i); 12841 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 12842 traffic.getUid()); 12843 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 12844 traffic.getUid()); 12845 12846 // Add to the global counters. 12847 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 12848 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 12849 12850 // Add to the UID counters. 12851 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()), elapsedRealtimeMs, uptimeMs); 12852 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 12853 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 12854 12855 // Calculate the total traffic. 12856 totalRxBytes += rxBytes; 12857 totalTxBytes += txBytes; 12858 } 12859 12860 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 12861 || leftOverTxTimeMs != 0)) { 12862 for (int i = 0; i < numUids; i++) { 12863 final UidTraffic traffic = uidTraffic.get(i); 12864 final int uid = traffic.getUid(); 12865 final long rxBytes = 12866 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 12867 final long txBytes = 12868 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 12869 12870 final Uid u = getUidStatsLocked(mapUid(uid), elapsedRealtimeMs, uptimeMs); 12871 final ControllerActivityCounterImpl counter = 12872 u.getOrCreateBluetoothControllerActivityLocked(); 12873 12874 if (totalRxBytes > 0 && rxBytes > 0) { 12875 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 12876 rxTimesMs.incrementValue(uid, timeRxMs); 12877 } 12878 12879 if (totalTxBytes > 0 && txBytes > 0) { 12880 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 12881 txTimesMs.incrementValue(uid, timeTxMs); 12882 } 12883 } 12884 12885 for (int i = 0; i < txTimesMs.size(); i++) { 12886 final int uid = txTimesMs.keyAt(i); 12887 final long myTxTimeMs = txTimesMs.valueAt(i); 12888 if (DEBUG_ENERGY) { 12889 Slog.d(TAG, " TxTime for UID " + uid + ": " + myTxTimeMs + " ms"); 12890 } 12891 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 12892 .getOrCreateBluetoothControllerActivityLocked() 12893 .getOrCreateTxTimeCounters()[0] 12894 .increment(myTxTimeMs, elapsedRealtimeMs); 12895 if (uidEstimatedConsumptionMah != null) { 12896 uidEstimatedConsumptionMah.incrementValue(uid, 12897 mBluetoothPowerCalculator.calculatePowerMah(0, myTxTimeMs, 0)); 12898 } 12899 } 12900 12901 for (int i = 0; i < rxTimesMs.size(); i++) { 12902 final int uid = rxTimesMs.keyAt(i); 12903 final long myRxTimeMs = rxTimesMs.valueAt(i); 12904 if (DEBUG_ENERGY) { 12905 Slog.d(TAG, " RxTime for UID " + uid + ": " + myRxTimeMs + " ms"); 12906 } 12907 12908 getUidStatsLocked(rxTimesMs.keyAt(i), elapsedRealtimeMs, uptimeMs) 12909 .getOrCreateBluetoothControllerActivityLocked() 12910 .getOrCreateRxTimeCounter() 12911 .increment(myRxTimeMs, elapsedRealtimeMs); 12912 if (uidEstimatedConsumptionMah != null) { 12913 uidEstimatedConsumptionMah.incrementValue(uid, 12914 mBluetoothPowerCalculator.calculatePowerMah(myRxTimeMs, 0, 0)); 12915 } 12916 } 12917 } 12918 12919 mBluetoothActivity.getOrCreateRxTimeCounter().increment(rxTimeMs, elapsedRealtimeMs); 12920 mBluetoothActivity.getOrCreateTxTimeCounters()[0].increment(txTimeMs, elapsedRealtimeMs); 12921 mBluetoothActivity.getOrCreateIdleTimeCounter().increment(idleTimeMs, elapsedRealtimeMs); 12922 12923 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12924 final double opVolt = mPowerProfile.getAveragePower( 12925 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12926 double controllerMaMs = 0; 12927 if (opVolt != 0) { 12928 controllerMaMs = (info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 12929 / opVolt; 12930 // We store the power drain as mAms. 12931 mBluetoothActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 12932 } 12933 12934 // Update the EnergyConsumerStats information. 12935 if (uidEstimatedConsumptionMah != null) { 12936 mGlobalEnergyConsumerStats.updateStandardBucket( 12937 EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, consumedChargeUC); 12938 12939 double totalEstimatedMah 12940 = mBluetoothPowerCalculator.calculatePowerMah(rxTimeMs, txTimeMs, idleTimeMs); 12941 totalEstimatedMah = Math.max(totalEstimatedMah, controllerMaMs / MILLISECONDS_IN_HOUR); 12942 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_BLUETOOTH, 12943 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedMah, 12944 elapsedRealtimeMs); 12945 } 12946 12947 mLastBluetoothActivityInfo.set(info); 12948 } 12949 /** 12950 * Read Resource Power Manager (RPM) state and voter times. 12951 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 12952 * instead of fetching it anew. 12953 * 12954 * Note: This should be called without synchronizing this BatteryStatsImpl object 12955 */ fillLowPowerStats()12956 public void fillLowPowerStats() { 12957 if (mPlatformIdleStateCallback == null) return; 12958 12959 RpmStats rpmStats = new RpmStats(); 12960 long now = SystemClock.elapsedRealtime(); 12961 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 12962 mPlatformIdleStateCallback.fillLowPowerStats(rpmStats); 12963 synchronized (this) { 12964 mTmpRpmStats = rpmStats; 12965 mLastRpmStatsUpdateTimeMs = now; 12966 } 12967 } 12968 } 12969 12970 /** 12971 * Record Resource Power Manager (RPM) state and voter times. 12972 * TODO(b/185252376): Remove this logging. PowerStatsService logs the same data more 12973 * efficiently. 12974 */ updateRpmStatsLocked(long elapsedRealtimeUs)12975 public void updateRpmStatsLocked(long elapsedRealtimeUs) { 12976 if (mTmpRpmStats == null) return; 12977 12978 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 12979 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 12980 12981 // Update values for this platform state. 12982 final String pName = pstate.getKey(); 12983 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 12984 final int pCount = pstate.getValue().mCount; 12985 getRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 12986 if (SCREEN_OFF_RPM_STATS_ENABLED) { 12987 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 12988 } 12989 12990 // Update values for each voter of this platform state. 12991 for (Map.Entry<String, RpmStats.PowerStateElement> voter 12992 : pstate.getValue().mVoters.entrySet()) { 12993 final String vName = pName + "." + voter.getKey(); 12994 final long vTimeUs = voter.getValue().mTimeMs * 1000; 12995 final int vCount = voter.getValue().mCount; 12996 getRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 12997 if (SCREEN_OFF_RPM_STATS_ENABLED) { 12998 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 12999 } 13000 } 13001 } 13002 13003 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 13004 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 13005 13006 final String subsysName = subsys.getKey(); 13007 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 13008 : subsys.getValue().mStates.entrySet()) { 13009 final String name = subsysName + "." + sstate.getKey(); 13010 final long timeUs = sstate.getValue().mTimeMs * 1000; 13011 final int count = sstate.getValue().mCount; 13012 getRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 13013 if (SCREEN_OFF_RPM_STATS_ENABLED) { 13014 getScreenOffRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 13015 } 13016 } 13017 } 13018 } 13019 13020 /** 13021 * Accumulate Cpu charge consumption and distribute it to the correct state and the apps. 13022 * Only call if device is on battery. 13023 * 13024 * @param clusterChargeUC amount of charge (microcoulombs) consumed by each Cpu Cluster 13025 * @param accumulator collection of calculated uid cpu power consumption to smear 13026 * clusterChargeUC against. 13027 */ 13028 @GuardedBy("this") 13029 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToStandardBucketLocked updateCpuEnergyConsumerStatsLocked(@onNull long[] clusterChargeUC, @NonNull CpuDeltaPowerAccumulator accumulator)13030 private void updateCpuEnergyConsumerStatsLocked(@NonNull long[] clusterChargeUC, 13031 @NonNull CpuDeltaPowerAccumulator accumulator) { 13032 if (DEBUG_ENERGY) { 13033 Slog.d(TAG, "Updating cpu cluster stats: " + Arrays.toString(clusterChargeUC)); 13034 } 13035 if (mGlobalEnergyConsumerStats == null) { 13036 return; 13037 } 13038 13039 final int numClusters = clusterChargeUC.length; 13040 long totalCpuChargeUC = 0; 13041 for (int i = 0; i < numClusters; i++) { 13042 totalCpuChargeUC += clusterChargeUC[i]; 13043 } 13044 if (totalCpuChargeUC <= 0) return; 13045 13046 final long timestampMs = mClock.elapsedRealtime(); 13047 13048 mGlobalEnergyConsumerStats.updateStandardBucket(EnergyConsumerStats.POWER_BUCKET_CPU, 13049 totalCpuChargeUC, timestampMs); 13050 13051 // Calculate the microcoulombs/milliamp-hour charge ratio for each 13052 // cluster to normalize each uid's estimated power usage against actual power usage for 13053 // a given cluster. 13054 final double[] clusterChargeRatio = new double[numClusters]; 13055 for (int cluster = 0; cluster < numClusters; cluster++) { 13056 13057 final double totalClusterChargeMah = accumulator.totalClusterChargesMah[cluster]; 13058 if (totalClusterChargeMah <= 0.0) { 13059 // This cluster did not have any work on it, since last update. 13060 // Avoid dividing by zero. 13061 clusterChargeRatio[cluster] = 0.0; 13062 } else { 13063 clusterChargeRatio[cluster] = 13064 clusterChargeUC[cluster] / accumulator.totalClusterChargesMah[cluster]; 13065 } 13066 } 13067 13068 // Assign and distribute power usage to apps based on their calculated cpu cluster charge. 13069 final long uidChargeArraySize = accumulator.perUidCpuClusterChargesMah.size(); 13070 for (int i = 0; i < uidChargeArraySize; i++) { 13071 final Uid uid = accumulator.perUidCpuClusterChargesMah.keyAt(i); 13072 final double[] uidClusterChargesMah = accumulator.perUidCpuClusterChargesMah.valueAt(i); 13073 13074 // Iterate each cpu cluster and sum the proportional cpu cluster charge to 13075 // get the total cpu charge consumed by a uid. 13076 long uidCpuChargeUC = 0; 13077 for (int cluster = 0; cluster < numClusters; cluster++) { 13078 final double uidClusterChargeMah = uidClusterChargesMah[cluster]; 13079 13080 // Proportionally allocate the cpu cluster charge to a uid using the 13081 // cluster charge/charge ratio. Add 0.5 to round the proportional 13082 // charge double to the nearest long value. 13083 final long uidClusterChargeUC = 13084 (long) (uidClusterChargeMah * clusterChargeRatio[cluster] 13085 + 0.5); 13086 13087 uidCpuChargeUC += uidClusterChargeUC; 13088 } 13089 13090 if (uidCpuChargeUC < 0) { 13091 Slog.wtf(TAG, "Unexpected proportional EnergyConsumer charge " 13092 + "(" + uidCpuChargeUC + ") for uid " + uid.mUid); 13093 continue; 13094 } 13095 13096 uid.addChargeToStandardBucketLocked(uidCpuChargeUC, 13097 EnergyConsumerStats.POWER_BUCKET_CPU, timestampMs); 13098 } 13099 } 13100 13101 /** 13102 * Accumulate Display charge consumption and distribute it to the correct state and the apps. 13103 * 13104 * NOTE: The algorithm used makes the strong assumption that app foreground activity time 13105 * is always 0 when the screen is not "ON" and whenever the rail energy is 0 (if supported). 13106 * To the extent that those assumptions are violated, the algorithm will err. 13107 * 13108 * @param chargesUC amount of charge (microcoulombs) used by each Display since this was last 13109 * called. 13110 * @param screenStates each screen state at the time this data collection was scheduled 13111 */ 13112 @GuardedBy("this") updateDisplayEnergyConsumerStatsLocked(long[] chargesUC, int[] screenStates, long elapsedRealtimeMs)13113 public void updateDisplayEnergyConsumerStatsLocked(long[] chargesUC, int[] screenStates, 13114 long elapsedRealtimeMs) { 13115 if (DEBUG_ENERGY) Slog.d(TAG, "Updating display stats: " + Arrays.toString(chargesUC)); 13116 if (mGlobalEnergyConsumerStats == null) { 13117 return; 13118 } 13119 13120 final int numDisplays; 13121 if (mPerDisplayBatteryStats.length == screenStates.length) { 13122 numDisplays = screenStates.length; 13123 } else { 13124 // if this point is reached, it will be reached every display state change. 13125 // Rate limit the wtf logging to once every 100 display updates. 13126 if (mDisplayMismatchWtfCount++ % 100 == 0) { 13127 Slog.wtf(TAG, "Mismatch between PowerProfile reported display count (" 13128 + mPerDisplayBatteryStats.length 13129 + ") and PowerStatsHal reported display count (" + screenStates.length 13130 + ")"); 13131 } 13132 // Keep the show going, use the shorter of the two. 13133 numDisplays = mPerDisplayBatteryStats.length < screenStates.length 13134 ? mPerDisplayBatteryStats.length : screenStates.length; 13135 } 13136 13137 final int[] oldScreenStates = new int[numDisplays]; 13138 for (int i = 0; i < numDisplays; i++) { 13139 final int screenState = screenStates[i]; 13140 oldScreenStates[i] = mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement; 13141 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 13142 } 13143 13144 if (!mOnBatteryInternal) { 13145 // There's nothing further to update. 13146 return; 13147 } 13148 if (mIgnoreNextExternalStats) { 13149 // Although under ordinary resets we won't get here, and typically a new sync will 13150 // happen right after the reset, strictly speaking we need to set all mark times to now. 13151 final int uidStatsSize = mUidStats.size(); 13152 for (int i = 0; i < uidStatsSize; i++) { 13153 final Uid uid = mUidStats.valueAt(i); 13154 uid.markProcessForegroundTimeUs(elapsedRealtimeMs, false); 13155 } 13156 return; 13157 } 13158 13159 long totalScreenOnChargeUC = 0; 13160 for (int i = 0; i < numDisplays; i++) { 13161 final long chargeUC = chargesUC[i]; 13162 if (chargeUC <= 0) { 13163 // There's nothing further to update. 13164 continue; 13165 } 13166 13167 final @StandardPowerBucket int powerBucket = 13168 EnergyConsumerStats.getDisplayPowerBucket(oldScreenStates[i]); 13169 mGlobalEnergyConsumerStats.updateStandardBucket(powerBucket, chargeUC); 13170 if (powerBucket == EnergyConsumerStats.POWER_BUCKET_SCREEN_ON) { 13171 totalScreenOnChargeUC += chargeUC; 13172 } 13173 } 13174 13175 // Now we blame individual apps, but only if the display was ON. 13176 if (totalScreenOnChargeUC <= 0) { 13177 return; 13178 } 13179 // TODO(b/175726779): Consider unifying the code with the non-rail display power blaming. 13180 13181 // NOTE: fg time is NOT pooled. If two uids are both somehow in fg, then that time is 13182 // 'double counted' and will simply exceed the realtime that elapsed. 13183 // TODO(b/175726779): collect per display uid visibility for display power attribution. 13184 13185 // Collect total time since mark so that we can normalize power. 13186 final SparseDoubleArray fgTimeUsArray = new SparseDoubleArray(); 13187 final long elapsedRealtimeUs = elapsedRealtimeMs * 1000; 13188 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 13189 final int uidStatsSize = mUidStats.size(); 13190 for (int i = 0; i < uidStatsSize; i++) { 13191 final Uid uid = mUidStats.valueAt(i); 13192 final long fgTimeUs = uid.markProcessForegroundTimeUs(elapsedRealtimeMs, true); 13193 if (fgTimeUs == 0) continue; 13194 fgTimeUsArray.put(uid.getUid(), (double) fgTimeUs); 13195 } 13196 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_SCREEN_ON, 13197 totalScreenOnChargeUC, fgTimeUsArray, 0, elapsedRealtimeMs); 13198 } 13199 13200 /** 13201 * Accumulate GNSS charge consumption and distribute it to the correct state and the apps. 13202 * 13203 * @param chargeUC amount of charge (microcoulombs) used by GNSS since this was last called. 13204 */ 13205 @GuardedBy("this") 13206 public void updateGnssEnergyConsumerStatsLocked(long chargeUC, long elapsedRealtimeMs) { 13207 if (DEBUG_ENERGY) Slog.d(TAG, "Updating gnss stats: " + chargeUC); 13208 if (mGlobalEnergyConsumerStats == null) { 13209 return; 13210 } 13211 13212 if (!mOnBatteryInternal || chargeUC <= 0) { 13213 // There's nothing further to update. 13214 return; 13215 } 13216 if (mIgnoreNextExternalStats) { 13217 // Although under ordinary resets we won't get here, and typically a new sync will 13218 // happen right after the reset, strictly speaking we need to set all mark times to now. 13219 final int uidStatsSize = mUidStats.size(); 13220 for (int i = 0; i < uidStatsSize; i++) { 13221 final Uid uid = mUidStats.valueAt(i); 13222 uid.markGnssTimeUs(elapsedRealtimeMs); 13223 } 13224 return; 13225 } 13226 13227 mGlobalEnergyConsumerStats.updateStandardBucket(EnergyConsumerStats.POWER_BUCKET_GNSS, 13228 chargeUC); 13229 13230 // Collect the per uid time since mark so that we can normalize power. 13231 final SparseDoubleArray gnssTimeUsArray = new SparseDoubleArray(); 13232 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 13233 final int uidStatsSize = mUidStats.size(); 13234 for (int i = 0; i < uidStatsSize; i++) { 13235 final Uid uid = mUidStats.valueAt(i); 13236 final long gnssTimeUs = uid.markGnssTimeUs(elapsedRealtimeMs); 13237 if (gnssTimeUs == 0) continue; 13238 gnssTimeUsArray.put(uid.getUid(), (double) gnssTimeUs); 13239 } 13240 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_GNSS, chargeUC, 13241 gnssTimeUsArray, 0, elapsedRealtimeMs); 13242 } 13243 13244 /** 13245 * Accumulate camera charge consumption and distribute it to the correct state and the apps. 13246 * 13247 * @param chargeUC amount of charge (microcoulombs) used by the camera since this was last 13248 * called. 13249 */ 13250 @GuardedBy("this") 13251 public void updateCameraEnergyConsumerStatsLocked(long chargeUC, long elapsedRealtimeMs) { 13252 if (DEBUG_ENERGY) Slog.d(TAG, "Updating camera stats: " + chargeUC); 13253 if (mGlobalEnergyConsumerStats == null) { 13254 return; 13255 } 13256 13257 if (!mOnBatteryInternal || chargeUC <= 0) { 13258 // There's nothing further to update. 13259 return; 13260 } 13261 13262 if (mIgnoreNextExternalStats) { 13263 // Although under ordinary resets we won't get here, and typically a new sync will 13264 // happen right after the reset, strictly speaking we need to set all mark times to now. 13265 final int uidStatsSize = mUidStats.size(); 13266 for (int i = 0; i < uidStatsSize; i++) { 13267 final Uid uid = mUidStats.valueAt(i); 13268 uid.markCameraTimeUs(elapsedRealtimeMs); 13269 } 13270 return; 13271 } 13272 13273 mGlobalEnergyConsumerStats.updateStandardBucket( 13274 EnergyConsumerStats.POWER_BUCKET_CAMERA, chargeUC); 13275 13276 // Collect the per uid time since mark so that we can normalize power. 13277 final SparseDoubleArray cameraTimeUsArray = new SparseDoubleArray(); 13278 13279 // Note: Iterating over all UIDs may be suboptimal. 13280 final int uidStatsSize = mUidStats.size(); 13281 for (int i = 0; i < uidStatsSize; i++) { 13282 final Uid uid = mUidStats.valueAt(i); 13283 final long cameraTimeUs = uid.markCameraTimeUs(elapsedRealtimeMs); 13284 if (cameraTimeUs == 0) continue; 13285 cameraTimeUsArray.put(uid.getUid(), (double) cameraTimeUs); 13286 } 13287 distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_CAMERA, chargeUC, 13288 cameraTimeUsArray, 0, elapsedRealtimeMs); 13289 } 13290 13291 /** 13292 * Accumulate Custom power bucket charge, globally and for each app. 13293 * 13294 * @param totalChargeUC charge (microcoulombs) used for this bucket since this was last called. 13295 * @param uidCharges map of uid->charge (microcoulombs) for this bucket since last called. 13296 * Data inside uidCharges will not be modified (treated immutable). 13297 * Uids not already known to BatteryStats will be ignored. 13298 */ 13299 @GuardedBy("this") 13300 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToCustomBucketLocked 13301 public void updateCustomEnergyConsumerStatsLocked(int customPowerBucket, 13302 long totalChargeUC, @Nullable SparseLongArray uidCharges) { 13303 if (DEBUG_ENERGY) { 13304 Slog.d(TAG, "Updating attributed EnergyConsumer stats for custom bucket " 13305 + customPowerBucket 13306 + " with total charge " + totalChargeUC 13307 + " and uid charges " + uidCharges); 13308 } 13309 if (mGlobalEnergyConsumerStats == null) return; 13310 if (!mOnBatteryInternal || mIgnoreNextExternalStats || totalChargeUC <= 0) return; 13311 13312 mGlobalEnergyConsumerStats.updateCustomBucket(customPowerBucket, totalChargeUC, 13313 mClock.elapsedRealtime()); 13314 13315 if (uidCharges == null) return; 13316 final int numUids = uidCharges.size(); 13317 for (int i = 0; i < numUids; i++) { 13318 final int uidInt = mapUid(uidCharges.keyAt(i)); 13319 final long uidChargeUC = uidCharges.valueAt(i); 13320 if (uidChargeUC == 0) continue; 13321 13322 final Uid uidObj = getAvailableUidStatsLocked(uidInt); 13323 if (uidObj != null) { 13324 uidObj.addChargeToCustomBucketLocked(uidChargeUC, customPowerBucket); 13325 } else { 13326 // Ignore any uid not already known to BatteryStats, rather than creating a new Uid. 13327 // Otherwise we could end up reviving dead Uids. Note that the CPU data is updated 13328 // first, so any uid that has used any CPU should already be known to BatteryStats. 13329 // Recently removed uids (especially common for isolated uids) can reach this path 13330 // and are ignored. 13331 if (!Process.isIsolated(uidInt)) { 13332 Slog.w(TAG, "Received EnergyConsumer charge " + totalChargeUC 13333 + " for custom bucket " + customPowerBucket + " for non-existent uid " 13334 + uidInt); 13335 } 13336 } 13337 } 13338 } 13339 13340 /** 13341 * Attributes energy (for the given bucket) to each uid according to the following formula: 13342 * blamedEnergy[uid] = totalEnergy * ratioNumerators[uid] / ratioDenominator; 13343 * <p>Does nothing if ratioDenominator is 0. 13344 * 13345 * <p>Here, ratioDenominator = max(sumOfAllRatioNumerators, minRatioDenominator), 13346 * so if given minRatioDenominator <= 0, then sumOfAllRatioNumerators will be used implicitly. 13347 * 13348 * <p>Note that ratioNumerators and minRatioDenominator must use the same units, but need not 13349 * use the same units as totalConsumedChargeUC (which must be in microcoulombs). 13350 * 13351 * <p>A consequence of minRatioDenominator is that the sum over all uids might be less than 13352 * totalConsumedChargeUC. This is intentional; the remainder is purposefully unnaccounted rather 13353 * than incorrectly blamed on uids, and implies unknown (non-uid) sources of drain. 13354 * 13355 * <p>All uids in ratioNumerators must exist in mUidStats already. 13356 */ 13357 @GuardedBy("this") 13358 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToStandardBucketLocked 13359 private void distributeEnergyToUidsLocked(@StandardPowerBucket int bucket, 13360 long totalConsumedChargeUC, SparseDoubleArray ratioNumerators, 13361 double minRatioDenominator, long timestampMs) { 13362 13363 // If the sum of all app usage was greater than the total, use that instead: 13364 double sumRatioNumerators = 0; 13365 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 13366 sumRatioNumerators += ratioNumerators.valueAt(i); 13367 } 13368 final double ratioDenominator = Math.max(sumRatioNumerators, minRatioDenominator); 13369 if (ratioDenominator <= 0) return; 13370 13371 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 13372 final Uid uid = getAvailableUidStatsLocked(ratioNumerators.keyAt(i)); 13373 final double ratioNumerator = ratioNumerators.valueAt(i); 13374 final long uidActualUC 13375 = (long) (totalConsumedChargeUC * ratioNumerator / ratioDenominator + 0.5); 13376 uid.addChargeToStandardBucketLocked(uidActualUC, bucket, timestampMs); 13377 } 13378 } 13379 13380 /** 13381 * Read and record Rail Energy data. 13382 */ 13383 public void updateRailStatsLocked() { 13384 if (mEnergyConsumerRetriever == null || !mTmpRailStats.isRailStatsAvailable()) { 13385 return; 13386 } 13387 mEnergyConsumerRetriever.fillRailDataStats(mTmpRailStats); 13388 } 13389 13390 /** Informs that external stats data has been completely flushed. */ 13391 public void informThatAllExternalStatsAreFlushed() { 13392 synchronized (this) { 13393 // Any data from the pre-reset era is flushed, so we can henceforth process future data. 13394 mIgnoreNextExternalStats = false; 13395 } 13396 } 13397 13398 /** 13399 * Read and distribute kernel wake lock use across apps. 13400 */ 13401 public void updateKernelWakelocksLocked(long elapsedRealtimeUs) { 13402 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 13403 mTmpWakelockStats); 13404 if (wakelockStats == null) { 13405 // Not crashing might make board bringup easier. 13406 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 13407 return; 13408 } 13409 13410 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 13411 String name = ent.getKey(); 13412 KernelWakelockStats.Entry kws = ent.getValue(); 13413 13414 SamplingTimer kwlt = mKernelWakelockStats.get(name); 13415 if (kwlt == null) { 13416 kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 13417 mKernelWakelockStats.put(name, kwlt); 13418 } 13419 13420 kwlt.update(kws.mTotalTime, kws.mCount, elapsedRealtimeUs); 13421 kwlt.setUpdateVersion(kws.mVersion); 13422 } 13423 13424 int numWakelocksSetStale = 0; 13425 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 13426 // this time. 13427 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 13428 SamplingTimer st = ent.getValue(); 13429 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 13430 st.endSample(elapsedRealtimeUs); 13431 numWakelocksSetStale++; 13432 } 13433 } 13434 13435 // Record whether we've seen a non-zero time (for debugging b/22716723). 13436 if (wakelockStats.isEmpty()) { 13437 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 13438 } 13439 13440 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 13441 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 13442 wakelockStats.kernelWakelockVersion); 13443 } 13444 } 13445 13446 // We use an anonymous class to access these variables, 13447 // so they can't live on the stack or they'd have to be 13448 // final MutableLong objects (more allocations). 13449 // Used in updateCpuTimeLocked(). 13450 long mTempTotalCpuUserTimeUs; 13451 long mTempTotalCpuSystemTimeUs; 13452 long[][] mWakeLockAllocationsUs; 13453 13454 /** 13455 * Reads the newest memory stats from the kernel. 13456 */ 13457 public void updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs) { 13458 mKernelMemoryBandwidthStats.updateStats(); 13459 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 13460 final int bandwidthEntryCount = bandwidthEntries.size(); 13461 int index; 13462 for (int i = 0; i < bandwidthEntryCount; i++) { 13463 SamplingTimer timer; 13464 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 13465 timer = mKernelMemoryStats.valueAt(index); 13466 } else { 13467 timer = new SamplingTimer(mClock, mOnBatteryTimeBase); 13468 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 13469 } 13470 timer.update(bandwidthEntries.valueAt(i), 1, elapsedRealtimeUs); 13471 if (DEBUG_MEMORY) { 13472 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 13473 + "mUnpluggedReportedTotalTimeUs %d size %d", bandwidthEntries.keyAt(i), 13474 mKernelMemoryStats.get( 13475 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTimeUs, 13476 mKernelMemoryStats.size())); 13477 } 13478 } 13479 } 13480 13481 public boolean isOnBatteryLocked() { 13482 return mOnBatteryTimeBase.isRunning(); 13483 } 13484 13485 public boolean isOnBatteryScreenOffLocked() { 13486 return mOnBatteryScreenOffTimeBase.isRunning(); 13487 } 13488 13489 /** 13490 * Object for calculating and accumulating the estimated cpu power used while reading the 13491 * various cpu kernel files. 13492 */ 13493 @VisibleForTesting 13494 public static class CpuDeltaPowerAccumulator { 13495 // Keeps track of total charge used per cluster. 13496 public final double[] totalClusterChargesMah; 13497 // Keeps track of charge used per cluster per uid. 13498 public final ArrayMap<Uid, double[]> perUidCpuClusterChargesMah; 13499 13500 private final CpuPowerCalculator mCalculator; 13501 private Uid mCachedUid = null; 13502 private double[] mUidClusterCache = null; 13503 13504 CpuDeltaPowerAccumulator(CpuPowerCalculator calculator, int nClusters) { 13505 mCalculator = calculator; 13506 totalClusterChargesMah = new double[nClusters]; 13507 perUidCpuClusterChargesMah = new ArrayMap<>(); 13508 } 13509 13510 /** Add per cpu cluster durations to the currently cached uid. */ 13511 public void addCpuClusterDurationsMs(Uid uid, long[] durationsMs) { 13512 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 13513 for (int cluster = 0; cluster < durationsMs.length; cluster++) { 13514 final double estimatedDeltaMah = mCalculator.calculatePerCpuClusterPowerMah(cluster, 13515 durationsMs[cluster]); 13516 uidChargesMah[cluster] += estimatedDeltaMah; 13517 totalClusterChargesMah[cluster] += estimatedDeltaMah; 13518 } 13519 } 13520 13521 /** Add per speed per cpu cluster durations to the currently cached uid. */ 13522 public void addCpuClusterSpeedDurationsMs(Uid uid, int cluster, int speed, 13523 long durationsMs) { 13524 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 13525 final double estimatedDeltaMah = mCalculator.calculatePerCpuFreqPowerMah(cluster, speed, 13526 durationsMs); 13527 uidChargesMah[cluster] += estimatedDeltaMah; 13528 totalClusterChargesMah[cluster] += estimatedDeltaMah; 13529 } 13530 13531 private double[] getOrCreateUidCpuClusterCharges(Uid uid) { 13532 // Repeated additions on the same uid is very likely. 13533 // Skip a lookup if getting the same uid as the last get. 13534 if (uid == mCachedUid) return mUidClusterCache; 13535 13536 double[] uidChargesMah = perUidCpuClusterChargesMah.get(uid); 13537 if (uidChargesMah == null) { 13538 uidChargesMah = new double[totalClusterChargesMah.length]; 13539 perUidCpuClusterChargesMah.put(uid, uidChargesMah); 13540 } 13541 mCachedUid = uid; 13542 mUidClusterCache = uidChargesMah; 13543 return uidChargesMah; 13544 } 13545 } 13546 13547 /** 13548 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 13549 * and we are on battery with screen off, we give more of the cpu time to those apps holding 13550 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 13551 * It's possible this will be invoked after the internal battery/screen states are updated, so 13552 * passing the appropriate battery/screen states to try attribute the cpu times to correct 13553 * buckets. 13554 */ 13555 @GuardedBy("this") 13556 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff, 13557 long[] cpuClusterChargeUC) { 13558 if (mPowerProfile == null) { 13559 return; 13560 } 13561 13562 if (DEBUG_ENERGY_CPU) { 13563 Slog.d(TAG, "!Cpu updating!"); 13564 } 13565 13566 if (mCpuFreqs == null) { 13567 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 13568 } 13569 13570 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 13571 // usually holding the wakelock on behalf of an app. 13572 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 13573 ArrayList<StopwatchTimer> partialTimersToConsider = null; 13574 if (onBatteryScreenOff) { 13575 partialTimersToConsider = new ArrayList<>(); 13576 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 13577 final StopwatchTimer timer = mPartialTimers.get(i); 13578 // Since the collection and blaming of wakelocks can be scheduled to run after 13579 // some delay, the mPartialTimers list may have new entries. We can't blame 13580 // the newly added timer for past cpu time, so we only consider timers that 13581 // were present for one round of collection. Once a timer has gone through 13582 // a round of collection, its mInList field is set to true. 13583 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 13584 partialTimersToConsider.add(timer); 13585 } 13586 } 13587 } 13588 markPartialTimersAsEligible(); 13589 13590 // When the battery is not on, we don't attribute the cpu times to any timers but we still 13591 // need to take the snapshots. 13592 if (!onBattery) { 13593 mCpuUidUserSysTimeReader.readDelta(false, null); 13594 mCpuUidFreqTimeReader.readDelta(false, null); 13595 mNumAllUidCpuTimeReads += 2; 13596 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 13597 mCpuUidActiveTimeReader.readDelta(false, null); 13598 mCpuUidClusterTimeReader.readDelta(false, null); 13599 mNumAllUidCpuTimeReads += 2; 13600 } 13601 for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) { 13602 mKernelCpuSpeedReaders[cluster].readDelta(); 13603 } 13604 mSystemServerCpuThreadReader.readDelta(); 13605 return; 13606 } 13607 13608 mUserInfoProvider.refreshUserIds(); 13609 final SparseLongArray updatedUids = mCpuUidFreqTimeReader.perClusterTimesAvailable() 13610 ? null : new SparseLongArray(); 13611 13612 final CpuDeltaPowerAccumulator powerAccumulator; 13613 if (mGlobalEnergyConsumerStats != null 13614 && mGlobalEnergyConsumerStats.isStandardBucketSupported( 13615 EnergyConsumerStats.POWER_BUCKET_CPU) && mCpuPowerCalculator != null) { 13616 if (cpuClusterChargeUC == null) { 13617 Slog.wtf(TAG, 13618 "POWER_BUCKET_CPU supported but no EnergyConsumer Cpu Cluster charge " 13619 + "reported on updateCpuTimeLocked!"); 13620 powerAccumulator = null; 13621 } else { 13622 // Cpu EnergyConsumer is supported, create an object to accumulate the estimated 13623 // charge consumption since the last cpu update 13624 final int numClusters = mPowerProfile.getNumCpuClusters(); 13625 powerAccumulator = new CpuDeltaPowerAccumulator(mCpuPowerCalculator, numClusters); 13626 } 13627 } else { 13628 powerAccumulator = null; 13629 } 13630 13631 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 13632 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 13633 // freqs, so no need to approximate these values. 13634 if (updatedUids != null) { 13635 updateClusterSpeedTimes(updatedUids, onBattery, powerAccumulator); 13636 } 13637 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff, 13638 powerAccumulator); 13639 mNumAllUidCpuTimeReads += 2; 13640 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 13641 // Cpu Active times do not get any info ony how to attribute Cpu Cluster 13642 // charge, so not need to provide the powerAccumulator 13643 readKernelUidCpuActiveTimesLocked(onBattery); 13644 readKernelUidCpuClusterTimesLocked(onBattery, powerAccumulator); 13645 mNumAllUidCpuTimeReads += 2; 13646 } 13647 13648 updateSystemServerThreadStats(); 13649 13650 if (powerAccumulator != null) { 13651 updateCpuEnergyConsumerStatsLocked(cpuClusterChargeUC, powerAccumulator); 13652 } 13653 } 13654 13655 /** 13656 * Estimates the proportion of the System Server CPU activity (per cluster per speed) 13657 * spent on handling incoming binder calls. 13658 */ 13659 @VisibleForTesting 13660 public void updateSystemServerThreadStats() { 13661 // There are some simplifying assumptions made in this algorithm 13662 // 1) We assume that if a thread handles incoming binder calls, all of its activity 13663 // is spent doing that. Most incoming calls are handled by threads allocated 13664 // by the native layer in the binder thread pool, so this assumption is reasonable. 13665 // 2) We use the aggregate CPU time spent in different threads as a proxy for the CPU 13666 // cost. In reality, in multi-core CPUs, the CPU cost may not be linearly 13667 // affected by additional threads. 13668 13669 SystemServerCpuThreadReader.SystemServiceCpuThreadTimes systemServiceCpuThreadTimes = 13670 mSystemServerCpuThreadReader.readDelta(); 13671 if (systemServiceCpuThreadTimes == null) { 13672 return; 13673 } 13674 13675 if (mBinderThreadCpuTimesUs == null) { 13676 mBinderThreadCpuTimesUs = new LongSamplingCounterArray(mOnBatteryTimeBase); 13677 } 13678 mBinderThreadCpuTimesUs.addCountLocked(systemServiceCpuThreadTimes.binderThreadCpuTimesUs); 13679 13680 if (DEBUG_BINDER_STATS) { 13681 Slog.d(TAG, "System server threads per CPU cluster (incoming binder threads)"); 13682 long binderThreadTimeMs = 0; 13683 int cpuIndex = 0; 13684 final long[] binderThreadCpuTimesUs = mBinderThreadCpuTimesUs.getCountsLocked( 13685 BatteryStats.STATS_SINCE_CHARGED); 13686 int index = 0; 13687 int numCpuClusters = mPowerProfile.getNumCpuClusters(); 13688 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 13689 StringBuilder sb = new StringBuilder(); 13690 sb.append("cpu").append(cpuIndex).append(": ["); 13691 int numSpeeds = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 13692 for (int speed = 0; speed < numSpeeds; speed++) { 13693 if (speed != 0) { 13694 sb.append(", "); 13695 } 13696 long binderCountMs = binderThreadCpuTimesUs[index] / 1000; 13697 sb.append(TextUtils.formatSimple("%10d", binderCountMs)); 13698 13699 binderThreadTimeMs += binderCountMs; 13700 index++; 13701 } 13702 cpuIndex += mPowerProfile.getNumCoresInCpuCluster(cluster); 13703 Slog.d(TAG, sb.toString()); 13704 } 13705 } 13706 } 13707 13708 /** 13709 * Mark the current partial timers as gone through a collection so that they will be 13710 * considered in the next cpu times distribution to wakelock holders. 13711 */ 13712 @VisibleForTesting 13713 public void markPartialTimersAsEligible() { 13714 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 13715 // No difference, so each timer is now considered for the next collection. 13716 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 13717 mPartialTimers.get(i).mInList = true; 13718 } 13719 } else { 13720 // The lists are different, meaning we added (or removed a timer) since the last 13721 // collection. 13722 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 13723 mLastPartialTimers.get(i).mInList = false; 13724 } 13725 mLastPartialTimers.clear(); 13726 13727 // Mark the current timers as gone through a collection. 13728 final int numPartialTimers = mPartialTimers.size(); 13729 for (int i = 0; i < numPartialTimers; ++i) { 13730 final StopwatchTimer timer = mPartialTimers.get(i); 13731 timer.mInList = true; 13732 mLastPartialTimers.add(timer); 13733 } 13734 } 13735 } 13736 13737 /** 13738 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 13739 * calculate cpu times spent by each uid at different frequencies. Will also add estimated 13740 * power consumptions, if powerAccumulator data structure is provided. 13741 * 13742 * @param updatedUids The uids for which times spent at different frequencies are calculated. 13743 * @param onBattery whether or not this is onBattery 13744 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 13745 */ 13746 @VisibleForTesting 13747 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery, 13748 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 13749 long totalCpuClustersTimeMs = 0; 13750 // Read the time spent for each cluster at various cpu frequencies. 13751 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 13752 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 13753 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 13754 if (clusterSpeedTimesMs[cluster] != null) { 13755 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 13756 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 13757 } 13758 } 13759 } 13760 if (totalCpuClustersTimeMs != 0) { 13761 // We have cpu times per freq aggregated over all uids but we need the times per uid. 13762 // So, we distribute total time spent by an uid to different cpu freqs based on the 13763 // amount of time cpu was running at that freq. 13764 final int updatedUidsCount = updatedUids.size(); 13765 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 13766 final long uptimeMs = mClock.uptimeMillis(); 13767 for (int i = 0; i < updatedUidsCount; ++i) { 13768 final Uid u = getUidStatsLocked(updatedUids.keyAt(i), elapsedRealtimeMs, uptimeMs); 13769 final long appCpuTimeUs = updatedUids.valueAt(i); 13770 // Add the cpu speeds to this UID. 13771 final int numClusters = mPowerProfile.getNumCpuClusters(); 13772 if (u.mCpuClusterSpeedTimesUs == null || 13773 u.mCpuClusterSpeedTimesUs.length != numClusters) { 13774 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13775 } 13776 13777 for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) { 13778 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 13779 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 13780 u.mCpuClusterSpeedTimesUs[cluster].length) { 13781 u.mCpuClusterSpeedTimesUs[cluster] 13782 = new LongSamplingCounter[speedsInCluster]; 13783 } 13784 13785 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 13786 for (int speed = 0; speed < speedsInCluster; speed++) { 13787 if (cpuSpeeds[speed] == null) { 13788 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 13789 } 13790 final long deltaSpeedCount = appCpuTimeUs 13791 * clusterSpeedTimesMs[cluster][speed] 13792 / totalCpuClustersTimeMs; 13793 cpuSpeeds[speed].addCountLocked(deltaSpeedCount, onBattery); 13794 13795 if (powerAccumulator != null) { 13796 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 13797 speed, deltaSpeedCount); 13798 } 13799 } 13800 } 13801 } 13802 } 13803 } 13804 13805 /** 13806 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 13807 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 13808 * wakelock holders. 13809 * 13810 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 13811 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 13812 */ 13813 @VisibleForTesting 13814 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 13815 @Nullable SparseLongArray updatedUids, boolean onBattery) { 13816 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 13817 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 13818 final long startTimeMs = mClock.uptimeMillis(); 13819 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 13820 13821 mCpuUidUserSysTimeReader.readDelta(false, (uid, timesUs) -> { 13822 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 13823 13824 uid = mapUid(uid); 13825 if (Process.isIsolated(uid)) { 13826 // This could happen if the isolated uid mapping was removed before that process 13827 // was actually killed. 13828 if (DEBUG) Slog.d(TAG, "Got readings for an isolated uid: " + uid); 13829 return; 13830 } 13831 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 13832 if (DEBUG) Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 13833 return; 13834 } 13835 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 13836 13837 // Accumulate the total system and user time. 13838 mTempTotalCpuUserTimeUs += userTimeUs; 13839 mTempTotalCpuSystemTimeUs += systemTimeUs; 13840 13841 StringBuilder sb = null; 13842 if (DEBUG_ENERGY_CPU) { 13843 sb = new StringBuilder(); 13844 sb.append(" got time for uid=").append(u.mUid).append(": u="); 13845 TimeUtils.formatDuration(userTimeUs / 1000, sb); 13846 sb.append(" s="); 13847 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 13848 sb.append("\n"); 13849 } 13850 13851 if (numWakelocks > 0) { 13852 // We have wakelocks being held, so only give a portion of the 13853 // time to the process. The rest will be distributed among wakelock 13854 // holders. 13855 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 13856 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 13857 } 13858 13859 if (sb != null) { 13860 sb.append(" adding to uid=").append(u.mUid).append(": u="); 13861 TimeUtils.formatDuration(userTimeUs / 1000, sb); 13862 sb.append(" s="); 13863 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 13864 Slog.d(TAG, sb.toString()); 13865 } 13866 13867 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 13868 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 13869 if (updatedUids != null) { 13870 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 13871 } 13872 }); 13873 13874 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 13875 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 13876 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 13877 } 13878 13879 if (numWakelocks > 0) { 13880 // Distribute a portion of the total cpu time to wakelock holders. 13881 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 13882 mTempTotalCpuSystemTimeUs = 13883 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 13884 13885 for (int i = 0; i < numWakelocks; ++i) { 13886 final StopwatchTimer timer = partialTimers.get(i); 13887 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 13888 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 13889 13890 if (DEBUG_ENERGY_CPU) { 13891 final StringBuilder sb = new StringBuilder(); 13892 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 13893 .append(": u="); 13894 TimeUtils.formatDuration(userTimeUs / 1000, sb); 13895 sb.append(" s="); 13896 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 13897 Slog.d(TAG, sb.toString()); 13898 } 13899 13900 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 13901 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 13902 if (updatedUids != null) { 13903 final int uid = timer.mUid.getUid(); 13904 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 13905 } 13906 13907 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 13908 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 13909 13910 mTempTotalCpuUserTimeUs -= userTimeUs; 13911 mTempTotalCpuSystemTimeUs -= systemTimeUs; 13912 } 13913 } 13914 } 13915 13916 /** 13917 * Take a snapshot of the cpu times spent by each uid in each freq and update the 13918 * corresponding counters. Will also add estimated power consumptions, if powerAccumulator 13919 * data structure is provided. 13920 * 13921 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 13922 * @param onBattery whether or not this is onBattery 13923 * @param onBatteryScreenOff whether or not this is onBattery with the screen off. 13924 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 13925 */ 13926 @VisibleForTesting 13927 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 13928 boolean onBattery, boolean onBatteryScreenOff, 13929 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 13930 final boolean perClusterTimesAvailable = 13931 mCpuUidFreqTimeReader.perClusterTimesAvailable(); 13932 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 13933 final int numClusters = mPowerProfile.getNumCpuClusters(); 13934 mWakeLockAllocationsUs = null; 13935 final long startTimeMs = mClock.uptimeMillis(); 13936 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 13937 // If power is being accumulated for attribution, data needs to be read immediately. 13938 final boolean forceRead = powerAccumulator != null; 13939 mCpuUidFreqTimeReader.readDelta(forceRead, (uid, cpuFreqTimeMs) -> { 13940 uid = mapUid(uid); 13941 if (Process.isIsolated(uid)) { 13942 if (DEBUG) Slog.d(TAG, "Got freq readings for an isolated uid: " + uid); 13943 return; 13944 } 13945 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 13946 if (DEBUG) Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 13947 return; 13948 } 13949 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 13950 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 13951 detachIfNotNull(u.mCpuFreqTimeMs); 13952 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 13953 } 13954 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 13955 if (u.mScreenOffCpuFreqTimeMs == null || 13956 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 13957 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 13958 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 13959 mOnBatteryScreenOffTimeBase); 13960 } 13961 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 13962 13963 if (perClusterTimesAvailable) { 13964 if (u.mCpuClusterSpeedTimesUs == null || 13965 u.mCpuClusterSpeedTimesUs.length != numClusters) { 13966 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13967 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13968 } 13969 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 13970 mWakeLockAllocationsUs = new long[numClusters][]; 13971 } 13972 13973 int freqIndex = 0; 13974 for (int cluster = 0; cluster < numClusters; ++cluster) { 13975 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 13976 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 13977 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 13978 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 13979 u.mCpuClusterSpeedTimesUs[cluster] 13980 = new LongSamplingCounter[speedsInCluster]; 13981 } 13982 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 13983 mWakeLockAllocationsUs[cluster] = new long[speedsInCluster]; 13984 } 13985 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 13986 for (int speed = 0; speed < speedsInCluster; ++speed) { 13987 if (cpuTimesUs[speed] == null) { 13988 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 13989 } 13990 final long appAllocationUs; 13991 if (mWakeLockAllocationsUs != null) { 13992 appAllocationUs = 13993 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 13994 mWakeLockAllocationsUs[cluster][speed] += 13995 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 13996 } else { 13997 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 13998 } 13999 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 14000 14001 if (powerAccumulator != null) { 14002 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14003 speed, appAllocationUs / 1000); 14004 } 14005 freqIndex++; 14006 } 14007 } 14008 } 14009 }); 14010 14011 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14012 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14013 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 14014 } 14015 14016 if (mWakeLockAllocationsUs != null) { 14017 for (int i = 0; i < numWakelocks; ++i) { 14018 final Uid u = partialTimers.get(i).mUid; 14019 if (u.mCpuClusterSpeedTimesUs == null || 14020 u.mCpuClusterSpeedTimesUs.length != numClusters) { 14021 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 14022 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 14023 } 14024 14025 for (int cluster = 0; cluster < numClusters; ++cluster) { 14026 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 14027 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 14028 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 14029 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 14030 u.mCpuClusterSpeedTimesUs[cluster] 14031 = new LongSamplingCounter[speedsInCluster]; 14032 } 14033 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 14034 for (int speed = 0; speed < speedsInCluster; ++speed) { 14035 if (cpuTimeUs[speed] == null) { 14036 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 14037 } 14038 final long allocationUs = 14039 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 14040 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 14041 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 14042 14043 if (powerAccumulator != null) { 14044 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 14045 speed, allocationUs / 1000); 14046 } 14047 } 14048 } 14049 } 14050 } 14051 } 14052 14053 /** 14054 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 14055 * counters. 14056 */ 14057 @VisibleForTesting 14058 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 14059 final long startTimeMs = mClock.uptimeMillis(); 14060 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14061 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { 14062 final int parentUid = mapUid(uid); 14063 if (Process.isIsolated(parentUid)) { 14064 if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); 14065 return; 14066 } 14067 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14068 if (DEBUG) Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 14069 return; 14070 } 14071 final Uid u = getUidStatsLocked(parentUid, elapsedRealtimeMs, startTimeMs); 14072 if (parentUid == uid) { 14073 u.getCpuActiveTimeCounter().update(cpuActiveTimesMs, elapsedRealtimeMs); 14074 } else { 14075 final SparseArray<Uid.ChildUid> childUids = u.mChildUids; 14076 if (childUids == null) { 14077 return; 14078 } 14079 14080 Uid.ChildUid childUid = childUids.get(uid); 14081 if (childUid != null) { 14082 final long delta = 14083 childUid.cpuActiveCounter.update(cpuActiveTimesMs, elapsedRealtimeMs); 14084 u.getCpuActiveTimeCounter().increment(delta, elapsedRealtimeMs); 14085 } 14086 } 14087 }); 14088 14089 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14090 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14091 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 14092 } 14093 } 14094 14095 /** 14096 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 14097 * counters. Will also add estimated power consumptions, if powerAccumulator data structure 14098 * is provided. 14099 * 14100 * @param onBattery whether or not this is onBattery 14101 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 14102 */ 14103 @VisibleForTesting 14104 public void readKernelUidCpuClusterTimesLocked(boolean onBattery, 14105 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 14106 final long startTimeMs = mClock.uptimeMillis(); 14107 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14108 // If power is being accumulated for attribution, data needs to be read immediately. 14109 final boolean forceRead = powerAccumulator != null; 14110 mCpuUidClusterTimeReader.readDelta(forceRead, (uid, cpuClusterTimesMs) -> { 14111 uid = mapUid(uid); 14112 if (Process.isIsolated(uid)) { 14113 if (DEBUG) Slog.w(TAG, "Got cluster times for an isolated uid: " + uid); 14114 return; 14115 } 14116 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 14117 if (DEBUG) Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 14118 return; 14119 } 14120 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 14121 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 14122 14123 if (powerAccumulator != null) { 14124 powerAccumulator.addCpuClusterDurationsMs(u, cpuClusterTimesMs); 14125 } 14126 }); 14127 14128 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 14129 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 14130 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 14131 } 14132 } 14133 14134 boolean setChargingLocked(boolean charging) { 14135 // if the device is no longer charging, remove the callback 14136 // if the device is now charging, it means that this is either called 14137 // 1. directly when level >= 90 14138 // 2. or from within the runnable that we deferred 14139 // For 1. if we have an existing callback, remove it, since we will immediately send a 14140 // ACTION_CHARGING 14141 // For 2. we remove existing callback so we don't send multiple ACTION_CHARGING 14142 mHandler.removeCallbacks(mDeferSetCharging); 14143 if (mCharging != charging) { 14144 mCharging = charging; 14145 mHistory.setChargingState(charging); 14146 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 14147 return true; 14148 } 14149 return false; 14150 } 14151 14152 /** 14153 * Notifies BatteryStatsImpl that the system server is ready. 14154 */ 14155 public void onSystemReady() { 14156 mSystemReady = true; 14157 } 14158 14159 /** 14160 * Force recording of all history events regardless of the "charging" state. 14161 */ 14162 @VisibleForTesting 14163 public void forceRecordAllHistory() { 14164 mHistory.forceRecordAllHistory(); 14165 mRecordAllHistory = true; 14166 } 14167 14168 /** 14169 * Might reset battery stats if conditions are met. Assumed the device is currently plugged in. 14170 */ 14171 @VisibleForTesting 14172 @GuardedBy("this") 14173 public void maybeResetWhilePluggedInLocked() { 14174 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 14175 if (shouldResetWhilePluggedInLocked(elapsedRealtimeMs)) { 14176 Slog.i(TAG, 14177 "Resetting due to long plug in duration. elapsed time = " + elapsedRealtimeMs 14178 + " ms, last plug in time = " + mBatteryPluggedInRealTimeMs 14179 + " ms, last reset time = " + mRealtimeStartUs / 1000); 14180 resetAllStatsAndHistoryLocked(RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION); 14181 } 14182 14183 scheduleNextResetWhilePluggedInCheck(); 14184 } 14185 14186 @GuardedBy("this") 14187 private void scheduleNextResetWhilePluggedInCheck() { 14188 if (mAlarmManager == null) return; 14189 final long timeoutMs = mClock.currentTimeMillis() 14190 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14191 * DateUtils.HOUR_IN_MILLIS; 14192 Calendar nextAlarm = Calendar.getInstance(); 14193 nextAlarm.setTimeInMillis(timeoutMs); 14194 14195 // Find the 2 AM the same day as the end of the minimum duration. 14196 // This logic does not handle a Daylight Savings transition, or a timezone change 14197 // while the alarm has been set. The need to reset after a long period while plugged 14198 // in is not strict enough to warrant a well architected out solution. 14199 nextAlarm.set(Calendar.MILLISECOND, 0); 14200 nextAlarm.set(Calendar.SECOND, 0); 14201 nextAlarm.set(Calendar.MINUTE, 0); 14202 nextAlarm.set(Calendar.HOUR_OF_DAY, 2); 14203 long possibleNextTimeMs = nextAlarm.getTimeInMillis(); 14204 if (possibleNextTimeMs < timeoutMs) { 14205 // The 2AM on the day of the timeout, move on the next day. 14206 possibleNextTimeMs += DateUtils.DAY_IN_MILLIS; 14207 } 14208 final long nextTimeMs = possibleNextTimeMs; 14209 final AlarmManager am = mAlarmManager; 14210 mHandler.post(() -> am.setWindow(AlarmManager.RTC, nextTimeMs, 14211 DateUtils.HOUR_IN_MILLIS, 14212 TAG, mLongPlugInAlarmHandler, mHandler)); 14213 } 14214 14215 14216 @GuardedBy("this") 14217 private boolean shouldResetWhilePluggedInLocked(long elapsedRealtimeMs) { 14218 if (mNoAutoReset) return false; 14219 if (!mSystemReady) return false; 14220 if (!mHistory.isResetEnabled()) return false; 14221 14222 final long pluggedInThresholdMs = mBatteryPluggedInRealTimeMs 14223 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14224 * DateUtils.HOUR_IN_MILLIS; 14225 if (elapsedRealtimeMs >= pluggedInThresholdMs) { 14226 // The device has been plugged in for a long time. 14227 final long resetThresholdMs = mRealtimeStartUs / 1000 14228 + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS 14229 * DateUtils.HOUR_IN_MILLIS; 14230 if (elapsedRealtimeMs >= resetThresholdMs) { 14231 // And it has been a long time since the last reset. 14232 return true; 14233 } 14234 } 14235 14236 return false; 14237 } 14238 14239 @GuardedBy("this") 14240 private boolean shouldResetOnUnplugLocked(int batteryStatus, int batteryLevel) { 14241 if (mNoAutoReset) return false; 14242 if (!mSystemReady) return false; 14243 if (!mHistory.isResetEnabled()) return false; 14244 if (mBatteryStatsConfig.shouldResetOnUnplugHighBatteryLevel()) { 14245 // Allow resetting due to currently being at high battery level 14246 if (batteryStatus == BatteryManager.BATTERY_STATUS_FULL) return true; 14247 if (batteryLevel >= 90) return true; 14248 } 14249 if (mBatteryStatsConfig.shouldResetOnUnplugAfterSignificantCharge()) { 14250 // Allow resetting after a significant charge (from a very low level to a now very 14251 // high level). 14252 if (mDischargePlugLevel < 20 && batteryLevel >= 80) return true; 14253 } 14254 if (getHighDischargeAmountSinceCharge() >= 200) { 14255 // Reset the stats if battery got partially charged and discharged repeatedly without 14256 // ever reaching the full charge. 14257 // This reset is done in order to prevent stats sessions from going on forever. 14258 // Exceedingly long battery sessions would lead to an overflow of 14259 // data structures such as mWakeupReasonStats. 14260 return true; 14261 } 14262 14263 return false; 14264 } 14265 14266 @GuardedBy("this") 14267 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 14268 final boolean onBattery, final int oldStatus, final int level, final int chargeUah) { 14269 boolean doWrite = false; 14270 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 14271 m.arg1 = onBattery ? 1 : 0; 14272 mHandler.sendMessage(m); 14273 14274 final long uptimeUs = mSecUptime * 1000; 14275 final long realtimeUs = mSecRealtime * 1000; 14276 final int screenState = mScreenState; 14277 if (onBattery) { 14278 boolean reset = false; 14279 if (shouldResetOnUnplugLocked(oldStatus, level)) { 14280 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 14281 + " dischargeLevel=" + mDischargePlugLevel 14282 + " lowAmount=" + getLowDischargeAmountSinceCharge() 14283 + " highAmount=" + getHighDischargeAmountSinceCharge()); 14284 // Before we write, collect a snapshot of the final aggregated 14285 // stats to be reported in the next checkin. Only do this if we have 14286 // a sufficient amount of data to make it interesting. 14287 if (getLowDischargeAmountSinceCharge() >= 20) { 14288 final long startTimeMs = SystemClock.uptimeMillis(); 14289 final Parcel parcel = Parcel.obtain(); 14290 writeSummaryToParcel(parcel, true); 14291 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 14292 BackgroundThread.getHandler().post(new Runnable() { 14293 @Override public void run() { 14294 synchronized (mCheckinFile) { 14295 final long startTimeMs2 = SystemClock.uptimeMillis(); 14296 FileOutputStream stream = null; 14297 try { 14298 stream = mCheckinFile.startWrite(); 14299 stream.write(parcel.marshall()); 14300 stream.flush(); 14301 mCheckinFile.finishWrite(stream); 14302 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 14303 "batterystats-checkin", initialTimeMs 14304 + SystemClock.uptimeMillis() - startTimeMs2); 14305 } catch (IOException e) { 14306 Slog.w("BatteryStats", 14307 "Error writing checkin battery statistics", e); 14308 mCheckinFile.failWrite(stream); 14309 } finally { 14310 parcel.recycle(); 14311 } 14312 } 14313 } 14314 }); 14315 } 14316 doWrite = true; 14317 resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_FULL_CHARGE); 14318 if (chargeUah > 0 && level > 0) { 14319 // Only use the reported coulomb charge value if it is supported and reported. 14320 mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0)); 14321 } 14322 reset = true; 14323 mDischargeStepTracker.init(); 14324 } 14325 if (mCharging) { 14326 setChargingLocked(false); 14327 } 14328 mOnBattery = mOnBatteryInternal = true; 14329 mLastDischargeStepLevel = level; 14330 mMinDischargeStepLevel = level; 14331 mDischargeStepTracker.clearTime(); 14332 mDailyDischargeStepTracker.clearTime(); 14333 mInitStepMode = mCurStepMode; 14334 mModStepMode = 0; 14335 pullPendingStateUpdatesLocked(); 14336 if (reset) { 14337 mHistory.startRecordingHistory(mSecRealtime, mSecUptime, reset); 14338 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 14339 } 14340 mBatteryPluggedIn = false; 14341 if (mAlarmManager != null) { 14342 final AlarmManager am = mAlarmManager; 14343 mHandler.post(() -> { 14344 // No longer plugged in. Cancel the long plug in alarm. 14345 am.cancel(mLongPlugInAlarmHandler); 14346 }); 14347 } 14348 mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn); 14349 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 14350 if (Display.isOnState(screenState)) { 14351 mDischargeScreenOnUnplugLevel = level; 14352 mDischargeScreenDozeUnplugLevel = 0; 14353 mDischargeScreenOffUnplugLevel = 0; 14354 } else if (Display.isDozeState(screenState)) { 14355 mDischargeScreenOnUnplugLevel = 0; 14356 mDischargeScreenDozeUnplugLevel = level; 14357 mDischargeScreenOffUnplugLevel = 0; 14358 } else { 14359 mDischargeScreenOnUnplugLevel = 0; 14360 mDischargeScreenDozeUnplugLevel = 0; 14361 mDischargeScreenOffUnplugLevel = level; 14362 } 14363 mDischargeAmountScreenOn = 0; 14364 mDischargeAmountScreenDoze = 0; 14365 mDischargeAmountScreenOff = 0; 14366 updateTimeBasesLocked(true, screenState, uptimeUs, realtimeUs); 14367 } else { 14368 mOnBattery = mOnBatteryInternal = false; 14369 pullPendingStateUpdatesLocked(); 14370 mBatteryPluggedIn = true; 14371 mBatteryPluggedInRealTimeMs = mSecRealtime; 14372 mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn); 14373 mDischargeCurrentLevel = mDischargePlugLevel = level; 14374 if (level < mDischargeUnplugLevel) { 14375 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 14376 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 14377 } 14378 updateDischargeScreenLevelsLocked(screenState, screenState); 14379 updateTimeBasesLocked(false, screenState, uptimeUs, realtimeUs); 14380 mChargeStepTracker.init(); 14381 mLastChargeStepLevel = level; 14382 mMaxChargeStepLevel = level; 14383 mInitStepMode = mCurStepMode; 14384 mModStepMode = 0; 14385 scheduleNextResetWhilePluggedInCheck(); 14386 } 14387 if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) { 14388 if (mStatsFile != null && !mHistory.isReadOnly()) { 14389 writeAsyncLocked(); 14390 } 14391 } 14392 } 14393 14394 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 14395 if (mExternalSync != null) { 14396 mExternalSync.scheduleSync(reason, updateFlags); 14397 } 14398 } 14399 14400 // This should probably be exposed in the API, though it's not critical 14401 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 14402 14403 @GuardedBy("this") 14404 public void setBatteryStateLocked(final int status, final int health, final int plugType, 14405 final int level, /* not final */ int temp, final int voltageMv, final int chargeUah, 14406 final int chargeFullUah, final long chargeTimeToFullSeconds, 14407 final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs) { 14408 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 14409 temp = Math.max(0, temp); 14410 14411 reportChangesToStatsLog(status, plugType, level); 14412 14413 final boolean onBattery = isOnBattery(plugType, status); 14414 if (!mHaveBatteryLevel) { 14415 mHaveBatteryLevel = true; 14416 // We start out assuming that the device is plugged in (not 14417 // on battery). If our first report is now that we are indeed 14418 // plugged in, then twiddle our state to correctly reflect that 14419 // since we won't be going through the full setOnBattery(). 14420 if (onBattery == mOnBattery) { 14421 mHistory.setPluggedInState(!onBattery); 14422 } 14423 mBatteryStatus = status; 14424 mBatteryLevel = level; 14425 mBatteryChargeUah = chargeUah; 14426 14427 // Always start out assuming charging, that will be updated later. 14428 mHistory.setBatteryState(true /* charging */, status, level, chargeUah); 14429 14430 mMaxChargeStepLevel = mMinDischargeStepLevel = 14431 mLastChargeStepLevel = mLastDischargeStepLevel = level; 14432 } else if (mBatteryLevel != level || mOnBattery != onBattery) { 14433 recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs); 14434 } 14435 int oldStatus = mBatteryStatus; 14436 if (onBattery) { 14437 mDischargeCurrentLevel = level; 14438 if (!mHistory.isRecordingHistory()) { 14439 mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 14440 } 14441 } else if (level < 96 && 14442 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 14443 if (!mHistory.isRecordingHistory()) { 14444 mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 14445 } 14446 } 14447 if (mDischargePlugLevel < 0) { 14448 mDischargePlugLevel = level; 14449 } 14450 14451 if (onBattery != mOnBattery) { 14452 mBatteryLevel = level; 14453 mBatteryStatus = status; 14454 mBatteryHealth = health; 14455 mBatteryPlugType = plugType; 14456 mBatteryTemperature = temp; 14457 mBatteryVoltageMv = voltageMv; 14458 mHistory.setBatteryState(status, level, health, plugType, temp, voltageMv, chargeUah); 14459 if (chargeUah < mBatteryChargeUah) { 14460 // Only record discharges 14461 final long chargeDiff = (long) mBatteryChargeUah - chargeUah; 14462 mDischargeCounter.addCountLocked(chargeDiff); 14463 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 14464 if (Display.isDozeState(mScreenState)) { 14465 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 14466 } 14467 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 14468 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 14469 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 14470 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 14471 } 14472 } 14473 mBatteryChargeUah = chargeUah; 14474 setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUah); 14475 } else { 14476 boolean changed = false; 14477 if (mBatteryLevel != level) { 14478 mBatteryLevel = level; 14479 changed = true; 14480 14481 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 14482 // which will pull external stats. 14483 mExternalSync.scheduleSyncDueToBatteryLevelChange( 14484 mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); 14485 } 14486 if (mBatteryStatus != status) { 14487 mBatteryStatus = status; 14488 changed = true; 14489 } 14490 if (mBatteryHealth != health) { 14491 mBatteryHealth = health; 14492 changed = true; 14493 } 14494 if (mBatteryPlugType != plugType) { 14495 mBatteryPlugType = plugType; 14496 changed = true; 14497 } 14498 if (temp >= (mBatteryTemperature + 10) 14499 || temp <= (mBatteryTemperature - 10)) { 14500 mBatteryTemperature = temp; 14501 changed = true; 14502 } 14503 if (voltageMv > (mBatteryVoltageMv + 20) 14504 || voltageMv < (mBatteryVoltageMv - 20)) { 14505 mBatteryVoltageMv = voltageMv; 14506 changed = true; 14507 } 14508 if (chargeUah >= (mBatteryChargeUah + 10) 14509 || chargeUah <= (mBatteryChargeUah - 10)) { 14510 if (chargeUah < mBatteryChargeUah) { 14511 // Only record discharges 14512 final long chargeDiff = (long) mBatteryChargeUah - chargeUah; 14513 mDischargeCounter.addCountLocked(chargeDiff); 14514 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 14515 if (Display.isDozeState(mScreenState)) { 14516 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 14517 } 14518 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 14519 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 14520 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 14521 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 14522 } 14523 } 14524 mBatteryChargeUah = chargeUah; 14525 changed = true; 14526 } 14527 14528 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 14529 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 14530 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 14531 if (onBattery) { 14532 changed |= setChargingLocked(false); 14533 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 14534 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 14535 modeBits, elapsedRealtimeMs); 14536 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 14537 modeBits, elapsedRealtimeMs); 14538 mLastDischargeStepLevel = level; 14539 mMinDischargeStepLevel = level; 14540 mInitStepMode = mCurStepMode; 14541 mModStepMode = 0; 14542 } 14543 } else { 14544 if (level >= 90) { 14545 // If the battery level is at least 90%, always consider the device to be 14546 // charging even if it happens to go down a level. 14547 changed |= setChargingLocked(true); 14548 } else if (!mCharging) { 14549 if (mLastChargeStepLevel < level) { 14550 // We have not reported that we are charging, but the level has gone up, 14551 // but we would like to not have tons of activity from charging-constraint 14552 // jobs, so instead of reporting ACTION_CHARGING immediately, we defer it. 14553 if (!mHandler.hasCallbacks(mDeferSetCharging)) { 14554 mHandler.postDelayed( 14555 mDeferSetCharging, 14556 mConstants.BATTERY_CHARGED_DELAY_MS); 14557 } 14558 } else if (mLastChargeStepLevel > level) { 14559 // if we had deferred a runnable due to charge level increasing, but then 14560 // later the charge level drops (could be due to thermal issues), we don't 14561 // want to trigger the deferred runnable, so remove it here 14562 mHandler.removeCallbacks(mDeferSetCharging); 14563 } 14564 } else { 14565 if (mLastChargeStepLevel > level) { 14566 // We had reported that the device was charging, but here we are with 14567 // power connected and the level going down. Looks like the current 14568 // power supplied isn't enough, so consider the device to now be 14569 // discharging. 14570 changed |= setChargingLocked(false); 14571 } 14572 } 14573 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 14574 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 14575 modeBits, elapsedRealtimeMs); 14576 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 14577 modeBits, elapsedRealtimeMs); 14578 mMaxChargeStepLevel = level; 14579 mInitStepMode = mCurStepMode; 14580 mModStepMode = 0; 14581 } 14582 mLastChargeStepLevel = level; 14583 } 14584 if (changed) { 14585 mHistory.setBatteryState(mBatteryStatus, mBatteryLevel, mBatteryHealth, 14586 mBatteryPlugType, mBatteryTemperature, mBatteryVoltageMv, 14587 mBatteryChargeUah); 14588 mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs); 14589 } 14590 } 14591 if (!onBattery && 14592 (status == BatteryManager.BATTERY_STATUS_FULL || 14593 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) { 14594 // We don't record history while we are plugged in and fully charged 14595 // (or when battery is not present). The next time we are 14596 // unplugged, history will be cleared. 14597 mHistory.setHistoryRecordingEnabled(DEBUG); 14598 } 14599 14600 mLastLearnedBatteryCapacityUah = chargeFullUah; 14601 if (mMinLearnedBatteryCapacityUah == -1) { 14602 mMinLearnedBatteryCapacityUah = chargeFullUah; 14603 } else { 14604 mMinLearnedBatteryCapacityUah = Math.min(mMinLearnedBatteryCapacityUah, chargeFullUah); 14605 } 14606 mMaxLearnedBatteryCapacityUah = Math.max(mMaxLearnedBatteryCapacityUah, chargeFullUah); 14607 14608 mBatteryTimeToFullSeconds = chargeTimeToFullSeconds; 14609 } 14610 14611 public static boolean isOnBattery(int plugType, int status) { 14612 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 14613 } 14614 14615 // Inform StatsLog of setBatteryState changes. 14616 private void reportChangesToStatsLog(final int status, final int plugType, final int level) { 14617 if (!mHaveBatteryLevel || mBatteryStatus != status) { 14618 FrameworkStatsLog.write(FrameworkStatsLog.CHARGING_STATE_CHANGED, status); 14619 } 14620 if (!mHaveBatteryLevel || mBatteryPlugType != plugType) { 14621 FrameworkStatsLog.write(FrameworkStatsLog.PLUGGED_STATE_CHANGED, plugType); 14622 } 14623 if (!mHaveBatteryLevel || mBatteryLevel != level) { 14624 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_LEVEL_CHANGED, level); 14625 } 14626 } 14627 14628 public long getAwakeTimeBattery() { 14629 // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); 14630 // for over a decade, but surely that was a mistake. 14631 return getBatteryUptimeLocked(mClock.uptimeMillis()); 14632 } 14633 14634 public long getAwakeTimePlugged() { 14635 return (mClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 14636 } 14637 14638 @Override 14639 public long computeUptime(long curTimeUs, int which) { 14640 return mUptimeUs + (curTimeUs - mUptimeStartUs); 14641 } 14642 14643 @Override 14644 public long computeRealtime(long curTimeUs, int which) { 14645 return mRealtimeUs + (curTimeUs - mRealtimeStartUs); 14646 } 14647 14648 @Override 14649 public long computeBatteryUptime(long curTimeUs, int which) { 14650 return mOnBatteryTimeBase.computeUptime(curTimeUs, which); 14651 } 14652 14653 @Override 14654 public long computeBatteryRealtime(long curTimeUs, int which) { 14655 return mOnBatteryTimeBase.computeRealtime(curTimeUs, which); 14656 } 14657 14658 @Override 14659 public long computeBatteryScreenOffUptime(long curTimeUs, int which) { 14660 return mOnBatteryScreenOffTimeBase.computeUptime(curTimeUs, which); 14661 } 14662 14663 @Override 14664 public long computeBatteryScreenOffRealtime(long curTimeUs, int which) { 14665 return mOnBatteryScreenOffTimeBase.computeRealtime(curTimeUs, which); 14666 } 14667 14668 @Override 14669 public long computeBatteryTimeRemaining(long curTime) { 14670 if (!mOnBattery) { 14671 return -1; 14672 } 14673 /* Simple implementation just looks at the average discharge per level across the 14674 entire sample period. 14675 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 14676 if (discharge < 2) { 14677 return -1; 14678 } 14679 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 14680 if (duration < 1000*1000) { 14681 return -1; 14682 } 14683 long usPerLevel = duration/discharge; 14684 return usPerLevel * mCurrentBatteryLevel; 14685 */ 14686 if (mDischargeStepTracker.mNumStepDurations < 1) { 14687 return -1; 14688 } 14689 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 14690 if (msPerLevel <= 0) { 14691 return -1; 14692 } 14693 return (msPerLevel * mBatteryLevel) * 1000; 14694 } 14695 14696 @Override 14697 public LevelStepTracker getDischargeLevelStepTracker() { 14698 return mDischargeStepTracker; 14699 } 14700 14701 @Override 14702 public LevelStepTracker getDailyDischargeLevelStepTracker() { 14703 return mDailyDischargeStepTracker; 14704 } 14705 14706 @Override 14707 public long computeChargeTimeRemaining(long curTime) { 14708 if (mOnBattery) { 14709 // Not yet working. 14710 return -1; 14711 } 14712 if (mBatteryTimeToFullSeconds >= 0) { 14713 return mBatteryTimeToFullSeconds * (1000 * 1000); // s to us 14714 } 14715 // Else use algorithmic approach 14716 if (mChargeStepTracker.mNumStepDurations < 1) { 14717 return -1; 14718 } 14719 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 14720 if (msPerLevel <= 0) { 14721 return -1; 14722 } 14723 return (msPerLevel * (100 - mBatteryLevel)) * 1000; 14724 } 14725 14726 /*@hide */ 14727 public CellularBatteryStats getCellularBatteryStats() { 14728 final int which = STATS_SINCE_CHARGED; 14729 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 14730 final ControllerActivityCounter counter = getModemControllerActivity(); 14731 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 14732 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 14733 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 14734 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 14735 final long monitoredRailChargeConsumedMaMs = 14736 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 14737 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 14738 for (int i = 0; i < timeInRatMs.length; i++) { 14739 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTimeUs, which) / 1000; 14740 } 14741 long[] timeInRxSignalStrengthLevelMs = 14742 new long[CellSignalStrength.getNumSignalStrengthLevels()]; 14743 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { 14744 timeInRxSignalStrengthLevelMs[i] = 14745 getPhoneSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 14746 } 14747 long[] txTimeMs = new long[Math.min(ModemActivityInfo.getNumTxPowerLevels(), 14748 counter.getTxTimeCounters().length)]; 14749 long totalTxTimeMs = 0; 14750 for (int i = 0; i < txTimeMs.length; i++) { 14751 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which); 14752 totalTxTimeMs += txTimeMs[i]; 14753 } 14754 14755 return new CellularBatteryStats(computeBatteryRealtime(rawRealTimeUs, which) / 1000, 14756 getMobileRadioActiveTime(rawRealTimeUs, which) / 1000, 14757 getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which), 14758 getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which), 14759 getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which), 14760 getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which), 14761 sleepTimeMs, idleTimeMs, rxTimeMs, energyConsumedMaMs, timeInRatMs, 14762 timeInRxSignalStrengthLevelMs, txTimeMs, 14763 monitoredRailChargeConsumedMaMs); 14764 } 14765 14766 /*@hide */ 14767 public WifiBatteryStats getWifiBatteryStats() { 14768 final int which = STATS_SINCE_CHARGED; 14769 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 14770 final ControllerActivityCounter counter = getWifiControllerActivity(); 14771 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 14772 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); 14773 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 14774 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); 14775 final long totalControllerActivityTimeMs 14776 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000; 14777 final long sleepTimeMs 14778 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs); 14779 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 14780 final long monitoredRailChargeConsumedMaMs = 14781 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 14782 long numAppScanRequest = 0; 14783 for (int i = 0; i < mUidStats.size(); i++) { 14784 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); 14785 } 14786 long[] timeInStateMs = new long[NUM_WIFI_STATES]; 14787 for (int i=0; i<NUM_WIFI_STATES; i++) { 14788 timeInStateMs[i] = getWifiStateTime(i, rawRealTimeUs, which) / 1000; 14789 } 14790 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; 14791 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14792 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTimeUs, which) / 1000; 14793 } 14794 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 14795 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14796 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 14797 } 14798 return new WifiBatteryStats( 14799 computeBatteryRealtime(rawRealTimeUs, which) / 1000, 14800 getWifiActiveTime(rawRealTimeUs, which) / 1000, 14801 getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which), 14802 getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which), 14803 getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which), 14804 getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which), 14805 sleepTimeMs, scanTimeMs, idleTimeMs, rxTimeMs, txTimeMs, energyConsumedMaMs, 14806 numAppScanRequest, timeInStateMs, timeSignalStrengthTimeMs, timeInSupplStateMs, 14807 monitoredRailChargeConsumedMaMs); 14808 } 14809 14810 /*@hide */ 14811 public GpsBatteryStats getGpsBatteryStats() { 14812 GpsBatteryStats s = new GpsBatteryStats(); 14813 final int which = STATS_SINCE_CHARGED; 14814 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 14815 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTimeUs, which) / 1000); 14816 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); 14817 long[] time = new long[mGpsSignalQualityTimer.length]; 14818 for (int i=0; i<time.length; i++) { 14819 time[i] = getGpsSignalQualityTime(i, rawRealTimeUs, which) / 1000; 14820 } 14821 s.setTimeInGpsSignalQualityLevel(time); 14822 return s; 14823 } 14824 14825 @Override 14826 public LevelStepTracker getChargeLevelStepTracker() { 14827 return mChargeStepTracker; 14828 } 14829 14830 @Override 14831 public LevelStepTracker getDailyChargeLevelStepTracker() { 14832 return mDailyChargeStepTracker; 14833 } 14834 14835 @Override 14836 public ArrayList<PackageChange> getDailyPackageChanges() { 14837 return mDailyPackageChanges; 14838 } 14839 14840 /** 14841 * @return battery uptime in microseconds 14842 */ 14843 protected long getBatteryUptimeLocked(long uptimeMs) { 14844 return mOnBatteryTimeBase.getUptime(uptimeMs * 1000); 14845 } 14846 14847 @Override 14848 public long getBatteryUptime(long curTimeUs) { 14849 return mOnBatteryTimeBase.getUptime(curTimeUs); 14850 } 14851 14852 @Override 14853 public long getBatteryRealtime(long curTimeUs) { 14854 return mOnBatteryTimeBase.getRealtime(curTimeUs); 14855 } 14856 14857 @Override 14858 public int getDischargeStartLevel() { 14859 synchronized(this) { 14860 return getDischargeStartLevelLocked(); 14861 } 14862 } 14863 14864 public int getDischargeStartLevelLocked() { 14865 return mDischargeUnplugLevel; 14866 } 14867 14868 @Override 14869 public int getDischargeCurrentLevel() { 14870 synchronized(this) { 14871 return getDischargeCurrentLevelLocked(); 14872 } 14873 } 14874 14875 public int getDischargeCurrentLevelLocked() { 14876 return mDischargeCurrentLevel; 14877 } 14878 14879 @Override 14880 public int getLowDischargeAmountSinceCharge() { 14881 synchronized(this) { 14882 int val = mLowDischargeAmountSinceCharge; 14883 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 14884 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 14885 } 14886 return val; 14887 } 14888 } 14889 14890 @Override 14891 public int getHighDischargeAmountSinceCharge() { 14892 synchronized(this) { 14893 int val = mHighDischargeAmountSinceCharge; 14894 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 14895 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 14896 } 14897 return val; 14898 } 14899 } 14900 14901 @Override 14902 public int getDischargeAmount(int which) { 14903 int dischargeAmount = which == STATS_SINCE_CHARGED 14904 ? getHighDischargeAmountSinceCharge() 14905 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 14906 if (dischargeAmount < 0) { 14907 dischargeAmount = 0; 14908 } 14909 return dischargeAmount; 14910 } 14911 14912 @Override 14913 public int getDischargeAmountScreenOn() { 14914 synchronized(this) { 14915 int val = mDischargeAmountScreenOn; 14916 if (mOnBattery && Display.isOnState(mScreenState) 14917 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 14918 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 14919 } 14920 return val; 14921 } 14922 } 14923 14924 @Override 14925 public int getDischargeAmountScreenOnSinceCharge() { 14926 synchronized(this) { 14927 int val = mDischargeAmountScreenOnSinceCharge; 14928 if (mOnBattery && Display.isOnState(mScreenState) 14929 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 14930 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 14931 } 14932 return val; 14933 } 14934 } 14935 14936 @Override 14937 public int getDischargeAmountScreenOff() { 14938 synchronized(this) { 14939 int val = mDischargeAmountScreenOff; 14940 if (mOnBattery && Display.isOffState(mScreenState) 14941 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 14942 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 14943 } 14944 // For backward compatibility, doze discharge is counted into screen off. 14945 return val + getDischargeAmountScreenDoze(); 14946 } 14947 } 14948 14949 @Override 14950 public int getDischargeAmountScreenOffSinceCharge() { 14951 synchronized(this) { 14952 int val = mDischargeAmountScreenOffSinceCharge; 14953 if (mOnBattery && Display.isOffState(mScreenState) 14954 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 14955 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 14956 } 14957 // For backward compatibility, doze discharge is counted into screen off. 14958 return val + getDischargeAmountScreenDozeSinceCharge(); 14959 } 14960 } 14961 14962 @Override 14963 public int getDischargeAmountScreenDoze() { 14964 synchronized(this) { 14965 int val = mDischargeAmountScreenDoze; 14966 if (mOnBattery && Display.isDozeState(mScreenState) 14967 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 14968 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 14969 } 14970 return val; 14971 } 14972 } 14973 14974 @Override 14975 public int getDischargeAmountScreenDozeSinceCharge() { 14976 synchronized(this) { 14977 int val = mDischargeAmountScreenDozeSinceCharge; 14978 if (mOnBattery && Display.isDozeState(mScreenState) 14979 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 14980 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 14981 } 14982 return val; 14983 } 14984 } 14985 14986 14987 /** 14988 * Estimates the time spent by the system server handling incoming binder requests. 14989 */ 14990 @Override 14991 public long[] getSystemServiceTimeAtCpuSpeeds() { 14992 if (mBinderThreadCpuTimesUs == null) { 14993 return null; 14994 } 14995 14996 return mBinderThreadCpuTimesUs.getCountsLocked(BatteryStats.STATS_SINCE_CHARGED); 14997 } 14998 14999 /** 15000 * Retrieve the statistics object for a particular uid, creating if needed. 15001 */ 15002 public Uid getUidStatsLocked(int uid) { 15003 return getUidStatsLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 15004 } 15005 15006 public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 15007 Uid u = mUidStats.get(uid); 15008 if (u == null) { 15009 if (Process.isSdkSandboxUid(uid)) { 15010 Log.wtf(TAG, "Tracking an SDK Sandbox UID"); 15011 } 15012 u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 15013 mUidStats.put(uid, u); 15014 } 15015 return u; 15016 } 15017 15018 /** 15019 * Retrieve the statistics object for a particular uid. Returns null if the object is not 15020 * available. 15021 */ 15022 public Uid getAvailableUidStatsLocked(int uid) { 15023 Uid u = mUidStats.get(uid); 15024 return u; 15025 } 15026 15027 @GuardedBy("this") 15028 public void onCleanupUserLocked(int userId, long elapsedRealtimeMs) { 15029 final int firstUidForUser = UserHandle.getUid(userId, 0); 15030 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 15031 mPendingRemovedUids.add( 15032 new UidToRemove(firstUidForUser, lastUidForUser, elapsedRealtimeMs)); 15033 } 15034 15035 @GuardedBy("this") 15036 public void onUserRemovedLocked(int userId) { 15037 if (mExternalSync != null) { 15038 // Clear out the removed user's UIDs after a short delay. The delay is needed 15039 // because at the point that this method is called, some activities are still 15040 // being wrapped up by those UIDs 15041 mExternalSync.scheduleCleanupDueToRemovedUser(userId); 15042 } 15043 } 15044 15045 /** 15046 * Removes battery stats for UIDs corresponding to a removed user. 15047 */ 15048 @GuardedBy("this") 15049 public void clearRemovedUserUidsLocked(int userId) { 15050 final int firstUidForUser = UserHandle.getUid(userId, 0); 15051 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 15052 mUidStats.put(firstUidForUser, null); 15053 mUidStats.put(lastUidForUser, null); 15054 final int firstIndex = mUidStats.indexOfKey(firstUidForUser); 15055 final int lastIndex = mUidStats.indexOfKey(lastUidForUser); 15056 for (int i = firstIndex; i <= lastIndex; i++) { 15057 final Uid uid = mUidStats.valueAt(i); 15058 if (uid != null) { 15059 uid.detachFromTimeBase(); 15060 } 15061 } 15062 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1); 15063 removeCpuStatsForUidRangeLocked(firstUidForUser, lastUidForUser); 15064 } 15065 15066 /** 15067 * @see #removeUidStatsLocked(int) 15068 */ 15069 @GuardedBy("this") 15070 public void removeUidStatsLocked(int uid, long elapsedRealtimeMs) { 15071 final Uid u = mUidStats.get(uid); 15072 if (u != null) { 15073 u.detachFromTimeBase(); 15074 } 15075 mUidStats.remove(uid); 15076 mPendingRemovedUids.add(new UidToRemove(uid, elapsedRealtimeMs)); 15077 } 15078 15079 /** 15080 * Removes the data for the deleted UIDs from the underlying kernel eBPF tables. 15081 */ 15082 @GuardedBy("this") 15083 private void removeCpuStatsForUidRangeLocked(int startUid, int endUid) { 15084 if (startUid == endUid) { 15085 mCpuUidUserSysTimeReader.removeUid(startUid); 15086 mCpuUidFreqTimeReader.removeUid(startUid); 15087 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 15088 mCpuUidActiveTimeReader.removeUid(startUid); 15089 mCpuUidClusterTimeReader.removeUid(startUid); 15090 } 15091 if (mKernelSingleUidTimeReader != null) { 15092 mKernelSingleUidTimeReader.removeUid(startUid); 15093 } 15094 mNumUidsRemoved++; 15095 } else if (startUid < endUid) { 15096 mCpuUidFreqTimeReader.removeUidsInRange(startUid, endUid); 15097 mCpuUidUserSysTimeReader.removeUidsInRange(startUid, endUid); 15098 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 15099 mCpuUidActiveTimeReader.removeUidsInRange(startUid, endUid); 15100 mCpuUidClusterTimeReader.removeUidsInRange(startUid, endUid); 15101 } 15102 if (mKernelSingleUidTimeReader != null) { 15103 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid); 15104 } 15105 // Treat as one. We don't know how many uids there are in between. 15106 mNumUidsRemoved++; 15107 } else { 15108 Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid); 15109 } 15110 } 15111 15112 /** 15113 * Retrieve the statistics object for a particular process, creating 15114 * if needed. 15115 */ 15116 public Uid.Proc getProcessStatsLocked(int uid, String name, 15117 long elapsedRealtimeMs, long uptimeMs) { 15118 uid = mapUid(uid); 15119 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15120 return u.getProcessStatsLocked(name); 15121 } 15122 15123 /** 15124 * Retrieve the statistics object for a particular process, creating 15125 * if needed. 15126 */ 15127 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 15128 return getPackageStatsLocked(uid, pkg, mClock.elapsedRealtime(), mClock.uptimeMillis()); 15129 } 15130 15131 /** 15132 * @see getPackageStatsLocked(int, String) 15133 */ 15134 public Uid.Pkg getPackageStatsLocked(int uid, String pkg, 15135 long elapsedRealtimeMs, long uptimeMs) { 15136 uid = mapUid(uid); 15137 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15138 return u.getPackageStatsLocked(pkg); 15139 } 15140 15141 /** 15142 * Retrieve the statistics object for a particular service, creating 15143 * if needed. 15144 */ 15145 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name, 15146 long elapsedRealtimeMs, long uptimeMs) { 15147 uid = mapUid(uid); 15148 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 15149 return u.getServiceStatsLocked(pkg, name); 15150 } 15151 15152 @GuardedBy("this") 15153 public void shutdownLocked() { 15154 mHistory.recordShutdownEvent(mClock.elapsedRealtime(), mClock.uptimeMillis(), 15155 mClock.currentTimeMillis()); 15156 writeSyncLocked(); 15157 mShuttingDown = true; 15158 } 15159 15160 @GuardedBy("this") 15161 @Override 15162 public boolean isProcessStateDataAvailable() { 15163 return trackPerProcStateCpuTimes(); 15164 } 15165 15166 @GuardedBy("this") 15167 private boolean trackPerProcStateCpuTimes() { 15168 return mCpuUidFreqTimeReader.isFastCpuTimesReader(); 15169 } 15170 15171 @GuardedBy("this") 15172 boolean isUsageHistoryEnabled() { 15173 return mConstants.RECORD_USAGE_HISTORY; 15174 } 15175 15176 @GuardedBy("this") 15177 public void systemServicesReady(Context context) { 15178 mConstants.startObserving(context.getContentResolver()); 15179 registerUsbStateReceiver(context); 15180 15181 synchronized (this) { 15182 mAlarmManager = context.getSystemService(AlarmManager.class); 15183 if (mBatteryPluggedIn) { 15184 // Already plugged in. Schedule the long plug in alarm. 15185 scheduleNextResetWhilePluggedInCheck(); 15186 } 15187 } 15188 } 15189 15190 /** 15191 * Initialize the EnergyConsumer stats data structures. 15192 * 15193 * @param supportedStandardBuckets boolean array indicating which {@link StandardPowerBucket}s 15194 * are currently supported. If null, none are supported 15195 * (regardless of customBucketNames). 15196 * @param customBucketNames names of custom (OTHER) EnergyConsumers on this device 15197 */ 15198 @GuardedBy("this") 15199 public void initEnergyConsumerStatsLocked(@Nullable boolean[] supportedStandardBuckets, 15200 String[] customBucketNames) { 15201 final int numDisplays = mPerDisplayBatteryStats.length; 15202 for (int i = 0; i < numDisplays; i++) { 15203 final int screenState = mPerDisplayBatteryStats[i].screenState; 15204 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 15205 } 15206 15207 final boolean compatibleConfig; 15208 if (supportedStandardBuckets != null) { 15209 final EnergyConsumerStats.Config config = new EnergyConsumerStats.Config( 15210 supportedStandardBuckets, customBucketNames, 15211 SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS, 15212 getBatteryConsumerProcessStateNames()); 15213 15214 if (mEnergyConsumerStatsConfig == null) { 15215 compatibleConfig = true; 15216 } else { 15217 compatibleConfig = mEnergyConsumerStatsConfig.isCompatible(config); 15218 } 15219 15220 mEnergyConsumerStatsConfig = config; 15221 mGlobalEnergyConsumerStats = new EnergyConsumerStats(config); 15222 15223 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_BLUETOOTH]) { 15224 mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile); 15225 } 15226 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_CPU]) { 15227 mCpuPowerCalculator = new CpuPowerCalculator(mPowerProfile); 15228 } 15229 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO]) { 15230 mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile); 15231 } 15232 if (supportedStandardBuckets[EnergyConsumerStats.POWER_BUCKET_WIFI]) { 15233 mWifiPowerCalculator = new WifiPowerCalculator(mPowerProfile); 15234 } 15235 } else { 15236 compatibleConfig = (mEnergyConsumerStatsConfig == null); 15237 // EnergyConsumer no longer supported, wipe out the existing data. 15238 mEnergyConsumerStatsConfig = null; 15239 mGlobalEnergyConsumerStats = null; 15240 } 15241 15242 if (!compatibleConfig) { 15243 // Supported power buckets changed since last boot. 15244 // Existing data is no longer reliable. 15245 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 15246 RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE); 15247 } 15248 } 15249 15250 @GuardedBy("this") 15251 private boolean isMobileRadioEnergyConsumerSupportedLocked() { 15252 if (mGlobalEnergyConsumerStats == null) return false; 15253 return mGlobalEnergyConsumerStats.isStandardBucketSupported( 15254 EnergyConsumerStats.POWER_BUCKET_MOBILE_RADIO); 15255 } 15256 15257 @NonNull 15258 private static String[] getBatteryConsumerProcessStateNames() { 15259 String[] procStateNames = new String[BatteryConsumer.PROCESS_STATE_COUNT]; 15260 for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { 15261 procStateNames[procState] = BatteryConsumer.processStateToString(procState); 15262 } 15263 return procStateNames; 15264 } 15265 15266 /** Get the last known Battery voltage (in millivolts), returns -1 if unknown */ 15267 @GuardedBy("this") 15268 public int getBatteryVoltageMvLocked() { 15269 return mBatteryVoltageMv; 15270 } 15271 15272 @VisibleForTesting 15273 public final class Constants extends ContentObserver { 15274 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME 15275 = "track_cpu_active_cluster_time"; 15276 public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME 15277 = "kernel_uid_readers_throttle_time"; 15278 public static final String KEY_UID_REMOVE_DELAY_MS 15279 = "uid_remove_delay_ms"; 15280 public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 15281 = "external_stats_collection_rate_limit_ms"; 15282 public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS 15283 = "battery_level_collection_delay_ms"; 15284 public static final String KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 15285 "procstate_change_collection_delay_ms"; 15286 public static final String KEY_MAX_HISTORY_FILES = "max_history_files"; 15287 public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb"; 15288 public static final String KEY_BATTERY_CHARGED_DELAY_MS = 15289 "battery_charged_delay_ms"; 15290 public static final String KEY_RECORD_USAGE_HISTORY = 15291 "record_usage_history"; 15292 public static final String KEY_PER_UID_MODEM_POWER_MODEL = 15293 "per_uid_modem_power_model"; 15294 public static final String KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION = 15295 "phone_on_external_stats_collection"; 15296 public static final String KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 15297 "reset_while_plugged_in_minimum_duration_hours"; 15298 15299 public static final String PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME = 15300 "mobile_radio_active_time"; 15301 public static final String PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME = 15302 "modem_activity_info_rx_tx"; 15303 15304 /** Convert {@link PerUidModemPowerModel} to string */ 15305 public String getPerUidModemModelName(@PerUidModemPowerModel int model) { 15306 switch(model) { 15307 case PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME: 15308 return PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME; 15309 case PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX: 15310 return PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME; 15311 default: 15312 Slog.w(TAG, "Unexpected per uid modem model (" + model + ")"); 15313 return "unknown_" + model; 15314 } 15315 } 15316 15317 /** Convert string to {@link PerUidModemPowerModel} */ 15318 @PerUidModemPowerModel 15319 public int getPerUidModemModel(String name) { 15320 switch(name) { 15321 case PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME_NAME: 15322 return PER_UID_MODEM_POWER_MODEL_MOBILE_RADIO_ACTIVE_TIME; 15323 case PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX_NAME: 15324 return PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX; 15325 default: 15326 Slog.w(TAG, "Unexpected per uid modem model name (" + name + ")"); 15327 return DEFAULT_PER_UID_MODEM_MODEL; 15328 } 15329 } 15330 15331 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; 15332 private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000; 15333 private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; 15334 private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; 15335 private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; 15336 private static final long DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 60_000; 15337 private static final int DEFAULT_MAX_HISTORY_FILES = 32; 15338 private static final int DEFAULT_MAX_HISTORY_BUFFER_KB = 128; /*Kilo Bytes*/ 15339 private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64; 15340 private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/ 15341 private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */ 15342 private static final boolean DEFAULT_RECORD_USAGE_HISTORY = false; 15343 @PerUidModemPowerModel 15344 private static final int DEFAULT_PER_UID_MODEM_MODEL = 15345 PER_UID_MODEM_POWER_MODEL_MODEM_ACTIVITY_INFO_RX_TX; 15346 private static final boolean DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION = true; 15347 // Little less than 2 days 15348 private static final int DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 47; 15349 15350 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; 15351 /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an 15352 * update when startObserving. */ 15353 public long KERNEL_UID_READERS_THROTTLE_TIME; 15354 public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; 15355 public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 15356 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 15357 public long BATTERY_LEVEL_COLLECTION_DELAY_MS 15358 = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; 15359 public long PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 15360 DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS; 15361 public int MAX_HISTORY_FILES; 15362 public int MAX_HISTORY_BUFFER; /*Bytes*/ 15363 public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS; 15364 public boolean RECORD_USAGE_HISTORY = DEFAULT_RECORD_USAGE_HISTORY; 15365 public int PER_UID_MODEM_MODEL = DEFAULT_PER_UID_MODEM_MODEL; 15366 public boolean PHONE_ON_EXTERNAL_STATS_COLLECTION = 15367 DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION; 15368 public int RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 15369 DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS; 15370 15371 private ContentResolver mResolver; 15372 private final KeyValueListParser mParser = new KeyValueListParser(','); 15373 15374 public Constants(Handler handler) { 15375 super(handler); 15376 if (ActivityManager.isLowRamDeviceStatic()) { 15377 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE; 15378 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB * 1024; 15379 } else { 15380 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES; 15381 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_KB * 1024; 15382 } 15383 } 15384 15385 public void startObserving(ContentResolver resolver) { 15386 mResolver = resolver; 15387 mResolver.registerContentObserver( 15388 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS), 15389 false /* notifyForDescendants */, this); 15390 mResolver.registerContentObserver( 15391 Settings.Global.getUriFor(Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY), 15392 false /* notifyForDescendants */, this); 15393 updateConstants(); 15394 } 15395 15396 @Override 15397 public void onChange(boolean selfChange, Uri uri) { 15398 if (uri.equals( 15399 Settings.Global.getUriFor( 15400 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY))) { 15401 synchronized (BatteryStatsImpl.this) { 15402 updateBatteryChargedDelayMsLocked(); 15403 } 15404 return; 15405 } 15406 updateConstants(); 15407 } 15408 15409 private void updateConstants() { 15410 synchronized (BatteryStatsImpl.this) { 15411 try { 15412 mParser.setString(Settings.Global.getString(mResolver, 15413 Settings.Global.BATTERY_STATS_CONSTANTS)); 15414 } catch (IllegalArgumentException e) { 15415 // Failed to parse the settings string, log this and move on 15416 // with defaults. 15417 Slog.e(TAG, "Bad batterystats settings", e); 15418 } 15419 15420 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( 15421 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); 15422 updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME, 15423 mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME, 15424 DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME)); 15425 updateUidRemoveDelay( 15426 mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS)); 15427 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( 15428 KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, 15429 DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 15430 BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( 15431 KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, 15432 DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); 15433 PROC_STATE_CHANGE_COLLECTION_DELAY_MS = mParser.getLong( 15434 KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS, 15435 DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 15436 MAX_HISTORY_FILES = mParser.getInt(KEY_MAX_HISTORY_FILES, 15437 ActivityManager.isLowRamDeviceStatic() ? 15438 DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE 15439 : DEFAULT_MAX_HISTORY_FILES); 15440 MAX_HISTORY_BUFFER = mParser.getInt(KEY_MAX_HISTORY_BUFFER_KB, 15441 ActivityManager.isLowRamDeviceStatic() ? 15442 DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB 15443 : DEFAULT_MAX_HISTORY_BUFFER_KB) 15444 * 1024; 15445 RECORD_USAGE_HISTORY = mParser.getBoolean( 15446 KEY_RECORD_USAGE_HISTORY, DEFAULT_RECORD_USAGE_HISTORY); 15447 final String perUidModemModel = mParser.getString(KEY_PER_UID_MODEM_POWER_MODEL, 15448 ""); 15449 PER_UID_MODEM_MODEL = getPerUidModemModel(perUidModemModel); 15450 15451 PHONE_ON_EXTERNAL_STATS_COLLECTION = mParser.getBoolean( 15452 KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION, 15453 DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION); 15454 15455 RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = mParser.getInt( 15456 KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS, 15457 DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); 15458 15459 updateBatteryChargedDelayMsLocked(); 15460 15461 onChange(); 15462 } 15463 } 15464 15465 /** 15466 * Propagates changes in constant values. 15467 */ 15468 @VisibleForTesting 15469 public void onChange() { 15470 mHistory.setMaxHistoryFiles(MAX_HISTORY_FILES); 15471 mHistory.setMaxHistoryBufferSize(MAX_HISTORY_BUFFER); 15472 } 15473 15474 private void updateBatteryChargedDelayMsLocked() { 15475 // a negative value indicates that we should ignore this override 15476 final int delay = Settings.Global.getInt(mResolver, 15477 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 15478 -1); 15479 15480 BATTERY_CHARGED_DELAY_MS = delay >= 0 ? delay : mParser.getInt( 15481 KEY_BATTERY_CHARGED_DELAY_MS, 15482 DEFAULT_BATTERY_CHARGED_DELAY_MS); 15483 15484 if (mHandler.hasCallbacks(mDeferSetCharging)) { 15485 mHandler.removeCallbacks(mDeferSetCharging); 15486 mHandler.postDelayed(mDeferSetCharging, BATTERY_CHARGED_DELAY_MS); 15487 } 15488 } 15489 15490 private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) { 15491 KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs; 15492 if (oldTimeMs != newTimeMs) { 15493 mCpuUidUserSysTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 15494 mCpuUidFreqTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 15495 mCpuUidActiveTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 15496 mCpuUidClusterTimeReader 15497 .setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 15498 } 15499 } 15500 15501 @GuardedBy("BatteryStatsImpl.this") 15502 private void updateUidRemoveDelay(long newTimeMs) { 15503 UID_REMOVE_DELAY_MS = newTimeMs; 15504 clearPendingRemovedUidsLocked(); 15505 } 15506 15507 public void dumpLocked(PrintWriter pw) { 15508 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); 15509 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); 15510 pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("="); 15511 pw.println(KERNEL_UID_READERS_THROTTLE_TIME); 15512 pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); 15513 pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 15514 pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); 15515 pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); 15516 pw.print(KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS); pw.print("="); 15517 pw.println(PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 15518 pw.print(KEY_MAX_HISTORY_FILES); pw.print("="); 15519 pw.println(MAX_HISTORY_FILES); 15520 pw.print(KEY_MAX_HISTORY_BUFFER_KB); pw.print("="); 15521 pw.println(MAX_HISTORY_BUFFER/1024); 15522 pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("="); 15523 pw.println(BATTERY_CHARGED_DELAY_MS); 15524 pw.print(KEY_RECORD_USAGE_HISTORY); pw.print("="); 15525 pw.println(RECORD_USAGE_HISTORY); 15526 pw.print(KEY_PER_UID_MODEM_POWER_MODEL); pw.print("="); 15527 pw.println(getPerUidModemModelName(PER_UID_MODEM_MODEL)); 15528 pw.print(KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION); pw.print("="); 15529 pw.println(PHONE_ON_EXTERNAL_STATS_COLLECTION); 15530 pw.print(KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); pw.print("="); 15531 pw.println(RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); 15532 } 15533 } 15534 15535 public long getExternalStatsCollectionRateLimitMs() { 15536 synchronized (this) { 15537 return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 15538 } 15539 } 15540 15541 @GuardedBy("this") 15542 public void dumpConstantsLocked(PrintWriter pw) { 15543 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 15544 iPw.println("BatteryStats constants:"); 15545 iPw.increaseIndent(); 15546 mConstants.dumpLocked(iPw); 15547 iPw.decreaseIndent(); 15548 } 15549 15550 @GuardedBy("this") 15551 public void dumpCpuStatsLocked(PrintWriter pw) { 15552 int size = mUidStats.size(); 15553 pw.println("Per UID CPU user & system time in ms:"); 15554 for (int i = 0; i < size; i++) { 15555 int u = mUidStats.keyAt(i); 15556 Uid uid = mUidStats.get(u); 15557 pw.print(" "); pw.print(u); pw.print(": "); 15558 pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" "); 15559 pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000); 15560 } 15561 15562 pw.println("Per UID CPU active time in ms:"); 15563 for (int i = 0; i < size; i++) { 15564 int u = mUidStats.keyAt(i); 15565 Uid uid = mUidStats.get(u); 15566 if (uid.getCpuActiveTime() > 0) { 15567 pw.print(" "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime()); 15568 } 15569 } 15570 pw.println("Per UID CPU cluster time in ms:"); 15571 for (int i = 0; i < size; i++) { 15572 int u = mUidStats.keyAt(i); 15573 long[] times = mUidStats.get(u).getCpuClusterTimes(); 15574 if (times != null) { 15575 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 15576 } 15577 } 15578 pw.println("Per UID CPU frequency time in ms:"); 15579 for (int i = 0; i < size; i++) { 15580 int u = mUidStats.keyAt(i); 15581 long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED); 15582 if (times != null) { 15583 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 15584 } 15585 } 15586 15587 updateSystemServiceCallStats(); 15588 if (mBinderThreadCpuTimesUs != null) { 15589 pw.println("Per UID System server binder time in ms:"); 15590 long[] systemServiceTimeAtCpuSpeeds = getSystemServiceTimeAtCpuSpeeds(); 15591 for (int i = 0; i < size; i++) { 15592 int u = mUidStats.keyAt(i); 15593 Uid uid = mUidStats.get(u); 15594 double proportionalSystemServiceUsage = uid.getProportionalSystemServiceUsage(); 15595 long timeUs = 0; 15596 for (int j = systemServiceTimeAtCpuSpeeds.length - 1; j >= 0; j--) { 15597 timeUs += systemServiceTimeAtCpuSpeeds[j] * proportionalSystemServiceUsage; 15598 } 15599 15600 pw.print(" "); 15601 pw.print(u); 15602 pw.print(": "); 15603 pw.println(timeUs / 1000); 15604 } 15605 } 15606 } 15607 15608 @GuardedBy("this") 15609 private void dumpCpuPowerBracketsLocked(PrintWriter pw) { 15610 pw.println("CPU power brackets; cluster/freq in MHz(avg current in mA):"); 15611 final int bracketCount = mPowerProfile.getCpuPowerBracketCount(); 15612 for (int bracket = 0; bracket < bracketCount; bracket++) { 15613 pw.print(" "); 15614 pw.print(bracket); 15615 pw.print(": "); 15616 pw.println(mPowerProfile.getCpuPowerBracketDescription(bracket)); 15617 } 15618 } 15619 15620 /** 15621 * Dump EnergyConsumer stats 15622 */ 15623 @GuardedBy("this") 15624 public void dumpEnergyConsumerStatsLocked(PrintWriter pw) { 15625 pw.printf("On-battery energy consumer stats (microcoulombs) \n"); 15626 if (mGlobalEnergyConsumerStats == null) { 15627 pw.printf(" Not supported on this device.\n"); 15628 return; 15629 } 15630 15631 dumpEnergyConsumerStatsLocked(pw, "global usage", mGlobalEnergyConsumerStats); 15632 15633 int size = mUidStats.size(); 15634 for (int i = 0; i < size; i++) { 15635 final int u = mUidStats.keyAt(i); 15636 final Uid uid = mUidStats.get(u); 15637 final String name = "uid " + uid.mUid; 15638 dumpEnergyConsumerStatsLocked(pw, name, uid.mUidEnergyConsumerStats); 15639 } 15640 } 15641 15642 /** Dump EnergyConsumer stats for the given uid */ 15643 @GuardedBy("this") 15644 private void dumpEnergyConsumerStatsLocked(PrintWriter pw, String name, 15645 EnergyConsumerStats stats) { 15646 if (stats == null) return; 15647 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 15648 iPw.increaseIndent(); 15649 iPw.printf("%s:\n", name); 15650 iPw.increaseIndent(); 15651 stats.dump(iPw); 15652 iPw.decreaseIndent(); 15653 } 15654 15655 /** 15656 * Dump Power Profile 15657 */ 15658 @GuardedBy("this") 15659 public void dumpPowerProfileLocked(PrintWriter pw) { 15660 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 15661 iPw.printf("Power Profile: \n"); 15662 iPw.increaseIndent(); 15663 mPowerProfile.dump(iPw); 15664 iPw.decreaseIndent(); 15665 } 15666 15667 private final Runnable mWriteAsyncRunnable = () -> { 15668 synchronized (BatteryStatsImpl.this) { 15669 writeSyncLocked(); 15670 } 15671 }; 15672 15673 @GuardedBy("this") 15674 public void writeAsyncLocked() { 15675 BackgroundThread.getHandler().removeCallbacks(mWriteAsyncRunnable); 15676 BackgroundThread.getHandler().post(mWriteAsyncRunnable); 15677 } 15678 15679 @GuardedBy("this") 15680 public void writeSyncLocked() { 15681 BackgroundThread.getHandler().removeCallbacks(mWriteAsyncRunnable); 15682 writeStatsLocked(); 15683 writeHistoryLocked(); 15684 } 15685 15686 @GuardedBy("this") 15687 private void writeStatsLocked() { 15688 if (mStatsFile == null) { 15689 Slog.w(TAG, 15690 "writeStatsLocked: no file associated with this instance"); 15691 return; 15692 } 15693 15694 if (mShuttingDown) { 15695 return; 15696 } 15697 15698 final Parcel p = Parcel.obtain(); 15699 try { 15700 final long start = SystemClock.uptimeMillis(); 15701 writeSummaryToParcel(p, false/*history is in separate file*/); 15702 if (DEBUG) { 15703 Slog.d(TAG, "writeSummaryToParcel duration ms:" 15704 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 15705 } 15706 mLastWriteTimeMs = mClock.elapsedRealtime(); 15707 writeParcelToFileLocked(p, mStatsFile); 15708 } finally { 15709 p.recycle(); 15710 } 15711 } 15712 15713 private void writeHistoryLocked() { 15714 if (mShuttingDown) { 15715 return; 15716 } 15717 15718 mHistory.writeHistory(); 15719 } 15720 15721 private final ReentrantLock mWriteLock = new ReentrantLock(); 15722 private void writeParcelToFileLocked(Parcel p, AtomicFile file) { 15723 mWriteLock.lock(); 15724 FileOutputStream fos = null; 15725 try { 15726 final long startTimeMs = SystemClock.uptimeMillis(); 15727 fos = file.startWrite(); 15728 fos.write(p.marshall()); 15729 fos.flush(); 15730 file.finishWrite(fos); 15731 if (DEBUG) { 15732 Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath() 15733 + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs) 15734 + " bytes:" + p.dataSize()); 15735 } 15736 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 15737 "batterystats", SystemClock.uptimeMillis() - startTimeMs); 15738 } catch (IOException e) { 15739 Slog.w(TAG, "Error writing battery statistics", e); 15740 file.failWrite(fos); 15741 } finally { 15742 mWriteLock.unlock(); 15743 } 15744 } 15745 15746 @GuardedBy("this") 15747 public void readLocked() { 15748 if (mDailyFile != null) { 15749 readDailyStatsLocked(); 15750 } 15751 15752 if (mStatsFile == null) { 15753 Slog.w(TAG, "readLocked: no file associated with this instance"); 15754 return; 15755 } 15756 15757 mUidStats.clear(); 15758 15759 Parcel stats = Parcel.obtain(); 15760 try { 15761 final long start = SystemClock.uptimeMillis(); 15762 if (mStatsFile.exists()) { 15763 byte[] raw = mStatsFile.readFully(); 15764 stats.unmarshall(raw, 0, raw.length); 15765 stats.setDataPosition(0); 15766 readSummaryFromParcel(stats); 15767 if (DEBUG) { 15768 Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath() 15769 + " bytes:" + raw.length + " took ms:" + (SystemClock.uptimeMillis() 15770 - start)); 15771 } 15772 } 15773 } catch (Exception e) { 15774 Slog.e(TAG, "Error reading battery statistics", e); 15775 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 15776 RESET_REASON_CORRUPT_FILE); 15777 } finally { 15778 stats.recycle(); 15779 } 15780 15781 if (!mHistory.readSummary()) { 15782 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 15783 RESET_REASON_CORRUPT_FILE); 15784 } 15785 15786 mEndPlatformVersion = Build.ID; 15787 15788 mHistory.continueRecordingHistory(); 15789 15790 recordDailyStatsIfNeededLocked(false, mClock.currentTimeMillis()); 15791 } 15792 15793 @GuardedBy("this") 15794 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 15795 final int version = in.readInt(); 15796 15797 if (version != VERSION) { 15798 Slog.w("BatteryStats", "readFromParcel: version got " + version 15799 + ", expected " + VERSION + "; erasing old stats"); 15800 return; 15801 } 15802 15803 mHistory.readSummaryFromParcel(in); 15804 15805 mStartCount = in.readInt(); 15806 mUptimeUs = in.readLong(); 15807 mRealtimeUs = in.readLong(); 15808 mStartClockTimeMs = in.readLong(); 15809 mStartPlatformVersion = in.readString(); 15810 mEndPlatformVersion = in.readString(); 15811 mOnBatteryTimeBase.readSummaryFromParcel(in); 15812 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 15813 mDischargeUnplugLevel = in.readInt(); 15814 mDischargePlugLevel = in.readInt(); 15815 mDischargeCurrentLevel = in.readInt(); 15816 mBatteryLevel = in.readInt(); 15817 mEstimatedBatteryCapacityMah = in.readInt(); 15818 mLastLearnedBatteryCapacityUah = in.readInt(); 15819 mMinLearnedBatteryCapacityUah = in.readInt(); 15820 mMaxLearnedBatteryCapacityUah = in.readInt(); 15821 mLowDischargeAmountSinceCharge = in.readInt(); 15822 mHighDischargeAmountSinceCharge = in.readInt(); 15823 mDischargeAmountScreenOnSinceCharge = in.readInt(); 15824 mDischargeAmountScreenOffSinceCharge = in.readInt(); 15825 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 15826 mDischargeStepTracker.readFromParcel(in); 15827 mChargeStepTracker.readFromParcel(in); 15828 mDailyDischargeStepTracker.readFromParcel(in); 15829 mDailyChargeStepTracker.readFromParcel(in); 15830 mDischargeCounter.readSummaryFromParcelLocked(in); 15831 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 15832 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in); 15833 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in); 15834 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in); 15835 int NPKG = in.readInt(); 15836 if (NPKG > 0) { 15837 mDailyPackageChanges = new ArrayList<>(NPKG); 15838 while (NPKG > 0) { 15839 NPKG--; 15840 PackageChange pc = new PackageChange(); 15841 pc.mPackageName = in.readString(); 15842 pc.mUpdate = in.readInt() != 0; 15843 pc.mVersionCode = in.readLong(); 15844 mDailyPackageChanges.add(pc); 15845 } 15846 } else { 15847 mDailyPackageChanges = null; 15848 } 15849 mDailyStartTimeMs = in.readLong(); 15850 mNextMinDailyDeadlineMs = in.readLong(); 15851 mNextMaxDailyDeadlineMs = in.readLong(); 15852 mBatteryTimeToFullSeconds = in.readLong(); 15853 15854 final EnergyConsumerStats.Config config = EnergyConsumerStats.Config.createFromParcel(in); 15855 final EnergyConsumerStats energyConsumerStats = 15856 EnergyConsumerStats.createAndReadSummaryFromParcel(mEnergyConsumerStatsConfig, in); 15857 if (config != null && Arrays.equals(config.getStateNames(), 15858 getBatteryConsumerProcessStateNames())) { 15859 /** 15860 * WARNING: Supported buckets may have changed across boots. Bucket mismatch is handled 15861 * later when {@link #initEnergyConsumerStatsLocked} is called. 15862 */ 15863 mEnergyConsumerStatsConfig = config; 15864 mGlobalEnergyConsumerStats = energyConsumerStats; 15865 } 15866 15867 mStartCount++; 15868 15869 mScreenState = Display.STATE_UNKNOWN; 15870 mScreenOnTimer.readSummaryFromParcelLocked(in); 15871 mScreenDozeTimer.readSummaryFromParcelLocked(in); 15872 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 15873 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 15874 } 15875 final int numDisplays = in.readInt(); 15876 for (int i = 0; i < numDisplays; i++) { 15877 mPerDisplayBatteryStats[i].readSummaryFromParcel(in); 15878 } 15879 mInteractive = false; 15880 mInteractiveTimer.readSummaryFromParcelLocked(in); 15881 mPhoneOn = false; 15882 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 15883 mLongestLightIdleTimeMs = in.readLong(); 15884 mLongestFullIdleTimeMs = in.readLong(); 15885 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 15886 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 15887 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 15888 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 15889 mPhoneOnTimer.readSummaryFromParcelLocked(in); 15890 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 15891 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 15892 } 15893 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 15894 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 15895 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 15896 } 15897 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 15898 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 15899 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 15900 } 15901 15902 final int numRat = in.readInt(); 15903 for (int i = 0; i < numRat; i++) { 15904 if (in.readInt() == 0) continue; 15905 getRatBatteryStatsLocked(i).readSummaryFromParcel(in); 15906 } 15907 15908 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 15909 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 15910 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 15911 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 15912 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 15913 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 15914 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in); 15915 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 15916 mWifiOn = false; 15917 mWifiOnTimer.readSummaryFromParcelLocked(in); 15918 mGlobalWifiRunning = false; 15919 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 15920 for (int i=0; i<NUM_WIFI_STATES; i++) { 15921 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 15922 } 15923 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15924 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 15925 } 15926 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15927 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 15928 } 15929 mWifiActiveTimer.readSummaryFromParcelLocked(in); 15930 mWifiActivity.readSummaryFromParcel(in); 15931 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 15932 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); 15933 } 15934 mBluetoothActivity.readSummaryFromParcel(in); 15935 mModemActivity.readSummaryFromParcel(in); 15936 mHasWifiReporting = in.readInt() != 0; 15937 mHasBluetoothReporting = in.readInt() != 0; 15938 mHasModemReporting = in.readInt() != 0; 15939 15940 mNumConnectivityChange = in.readInt(); 15941 mFlashlightOnNesting = 0; 15942 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 15943 mCameraOnNesting = 0; 15944 mCameraOnTimer.readSummaryFromParcelLocked(in); 15945 mBluetoothScanNesting = 0; 15946 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 15947 15948 int NRPMS = in.readInt(); 15949 if (NRPMS > 10000) { 15950 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 15951 } 15952 for (int irpm = 0; irpm < NRPMS; irpm++) { 15953 if (in.readInt() != 0) { 15954 String rpmName = in.readString(); 15955 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 15956 } 15957 } 15958 int NSORPMS = in.readInt(); 15959 if (NSORPMS > 10000) { 15960 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS); 15961 } 15962 for (int irpm = 0; irpm < NSORPMS; irpm++) { 15963 if (in.readInt() != 0) { 15964 String rpmName = in.readString(); 15965 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 15966 } 15967 } 15968 int NKW = in.readInt(); 15969 if (NKW > 10000) { 15970 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 15971 } 15972 for (int ikw = 0; ikw < NKW; ikw++) { 15973 if (in.readInt() != 0) { 15974 String kwltName = in.readString(); 15975 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 15976 } 15977 } 15978 15979 int NWR = in.readInt(); 15980 if (NWR > 10000) { 15981 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 15982 } 15983 for (int iwr = 0; iwr < NWR; iwr++) { 15984 if (in.readInt() != 0) { 15985 String reasonName = in.readString(); 15986 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 15987 } 15988 } 15989 15990 int NMS = in.readInt(); 15991 for (int ims = 0; ims < NMS; ims++) { 15992 if (in.readInt() != 0) { 15993 long kmstName = in.readLong(); 15994 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 15995 } 15996 } 15997 15998 final int NU = in.readInt(); 15999 if (NU > 10000) { 16000 throw new ParcelFormatException("File corrupt: too many uids " + NU); 16001 } 16002 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 16003 final long uptimeMs = mClock.uptimeMillis(); 16004 for (int iu = 0; iu < NU; iu++) { 16005 int uid = in.readInt(); 16006 Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 16007 mUidStats.put(uid, u); 16008 16009 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 16010 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 16011 16012 u.mWifiRunning = false; 16013 if (in.readInt() != 0) { 16014 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 16015 } 16016 u.mFullWifiLockOut = false; 16017 if (in.readInt() != 0) { 16018 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 16019 } 16020 u.mWifiScanStarted = false; 16021 if (in.readInt() != 0) { 16022 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 16023 } 16024 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 16025 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 16026 if (in.readInt() != 0) { 16027 u.makeWifiBatchedScanBin(i, null); 16028 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 16029 } 16030 } 16031 u.mWifiMulticastWakelockCount = 0; 16032 if (in.readInt() != 0) { 16033 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 16034 } 16035 if (in.readInt() != 0) { 16036 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16037 } 16038 if (in.readInt() != 0) { 16039 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16040 } 16041 if (in.readInt() != 0) { 16042 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16043 } 16044 if (in.readInt() != 0) { 16045 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 16046 } 16047 if (in.readInt() != 0) { 16048 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 16049 } 16050 if (in.readInt() != 0) { 16051 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 16052 } 16053 if (in.readInt() != 0) { 16054 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 16055 } 16056 if (in.readInt() != 0) { 16057 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 16058 } 16059 if (in.readInt() != 0) { 16060 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 16061 } 16062 if (in.readInt() != 0) { 16063 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 16064 } 16065 if (in.readInt() != 0) { 16066 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 16067 } 16068 u.mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 16069 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 16070 if (in.readInt() != 0) { 16071 u.makeProcessState(i, null); 16072 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 16073 } 16074 } 16075 if (in.readInt() != 0) { 16076 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 16077 } 16078 16079 if (in.readInt() != 0) { 16080 if (u.mUserActivityCounters == null) { 16081 u.initUserActivityLocked(); 16082 } 16083 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 16084 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 16085 } 16086 } 16087 16088 if (in.readInt() != 0) { 16089 u.ensureNetworkActivityLocked(); 16090 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16091 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 16092 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 16093 } 16094 if (in.readBoolean()) { 16095 u.mMobileRadioActiveTime = TimeMultiStateCounter.readFromParcel(in, 16096 mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 16097 elapsedRealtimeMs); 16098 } 16099 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 16100 } 16101 16102 u.mUserCpuTime.readSummaryFromParcelLocked(in); 16103 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 16104 16105 if (in.readInt() != 0) { 16106 final int numClusters = in.readInt(); 16107 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 16108 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 16109 } 16110 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 16111 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 16112 for (int cluster = 0; cluster < numClusters; cluster++) { 16113 if (in.readInt() != 0) { 16114 final int NSB = in.readInt(); 16115 if (mPowerProfile != null && 16116 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 16117 throw new ParcelFormatException("File corrupt: too many speed bins " + 16118 NSB); 16119 } 16120 16121 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 16122 for (int speed = 0; speed < NSB; speed++) { 16123 if (in.readInt() != 0) { 16124 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 16125 mOnBatteryTimeBase); 16126 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 16127 } 16128 } 16129 } else { 16130 u.mCpuClusterSpeedTimesUs[cluster] = null; 16131 } 16132 } 16133 } else { 16134 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 16135 u.mCpuClusterSpeedTimesUs = null; 16136 } 16137 16138 detachIfNotNull(u.mCpuFreqTimeMs); 16139 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 16140 in, mOnBatteryTimeBase); 16141 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 16142 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 16143 in, mOnBatteryScreenOffTimeBase); 16144 16145 int stateCount = in.readInt(); 16146 if (stateCount != 0) { 16147 u.mCpuActiveTimeMs = TimeMultiStateCounter.readFromParcel(in, 16148 mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 16149 mClock.elapsedRealtime()); 16150 } 16151 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 16152 16153 detachIfNotNull(u.mProcStateTimeMs); 16154 u.mProcStateTimeMs = null; 16155 16156 stateCount = in.readInt(); 16157 if (stateCount != 0) { 16158 detachIfNotNull(u.mProcStateTimeMs); 16159 u.mProcStateTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 16160 mOnBatteryTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 16161 getCpuFreqCount(), mClock.elapsedRealtime()); 16162 } 16163 16164 detachIfNotNull(u.mProcStateScreenOffTimeMs); 16165 u.mProcStateScreenOffTimeMs = null; 16166 16167 stateCount = in.readInt(); 16168 if (stateCount != 0) { 16169 detachIfNotNull(u.mProcStateScreenOffTimeMs); 16170 u.mProcStateScreenOffTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 16171 mOnBatteryScreenOffTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 16172 getCpuFreqCount(), mClock.elapsedRealtime()); 16173 } 16174 16175 if (in.readInt() != 0) { 16176 detachIfNotNull(u.mMobileRadioApWakeupCount); 16177 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 16178 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 16179 } else { 16180 detachIfNotNull(u.mMobileRadioApWakeupCount); 16181 u.mMobileRadioApWakeupCount = null; 16182 } 16183 16184 if (in.readInt() != 0) { 16185 detachIfNotNull(u.mWifiRadioApWakeupCount); 16186 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 16187 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 16188 } else { 16189 detachIfNotNull(u.mWifiRadioApWakeupCount); 16190 u.mWifiRadioApWakeupCount = null; 16191 } 16192 16193 u.mUidEnergyConsumerStats = EnergyConsumerStats.createAndReadSummaryFromParcel( 16194 mEnergyConsumerStatsConfig, in); 16195 16196 int NW = in.readInt(); 16197 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 16198 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 16199 } 16200 for (int iw = 0; iw < NW; iw++) { 16201 String wlName = in.readString(); 16202 u.readWakeSummaryFromParcelLocked(wlName, in); 16203 } 16204 16205 int NS = in.readInt(); 16206 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 16207 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 16208 } 16209 for (int is = 0; is < NS; is++) { 16210 String name = in.readString(); 16211 u.readSyncSummaryFromParcelLocked(name, in); 16212 } 16213 16214 int NJ = in.readInt(); 16215 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 16216 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 16217 } 16218 for (int ij = 0; ij < NJ; ij++) { 16219 String name = in.readString(); 16220 u.readJobSummaryFromParcelLocked(name, in); 16221 } 16222 16223 u.readJobCompletionsFromParcelLocked(in); 16224 16225 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 16226 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 16227 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 16228 detachIfNotNull(u.mJobsFreshnessBuckets); 16229 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 16230 if (in.readInt() != 0) { 16231 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 16232 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 16233 } 16234 } 16235 16236 int NP = in.readInt(); 16237 if (NP > 1000) { 16238 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 16239 } 16240 for (int is = 0; is < NP; is++) { 16241 int seNumber = in.readInt(); 16242 if (in.readInt() != 0) { 16243 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 16244 } 16245 } 16246 16247 NP = in.readInt(); 16248 if (NP > 10000) { 16249 throw new ParcelFormatException("File corrupt: too many processes " + NP); 16250 } 16251 for (int ip = 0; ip < NP; ip++) { 16252 String procName = in.readString(); 16253 Uid.Proc p = u.getProcessStatsLocked(procName); 16254 p.mUserTimeMs = in.readLong(); 16255 p.mSystemTimeMs = in.readLong(); 16256 p.mForegroundTimeMs = in.readLong(); 16257 p.mStarts = in.readInt(); 16258 p.mNumCrashes = in.readInt(); 16259 p.mNumAnrs = in.readInt(); 16260 p.readExcessivePowerFromParcelLocked(in); 16261 } 16262 16263 NP = in.readInt(); 16264 if (NP > 10000) { 16265 throw new ParcelFormatException("File corrupt: too many packages " + NP); 16266 } 16267 for (int ip = 0; ip < NP; ip++) { 16268 String pkgName = in.readString(); 16269 detachIfNotNull(u.mPackageStats.get(pkgName)); 16270 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 16271 final int NWA = in.readInt(); 16272 if (NWA > 10000) { 16273 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 16274 } 16275 p.mWakeupAlarms.clear(); 16276 for (int iwa = 0; iwa < NWA; iwa++) { 16277 String tag = in.readString(); 16278 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 16279 c.readSummaryFromParcelLocked(in); 16280 p.mWakeupAlarms.put(tag, c); 16281 } 16282 NS = in.readInt(); 16283 if (NS > 10000) { 16284 throw new ParcelFormatException("File corrupt: too many services " + NS); 16285 } 16286 for (int is = 0; is < NS; is++) { 16287 String servName = in.readString(); 16288 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 16289 s.mStartTimeMs = in.readLong(); 16290 s.mStarts = in.readInt(); 16291 s.mLaunches = in.readInt(); 16292 } 16293 } 16294 } 16295 16296 mBinderThreadCpuTimesUs = 16297 LongSamplingCounterArray.readSummaryFromParcelLocked(in, mOnBatteryTimeBase); 16298 } 16299 16300 /** 16301 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 16302 * disk. This format does not allow a lossless round-trip. 16303 * 16304 * @param out the Parcel to be written to. 16305 */ 16306 @GuardedBy("this") 16307 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 16308 pullPendingStateUpdatesLocked(); 16309 16310 // Pull the clock time. This may update the time and make a new history entry 16311 // if we had originally pulled a time before the RTC was set. 16312 getStartClockTime(); 16313 16314 final long nowUptime = mClock.uptimeMillis() * 1000; 16315 final long nowRealtime = mClock.elapsedRealtime() * 1000; 16316 16317 out.writeInt(VERSION); 16318 16319 mHistory.writeSummaryToParcel(out, inclHistory); 16320 16321 out.writeInt(mStartCount); 16322 out.writeLong(computeUptime(nowUptime, STATS_SINCE_CHARGED)); 16323 out.writeLong(computeRealtime(nowRealtime, STATS_SINCE_CHARGED)); 16324 out.writeLong(mStartClockTimeMs); 16325 out.writeString(mStartPlatformVersion); 16326 out.writeString(mEndPlatformVersion); 16327 mOnBatteryTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 16328 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 16329 out.writeInt(mDischargeUnplugLevel); 16330 out.writeInt(mDischargePlugLevel); 16331 out.writeInt(mDischargeCurrentLevel); 16332 out.writeInt(mBatteryLevel); 16333 out.writeInt(mEstimatedBatteryCapacityMah); 16334 out.writeInt(mLastLearnedBatteryCapacityUah); 16335 out.writeInt(mMinLearnedBatteryCapacityUah); 16336 out.writeInt(mMaxLearnedBatteryCapacityUah); 16337 out.writeInt(getLowDischargeAmountSinceCharge()); 16338 out.writeInt(getHighDischargeAmountSinceCharge()); 16339 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 16340 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 16341 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 16342 mDischargeStepTracker.writeToParcel(out); 16343 mChargeStepTracker.writeToParcel(out); 16344 mDailyDischargeStepTracker.writeToParcel(out); 16345 mDailyChargeStepTracker.writeToParcel(out); 16346 mDischargeCounter.writeSummaryFromParcelLocked(out); 16347 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 16348 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 16349 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 16350 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 16351 if (mDailyPackageChanges != null) { 16352 final int NPKG = mDailyPackageChanges.size(); 16353 out.writeInt(NPKG); 16354 for (int i=0; i<NPKG; i++) { 16355 PackageChange pc = mDailyPackageChanges.get(i); 16356 out.writeString(pc.mPackageName); 16357 out.writeInt(pc.mUpdate ? 1 : 0); 16358 out.writeLong(pc.mVersionCode); 16359 } 16360 } else { 16361 out.writeInt(0); 16362 } 16363 out.writeLong(mDailyStartTimeMs); 16364 out.writeLong(mNextMinDailyDeadlineMs); 16365 out.writeLong(mNextMaxDailyDeadlineMs); 16366 out.writeLong(mBatteryTimeToFullSeconds); 16367 16368 EnergyConsumerStats.Config.writeToParcel(mEnergyConsumerStatsConfig, out); 16369 EnergyConsumerStats.writeSummaryToParcel(mGlobalEnergyConsumerStats, out); 16370 16371 mScreenOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16372 mScreenDozeTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16373 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16374 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 16375 } 16376 final int numDisplays = mPerDisplayBatteryStats.length; 16377 out.writeInt(numDisplays); 16378 for (int i = 0; i < numDisplays; i++) { 16379 mPerDisplayBatteryStats[i].writeSummaryToParcel(out, nowRealtime); 16380 } 16381 mInteractiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16382 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16383 out.writeLong(mLongestLightIdleTimeMs); 16384 out.writeLong(mLongestFullIdleTimeMs); 16385 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16386 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16387 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16388 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16389 mPhoneOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16390 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 16391 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 16392 } 16393 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16394 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 16395 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 16396 } 16397 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16398 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 16399 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 16400 } 16401 final int numRat = mPerRatBatteryStats.length; 16402 out.writeInt(numRat); 16403 for (int i = 0; i < numRat; i++) { 16404 final RadioAccessTechnologyBatteryStats ratStat = mPerRatBatteryStats[i]; 16405 if (ratStat == null) { 16406 out.writeInt(0); 16407 continue; 16408 } 16409 out.writeInt(1); 16410 ratStat.writeSummaryToParcel(out, nowRealtime); 16411 } 16412 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16413 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16414 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 16415 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 16416 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 16417 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16418 mWifiOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16419 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16420 for (int i=0; i<NUM_WIFI_STATES; i++) { 16421 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 16422 } 16423 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 16424 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 16425 } 16426 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16427 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 16428 } 16429 mWifiActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16430 mWifiActivity.writeSummaryToParcel(out); 16431 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 16432 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 16433 } 16434 mBluetoothActivity.writeSummaryToParcel(out); 16435 mModemActivity.writeSummaryToParcel(out); 16436 out.writeInt(mHasWifiReporting ? 1 : 0); 16437 out.writeInt(mHasBluetoothReporting ? 1 : 0); 16438 out.writeInt(mHasModemReporting ? 1 : 0); 16439 16440 out.writeInt(mNumConnectivityChange); 16441 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16442 mCameraOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16443 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16444 16445 out.writeInt(mRpmStats.size()); 16446 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 16447 Timer rpmt = ent.getValue(); 16448 if (rpmt != null) { 16449 out.writeInt(1); 16450 out.writeString(ent.getKey()); 16451 rpmt.writeSummaryFromParcelLocked(out, nowRealtime); 16452 } else { 16453 out.writeInt(0); 16454 } 16455 } 16456 out.writeInt(mScreenOffRpmStats.size()); 16457 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 16458 Timer rpmt = ent.getValue(); 16459 if (rpmt != null) { 16460 out.writeInt(1); 16461 out.writeString(ent.getKey()); 16462 rpmt.writeSummaryFromParcelLocked(out, nowRealtime); 16463 } else { 16464 out.writeInt(0); 16465 } 16466 } 16467 16468 out.writeInt(mKernelWakelockStats.size()); 16469 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 16470 Timer kwlt = ent.getValue(); 16471 if (kwlt != null) { 16472 out.writeInt(1); 16473 out.writeString(ent.getKey()); 16474 kwlt.writeSummaryFromParcelLocked(out, nowRealtime); 16475 } else { 16476 out.writeInt(0); 16477 } 16478 } 16479 16480 out.writeInt(mWakeupReasonStats.size()); 16481 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 16482 SamplingTimer timer = ent.getValue(); 16483 if (timer != null) { 16484 out.writeInt(1); 16485 out.writeString(ent.getKey()); 16486 timer.writeSummaryFromParcelLocked(out, nowRealtime); 16487 } else { 16488 out.writeInt(0); 16489 } 16490 } 16491 16492 out.writeInt(mKernelMemoryStats.size()); 16493 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 16494 Timer kmt = mKernelMemoryStats.valueAt(i); 16495 if (kmt != null) { 16496 out.writeInt(1); 16497 out.writeLong(mKernelMemoryStats.keyAt(i)); 16498 kmt.writeSummaryFromParcelLocked(out, nowRealtime); 16499 } else { 16500 out.writeInt(0); 16501 } 16502 } 16503 16504 final int NU = mUidStats.size(); 16505 out.writeInt(NU); 16506 for (int iu = 0; iu < NU; iu++) { 16507 out.writeInt(mUidStats.keyAt(iu)); 16508 Uid u = mUidStats.valueAt(iu); 16509 16510 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 16511 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, nowUptime, 16512 nowRealtime); 16513 16514 if (u.mWifiRunningTimer != null) { 16515 out.writeInt(1); 16516 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16517 } else { 16518 out.writeInt(0); 16519 } 16520 if (u.mFullWifiLockTimer != null) { 16521 out.writeInt(1); 16522 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16523 } else { 16524 out.writeInt(0); 16525 } 16526 if (u.mWifiScanTimer != null) { 16527 out.writeInt(1); 16528 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16529 } else { 16530 out.writeInt(0); 16531 } 16532 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 16533 if (u.mWifiBatchedScanTimer[i] != null) { 16534 out.writeInt(1); 16535 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 16536 } else { 16537 out.writeInt(0); 16538 } 16539 } 16540 if (u.mWifiMulticastTimer != null) { 16541 out.writeInt(1); 16542 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16543 } else { 16544 out.writeInt(0); 16545 } 16546 if (u.mAudioTurnedOnTimer != null) { 16547 out.writeInt(1); 16548 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16549 } else { 16550 out.writeInt(0); 16551 } 16552 if (u.mVideoTurnedOnTimer != null) { 16553 out.writeInt(1); 16554 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16555 } else { 16556 out.writeInt(0); 16557 } 16558 if (u.mFlashlightTurnedOnTimer != null) { 16559 out.writeInt(1); 16560 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16561 } else { 16562 out.writeInt(0); 16563 } 16564 if (u.mCameraTurnedOnTimer != null) { 16565 out.writeInt(1); 16566 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16567 } else { 16568 out.writeInt(0); 16569 } 16570 if (u.mForegroundActivityTimer != null) { 16571 out.writeInt(1); 16572 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16573 } else { 16574 out.writeInt(0); 16575 } 16576 if (u.mForegroundServiceTimer != null) { 16577 out.writeInt(1); 16578 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16579 } else { 16580 out.writeInt(0); 16581 } 16582 if (u.mAggregatedPartialWakelockTimer != null) { 16583 out.writeInt(1); 16584 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16585 } else { 16586 out.writeInt(0); 16587 } 16588 if (u.mBluetoothScanTimer != null) { 16589 out.writeInt(1); 16590 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16591 } else { 16592 out.writeInt(0); 16593 } 16594 if (u.mBluetoothUnoptimizedScanTimer != null) { 16595 out.writeInt(1); 16596 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16597 } else { 16598 out.writeInt(0); 16599 } 16600 if (u.mBluetoothScanResultCounter != null) { 16601 out.writeInt(1); 16602 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 16603 } else { 16604 out.writeInt(0); 16605 } 16606 if (u.mBluetoothScanResultBgCounter != null) { 16607 out.writeInt(1); 16608 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 16609 } else { 16610 out.writeInt(0); 16611 } 16612 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 16613 if (u.mProcessStateTimer[i] != null) { 16614 out.writeInt(1); 16615 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 16616 } else { 16617 out.writeInt(0); 16618 } 16619 } 16620 if (u.mVibratorOnTimer != null) { 16621 out.writeInt(1); 16622 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16623 } else { 16624 out.writeInt(0); 16625 } 16626 16627 if (u.mUserActivityCounters == null) { 16628 out.writeInt(0); 16629 } else { 16630 out.writeInt(1); 16631 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 16632 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 16633 } 16634 } 16635 16636 if (u.mNetworkByteActivityCounters == null) { 16637 out.writeInt(0); 16638 } else { 16639 out.writeInt(1); 16640 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16641 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 16642 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 16643 } 16644 if (u.mMobileRadioActiveTime != null) { 16645 out.writeBoolean(true); 16646 u.mMobileRadioActiveTime.writeToParcel(out); 16647 } else { 16648 out.writeBoolean(false); 16649 } 16650 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 16651 } 16652 16653 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 16654 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 16655 16656 if (u.mCpuClusterSpeedTimesUs != null) { 16657 out.writeInt(1); 16658 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 16659 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 16660 if (cpuSpeeds != null) { 16661 out.writeInt(1); 16662 out.writeInt(cpuSpeeds.length); 16663 for (LongSamplingCounter c : cpuSpeeds) { 16664 if (c != null) { 16665 out.writeInt(1); 16666 c.writeSummaryFromParcelLocked(out); 16667 } else { 16668 out.writeInt(0); 16669 } 16670 } 16671 } else { 16672 out.writeInt(0); 16673 } 16674 } 16675 } else { 16676 out.writeInt(0); 16677 } 16678 16679 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 16680 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 16681 16682 if (u.mCpuActiveTimeMs != null) { 16683 out.writeInt(u.mCpuActiveTimeMs.getStateCount()); 16684 u.mCpuActiveTimeMs.writeToParcel(out); 16685 } else { 16686 out.writeInt(0); 16687 } 16688 16689 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 16690 16691 if (u.mProcStateTimeMs != null) { 16692 out.writeInt(u.mProcStateTimeMs.getStateCount()); 16693 u.mProcStateTimeMs.writeToParcel(out); 16694 } else { 16695 out.writeInt(0); 16696 } 16697 16698 if (u.mProcStateScreenOffTimeMs != null) { 16699 out.writeInt(u.mProcStateScreenOffTimeMs.getStateCount()); 16700 u.mProcStateScreenOffTimeMs.writeToParcel(out); 16701 } else { 16702 out.writeInt(0); 16703 } 16704 16705 if (u.mMobileRadioApWakeupCount != null) { 16706 out.writeInt(1); 16707 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 16708 } else { 16709 out.writeInt(0); 16710 } 16711 16712 if (u.mWifiRadioApWakeupCount != null) { 16713 out.writeInt(1); 16714 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 16715 } else { 16716 out.writeInt(0); 16717 } 16718 16719 EnergyConsumerStats.writeSummaryToParcel(u.mUidEnergyConsumerStats, out); 16720 16721 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 16722 int NW = wakeStats.size(); 16723 out.writeInt(NW); 16724 for (int iw=0; iw<NW; iw++) { 16725 out.writeString(wakeStats.keyAt(iw)); 16726 Uid.Wakelock wl = wakeStats.valueAt(iw); 16727 if (wl.mTimerFull != null) { 16728 out.writeInt(1); 16729 wl.mTimerFull.writeSummaryFromParcelLocked(out, nowRealtime); 16730 } else { 16731 out.writeInt(0); 16732 } 16733 if (wl.mTimerPartial != null) { 16734 out.writeInt(1); 16735 wl.mTimerPartial.writeSummaryFromParcelLocked(out, nowRealtime); 16736 } else { 16737 out.writeInt(0); 16738 } 16739 if (wl.mTimerWindow != null) { 16740 out.writeInt(1); 16741 wl.mTimerWindow.writeSummaryFromParcelLocked(out, nowRealtime); 16742 } else { 16743 out.writeInt(0); 16744 } 16745 if (wl.mTimerDraw != null) { 16746 out.writeInt(1); 16747 wl.mTimerDraw.writeSummaryFromParcelLocked(out, nowRealtime); 16748 } else { 16749 out.writeInt(0); 16750 } 16751 } 16752 16753 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 16754 int NS = syncStats.size(); 16755 out.writeInt(NS); 16756 for (int is=0; is<NS; is++) { 16757 out.writeString(syncStats.keyAt(is)); 16758 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, nowRealtime); 16759 } 16760 16761 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 16762 int NJ = jobStats.size(); 16763 out.writeInt(NJ); 16764 for (int ij=0; ij<NJ; ij++) { 16765 out.writeString(jobStats.keyAt(ij)); 16766 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, nowRealtime); 16767 } 16768 16769 u.writeJobCompletionsToParcelLocked(out); 16770 16771 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 16772 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 16773 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 16774 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 16775 if (u.mJobsFreshnessBuckets[i] != null) { 16776 out.writeInt(1); 16777 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 16778 } else { 16779 out.writeInt(0); 16780 } 16781 } 16782 16783 int NSE = u.mSensorStats.size(); 16784 out.writeInt(NSE); 16785 for (int ise=0; ise<NSE; ise++) { 16786 out.writeInt(u.mSensorStats.keyAt(ise)); 16787 Uid.Sensor se = u.mSensorStats.valueAt(ise); 16788 if (se.mTimer != null) { 16789 out.writeInt(1); 16790 se.mTimer.writeSummaryFromParcelLocked(out, nowRealtime); 16791 } else { 16792 out.writeInt(0); 16793 } 16794 } 16795 16796 int NP = u.mProcessStats.size(); 16797 out.writeInt(NP); 16798 for (int ip=0; ip<NP; ip++) { 16799 out.writeString(u.mProcessStats.keyAt(ip)); 16800 Uid.Proc ps = u.mProcessStats.valueAt(ip); 16801 out.writeLong(ps.mUserTimeMs); 16802 out.writeLong(ps.mSystemTimeMs); 16803 out.writeLong(ps.mForegroundTimeMs); 16804 out.writeInt(ps.mStarts); 16805 out.writeInt(ps.mNumCrashes); 16806 out.writeInt(ps.mNumAnrs); 16807 ps.writeExcessivePowerToParcelLocked(out); 16808 } 16809 16810 NP = u.mPackageStats.size(); 16811 out.writeInt(NP); 16812 if (NP > 0) { 16813 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 16814 : u.mPackageStats.entrySet()) { 16815 out.writeString(ent.getKey()); 16816 Uid.Pkg ps = ent.getValue(); 16817 final int NWA = ps.mWakeupAlarms.size(); 16818 out.writeInt(NWA); 16819 for (int iwa=0; iwa<NWA; iwa++) { 16820 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 16821 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 16822 } 16823 NS = ps.mServiceStats.size(); 16824 out.writeInt(NS); 16825 for (int is=0; is<NS; is++) { 16826 out.writeString(ps.mServiceStats.keyAt(is)); 16827 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 16828 long time = ss.getStartTimeToNowLocked( 16829 mOnBatteryTimeBase.getUptime(nowUptime) / 1000); 16830 out.writeLong(time); 16831 out.writeInt(ss.mStarts); 16832 out.writeInt(ss.mLaunches); 16833 } 16834 } 16835 } 16836 } 16837 16838 LongSamplingCounterArray.writeSummaryToParcelLocked(out, mBinderThreadCpuTimesUs); 16839 } 16840 16841 @GuardedBy("this") 16842 public void prepareForDumpLocked() { 16843 // Need to retrieve current kernel wake lock stats before printing. 16844 pullPendingStateUpdatesLocked(); 16845 16846 // Pull the clock time. This may update the time and make a new history entry 16847 // if we had originally pulled a time before the RTC was set. 16848 getStartClockTime(); 16849 16850 updateSystemServiceCallStats(); 16851 } 16852 16853 @GuardedBy("this") 16854 public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 16855 if (DEBUG) { 16856 pw.println("mOnBatteryTimeBase:"); 16857 mOnBatteryTimeBase.dump(pw, " "); 16858 pw.println("mOnBatteryScreenOffTimeBase:"); 16859 mOnBatteryScreenOffTimeBase.dump(pw, " "); 16860 Printer pr = new PrintWriterPrinter(pw); 16861 pr.println("*** Screen on timer:"); 16862 mScreenOnTimer.logState(pr, " "); 16863 pr.println("*** Screen doze timer:"); 16864 mScreenDozeTimer.logState(pr, " "); 16865 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16866 pr.println("*** Screen brightness #" + i + ":"); 16867 mScreenBrightnessTimer[i].logState(pr, " "); 16868 } 16869 pr.println("*** Interactive timer:"); 16870 mInteractiveTimer.logState(pr, " "); 16871 pr.println("*** Power save mode timer:"); 16872 mPowerSaveModeEnabledTimer.logState(pr, " "); 16873 pr.println("*** Device idle mode light timer:"); 16874 mDeviceIdleModeLightTimer.logState(pr, " "); 16875 pr.println("*** Device idle mode full timer:"); 16876 mDeviceIdleModeFullTimer.logState(pr, " "); 16877 pr.println("*** Device light idling timer:"); 16878 mDeviceLightIdlingTimer.logState(pr, " "); 16879 pr.println("*** Device idling timer:"); 16880 mDeviceIdlingTimer.logState(pr, " "); 16881 pr.println("*** Phone timer:"); 16882 mPhoneOnTimer.logState(pr, " "); 16883 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 16884 pr.println("*** Phone signal strength #" + i + ":"); 16885 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 16886 } 16887 pr.println("*** Signal scanning :"); 16888 mPhoneSignalScanningTimer.logState(pr, " "); 16889 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 16890 pr.println("*** Data connection type #" + i + ":"); 16891 mPhoneDataConnectionsTimer[i].logState(pr, " "); 16892 } 16893 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 16894 pr.println("*** Mobile network active timer:"); 16895 mMobileRadioActiveTimer.logState(pr, " "); 16896 pr.println("*** Mobile network active adjusted timer:"); 16897 mMobileRadioActiveAdjustedTime.logState(pr, " "); 16898 pr.println("*** Wifi Multicast WakeLock Timer:"); 16899 mWifiMulticastWakelockTimer.logState(pr, " "); 16900 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 16901 pr.println("*** Wifi timer:"); 16902 mWifiOnTimer.logState(pr, " "); 16903 pr.println("*** WifiRunning timer:"); 16904 mGlobalWifiRunningTimer.logState(pr, " "); 16905 for (int i=0; i<NUM_WIFI_STATES; i++) { 16906 pr.println("*** Wifi state #" + i + ":"); 16907 mWifiStateTimer[i].logState(pr, " "); 16908 } 16909 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 16910 pr.println("*** Wifi suppl state #" + i + ":"); 16911 mWifiSupplStateTimer[i].logState(pr, " "); 16912 } 16913 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16914 pr.println("*** Wifi signal strength #" + i + ":"); 16915 mWifiSignalStrengthsTimer[i].logState(pr, " "); 16916 } 16917 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 16918 pr.println("*** GPS signal quality #" + i + ":"); 16919 mGpsSignalQualityTimer[i].logState(pr, " "); 16920 } 16921 pr.println("*** Flashlight timer:"); 16922 mFlashlightOnTimer.logState(pr, " "); 16923 pr.println("*** Camera timer:"); 16924 mCameraOnTimer.logState(pr, " "); 16925 } 16926 super.dump(context, pw, flags, reqUid, histStart); 16927 16928 synchronized (this) { 16929 pw.print("Per process state tracking available: "); 16930 pw.println(trackPerProcStateCpuTimes()); 16931 pw.print("Total cpu time reads: "); 16932 pw.println(mNumSingleUidCpuTimeReads); 16933 pw.print("Batching Duration (min): "); 16934 pw.println((mClock.uptimeMillis() - mCpuTimeReadsTrackingStartTimeMs) / (60 * 1000)); 16935 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 16936 pw.println(mNumAllUidCpuTimeReads); 16937 pw.print("UIDs removed since the later of device start or stats reset: "); 16938 pw.println(mNumUidsRemoved); 16939 16940 pw.println("Currently mapped isolated uids:"); 16941 final int numIsolatedUids = mIsolatedUids.size(); 16942 for (int i = 0; i < numIsolatedUids; i++) { 16943 final int isolatedUid = mIsolatedUids.keyAt(i); 16944 final int ownerUid = mIsolatedUids.valueAt(i); 16945 final int refCount = mIsolatedUidRefCounts.get(isolatedUid); 16946 pw.println( 16947 " " + isolatedUid + "->" + ownerUid + " (ref count = " + refCount + ")"); 16948 } 16949 16950 pw.println(); 16951 dumpConstantsLocked(pw); 16952 16953 pw.println(); 16954 dumpCpuPowerBracketsLocked(pw); 16955 16956 pw.println(); 16957 dumpEnergyConsumerStatsLocked(pw); 16958 } 16959 } 16960 16961 @Override 16962 protected BatteryUsageStats getBatteryUsageStats(Context context, boolean detailed) { 16963 final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this); 16964 BatteryUsageStatsQuery.Builder builder = new BatteryUsageStatsQuery.Builder() 16965 .setMaxStatsAgeMs(0); 16966 if (detailed) { 16967 builder.includePowerModels().includeProcessStateData().includeVirtualUids(); 16968 } 16969 return provider.getBatteryUsageStats(builder.build()); 16970 } 16971 } 16972